PageSourceSearch

https://legumehub.eu/wp-content/plugins/is-legumehub-plugin/assets/dist/js/jquery-ui.js?ver=1787728486939

js legumehub.eu collected 2026-09-24 21:53:39 UTC 556,260 bytes, 18,707 lines download raw bytes

vendor: 21,959 bytes, lines 1-729
1/*! jQuery UI - v1.12.1 - 2016-09-14
2 * http://jqueryui.com
3 * Includes: widget.js, position.js, data.js, disable-selection.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.js, focusable.js, form-reset-mixin.js, jquery-1-7.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/draggable.js, widgets/droppable.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/resizable.js, widgets/selectable.js, widgets/selectmenu.js, widgets/slider.js, widgets/sortable.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js
4 * Copyright jQuery Foundation and other contributors; Licensed MIT */
5
6(function( factory ) {
7	if ( typeof define === "function" && define.amd ) {
8
9		// AMD. Register as an anonymous module.
10		define([ "jquery" ], factory );
11	} else {
12
13		// Browser globals
14		factory( jQuery );
15	}
16}(function( $ ) {
17
18	$.ui = $.ui || {};
19
20	var version = $.ui.version = "1.12.1";
21
22
23	/*!
24	 * jQuery UI Widget 1.12.1
25	 * http://jqueryui.com
26	 *
27	 * Copyright jQuery Foundation and other contributors
28	 * Released under the MIT license.
29	 * http://jquery.org/license
30	 */
31
32//>>label: Widget
33//>>group: Core
34//>>description: Provides a factory for creating stateful widgets with a common API.
35//>>docs: http://api.jqueryui.com/jQuery.widget/
36//>>demos: http://jqueryui.com/widget/
37
38
39
40	var widgetUuid = 0;
41	var widgetSlice = Array.prototype.slice;
42
43	$.cleanData = ( function( orig ) {
44		return function( elems ) {
45			var events, elem, i;
46			for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
47				try {
48
49					// Only trigger remove when necessary to save time
50					events = $._data( elem, "events" );
51					if ( events && events.remove ) {
52						$( elem ).triggerHandler( "remove" );
53					}
54
55					// Http://bugs.jquery.com/ticket/8235
56				} catch ( e ) {}
57			}
58			orig( elems );
59		};
60	} )( $.cleanData );
61
62	$.widget = function( name, base, prototype ) {
63		var existingConstructor, constructor, basePrototype;
64
65		// ProxiedPrototype allows the provided prototype to remain unmodified
66		// so that it can be used as a mixin for multiple widgets (#8876)
67		var proxiedPrototype = {};
68
69		var namespace = name.split( "." )[ 0 ];
70		name = name.split( "." )[ 1 ];
71		var fullName = namespace + "-" + name;
72
73		if ( !prototype ) {
74			prototype = base;
75			base = $.Widget;
76		}
77
78		if ( $.isArray( prototype ) ) {
79			prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
80		}
81
82		// Create selector for plugin
83		$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
84			return !!$.data( elem, fullName );
85		};
86
87		$[ namespace ] = $[ namespace ] || {};
88		existingConstructor = $[ namespace ][ name ];
89		constructor = $[ namespace ][ name ] = function( options, element ) {
90
91			// Allow instantiation without "new" keyword
92			if ( !this._createWidget ) {
93				return new constructor( options, element );
94			}
95
96			// Allow instantiation without initializing for simple inheritance
97			// must use "new" keyword (the code above always passes args)
98			if ( arguments.length ) {
99				this._createWidget( options, element );
100			}
101		};
102
103		// Extend with the existing constructor to carry over any static properties
104		$.extend( constructor, existingConstructor, {
105			version: prototype.version,
106
107			// Copy the object used to create the prototype in case we need to
108			// redefine the widget later
109			_proto: $.extend( {}, prototype ),
110
111			// Track widgets that inherit from this widget in case this widget is
112			// redefined after a widget inherits from it
113			_childConstructors: []
114		} );
115
116		basePrototype = new base();
117
118		// We need to make the options hash a property directly on the new instance
119		// otherwise we'll modify the options hash on the prototype that we're
120		// inheriting from
121		basePrototype.options = $.widget.extend( {}, basePrototype.options );
122		$.each( prototype, function( prop, value ) {
123			if ( !$.isFunction( value ) ) {
124				proxiedPrototype[ prop ] = value;
125				return;
126			}
127			proxiedPrototype[ prop ] = ( function() {
128				function _super() {
129					return base.prototype[ prop ].apply( this, arguments );
130				}
131
132				function _superApply( args ) {
133					return base.prototype[ prop ].apply( this, args );
134				}
135
136				return function() {
137					var __super = this._super;
138					var __superApply = this._superApply;
139					var returnValue;
140
141					this._super = _super;
142					this._superApply = _superApply;
143
144					returnValue = value.apply( this, arguments );
145
146					this._super = __super;
147					this._superApply = __superApply;
148
149					return returnValue;
150				};
151			} )();
152		} );
153		constructor.prototype = $.widget.extend( basePrototype, {
154
155			// TODO: remove support for widgetEventPrefix
156			// always use the name + a colon as the prefix, e.g., draggable:start
157			// don't prefix for widgets that aren't DOM-based
158			widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
159		}, proxiedPrototype, {
160			constructor: constructor,
161			namespace: namespace,
162			widgetName: name,
163			widgetFullName: fullName
164		} );
165
166		// If this widget is being redefined then we need to find all widgets that
167		// are inheriting from it and redefine all of them so that they inherit from
168		// the new version of this widget. We're essentially trying to replace one
169		// level in the prototype chain.
170		if ( existingConstructor ) {
171			$.each( existingConstructor._childConstructors, function( i, child ) {
172				var childPrototype = child.prototype;
173
174				// Redefine the child widget using the same prototype that was
175				// originally used, but inherit from the new version of the base
176				$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
177					child._proto );
178			} );
179
180			// Remove the list of existing child constructors from the old constructor
181			// so the old child constructors can be garbage collected
182			delete existingConstructor._childConstructors;
183		} else {
184			base._childConstructors.push( constructor );
185		}
186
187		$.widget.bridge( name, constructor );
188
189		return constructor;
190	};
191
192	$.widget.extend = function( target ) {
193		var input = widgetSlice.call( arguments, 1 );
194		var inputIndex = 0;
195		var inputLength = input.length;
196		var key;
197		var value;
198
199		for ( ; inputIndex < inputLength; inputIndex++ ) {
200			for ( key in input[ inputIndex ] ) {
201				value = input[ inputIndex ][ key ];
202				if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
203
204					// Clone objects
205					if ( $.isPlainObject( value ) ) {
206						target[ key ] = $.isPlainObject( target[ key ] ) ?
207							$.widget.extend( {}, target[ key ], value ) :
208
209							// Don't extend strings, arrays, etc. with objects
210							$.widget.extend( {}, value );
211
212						// Copy everything else by reference
213					} else {
214						target[ key ] = value;
215					}
216				}
217			}
218		}
219		return target;
220	};
221
222	$.widget.bridge = function( name, object ) {
223		var fullName = object.prototype.widgetFullName || name;
224		$.fn[ name ] = function( options ) {
225			var isMethodCall = typeof options === "string";
226			var args = widgetSlice.call( arguments, 1 );
227			var returnValue = this;
228
229			if ( isMethodCall ) {
230
231				// If this is an empty collection, we need to have the instance method
232				// return undefined instead of the jQuery instance
233				if ( !this.length && options === "instance" ) {
234					returnValue = undefined;
235				} else {
236					this.each( function() {
237						var methodValue;
238						var instance = $.data( this, fullName );
239
240						if ( options === "instance" ) {
241							returnValue = instance;
242							return false;
243						}
244
245						if ( !instance ) {
246							return $.error( "cannot call methods on " + name +
247								" prior to initialization; " +
248								"attempted to call method '" + options + "'" );
249						}
250
251						if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
252							return $.error( "no such method '" + options + "' for " + name +
253								" widget instance" );
254						}
255
256						methodValue = instance[ options ].apply( instance, args );
257
258						if ( methodValue !== instance && methodValue !== undefined ) {
259							returnValue = methodValue && methodValue.jquery ?
260								returnValue.pushStack( methodValue.get() ) :
261								methodValue;
262							return false;
263						}
264					} );
265				}
266			} else {
267
268				// Allow multiple hashes to be passed on init
269				if ( args.length ) {
270					options = $.widget.extend.apply( null, [ options ].concat( args ) );
271				}
272
273				this.each( function() {
274					var instance = $.data( this, fullName );
275					if ( instance ) {
276						instance.option( options || {} );
277						if ( instance._init ) {
278							instance._init();
279						}
280					} else {
281						$.data( this, fullName, new object( options, this ) );
282					}
283				} );
284			}
285
286			return returnValue;
287		};
288	};
289
290	$.Widget = function( /* options, element */ ) {};
291	$.Widget._childConstructors = [];
292
293	$.Widget.prototype = {
294		widgetName: "widget",
295		widgetEventPrefix: "",
296		defaultElement: "<div>",
297
298		options: {
299			classes: {},
300			disabled: false,
301
302			// Callbacks
303			create: null
304		},
305
306		_createWidget: function( options, element ) {
307			element = $( element || this.defaultElement || this )[ 0 ];
308			this.element = $( element );
309			this.uuid = widgetUuid++;
310			this.eventNamespace = "." + this.widgetName + this.uuid;
311
312			this.bindings = $();
313			this.hoverable = $();
314			this.focusable = $();
315			this.classesElementLookup = {};
316
317			if ( element !== this ) {
318				$.data( element, this.widgetFullName, this );
319				this._on( true, this.element, {
320					remove: function( event ) {
321						if ( event.target === element ) {
322							this.destroy();
323						}
324					}
325				} );
326				this.document = $( element.style ?
327
328					// Element within the document
329					element.ownerDocument :
330
331					// Element is window or document
332				element.document || element );
333				this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
334			}
335
336			this.options = $.widget.extend( {},
337				this.options,
338				this._getCreateOptions(),
339				options );
340
341			this._create();
342
343			if ( this.options.disabled ) {
344				this._setOptionDisabled( this.options.disabled );
345			}
346
347			this._trigger( "create", null, this._getCreateEventData() );
348			this._init();
349		},
350
351		_getCreateOptions: function() {
352			return {};
353		},
354
355		_getCreateEventData: $.noop,
356
357		_create: $.noop,
358
359		_init: $.noop,
360
361		destroy: function() {
362			var that = this;
363
364			this._destroy();
365			$.each( this.classesElementLookup, function( key, value ) {
366				that._removeClass( value, key );
367			} );
368
369			// We can probably remove the unbind calls in 2.0
370			// all event bindings should go through this._on()
371			this.element
372				.off( this.eventNamespace )
373				.removeData( this.widgetFullName );
374			this.widget()
375				.off( this.eventNamespace )
376				.removeAttr( "aria-disabled" );
377
378			// Clean up events and states
379			this.bindings.off( this.eventNamespace );
380		},
381
382		_destroy: $.noop,
383
384		widget: function() {
385			return this.element;
386		},
387
388		option: function( key, value ) {
389			var options = key;
390			var parts;
391			var curOption;
392			var i;
393
394			if ( arguments.length === 0 ) {
395
396				// Don't return a reference to the internal hash
397				return $.widget.extend( {}, this.options );
398			}
399
400			if ( typeof key === "string" ) {
401
402				// Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
403				options = {};
404				parts = key.split( "." );
405				key = parts.shift();
406				if ( parts.length ) {
407					curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
408					for ( i = 0; i < parts.length - 1; i++ ) {
409						curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
410						curOption = curOption[ parts[ i ] ];
411					}
412					key = parts.pop();
413					if ( arguments.length === 1 ) {
414						return curOption[ key ] === undefined ? null : curOption[ key ];
415					}
416					curOption[ key ] = value;
417				} else {
418					if ( arguments.length === 1 ) {
419						return this.options[ key ] === undefined ? null : this.options[ key ];
420					}
421					options[ key ] = value;
422				}
423			}
424
425			this._setOptions( options );
426
427			return this;
428		},
429
430		_setOptions: function( options ) {
431			var key;
432
433			for ( key in options ) {
434				this._setOption( key, options[ key ] );
435			}
436
437			return this;
438		},
439
440		_setOption: function( key, value ) {
441			if ( key === "classes" ) {
442				this._setOptionClasses( value );
443			}
444
445			this.options[ key ] = value;
446
447			if ( key === "disabled" ) {
448				this._setOptionDisabled( value );
449			}
450
451			return this;
452		},
453
454		_setOptionClasses: function( value ) {
455			var classKey, elements, currentElements;
456
457			for ( classKey in value ) {
458				currentElements = this.classesElementLookup[ classKey ];
459				if ( value[ classKey ] === this.options.classes[ classKey ] ||
460					!currentElements ||
461					!currentElements.length ) {
462					continue;
463				}
464
465				// We are doing this to create a new jQuery object because the _removeClass() call
466				// on the next line is going to destroy the reference to the current elements being
467				// tracked. We need to save a copy of this collection so that we can add the new classes
468				// below.
469				elements = $( currentElements.get() );
470				this._removeClass( currentElements, classKey );
471
472				// We don't use _addClass() here, because that uses this.options.classes
473				// for generating the string of classes. We want to use the value passed in from
474				// _setOption(), this is the new value of the classes option which was passed to
475				// _setOption(). We pass this value directly to _classes().
476				elements.addClass( this._classes( {
477					element: elements,
478					keys: classKey,
479					classes: value,
480					add: true
481				} ) );
482			}
483		},
484
485		_setOptionDisabled: function( value ) {
486			this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
487
488			// If the widget is becoming disabled, then nothing is interactive
489			if ( value ) {
490				this._removeClass( this.hoverable, null, "ui-state-hover" );
491				this._removeClass( this.focusable, null, "ui-state-focus" );
492			}
493		},
494
495		enable: function() {
496			return this._setOptions( { disabled: false } );
497		},
498
499		disable: function() {
500			return this._setOptions( { disabled: true } );
501		},
502
503		_classes: function( options ) {
504			var full = [];
505			var that = this;
506
507			options = $.extend( {
508				element: this.element,
509				classes: this.options.classes || {}
510			}, options );
511
512			function processClassString( classes, checkOption ) {
513				var current, i;
514				for ( i = 0; i < classes.length; i++ ) {
515					current = that.classesElementLookup[ classes[ i ] ] || $();
516					if ( options.add ) {
517						current = $( $.unique( current.get().concat( options.element.get() ) ) );
518					} else {
519						current = $( current.not( options.element ).get() );
520					}
521					that.classesElementLookup[ classes[ i ] ] = current;
522					full.push( classes[ i ] );
523					if ( checkOption && options.classes[ classes[ i ] ] ) {
524						full.push( options.classes[ classes[ i ] ] );
525					}
526				}
527			}
528
529			this._on( options.element, {
530				"remove": "_untrackClassesElement"
531			} );
532
533			if ( options.keys ) {
534				processClassString( options.keys.match( /\S+/g ) || [], true );
535			}
536			if ( options.extra ) {
537				processClassString( options.extra.match( /\S+/g ) || [] );
538			}
539
540			return full.join( " " );
541		},
542
543		_untrackClassesElement: function( event ) {
544			var that = this;
545			$.each( that.classesElementLookup, function( key, value ) {
546				if ( $.inArray( event.target, value ) !== -1 ) {
547					that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
548				}
549			} );
550		},
551
552		_removeClass: function( element, keys, extra ) {
553			return this._toggleClass( element, keys, extra, false );
554		},
555
556		_addClass: function( element, keys, extra ) {
557			return this._toggleClass( element, keys, extra, true );
558		},
559
560		_toggleClass: function( element, keys, extra, add ) {
561			add = ( typeof add === "boolean" ) ? add : extra;
562			var shift = ( typeof element === "string" || element === null ),
563				options = {
564					extra: shift ? keys : extra,
565					keys: shift ? element : keys,
566					element: shift ? this.element : element,
567					add: add
568				};
569			options.element.toggleClass( this._classes( options ), add );
570			return this;
571		},
572
573		_on: function( suppressDisabledCheck, element, handlers ) {
574			var delegateElement;
575			var instance = this;
576
577			// No suppressDisabledCheck flag, shuffle arguments
578			if ( typeof suppressDisabledCheck !== "boolean" ) {
579				handlers = element;
580				element = suppressDisabledCheck;
581				suppressDisabledCheck = false;
582			}
583
584			// No element argument, shuffle and use this.element
585			if ( !handlers ) {
586				handlers = element;
587				element = this.element;
588				delegateElement = this.widget();
589			} else {
590				element = delegateElement = $( element );
591				this.bindings = this.bindings.add( element );
592			}
593
594			$.each( handlers, function( event, handler ) {
595				function handlerProxy() {
596
597					// Allow widgets to customize the disabled handling
598					// - disabled as an array instead of boolean
599					// - disabled class as method for disabling individual parts
600					if ( !suppressDisabledCheck &&
601						( instance.options.disabled === true ||
602						$( this ).hasClass( "ui-state-disabled" ) ) ) {
603						return;
604					}
605					return ( typeof handler === "string" ? instance[ handler ] : handler )
606						.apply( instance, arguments );
607				}
608
609				// Copy the guid so direct unbinding works
610				if ( typeof handler !== "string" ) {
611					handlerProxy.guid = handler.guid =
612						handler.guid || handlerProxy.guid || $.guid++;
613				}
614
615				var match = event.match( /^([\w:-]*)\s*(.*)$/ );
616				var eventName = match[ 1 ] + instance.eventNamespace;
617				var selector = match[ 2 ];
618
619				if ( selector ) {
620					delegateElement.on( eventName, selector, handlerProxy );
621				} else {
622					element.on( eventName, handlerProxy );
623				}
624			} );
625		},
626
627		_off: function( element, eventName ) {
628			eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
629				this.eventNamespace;
630			element.off( eventName ).off( eventName );
631
632			// Clear the stack to avoid memory leaks (#10056)
633			this.bindings = $( this.bindings.not( element ).get() );
634			this.focusable = $( this.focusable.not( element ).get() );
635			this.hoverable = $( this.hoverable.not( element ).get() );
636		},
637
638		_delay: function( handler, delay ) {
639			function handlerProxy() {
640				return ( typeof handler === "string" ? instance[ handler ] : handler )
641					.apply( instance, arguments );
642			}
643			var instance = this;
644			return setTimeout( handlerProxy, delay || 0 );
645		},
646
647		_hoverable: function( element ) {
648			this.hoverable = this.hoverable.add( element );
649			this._on( element, {
650				mouseenter: function( event ) {
651					this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
652				},
653				mouseleave: function( event ) {
654					this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
655				}
656			} );
657		},
658
659		_focusable: function( element ) {
660			this.focusable = this.focusable.add( element );
661			this._on( element, {
662				focusin: function( event ) {
663					this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
664				},
665				focusout: function( event ) {
666					this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
667				}
668			} );
669		},
670
671		_trigger: function( type, event, data ) {
672			var prop, orig;
673			var callback = this.options[ type ];
674
675			data = data || {};
676			event = $.Event( event );
677			event.type = ( type === this.widgetEventPrefix ?
678				type :
679			this.widgetEventPrefix + type ).toLowerCase();
680
681			// The original event may come from any element
682			// so we need to reset the target on the new event
683			event.target = this.element[ 0 ];
684
685			// Copy original event properties over to the new event
686			orig = event.originalEvent;
687			if ( orig ) {
688				for ( prop in orig ) {
689					if ( !( prop in event ) ) {
690						event[ prop ] = orig[ prop ];
691					}
692				}
693			}
694
695			this.element.trigger( event, data );
696			return !( $.isFunction( callback ) &&
697			callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
698			event.isDefaultPrevented() );
699		}
700	};
701
702	$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
703		$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
704			if ( typeof options === "string" ) {
705				options = { effect: options };
706			}
707
708			var hasOptions;
709			var effectName = !options ?
710				method :
711				options === true || typeof options === "number" ?
712					defaultEffect :
713				options.effect || defaultEffect;
714
715			options = options || {};
716			if ( typeof options === "number" ) {
717				options = { duration: options };
718			}
719
720			hasOptions = !$.isEmptyObject( options );
721			options.complete = callback;
722
723			if ( options.delay ) {
724				element.delay( options.delay );
725			}
726
727			if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
728				element[ method ]( options );
729			} else if ( effectName !== method && element[ effectName ] ) {
vendor: 5,262 bytes, lines 730-909
730				element[ effectName ]( options.duration, options.easing, callback );
731			} else {
732				element.queue( function( next ) {
733					$( this )[ method ]();
734					if ( callback ) {
735						callback.call( element[ 0 ] );
736					}
737					next();
738				} );
739			}
740		};
741	} );
742
743	var widget = $.widget;
744
745
746	/*!
747	 * jQuery UI Position 1.12.1
748	 * http://jqueryui.com
749	 *
750	 * Copyright jQuery Foundation and other contributors
751	 * Released under the MIT license.
752	 * http://jquery.org/license
753	 *
754	 * http://api.jqueryui.com/position/
755	 */
756
757//>>label: Position
758//>>group: Core
759//>>description: Positions elements relative to other elements.
760//>>docs: http://api.jqueryui.com/position/
761//>>demos: http://jqueryui.com/position/
762
763
764	( function() {
765		var cachedScrollbarWidth,
766			max = Math.max,
767			abs = Math.abs,
768			rhorizontal = /left|center|right/,
769			rvertical = /top|center|bottom/,
770			roffset = /[\+\-]\d+(\.[\d]+)?%?/,
771			rposition = /^\w+/,
772			rpercent = /%$/,
773			_position = $.fn.position;
774
775		function getOffsets( offsets, width, height ) {
776			return [
777				parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
778				parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
779			];
780		}
781
782		function parseCss( element, property ) {
783			return parseInt( $.css( element, property ), 10 ) || 0;
784		}
785
786		function getDimensions( elem ) {
787			var raw = elem[ 0 ];
788			if ( raw.nodeType === 9 ) {
789				return {
790					width: elem.width(),
791					height: elem.height(),
792					offset: { top: 0, left: 0 }
793				};
794			}
795			if ( $.isWindow( raw ) ) {
796				return {
797					width: elem.width(),
798					height: elem.height(),
799					offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
800				};
801			}
802			if ( raw.preventDefault ) {
803				return {
804					width: 0,
805					height: 0,
806					offset: { top: raw.pageY, left: raw.pageX }
807				};
808			}
809			return {
810				width: elem.outerWidth(),
811				height: elem.outerHeight(),
812				offset: elem.offset()
813			};
814		}
815
816		$.position = {
817			scrollbarWidth: function() {
818				if ( cachedScrollbarWidth !== undefined ) {
819					return cachedScrollbarWidth;
820				}
821				var w1, w2,
822					div = $( "<div " +
823						"style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>" +
824						"<div style='height:100px;width:auto;'></div></div>" ),
825					innerDiv = div.children()[ 0 ];
826
827				$( "body" ).append( div );
828				w1 = innerDiv.offsetWidth;
829				div.css( "overflow", "scroll" );
830
831				w2 = innerDiv.offsetWidth;
832
833				if ( w1 === w2 ) {
834					w2 = div[ 0 ].clientWidth;
835				}
836
837				div.remove();
838
839				return ( cachedScrollbarWidth = w1 - w2 );
840			},
841			getScrollInfo: function( within ) {
842				var overflowX = within.isWindow || within.isDocument ? "" :
843						within.element.css( "overflow-x" ),
844					overflowY = within.isWindow || within.isDocument ? "" :
845						within.element.css( "overflow-y" ),
846					hasOverflowX = overflowX === "scroll" ||
847						( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ),
848					hasOverflowY = overflowY === "scroll" ||
849						( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight );
850				return {
851					width: hasOverflowY ? $.position.scrollbarWidth() : 0,
852					height: hasOverflowX ? $.position.scrollbarWidth() : 0
853				};
854			},
855			getWithinInfo: function( element ) {
856				var withinElement = $( element || window ),
857					isWindow = $.isWindow( withinElement[ 0 ] ),
858					isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,
859					hasOffset = !isWindow && !isDocument;
860				return {
861					element: withinElement,
862					isWindow: isWindow,
863					isDocument: isDocument,
864					offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },
865					scrollLeft: withinElement.scrollLeft(),
866					scrollTop: withinElement.scrollTop(),
867					width: withinElement.outerWidth(),
868					height: withinElement.outerHeight()
869				};
870			}
871		};
872
873		$.fn.position = function( options ) {
874			if ( !options || !options.of ) {
875				return _position.apply( this, arguments );
876			}
877
878			// Make a copy, we don't want to modify arguments
879			options = $.extend( {}, options );
880
881			var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
882				target = $( options.of ),
883				within = $.position.getWithinInfo( options.within ),
884				scrollInfo = $.position.getScrollInfo( within ),
885				collision = ( options.collision || "flip" ).split( " " ),
886				offsets = {};
887
888			dimensions = getDimensions( target );
889			if ( target[ 0 ].preventDefault ) {
890
891				// Force left top to allow flipping
892				options.at = "left top";
893			}
894			targetWidth = dimensions.width;
895			targetHeight = dimensions.height;
896			targetOffset = dimensions.offset;
897
898			// Clone to reuse original targetOffset later
899			basePosition = $.extend( {}, targetOffset );
900
901			// Force my and at to have valid horizontal and vertical positions
902			// if a value is missing or invalid, it will be converted to center
903			$.each( [ "my", "at" ], function() {
904				var pos = ( options[ this ] || "" ).split( " " ),
905					horizontalOffset,
906					verticalOffset;
907
908				if ( pos.length === 1 ) {
909					pos = rhorizontal.test( pos[ 0 ] ) ?
vendor: 11,072 bytes, lines 910-1236
910						pos.concat( [ "center" ] ) :
911						rvertical.test( pos[ 0 ] ) ?
912							[ "center" ].concat( pos ) :
913							[ "center", "center" ];
914				}
915				pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
916				pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
917
918				// Calculate offsets
919				horizontalOffset = roffset.exec( pos[ 0 ] );
920				verticalOffset = roffset.exec( pos[ 1 ] );
921				offsets[ this ] = [
922					horizontalOffset ? horizontalOffset[ 0 ] : 0,
923					verticalOffset ? verticalOffset[ 0 ] : 0
924				];
925
926				// Reduce to just the positions without the offsets
927				options[ this ] = [
928					rposition.exec( pos[ 0 ] )[ 0 ],
929					rposition.exec( pos[ 1 ] )[ 0 ]
930				];
931			} );
932
933			// Normalize collision option
934			if ( collision.length === 1 ) {
935				collision[ 1 ] = collision[ 0 ];
936			}
937
938			if ( options.at[ 0 ] === "right" ) {
939				basePosition.left += targetWidth;
940			} else if ( options.at[ 0 ] === "center" ) {
941				basePosition.left += targetWidth / 2;
942			}
943
944			if ( options.at[ 1 ] === "bottom" ) {
945				basePosition.top += targetHeight;
946			} else if ( options.at[ 1 ] === "center" ) {
947				basePosition.top += targetHeight / 2;
948			}
949
950			atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
951			basePosition.left += atOffset[ 0 ];
952			basePosition.top += atOffset[ 1 ];
953
954			return this.each( function() {
955				var collisionPosition, using,
956					elem = $( this ),
957					elemWidth = elem.outerWidth(),
958					elemHeight = elem.outerHeight(),
959					marginLeft = parseCss( this, "marginLeft" ),
960					marginTop = parseCss( this, "marginTop" ),
961					collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) +
962						scrollInfo.width,
963					collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) +
964						scrollInfo.height,
965					position = $.extend( {}, basePosition ),
966					myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
967
968				if ( options.my[ 0 ] === "right" ) {
969					position.left -= elemWidth;
970				} else if ( options.my[ 0 ] === "center" ) {
971					position.left -= elemWidth / 2;
972				}
973
974				if ( options.my[ 1 ] === "bottom" ) {
975					position.top -= elemHeight;
976				} else if ( options.my[ 1 ] === "center" ) {
977					position.top -= elemHeight / 2;
978				}
979
980				position.left += myOffset[ 0 ];
981				position.top += myOffset[ 1 ];
982
983				collisionPosition = {
984					marginLeft: marginLeft,
985					marginTop: marginTop
986				};
987
988				$.each( [ "left", "top" ], function( i, dir ) {
989					if ( $.ui.position[ collision[ i ] ] ) {
990						$.ui.position[ collision[ i ] ][ dir ]( position, {
991							targetWidth: targetWidth,
992							targetHeight: targetHeight,
993							elemWidth: elemWidth,
994							elemHeight: elemHeight,
995							collisionPosition: collisionPosition,
996							collisionWidth: collisionWidth,
997							collisionHeight: collisionHeight,
998							offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
999							my: options.my,
1000							at: options.at,
1001							within: within,
1002							elem: elem
1003						} );
1004					}
1005				} );
1006
1007				if ( options.using ) {
1008
1009					// Adds feedback as second argument to using callback, if present
1010					using = function( props ) {
1011						var left = targetOffset.left - position.left,
1012							right = left + targetWidth - elemWidth,
1013							top = targetOffset.top - position.top,
1014							bottom = top + targetHeight - elemHeight,
1015							feedback = {
1016								target: {
1017									element: target,
1018									left: targetOffset.left,
1019									top: targetOffset.top,
1020									width: targetWidth,
1021									height: targetHeight
1022								},
1023								element: {
1024									element: elem,
1025									left: position.left,
1026									top: position.top,
1027									width: elemWidth,
1028									height: elemHeight
1029								},
1030								horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1031								vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1032							};
1033						if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1034							feedback.horizontal = "center";
1035						}
1036						if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1037							feedback.vertical = "middle";
1038						}
1039						if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1040							feedback.important = "horizontal";
1041						} else {
1042							feedback.important = "vertical";
1043						}
1044						options.using.call( this, props, feedback );
1045					};
1046				}
1047
1048				elem.offset( $.extend( position, { using: using } ) );
1049			} );
1050		};
1051
1052		$.ui.position = {
1053			fit: {
1054				left: function( position, data ) {
1055					var within = data.within,
1056						withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1057						outerWidth = within.width,
1058						collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1059						overLeft = withinOffset - collisionPosLeft,
1060						overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1061						newOverRight;
1062
1063					// Element is wider than within
1064					if ( data.collisionWidth > outerWidth ) {
1065
1066						// Element is initially over the left side of within
1067						if ( overLeft > 0 && overRight <= 0 ) {
1068							newOverRight = position.left + overLeft + data.collisionWidth - outerWidth -
1069								withinOffset;
1070							position.left += overLeft - newOverRight;
1071
1072							// Element is initially over right side of within
1073						} else if ( overRight > 0 && overLeft <= 0 ) {
1074							position.left = withinOffset;
1075
1076							// Element is initially over both left and right sides of within
1077						} else {
1078							if ( overLeft > overRight ) {
1079								position.left = withinOffset + outerWidth - data.collisionWidth;
1080							} else {
1081								position.left = withinOffset;
1082							}
1083						}
1084
1085						// Too far left -> align with left edge
1086					} else if ( overLeft > 0 ) {
1087						position.left += overLeft;
1088
1089						// Too far right -> align with right edge
1090					} else if ( overRight > 0 ) {
1091						position.left -= overRight;
1092
1093						// Adjust based on position and margin
1094					} else {
1095						position.left = max( position.left - collisionPosLeft, position.left );
1096					}
1097				},
1098				top: function( position, data ) {
1099					var within = data.within,
1100						withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1101						outerHeight = data.within.height,
1102						collisionPosTop = position.top - data.collisionPosition.marginTop,
1103						overTop = withinOffset - collisionPosTop,
1104						overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1105						newOverBottom;
1106
1107					// Element is taller than within
1108					if ( data.collisionHeight > outerHeight ) {
1109
1110						// Element is initially over the top of within
1111						if ( overTop > 0 && overBottom <= 0 ) {
1112							newOverBottom = position.top + overTop + data.collisionHeight - outerHeight -
1113								withinOffset;
1114							position.top += overTop - newOverBottom;
1115
1116							// Element is initially over bottom of within
1117						} else if ( overBottom > 0 && overTop <= 0 ) {
1118							position.top = withinOffset;
1119
1120							// Element is initially over both top and bottom of within
1121						} else {
1122							if ( overTop > overBottom ) {
1123								position.top = withinOffset + outerHeight - data.collisionHeight;
1124							} else {
1125								position.top = withinOffset;
1126							}
1127						}
1128
1129						// Too far up -> align with top
1130					} else if ( overTop > 0 ) {
1131						position.top += overTop;
1132
1133						// Too far down -> align with bottom edge
1134					} else if ( overBottom > 0 ) {
1135						position.top -= overBottom;
1136
1137						// Adjust based on position and margin
1138					} else {
1139						position.top = max( position.top - collisionPosTop, position.top );
1140					}
1141				}
1142			},
1143			flip: {
1144				left: function( position, data ) {
1145					var within = data.within,
1146						withinOffset = within.offset.left + within.scrollLeft,
1147						outerWidth = within.width,
1148						offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1149						collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1150						overLeft = collisionPosLeft - offsetLeft,
1151						overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1152						myOffset = data.my[ 0 ] === "left" ?
1153							-data.elemWidth :
1154							data.my[ 0 ] === "right" ?
1155								data.elemWidth :
1156								0,
1157						atOffset = data.at[ 0 ] === "left" ?
1158							data.targetWidth :
1159							data.at[ 0 ] === "right" ?
1160								-data.targetWidth :
1161								0,
1162						offset = -2 * data.offset[ 0 ],
1163						newOverRight,
1164						newOverLeft;
1165
1166					if ( overLeft < 0 ) {
1167						newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -
1168							outerWidth - withinOffset;
1169						if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1170							position.left += myOffset + atOffset + offset;
1171						}
1172					} else if ( overRight > 0 ) {
1173						newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +
1174							atOffset + offset - offsetLeft;
1175						if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1176							position.left += myOffset + atOffset + offset;
1177						}
1178					}
1179				},
1180				top: function( position, data ) {
1181					var within = data.within,
1182						withinOffset = within.offset.top + within.scrollTop,
1183						outerHeight = within.height,
1184						offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1185						collisionPosTop = position.top - data.collisionPosition.marginTop,
1186						overTop = collisionPosTop - offsetTop,
1187						overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1188						top = data.my[ 1 ] === "top",
1189						myOffset = top ?
1190							-data.elemHeight :
1191							data.my[ 1 ] === "bottom" ?
1192								data.elemHeight :
1193								0,
1194						atOffset = data.at[ 1 ] === "top" ?
1195							data.targetHeight :
1196							data.at[ 1 ] === "bottom" ?
1197								-data.targetHeight :
1198								0,
1199						offset = -2 * data.offset[ 1 ],
1200						newOverTop,
1201						newOverBottom;
1202					if ( overTop < 0 ) {
1203						newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -
1204							outerHeight - withinOffset;
1205						if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
1206							position.top += myOffset + atOffset + offset;
1207						}
1208					} else if ( overBottom > 0 ) {
1209						newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +
1210							offset - offsetTop;
1211						if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
1212							position.top += myOffset + atOffset + offset;
1213						}
1214					}
1215				}
1216			},
1217			flipfit: {
1218				left: function() {
1219					$.ui.position.flip.left.apply( this, arguments );
1220					$.ui.position.fit.left.apply( this, arguments );
1221				},
1222				top: function() {
1223					$.ui.position.flip.top.apply( this, arguments );
1224					$.ui.position.fit.top.apply( this, arguments );
1225				}
1226			}
1227		};
1228
1229	} )();
1230
1231	var position = $.ui.position;
1232
1233
1234	/*!
1235	 * jQuery UI :data 1.12.1
1236	 * http://jqueryui.com
vendor: 5,748 bytes, lines 1237-1466
1237	 *
1238	 * Copyright jQuery Foundation and other contributors
1239	 * Released under the MIT license.
1240	 * http://jquery.org/license
1241	 */
1242
1243//>>label: :data Selector
1244//>>group: Core
1245//>>description: Selects elements which have data stored under the specified key.
1246//>>docs: http://api.jqueryui.com/data-selector/
1247
1248
1249	var data = $.extend( $.expr[ ":" ], {
1250		data: $.expr.createPseudo ?
1251			$.expr.createPseudo( function( dataName ) {
1252				return function( elem ) {
1253					return !!$.data( elem, dataName );
1254				};
1255			} ) :
1256
1257			// Support: jQuery <1.8
1258			function( elem, i, match ) {
1259				return !!$.data( elem, match[ 3 ] );
1260			}
1261	} );
1262
1263	/*!
1264	 * jQuery UI Disable Selection 1.12.1
1265	 * http://jqueryui.com
1266	 *
1267	 * Copyright jQuery Foundation and other contributors
1268	 * Released under the MIT license.
1269	 * http://jquery.org/license
1270	 */
1271
1272//>>label: disableSelection
1273//>>group: Core
1274//>>description: Disable selection of text content within the set of matched elements.
1275//>>docs: http://api.jqueryui.com/disableSelection/
1276
1277// This file is deprecated
1278
1279
1280	var disableSelection = $.fn.extend( {
1281		disableSelection: ( function() {
1282			var eventType = "onselectstart" in document.createElement( "div" ) ?
1283				"selectstart" :
1284				"mousedown";
1285
1286			return function() {
1287				return this.on( eventType + ".ui-disableSelection", function( event ) {
1288					event.preventDefault();
1289				} );
1290			};
1291		} )(),
1292
1293		enableSelection: function() {
1294			return this.off( ".ui-disableSelection" );
1295		}
1296	} );
1297
1298
1299	/*!
1300	 * jQuery UI Effects 1.12.1
1301	 * http://jqueryui.com
1302	 *
1303	 * Copyright jQuery Foundation and other contributors
1304	 * Released under the MIT license.
1305	 * http://jquery.org/license
1306	 */
1307
1308//>>label: Effects Core
1309//>>group: Effects
1310// jscs:disable maximumLineLength
1311//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects.
1312// jscs:enable maximumLineLength
1313//>>docs: http://api.jqueryui.com/category/effects-core/
1314//>>demos: http://jqueryui.com/effect/
1315
1316
1317
1318	var dataSpace = "ui-effects-",
1319		dataSpaceStyle = "ui-effects-style",
1320		dataSpaceAnimated = "ui-effects-animated",
1321
1322	// Create a local jQuery because jQuery Color relies on it and the
1323	// global may not exist with AMD and a custom build (#10199)
1324		jQuery = $;
1325
1326	$.effects = {
1327		effect: {}
1328	};
1329
1330	/*!
1331	 * jQuery Color Animations v2.1.2
1332	 * https://github.com/jquery/jquery-color
1333	 *
1334	 * Copyright 2014 jQuery Foundation and other contributors
1335	 * Released under the MIT license.
1336	 * http://jquery.org/license
1337	 *
1338	 * Date: Wed Jan 16 08:47:09 2013 -0600
1339	 */
1340	( function( jQuery, undefined ) {
1341
1342		var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " +
1343				"borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
1344
1345		// Plusequals test for += 100 -= 100
1346			rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
1347
1348		// A set of RE's that can match strings and generate color tuples.
1349			stringParsers = [ {
1350				re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1351				parse: function( execResult ) {
1352					return [
1353						execResult[ 1 ],
1354						execResult[ 2 ],
1355						execResult[ 3 ],
1356						execResult[ 4 ]
1357					];
1358				}
1359			}, {
1360				re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1361				parse: function( execResult ) {
1362					return [
1363						execResult[ 1 ] * 2.55,
1364						execResult[ 2 ] * 2.55,
1365						execResult[ 3 ] * 2.55,
1366						execResult[ 4 ]
1367					];
1368				}
1369			}, {
1370
1371				// This regex ignores A-F because it's compared against an already lowercased string
1372				re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
1373				parse: function( execResult ) {
1374					return [
1375						parseInt( execResult[ 1 ], 16 ),
1376						parseInt( execResult[ 2 ], 16 ),
1377						parseInt( execResult[ 3 ], 16 )
1378					];
1379				}
1380			}, {
1381
1382				// This regex ignores A-F because it's compared against an already lowercased string
1383				re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
1384				parse: function( execResult ) {
1385					return [
1386						parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
1387						parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
1388						parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
1389					];
1390				}
1391			}, {
1392				re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1393				space: "hsla",
1394				parse: function( execResult ) {
1395					return [
1396						execResult[ 1 ],
1397						execResult[ 2 ] / 100,
1398						execResult[ 3 ] / 100,
1399						execResult[ 4 ]
1400					];
1401				}
1402			} ],
1403
1404		// JQuery.Color( )
1405			color = jQuery.Color = function( color, green, blue, alpha ) {
1406				return new jQuery.Color.fn.parse( color, green, blue, alpha );
1407			},
1408			spaces = {
1409				rgba: {
1410					props: {
1411						red: {
1412							idx: 0,
1413							type: "byte"
1414						},
1415						green: {
1416							idx: 1,
1417							type: "byte"
1418						},
1419						blue: {
1420							idx: 2,
1421							type: "byte"
1422						}
1423					}
1424				},
1425
1426				hsla: {
1427					props: {
1428						hue: {
1429							idx: 0,
1430							type: "degrees"
1431						},
1432						saturation: {
1433							idx: 1,
1434							type: "percent"
1435						},
1436						lightness: {
1437							idx: 2,
1438							type: "percent"
1439						}
1440					}
1441				}
1442			},
1443			propTypes = {
1444				"byte": {
1445					floor: true,
1446					max: 255
1447				},
1448				"percent": {
1449					max: 1
1450				},
1451				"degrees": {
1452					mod: 360,
1453					floor: true
1454				}
1455			},
1456			support = color.support = {},
1457
1458		// Element for support tests
1459			supportElem = jQuery( "<p>" )[ 0 ],
1460
1461		// Colors = jQuery.Color.names
1462			colors,
1463
1464		// Local aliases of functions called often
1465			each = jQuery.each;
1466
vendor: 13,323 bytes, lines 1467-1945
1467// Determine rgba support immediately
1468		supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
1469		support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
1470
1471// Define cache name and alpha properties
1472// for rgba and hsla spaces
1473		each( spaces, function( spaceName, space ) {
1474			space.cache = "_" + spaceName;
1475			space.props.alpha = {
1476				idx: 3,
1477				type: "percent",
1478				def: 1
1479			};
1480		} );
1481
1482		function clamp( value, prop, allowEmpty ) {
1483			var type = propTypes[ prop.type ] || {};
1484
1485			if ( value == null ) {
1486				return ( allowEmpty || !prop.def ) ? null : prop.def;
1487			}
1488
1489			// ~~ is an short way of doing floor for positive numbers
1490			value = type.floor ? ~~value : parseFloat( value );
1491
1492			// IE will pass in empty strings as value for alpha,
1493			// which will hit this case
1494			if ( isNaN( value ) ) {
1495				return prop.def;
1496			}
1497
1498			if ( type.mod ) {
1499
1500				// We add mod before modding to make sure that negatives values
1501				// get converted properly: -10 -> 350
1502				return ( value + type.mod ) % type.mod;
1503			}
1504
1505			// For now all property types without mod have min and max
1506			return 0 > value ? 0 : type.max < value ? type.max : value;
1507		}
1508
1509		function stringParse( string ) {
1510			var inst = color(),
1511				rgba = inst._rgba = [];
1512
1513			string = string.toLowerCase();
1514
1515			each( stringParsers, function( i, parser ) {
1516				var parsed,
1517					match = parser.re.exec( string ),
1518					values = match && parser.parse( match ),
1519					spaceName = parser.space || "rgba";
1520
1521				if ( values ) {
1522					parsed = inst[ spaceName ]( values );
1523
1524					// If this was an rgba parse the assignment might happen twice
1525					// oh well....
1526					inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
1527					rgba = inst._rgba = parsed._rgba;
1528
1529					// Exit each( stringParsers ) here because we matched
1530					return false;
1531				}
1532			} );
1533
1534			// Found a stringParser that handled it
1535			if ( rgba.length ) {
1536
1537				// If this came from a parsed string, force "transparent" when alpha is 0
1538				// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
1539				if ( rgba.join() === "0,0,0,0" ) {
1540					jQuery.extend( rgba, colors.transparent );
1541				}
1542				return inst;
1543			}
1544
1545			// Named colors
1546			return colors[ string ];
1547		}
1548
1549		color.fn = jQuery.extend( color.prototype, {
1550			parse: function( red, green, blue, alpha ) {
1551				if ( red === undefined ) {
1552					this._rgba = [ null, null, null, null ];
1553					return this;
1554				}
1555				if ( red.jquery || red.nodeType ) {
1556					red = jQuery( red ).css( green );
1557					green = undefined;
1558				}
1559
1560				var inst = this,
1561					type = jQuery.type( red ),
1562					rgba = this._rgba = [];
1563
1564				// More than 1 argument specified - assume ( red, green, blue, alpha )
1565				if ( green !== undefined ) {
1566					red = [ red, green, blue, alpha ];
1567					type = "array";
1568				}
1569
1570				if ( type === "string" ) {
1571					return this.parse( stringParse( red ) || colors._default );
1572				}
1573
1574				if ( type === "array" ) {
1575					each( spaces.rgba.props, function( key, prop ) {
1576						rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
1577					} );
1578					return this;
1579				}
1580
1581				if ( type === "object" ) {
1582					if ( red instanceof color ) {
1583						each( spaces, function( spaceName, space ) {
1584							if ( red[ space.cache ] ) {
1585								inst[ space.cache ] = red[ space.cache ].slice();
1586							}
1587						} );
1588					} else {
1589						each( spaces, function( spaceName, space ) {
1590							var cache = space.cache;
1591							each( space.props, function( key, prop ) {
1592
1593								// If the cache doesn't exist, and we know how to convert
1594								if ( !inst[ cache ] && space.to ) {
1595
1596									// If the value was null, we don't need to copy it
1597									// if the key was alpha, we don't need to copy it either
1598									if ( key === "alpha" || red[ key ] == null ) {
1599										return;
1600									}
1601									inst[ cache ] = space.to( inst._rgba );
1602								}
1603
1604								// This is the only case where we allow nulls for ALL properties.
1605								// call clamp with alwaysAllowEmpty
1606								inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
1607							} );
1608
1609							// Everything defined but alpha?
1610							if ( inst[ cache ] &&
1611								jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
1612
1613								// Use the default of 1
1614								inst[ cache ][ 3 ] = 1;
1615								if ( space.from ) {
1616									inst._rgba = space.from( inst[ cache ] );
1617								}
1618							}
1619						} );
1620					}
1621					return this;
1622				}
1623			},
1624			is: function( compare ) {
1625				var is = color( compare ),
1626					same = true,
1627					inst = this;
1628
1629				each( spaces, function( _, space ) {
1630					var localCache,
1631						isCache = is[ space.cache ];
1632					if ( isCache ) {
1633						localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
1634						each( space.props, function( _, prop ) {
1635							if ( isCache[ prop.idx ] != null ) {
1636								same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
1637								return same;
1638							}
1639						} );
1640					}
1641					return same;
1642				} );
1643				return same;
1644			},
1645			_space: function() {
1646				var used = [],
1647					inst = this;
1648				each( spaces, function( spaceName, space ) {
1649					if ( inst[ space.cache ] ) {
1650						used.push( spaceName );
1651					}
1652				} );
1653				return used.pop();
1654			},
1655			transition: function( other, distance ) {
1656				var end = color( other ),
1657					spaceName = end._space(),
1658					space = spaces[ spaceName ],
1659					startColor = this.alpha() === 0 ? color( "transparent" ) : this,
1660					start = startColor[ space.cache ] || space.to( startColor._rgba ),
1661					result = start.slice();
1662
1663				end = end[ space.cache ];
1664				each( space.props, function( key, prop ) {
1665					var index = prop.idx,
1666						startValue = start[ index ],
1667						endValue = end[ index ],
1668						type = propTypes[ prop.type ] || {};
1669
1670					// If null, don't override start value
1671					if ( endValue === null ) {
1672						return;
1673					}
1674
1675					// If null - use end
1676					if ( startValue === null ) {
1677						result[ index ] = endValue;
1678					} else {
1679						if ( type.mod ) {
1680							if ( endValue - startValue > type.mod / 2 ) {
1681								startValue += type.mod;
1682							} else if ( startValue - endValue > type.mod / 2 ) {
1683								startValue -= type.mod;
1684							}
1685						}
1686						result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
1687					}
1688				} );
1689				return this[ spaceName ]( result );
1690			},
1691			blend: function( opaque ) {
1692
1693				// If we are already opaque - return ourself
1694				if ( this._rgba[ 3 ] === 1 ) {
1695					return this;
1696				}
1697
1698				var rgb = this._rgba.slice(),
1699					a = rgb.pop(),
1700					blend = color( opaque )._rgba;
1701
1702				return color( jQuery.map( rgb, function( v, i ) {
1703					return ( 1 - a ) * blend[ i ] + a * v;
1704				} ) );
1705			},
1706			toRgbaString: function() {
1707				var prefix = "rgba(",
1708					rgba = jQuery.map( this._rgba, function( v, i ) {
1709						return v == null ? ( i > 2 ? 1 : 0 ) : v;
1710					} );
1711
1712				if ( rgba[ 3 ] === 1 ) {
1713					rgba.pop();
1714					prefix = "rgb(";
1715				}
1716
1717				return prefix + rgba.join() + ")";
1718			},
1719			toHslaString: function() {
1720				var prefix = "hsla(",
1721					hsla = jQuery.map( this.hsla(), function( v, i ) {
1722						if ( v == null ) {
1723							v = i > 2 ? 1 : 0;
1724						}
1725
1726						// Catch 1 and 2
1727						if ( i && i < 3 ) {
1728							v = Math.round( v * 100 ) + "%";
1729						}
1730						return v;
1731					} );
1732
1733				if ( hsla[ 3 ] === 1 ) {
1734					hsla.pop();
1735					prefix = "hsl(";
1736				}
1737				return prefix + hsla.join() + ")";
1738			},
1739			toHexString: function( includeAlpha ) {
1740				var rgba = this._rgba.slice(),
1741					alpha = rgba.pop();
1742
1743				if ( includeAlpha ) {
1744					rgba.push( ~~( alpha * 255 ) );
1745				}
1746
1747				return "#" + jQuery.map( rgba, function( v ) {
1748
1749						// Default to 0 when nulls exist
1750						v = ( v || 0 ).toString( 16 );
1751						return v.length === 1 ? "0" + v : v;
1752					} ).join( "" );
1753			},
1754			toString: function() {
1755				return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
1756			}
1757		} );
1758		color.fn.parse.prototype = color.fn;
1759
1760// Hsla conversions adapted from:
1761// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
1762
1763		function hue2rgb( p, q, h ) {
1764			h = ( h + 1 ) % 1;
1765			if ( h * 6 < 1 ) {
1766				return p + ( q - p ) * h * 6;
1767			}
1768			if ( h * 2 < 1 ) {
1769				return q;
1770			}
1771			if ( h * 3 < 2 ) {
1772				return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
1773			}
1774			return p;
1775		}
1776
1777		spaces.hsla.to = function( rgba ) {
1778			if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
1779				return [ null, null, null, rgba[ 3 ] ];
1780			}
1781			var r = rgba[ 0 ] / 255,
1782				g = rgba[ 1 ] / 255,
1783				b = rgba[ 2 ] / 255,
1784				a = rgba[ 3 ],
1785				max = Math.max( r, g, b ),
1786				min = Math.min( r, g, b ),
1787				diff = max - min,
1788				add = max + min,
1789				l = add * 0.5,
1790				h, s;
1791
1792			if ( min === max ) {
1793				h = 0;
1794			} else if ( r === max ) {
1795				h = ( 60 * ( g - b ) / diff ) + 360;
1796			} else if ( g === max ) {
1797				h = ( 60 * ( b - r ) / diff ) + 120;
1798			} else {
1799				h = ( 60 * ( r - g ) / diff ) + 240;
1800			}
1801
1802			// Chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
1803			// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
1804			if ( diff === 0 ) {
1805				s = 0;
1806			} else if ( l <= 0.5 ) {
1807				s = diff / add;
1808			} else {
1809				s = diff / ( 2 - add );
1810			}
1811			return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ];
1812		};
1813
1814		spaces.hsla.from = function( hsla ) {
1815			if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
1816				return [ null, null, null, hsla[ 3 ] ];
1817			}
1818			var h = hsla[ 0 ] / 360,
1819				s = hsla[ 1 ],
1820				l = hsla[ 2 ],
1821				a = hsla[ 3 ],
1822				q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
1823				p = 2 * l - q;
1824
1825			return [
1826				Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
1827				Math.round( hue2rgb( p, q, h ) * 255 ),
1828				Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
1829				a
1830			];
1831		};
1832
1833		each( spaces, function( spaceName, space ) {
1834			var props = space.props,
1835				cache = space.cache,
1836				to = space.to,
1837				from = space.from;
1838
1839			// Makes rgba() and hsla()
1840			color.fn[ spaceName ] = function( value ) {
1841
1842				// Generate a cache for this space if it doesn't exist
1843				if ( to && !this[ cache ] ) {
1844					this[ cache ] = to( this._rgba );
1845				}
1846				if ( value === undefined ) {
1847					return this[ cache ].slice();
1848				}
1849
1850				var ret,
1851					type = jQuery.type( value ),
1852					arr = ( type === "array" || type === "object" ) ? value : arguments,
1853					local = this[ cache ].slice();
1854
1855				each( props, function( key, prop ) {
1856					var val = arr[ type === "object" ? key : prop.idx ];
1857					if ( val == null ) {
1858						val = local[ prop.idx ];
1859					}
1860					local[ prop.idx ] = clamp( val, prop );
1861				} );
1862
1863				if ( from ) {
1864					ret = color( from( local ) );
1865					ret[ cache ] = local;
1866					return ret;
1867				} else {
1868					return color( local );
1869				}
1870			};
1871
1872			// Makes red() green() blue() alpha() hue() saturation() lightness()
1873			each( props, function( key, prop ) {
1874
1875				// Alpha is included in more than one space
1876				if ( color.fn[ key ] ) {
1877					return;
1878				}
1879				color.fn[ key ] = function( value ) {
1880					var vtype = jQuery.type( value ),
1881						fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
1882						local = this[ fn ](),
1883						cur = local[ prop.idx ],
1884						match;
1885
1886					if ( vtype === "undefined" ) {
1887						return cur;
1888					}
1889
1890					if ( vtype === "function" ) {
1891						value = value.call( this, cur );
1892						vtype = jQuery.type( value );
1893					}
1894					if ( value == null && prop.empty ) {
1895						return this;
1896					}
1897					if ( vtype === "string" ) {
1898						match = rplusequals.exec( value );
1899						if ( match ) {
1900							value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
1901						}
1902					}
1903					local[ prop.idx ] = value;
1904					return this[ fn ]( local );
1905				};
1906			} );
1907		} );
1908
1909// Add cssHook and .fx.step function for each named hook.
1910// accept a space separated string of properties
1911		color.hook = function( hook ) {
1912			var hooks = hook.split( " " );
1913			each( hooks, function( i, hook ) {
1914				jQuery.cssHooks[ hook ] = {
1915					set: function( elem, value ) {
1916						var parsed, curElem,
1917							backgroundColor = "";
1918
1919						if ( value !== "transparent" && ( jQuery.type( value ) !== "string" ||
1920							( parsed = stringParse( value ) ) ) ) {
1921							value = color( parsed || value );
1922							if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
1923								curElem = hook === "backgroundColor" ? elem.parentNode : elem;
1924								while (
1925								( backgroundColor === "" || backgroundColor === "transparent" ) &&
1926								curElem && curElem.style
1927									) {
1928									try {
1929										backgroundColor = jQuery.css( curElem, "backgroundColor" );
1930										curElem = curElem.parentNode;
1931									} catch ( e ) {
1932									}
1933								}
1934
1935								value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
1936									backgroundColor :
1937									"_default" );
1938							}
1939
1940							value = value.toRgbaString();
1941						}
1942						try {
1943							elem.style[ hook ] = value;
1944						} catch ( e ) {
1945
vendor: 8,692 bytes, lines 1946-2261
1946							// Wrapped to prevent IE from throwing errors on "invalid" values like
1947							// 'auto' or 'inherit'
1948						}
1949					}
1950				};
1951				jQuery.fx.step[ hook ] = function( fx ) {
1952					if ( !fx.colorInit ) {
1953						fx.start = color( fx.elem, hook );
1954						fx.end = color( fx.end );
1955						fx.colorInit = true;
1956					}
1957					jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
1958				};
1959			} );
1960
1961		};
1962
1963		color.hook( stepHooks );
1964
1965		jQuery.cssHooks.borderColor = {
1966			expand: function( value ) {
1967				var expanded = {};
1968
1969				each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
1970					expanded[ "border" + part + "Color" ] = value;
1971				} );
1972				return expanded;
1973			}
1974		};
1975
1976// Basic color names only.
1977// Usage of any of the other color names requires adding yourself or including
1978// jquery.color.svg-names.js.
1979		colors = jQuery.Color.names = {
1980
1981			// 4.1. Basic color keywords
1982			aqua: "#00ffff",
1983			black: "#000000",
1984			blue: "#0000ff",
1985			fuchsia: "#ff00ff",
1986			gray: "#808080",
1987			green: "#008000",
1988			lime: "#00ff00",
1989			maroon: "#800000",
1990			navy: "#000080",
1991			olive: "#808000",
1992			purple: "#800080",
1993			red: "#ff0000",
1994			silver: "#c0c0c0",
1995			teal: "#008080",
1996			white: "#ffffff",
1997			yellow: "#ffff00",
1998
1999			// 4.2.3. "transparent" color keyword
2000			transparent: [ null, null, null, 0 ],
2001
2002			_default: "#ffffff"
2003		};
2004
2005	} )( jQuery );
2006
2007	/******************************************************************************/
2008	/****************************** CLASS ANIMATIONS ******************************/
2009	/******************************************************************************/
2010	( function() {
2011
2012		var classAnimationActions = [ "add", "remove", "toggle" ],
2013			shorthandStyles = {
2014				border: 1,
2015				borderBottom: 1,
2016				borderColor: 1,
2017				borderLeft: 1,
2018				borderRight: 1,
2019				borderTop: 1,
2020				borderWidth: 1,
2021				margin: 1,
2022				padding: 1
2023			};
2024
2025		$.each(
2026			[ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ],
2027			function( _, prop ) {
2028				$.fx.step[ prop ] = function( fx ) {
2029					if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
2030						jQuery.style( fx.elem, prop, fx.end );
2031						fx.setAttr = true;
2032					}
2033				};
2034			}
2035		);
2036
2037		function getElementStyles( elem ) {
2038			var key, len,
2039				style = elem.ownerDocument.defaultView ?
2040					elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
2041					elem.currentStyle,
2042				styles = {};
2043
2044			if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
2045				len = style.length;
2046				while ( len-- ) {
2047					key = style[ len ];
2048					if ( typeof style[ key ] === "string" ) {
2049						styles[ $.camelCase( key ) ] = style[ key ];
2050					}
2051				}
2052
2053				// Support: Opera, IE <9
2054			} else {
2055				for ( key in style ) {
2056					if ( typeof style[ key ] === "string" ) {
2057						styles[ key ] = style[ key ];
2058					}
2059				}
2060			}
2061
2062			return styles;
2063		}
2064
2065		function styleDifference( oldStyle, newStyle ) {
2066			var diff = {},
2067				name, value;
2068
2069			for ( name in newStyle ) {
2070				value = newStyle[ name ];
2071				if ( oldStyle[ name ] !== value ) {
2072					if ( !shorthandStyles[ name ] ) {
2073						if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
2074							diff[ name ] = value;
2075						}
2076					}
2077				}
2078			}
2079
2080			return diff;
2081		}
2082
2083// Support: jQuery <1.8
2084		if ( !$.fn.addBack ) {
2085			$.fn.addBack = function( selector ) {
2086				return this.add( selector == null ?
2087						this.prevObject : this.prevObject.filter( selector )
2088				);
2089			};
2090		}
2091
2092		$.effects.animateClass = function( value, duration, easing, callback ) {
2093			var o = $.speed( duration, easing, callback );
2094
2095			return this.queue( function() {
2096				var animated = $( this ),
2097					baseClass = animated.attr( "class" ) || "",
2098					applyClassChange,
2099					allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
2100
2101				// Map the animated objects to store the original styles.
2102				allAnimations = allAnimations.map( function() {
2103					var el = $( this );
2104					return {
2105						el: el,
2106						start: getElementStyles( this )
2107					};
2108				} );
2109
2110				// Apply class change
2111				applyClassChange = function() {
2112					$.each( classAnimationActions, function( i, action ) {
2113						if ( value[ action ] ) {
2114							animated[ action + "Class" ]( value[ action ] );
2115						}
2116					} );
2117				};
2118				applyClassChange();
2119
2120				// Map all animated objects again - calculate new styles and diff
2121				allAnimations = allAnimations.map( function() {
2122					this.end = getElementStyles( this.el[ 0 ] );
2123					this.diff = styleDifference( this.start, this.end );
2124					return this;
2125				} );
2126
2127				// Apply original class
2128				animated.attr( "class", baseClass );
2129
2130				// Map all animated objects again - this time collecting a promise
2131				allAnimations = allAnimations.map( function() {
2132					var styleInfo = this,
2133						dfd = $.Deferred(),
2134						opts = $.extend( {}, o, {
2135							queue: false,
2136							complete: function() {
2137								dfd.resolve( styleInfo );
2138							}
2139						} );
2140
2141					this.el.animate( this.diff, opts );
2142					return dfd.promise();
2143				} );
2144
2145				// Once all animations have completed:
2146				$.when.apply( $, allAnimations.get() ).done( function() {
2147
2148					// Set the final class
2149					applyClassChange();
2150
2151					// For each animated element,
2152					// clear all css properties that were animated
2153					$.each( arguments, function() {
2154						var el = this.el;
2155						$.each( this.diff, function( key ) {
2156							el.css( key, "" );
2157						} );
2158					} );
2159
2160					// This is guarnteed to be there if you use jQuery.speed()
2161					// it also handles dequeuing the next anim...
2162					o.complete.call( animated[ 0 ] );
2163				} );
2164			} );
2165		};
2166
2167		$.fn.extend( {
2168			addClass: ( function( orig ) {
2169				return function( classNames, speed, easing, callback ) {
2170					return speed ?
2171						$.effects.animateClass.call( this,
2172							{ add: classNames }, speed, easing, callback ) :
2173						orig.apply( this, arguments );
2174				};
2175			} )( $.fn.addClass ),
2176
2177			removeClass: ( function( orig ) {
2178				return function( classNames, speed, easing, callback ) {
2179					return arguments.length > 1 ?
2180						$.effects.animateClass.call( this,
2181							{ remove: classNames }, speed, easing, callback ) :
2182						orig.apply( this, arguments );
2183				};
2184			} )( $.fn.removeClass ),
2185
2186			toggleClass: ( function( orig ) {
2187				return function( classNames, force, speed, easing, callback ) {
2188					if ( typeof force === "boolean" || force === undefined ) {
2189						if ( !speed ) {
2190
2191							// Without speed parameter
2192							return orig.apply( this, arguments );
2193						} else {
2194							return $.effects.animateClass.call( this,
2195								( force ? { add: classNames } : { remove: classNames } ),
2196								speed, easing, callback );
2197						}
2198					} else {
2199
2200						// Without force parameter
2201						return $.effects.animateClass.call( this,
2202							{ toggle: classNames }, force, speed, easing );
2203					}
2204				};
2205			} )( $.fn.toggleClass ),
2206
2207			switchClass: function( remove, add, speed, easing, callback ) {
2208				return $.effects.animateClass.call( this, {
2209					add: add,
2210					remove: remove
2211				}, speed, easing, callback );
2212			}
2213		} );
2214
2215	} )();
2216
2217	/******************************************************************************/
2218	/*********************************** EFFECTS **********************************/
2219	/******************************************************************************/
2220
2221	( function() {
2222
2223		if ( $.expr && $.expr.filters && $.expr.filters.animated ) {
2224			$.expr.filters.animated = ( function( orig ) {
2225				return function( elem ) {
2226					return !!$( elem ).data( dataSpaceAnimated ) || orig( elem );
2227				};
2228			} )( $.expr.filters.animated );
2229		}
2230
2231		if ( $.uiBackCompat !== false ) {
2232			$.extend( $.effects, {
2233
2234				// Saves a set of properties in a data storage
2235				save: function( element, set ) {
2236					var i = 0, length = set.length;
2237					for ( ; i < length; i++ ) {
2238						if ( set[ i ] !== null ) {
2239							element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
2240						}
2241					}
2242				},
2243
2244				// Restores a set of previously saved properties from a data storage
2245				restore: function( element, set ) {
2246					var val, i = 0, length = set.length;
2247					for ( ; i < length; i++ ) {
2248						if ( set[ i ] !== null ) {
2249							val = element.data( dataSpace + set[ i ] );
2250							element.css( set[ i ], val );
2251						}
2252					}
2253				},
2254
2255				setMode: function( el, mode ) {
2256					if ( mode === "toggle" ) {
2257						mode = el.is( ":hidden" ) ? "show" : "hide";
2258					}
2259					return mode;
2260				},
2261
vendor: 5,122 bytes, lines 2262-2454
2262				// Wraps the element around a wrapper that copies position properties
2263				createWrapper: function( element ) {
2264
2265					// If the element is already wrapped, return it
2266					if ( element.parent().is( ".ui-effects-wrapper" ) ) {
2267						return element.parent();
2268					}
2269
2270					// Wrap the element
2271					var props = {
2272							width: element.outerWidth( true ),
2273							height: element.outerHeight( true ),
2274							"float": element.css( "float" )
2275						},
2276						wrapper = $( "<div></div>" )
2277							.addClass( "ui-effects-wrapper" )
2278							.css( {
2279								fontSize: "100%",
2280								background: "transparent",
2281								border: "none",
2282								margin: 0,
2283								padding: 0
2284							} ),
2285
2286					// Store the size in case width/height are defined in % - Fixes #5245
2287						size = {
2288							width: element.width(),
2289							height: element.height()
2290						},
2291						active = document.activeElement;
2292
2293					// Support: Firefox
2294					// Firefox incorrectly exposes anonymous content
2295					// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
2296					try {
2297						active.id;
2298					} catch ( e ) {
2299						active = document.body;
2300					}
2301
2302					element.wrap( wrapper );
2303
2304					// Fixes #7595 - Elements lose focus when wrapped.
2305					if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
2306						$( active ).trigger( "focus" );
2307					}
2308
2309					// Hotfix for jQuery 1.4 since some change in wrap() seems to actually
2310					// lose the reference to the wrapped element
2311					wrapper = element.parent();
2312
2313					// Transfer positioning properties to the wrapper
2314					if ( element.css( "position" ) === "static" ) {
2315						wrapper.css( { position: "relative" } );
2316						element.css( { position: "relative" } );
2317					} else {
2318						$.extend( props, {
2319							position: element.css( "position" ),
2320							zIndex: element.css( "z-index" )
2321						} );
2322						$.each( [ "top", "left", "bottom", "right" ], function( i, pos ) {
2323							props[ pos ] = element.css( pos );
2324							if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
2325								props[ pos ] = "auto";
2326							}
2327						} );
2328						element.css( {
2329							position: "relative",
2330							top: 0,
2331							left: 0,
2332							right: "auto",
2333							bottom: "auto"
2334						} );
2335					}
2336					element.css( size );
2337
2338					return wrapper.css( props ).show();
2339				},
2340
2341				removeWrapper: function( element ) {
2342					var active = document.activeElement;
2343
2344					if ( element.parent().is( ".ui-effects-wrapper" ) ) {
2345						element.parent().replaceWith( element );
2346
2347						// Fixes #7595 - Elements lose focus when wrapped.
2348						if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
2349							$( active ).trigger( "focus" );
2350						}
2351					}
2352
2353					return element;
2354				}
2355			} );
2356		}
2357
2358		$.extend( $.effects, {
2359			version: "1.12.1",
2360
2361			define: function( name, mode, effect ) {
2362				if ( !effect ) {
2363					effect = mode;
2364					mode = "effect";
2365				}
2366
2367				$.effects.effect[ name ] = effect;
2368				$.effects.effect[ name ].mode = mode;
2369
2370				return effect;
2371			},
2372
2373			scaledDimensions: function( element, percent, direction ) {
2374				if ( percent === 0 ) {
2375					return {
2376						height: 0,
2377						width: 0,
2378						outerHeight: 0,
2379						outerWidth: 0
2380					};
2381				}
2382
2383				var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1,
2384					y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1;
2385
2386				return {
2387					height: element.height() * y,
2388					width: element.width() * x,
2389					outerHeight: element.outerHeight() * y,
2390					outerWidth: element.outerWidth() * x
2391				};
2392
2393			},
2394
2395			clipToBox: function( animation ) {
2396				return {
2397					width: animation.clip.right - animation.clip.left,
2398					height: animation.clip.bottom - animation.clip.top,
2399					left: animation.clip.left,
2400					top: animation.clip.top
2401				};
2402			},
2403
2404			// Injects recently queued functions to be first in line (after "inprogress")
2405			unshift: function( element, queueLength, count ) {
2406				var queue = element.queue();
2407
2408				if ( queueLength > 1 ) {
2409					queue.splice.apply( queue,
2410						[ 1, 0 ].concat( queue.splice( queueLength, count ) ) );
2411				}
2412				element.dequeue();
2413			},
2414
2415			saveStyle: function( element ) {
2416				element.data( dataSpaceStyle, element[ 0 ].style.cssText );
2417			},
2418
2419			restoreStyle: function( element ) {
2420				element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || "";
2421				element.removeData( dataSpaceStyle );
2422			},
2423
2424			mode: function( element, mode ) {
2425				var hidden = element.is( ":hidden" );
2426
2427				if ( mode === "toggle" ) {
2428					mode = hidden ? "show" : "hide";
2429				}
2430				if ( hidden ? mode === "hide" : mode === "show" ) {
2431					mode = "none";
2432				}
2433				return mode;
2434			},
2435
2436			// Translates a [top,left] array into a baseline value
2437			getBaseline: function( origin, original ) {
2438				var y, x;
2439
2440				switch ( origin[ 0 ] ) {
2441					case "top":
2442						y = 0;
2443						break;
2444					case "middle":
2445						y = 0.5;
2446						break;
2447					case "bottom":
2448						y = 1;
2449						break;
2450					default:
2451						y = origin[ 0 ] / original.height;
2452				}
2453
2454				switch ( origin[ 1 ] ) {
vendor: 14,875 bytes, lines 2455-2974
2455					case "left":
2456						x = 0;
2457						break;
2458					case "center":
2459						x = 0.5;
2460						break;
2461					case "right":
2462						x = 1;
2463						break;
2464					default:
2465						x = origin[ 1 ] / original.width;
2466				}
2467
2468				return {
2469					x: x,
2470					y: y
2471				};
2472			},
2473
2474			// Creates a placeholder element so that the original element can be made absolute
2475			createPlaceholder: function( element ) {
2476				var placeholder,
2477					cssPosition = element.css( "position" ),
2478					position = element.position();
2479
2480				// Lock in margins first to account for form elements, which
2481				// will change margin if you explicitly set height
2482				// see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380
2483				// Support: Safari
2484				element.css( {
2485					marginTop: element.css( "marginTop" ),
2486					marginBottom: element.css( "marginBottom" ),
2487					marginLeft: element.css( "marginLeft" ),
2488					marginRight: element.css( "marginRight" )
2489				} )
2490					.outerWidth( element.outerWidth() )
2491					.outerHeight( element.outerHeight() );
2492
2493				if ( /^(static|relative)/.test( cssPosition ) ) {
2494					cssPosition = "absolute";
2495
2496					placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( {
2497
2498						// Convert inline to inline block to account for inline elements
2499						// that turn to inline block based on content (like img)
2500						display: /^(inline|ruby)/.test( element.css( "display" ) ) ?
2501							"inline-block" :
2502							"block",
2503						visibility: "hidden",
2504
2505						// Margins need to be set to account for margin collapse
2506						marginTop: element.css( "marginTop" ),
2507						marginBottom: element.css( "marginBottom" ),
2508						marginLeft: element.css( "marginLeft" ),
2509						marginRight: element.css( "marginRight" ),
2510						"float": element.css( "float" )
2511					} )
2512						.outerWidth( element.outerWidth() )
2513						.outerHeight( element.outerHeight() )
2514						.addClass( "ui-effects-placeholder" );
2515
2516					element.data( dataSpace + "placeholder", placeholder );
2517				}
2518
2519				element.css( {
2520					position: cssPosition,
2521					left: position.left,
2522					top: position.top
2523				} );
2524
2525				return placeholder;
2526			},
2527
2528			removePlaceholder: function( element ) {
2529				var dataKey = dataSpace + "placeholder",
2530					placeholder = element.data( dataKey );
2531
2532				if ( placeholder ) {
2533					placeholder.remove();
2534					element.removeData( dataKey );
2535				}
2536			},
2537
2538			// Removes a placeholder if it exists and restores
2539			// properties that were modified during placeholder creation
2540			cleanUp: function( element ) {
2541				$.effects.restoreStyle( element );
2542				$.effects.removePlaceholder( element );
2543			},
2544
2545			setTransition: function( element, list, factor, value ) {
2546				value = value || {};
2547				$.each( list, function( i, x ) {
2548					var unit = element.cssUnit( x );
2549					if ( unit[ 0 ] > 0 ) {
2550						value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
2551					}
2552				} );
2553				return value;
2554			}
2555		} );
2556
2557// Return an effect options object for the given parameters:
2558		function _normalizeArguments( effect, options, speed, callback ) {
2559
2560			// Allow passing all options as the first parameter
2561			if ( $.isPlainObject( effect ) ) {
2562				options = effect;
2563				effect = effect.effect;
2564			}
2565
2566			// Convert to an object
2567			effect = { effect: effect };
2568
2569			// Catch (effect, null, ...)
2570			if ( options == null ) {
2571				options = {};
2572			}
2573
2574			// Catch (effect, callback)
2575			if ( $.isFunction( options ) ) {
2576				callback = options;
2577				speed = null;
2578				options = {};
2579			}
2580
2581			// Catch (effect, speed, ?)
2582			if ( typeof options === "number" || $.fx.speeds[ options ] ) {
2583				callback = speed;
2584				speed = options;
2585				options = {};
2586			}
2587
2588			// Catch (effect, options, callback)
2589			if ( $.isFunction( speed ) ) {
2590				callback = speed;
2591				speed = null;
2592			}
2593
2594			// Add options to effect
2595			if ( options ) {
2596				$.extend( effect, options );
2597			}
2598
2599			speed = speed || options.duration;
2600			effect.duration = $.fx.off ? 0 :
2601				typeof speed === "number" ? speed :
2602					speed in $.fx.speeds ? $.fx.speeds[ speed ] :
2603						$.fx.speeds._default;
2604
2605			effect.complete = callback || options.complete;
2606
2607			return effect;
2608		}
2609
2610		function standardAnimationOption( option ) {
2611
2612			// Valid standard speeds (nothing, number, named speed)
2613			if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
2614				return true;
2615			}
2616
2617			// Invalid strings - treat as "normal" speed
2618			if ( typeof option === "string" && !$.effects.effect[ option ] ) {
2619				return true;
2620			}
2621
2622			// Complete callback
2623			if ( $.isFunction( option ) ) {
2624				return true;
2625			}
2626
2627			// Options hash (but not naming an effect)
2628			if ( typeof option === "object" && !option.effect ) {
2629				return true;
2630			}
2631
2632			// Didn't match any standard API
2633			return false;
2634		}
2635
2636		$.fn.extend( {
2637			effect: function( /* effect, options, speed, callback */ ) {
2638				var args = _normalizeArguments.apply( this, arguments ),
2639					effectMethod = $.effects.effect[ args.effect ],
2640					defaultMode = effectMethod.mode,
2641					queue = args.queue,
2642					queueName = queue || "fx",
2643					complete = args.complete,
2644					mode = args.mode,
2645					modes = [],
2646					prefilter = function( next ) {
2647						var el = $( this ),
2648							normalizedMode = $.effects.mode( el, mode ) || defaultMode;
2649
2650						// Sentinel for duck-punching the :animated psuedo-selector
2651						el.data( dataSpaceAnimated, true );
2652
2653						// Save effect mode for later use,
2654						// we can't just call $.effects.mode again later,
2655						// as the .show() below destroys the initial state
2656						modes.push( normalizedMode );
2657
2658						// See $.uiBackCompat inside of run() for removal of defaultMode in 1.13
2659						if ( defaultMode && ( normalizedMode === "show" ||
2660							( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) {
2661							el.show();
2662						}
2663
2664						if ( !defaultMode || normalizedMode !== "none" ) {
2665							$.effects.saveStyle( el );
2666						}
2667
2668						if ( $.isFunction( next ) ) {
2669							next();
2670						}
2671					};
2672
2673				if ( $.fx.off || !effectMethod ) {
2674
2675					// Delegate to the original method (e.g., .show()) if possible
2676					if ( mode ) {
2677						return this[ mode ]( args.duration, complete );
2678					} else {
2679						return this.each( function() {
2680							if ( complete ) {
2681								complete.call( this );
2682							}
2683						} );
2684					}
2685				}
2686
2687				function run( next ) {
2688					var elem = $( this );
2689
2690					function cleanup() {
2691						elem.removeData( dataSpaceAnimated );
2692
2693						$.effects.cleanUp( elem );
2694
2695						if ( args.mode === "hide" ) {
2696							elem.hide();
2697						}
2698
2699						done();
2700					}
2701
2702					function done() {
2703						if ( $.isFunction( complete ) ) {
2704							complete.call( elem[ 0 ] );
2705						}
2706
2707						if ( $.isFunction( next ) ) {
2708							next();
2709						}
2710					}
2711
2712					// Override mode option on a per element basis,
2713					// as toggle can be either show or hide depending on element state
2714					args.mode = modes.shift();
2715
2716					if ( $.uiBackCompat !== false && !defaultMode ) {
2717						if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
2718
2719							// Call the core method to track "olddisplay" properly
2720							elem[ mode ]();
2721							done();
2722						} else {
2723							effectMethod.call( elem[ 0 ], args, done );
2724						}
2725					} else {
2726						if ( args.mode === "none" ) {
2727
2728							// Call the core method to track "olddisplay" properly
2729							elem[ mode ]();
2730							done();
2731						} else {
2732							effectMethod.call( elem[ 0 ], args, cleanup );
2733						}
2734					}
2735				}
2736
2737				// Run prefilter on all elements first to ensure that
2738				// any showing or hiding happens before placeholder creation,
2739				// which ensures that any layout changes are correctly captured.
2740				return queue === false ?
2741					this.each( prefilter ).each( run ) :
2742					this.queue( queueName, prefilter ).queue( queueName, run );
2743			},
2744
2745			show: ( function( orig ) {
2746				return function( option ) {
2747					if ( standardAnimationOption( option ) ) {
2748						return orig.apply( this, arguments );
2749					} else {
2750						var args = _normalizeArguments.apply( this, arguments );
2751						args.mode = "show";
2752						return this.effect.call( this, args );
2753					}
2754				};
2755			} )( $.fn.show ),
2756
2757			hide: ( function( orig ) {
2758				return function( option ) {
2759					if ( standardAnimationOption( option ) ) {
2760						return orig.apply( this, arguments );
2761					} else {
2762						var args = _normalizeArguments.apply( this, arguments );
2763						args.mode = "hide";
2764						return this.effect.call( this, args );
2765					}
2766				};
2767			} )( $.fn.hide ),
2768
2769			toggle: ( function( orig ) {
2770				return function( option ) {
2771					if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
2772						return orig.apply( this, arguments );
2773					} else {
2774						var args = _normalizeArguments.apply( this, arguments );
2775						args.mode = "toggle";
2776						return this.effect.call( this, args );
2777					}
2778				};
2779			} )( $.fn.toggle ),
2780
2781			cssUnit: function( key ) {
2782				var style = this.css( key ),
2783					val = [];
2784
2785				$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
2786					if ( style.indexOf( unit ) > 0 ) {
2787						val = [ parseFloat( style ), unit ];
2788					}
2789				} );
2790				return val;
2791			},
2792
2793			cssClip: function( clipObj ) {
2794				if ( clipObj ) {
2795					return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " +
2796						clipObj.bottom + "px " + clipObj.left + "px)" );
2797				}
2798				return parseClip( this.css( "clip" ), this );
2799			},
2800
2801			transfer: function( options, done ) {
2802				var element = $( this ),
2803					target = $( options.to ),
2804					targetFixed = target.css( "position" ) === "fixed",
2805					body = $( "body" ),
2806					fixTop = targetFixed ? body.scrollTop() : 0,
2807					fixLeft = targetFixed ? body.scrollLeft() : 0,
2808					endPosition = target.offset(),
2809					animation = {
2810						top: endPosition.top - fixTop,
2811						left: endPosition.left - fixLeft,
2812						height: target.innerHeight(),
2813						width: target.innerWidth()
2814					},
2815					startPosition = element.offset(),
2816					transfer = $( "<div class='ui-effects-transfer'></div>" )
2817						.appendTo( "body" )
2818						.addClass( options.className )
2819						.css( {
2820							top: startPosition.top - fixTop,
2821							left: startPosition.left - fixLeft,
2822							height: element.innerHeight(),
2823							width: element.innerWidth(),
2824							position: targetFixed ? "fixed" : "absolute"
2825						} )
2826						.animate( animation, options.duration, options.easing, function() {
2827							transfer.remove();
2828							if ( $.isFunction( done ) ) {
2829								done();
2830							}
2831						} );
2832			}
2833		} );
2834
2835		function parseClip( str, element ) {
2836			var outerWidth = element.outerWidth(),
2837				outerHeight = element.outerHeight(),
2838				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)\)$/,
2839				values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ];
2840
2841			return {
2842				top: parseFloat( values[ 1 ] ) || 0,
2843				right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ),
2844				bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ),
2845				left: parseFloat( values[ 4 ] ) || 0
2846			};
2847		}
2848
2849		$.fx.step.clip = function( fx ) {
2850			if ( !fx.clipInit ) {
2851				fx.start = $( fx.elem ).cssClip();
2852				if ( typeof fx.end === "string" ) {
2853					fx.end = parseClip( fx.end, fx.elem );
2854				}
2855				fx.clipInit = true;
2856			}
2857
2858			$( fx.elem ).cssClip( {
2859				top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top,
2860				right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right,
2861				bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom,
2862				left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left
2863			} );
2864		};
2865
2866	} )();
2867
2868	/******************************************************************************/
2869	/*********************************** EASING ***********************************/
2870	/******************************************************************************/
2871
2872	( function() {
2873
2874// Based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
2875
2876		var baseEasings = {};
2877
2878		$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
2879			baseEasings[ name ] = function( p ) {
2880				return Math.pow( p, i + 2 );
2881			};
2882		} );
2883
2884		$.extend( baseEasings, {
2885			Sine: function( p ) {
2886				return 1 - Math.cos( p * Math.PI / 2 );
2887			},
2888			Circ: function( p ) {
2889				return 1 - Math.sqrt( 1 - p * p );
2890			},
2891			Elastic: function( p ) {
2892				return p === 0 || p === 1 ? p :
2893				-Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );
2894			},
2895			Back: function( p ) {
2896				return p * p * ( 3 * p - 2 );
2897			},
2898			Bounce: function( p ) {
2899				var pow2,
2900					bounce = 4;
2901
2902				while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
2903				return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
2904			}
2905		} );
2906
2907		$.each( baseEasings, function( name, easeIn ) {
2908			$.easing[ "easeIn" + name ] = easeIn;
2909			$.easing[ "easeOut" + name ] = function( p ) {
2910				return 1 - easeIn( 1 - p );
2911			};
2912			$.easing[ "easeInOut" + name ] = function( p ) {
2913				return p < 0.5 ?
2914				easeIn( p * 2 ) / 2 :
2915				1 - easeIn( p * -2 + 2 ) / 2;
2916			};
2917		} );
2918
2919	} )();
2920
2921	var effect = $.effects;
2922
2923
2924	/*!
2925	 * jQuery UI Effects Blind 1.12.1
2926	 * http://jqueryui.com
2927	 *
2928	 * Copyright jQuery Foundation and other contributors
2929	 * Released under the MIT license.
2930	 * http://jquery.org/license
2931	 */
2932
2933//>>label: Blind Effect
2934//>>group: Effects
2935//>>description: Blinds the element.
2936//>>docs: http://api.jqueryui.com/blind-effect/
2937//>>demos: http://jqueryui.com/effect/
2938
2939
2940
2941	var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) {
2942		var map = {
2943				up: [ "bottom", "top" ],
2944				vertical: [ "bottom", "top" ],
2945				down: [ "top", "bottom" ],
2946				left: [ "right", "left" ],
2947				horizontal: [ "right", "left" ],
2948				right: [ "left", "right" ]
2949			},
2950			element = $( this ),
2951			direction = options.direction || "up",
2952			start = element.cssClip(),
2953			animate = { clip: $.extend( {}, start ) },
2954			placeholder = $.effects.createPlaceholder( element );
2955
2956		animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ];
2957
2958		if ( options.mode === "show" ) {
2959			element.cssClip( animate.clip );
2960			if ( placeholder ) {
2961				placeholder.css( $.effects.clipToBox( animate ) );
2962			}
2963
2964			animate.clip = start;
2965		}
2966
2967		if ( placeholder ) {
2968			placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing );
2969		}
2970
2971		element.animate( animate, {
2972			queue: false,
2973			duration: options.duration,
2974			easing: options.easing,
vendor: 10,962 bytes, lines 2975-3389
2975			complete: done
2976		} );
2977	} );
2978
2979
2980	/*!
2981	 * jQuery UI Effects Bounce 1.12.1
2982	 * http://jqueryui.com
2983	 *
2984	 * Copyright jQuery Foundation and other contributors
2985	 * Released under the MIT license.
2986	 * http://jquery.org/license
2987	 */
2988
2989//>>label: Bounce Effect
2990//>>group: Effects
2991//>>description: Bounces an element horizontally or vertically n times.
2992//>>docs: http://api.jqueryui.com/bounce-effect/
2993//>>demos: http://jqueryui.com/effect/
2994
2995
2996
2997	var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) {
2998		var upAnim, downAnim, refValue,
2999			element = $( this ),
3000
3001		// Defaults:
3002			mode = options.mode,
3003			hide = mode === "hide",
3004			show = mode === "show",
3005			direction = options.direction || "up",
3006			distance = options.distance,
3007			times = options.times || 5,
3008
3009		// Number of internal animations
3010			anims = times * 2 + ( show || hide ? 1 : 0 ),
3011			speed = options.duration / anims,
3012			easing = options.easing,
3013
3014		// Utility:
3015			ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3016			motion = ( direction === "up" || direction === "left" ),
3017			i = 0,
3018
3019			queuelen = element.queue().length;
3020
3021		$.effects.createPlaceholder( element );
3022
3023		refValue = element.css( ref );
3024
3025		// Default distance for the BIGGEST bounce is the outer Distance / 3
3026		if ( !distance ) {
3027			distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
3028		}
3029
3030		if ( show ) {
3031			downAnim = { opacity: 1 };
3032			downAnim[ ref ] = refValue;
3033
3034			// If we are showing, force opacity 0 and set the initial position
3035			// then do the "first" animation
3036			element
3037				.css( "opacity", 0 )
3038				.css( ref, motion ? -distance * 2 : distance * 2 )
3039				.animate( downAnim, speed, easing );
3040		}
3041
3042		// Start at the smallest distance if we are hiding
3043		if ( hide ) {
3044			distance = distance / Math.pow( 2, times - 1 );
3045		}
3046
3047		downAnim = {};
3048		downAnim[ ref ] = refValue;
3049
3050		// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
3051		for ( ; i < times; i++ ) {
3052			upAnim = {};
3053			upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
3054
3055			element
3056				.animate( upAnim, speed, easing )
3057				.animate( downAnim, speed, easing );
3058
3059			distance = hide ? distance * 2 : distance / 2;
3060		}
3061
3062		// Last Bounce when Hiding
3063		if ( hide ) {
3064			upAnim = { opacity: 0 };
3065			upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
3066
3067			element.animate( upAnim, speed, easing );
3068		}
3069
3070		element.queue( done );
3071
3072		$.effects.unshift( element, queuelen, anims + 1 );
3073	} );
3074
3075
3076	/*!
3077	 * jQuery UI Effects Clip 1.12.1
3078	 * http://jqueryui.com
3079	 *
3080	 * Copyright jQuery Foundation and other contributors
3081	 * Released under the MIT license.
3082	 * http://jquery.org/license
3083	 */
3084
3085//>>label: Clip Effect
3086//>>group: Effects
3087//>>description: Clips the element on and off like an old TV.
3088//>>docs: http://api.jqueryui.com/clip-effect/
3089//>>demos: http://jqueryui.com/effect/
3090
3091
3092
3093	var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) {
3094		var start,
3095			animate = {},
3096			element = $( this ),
3097			direction = options.direction || "vertical",
3098			both = direction === "both",
3099			horizontal = both || direction === "horizontal",
3100			vertical = both || direction === "vertical";
3101
3102		start = element.cssClip();
3103		animate.clip = {
3104			top: vertical ? ( start.bottom - start.top ) / 2 : start.top,
3105			right: horizontal ? ( start.right - start.left ) / 2 : start.right,
3106			bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom,
3107			left: horizontal ? ( start.right - start.left ) / 2 : start.left
3108		};
3109
3110		$.effects.createPlaceholder( element );
3111
3112		if ( options.mode === "show" ) {
3113			element.cssClip( animate.clip );
3114			animate.clip = start;
3115		}
3116
3117		element.animate( animate, {
3118			queue: false,
3119			duration: options.duration,
3120			easing: options.easing,
3121			complete: done
3122		} );
3123
3124	} );
3125
3126
3127	/*!
3128	 * jQuery UI Effects Drop 1.12.1
3129	 * http://jqueryui.com
3130	 *
3131	 * Copyright jQuery Foundation and other contributors
3132	 * Released under the MIT license.
3133	 * http://jquery.org/license
3134	 */
3135
3136//>>label: Drop Effect
3137//>>group: Effects
3138//>>description: Moves an element in one direction and hides it at the same time.
3139//>>docs: http://api.jqueryui.com/drop-effect/
3140//>>demos: http://jqueryui.com/effect/
3141
3142
3143
3144	var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) {
3145
3146		var distance,
3147			element = $( this ),
3148			mode = options.mode,
3149			show = mode === "show",
3150			direction = options.direction || "left",
3151			ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3152			motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=",
3153			oppositeMotion = ( motion === "+=" ) ? "-=" : "+=",
3154			animation = {
3155				opacity: 0
3156			};
3157
3158		$.effects.createPlaceholder( element );
3159
3160		distance = options.distance ||
3161			element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
3162
3163		animation[ ref ] = motion + distance;
3164
3165		if ( show ) {
3166			element.css( animation );
3167
3168			animation[ ref ] = oppositeMotion + distance;
3169			animation.opacity = 1;
3170		}
3171
3172		// Animate
3173		element.animate( animation, {
3174			queue: false,
3175			duration: options.duration,
3176			easing: options.easing,
3177			complete: done
3178		} );
3179	} );
3180
3181
3182	/*!
3183	 * jQuery UI Effects Explode 1.12.1
3184	 * http://jqueryui.com
3185	 *
3186	 * Copyright jQuery Foundation and other contributors
3187	 * Released under the MIT license.
3188	 * http://jquery.org/license
3189	 */
3190
3191//>>label: Explode Effect
3192//>>group: Effects
3193// jscs:disable maximumLineLength
3194//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness.
3195// jscs:enable maximumLineLength
3196//>>docs: http://api.jqueryui.com/explode-effect/
3197//>>demos: http://jqueryui.com/effect/
3198
3199
3200
3201	var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) {
3202
3203		var i, j, left, top, mx, my,
3204			rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3,
3205			cells = rows,
3206			element = $( this ),
3207			mode = options.mode,
3208			show = mode === "show",
3209
3210		// Show and then visibility:hidden the element before calculating offset
3211			offset = element.show().css( "visibility", "hidden" ).offset(),
3212
3213		// Width and height of a piece
3214			width = Math.ceil( element.outerWidth() / cells ),
3215			height = Math.ceil( element.outerHeight() / rows ),
3216			pieces = [];
3217
3218		// Children animate complete:
3219		function childComplete() {
3220			pieces.push( this );
3221			if ( pieces.length === rows * cells ) {
3222				animComplete();
3223			}
3224		}
3225
3226		// Clone the element for each row and cell.
3227		for ( i = 0; i < rows; i++ ) { // ===>
3228			top = offset.top + i * height;
3229			my = i - ( rows - 1 ) / 2;
3230
3231			for ( j = 0; j < cells; j++ ) { // |||
3232				left = offset.left + j * width;
3233				mx = j - ( cells - 1 ) / 2;
3234
3235				// Create a clone of the now hidden main element that will be absolute positioned
3236				// within a wrapper div off the -left and -top equal to size of our pieces
3237				element
3238					.clone()
3239					.appendTo( "body" )
3240					.wrap( "<div></div>" )
3241					.css( {
3242						position: "absolute",
3243						visibility: "visible",
3244						left: -j * width,
3245						top: -i * height
3246					} )
3247
3248					// Select the wrapper - make it overflow: hidden and absolute positioned based on
3249					// where the original was located +left and +top equal to the size of pieces
3250					.parent()
3251					.addClass( "ui-effects-explode" )
3252					.css( {
3253						position: "absolute",
3254						overflow: "hidden",
3255						width: width,
3256						height: height,
3257						left: left + ( show ? mx * width : 0 ),
3258						top: top + ( show ? my * height : 0 ),
3259						opacity: show ? 0 : 1
3260					} )
3261					.animate( {
3262						left: left + ( show ? 0 : mx * width ),
3263						top: top + ( show ? 0 : my * height ),
3264						opacity: show ? 1 : 0
3265					}, options.duration || 500, options.easing, childComplete );
3266			}
3267		}
3268
3269		function animComplete() {
3270			element.css( {
3271				visibility: "visible"
3272			} );
3273			$( pieces ).remove();
3274			done();
3275		}
3276	} );
3277
3278
3279	/*!
3280	 * jQuery UI Effects Fade 1.12.1
3281	 * http://jqueryui.com
3282	 *
3283	 * Copyright jQuery Foundation and other contributors
3284	 * Released under the MIT license.
3285	 * http://jquery.org/license
3286	 */
3287
3288//>>label: Fade Effect
3289//>>group: Effects
3290//>>description: Fades the element.
3291//>>docs: http://api.jqueryui.com/fade-effect/
3292//>>demos: http://jqueryui.com/effect/
3293
3294
3295
3296	var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) {
3297		var show = options.mode === "show";
3298
3299		$( this )
3300			.css( "opacity", show ? 0 : 1 )
3301			.animate( {
3302				opacity: show ? 1 : 0
3303			}, {
3304				queue: false,
3305				duration: options.duration,
3306				easing: options.easing,
3307				complete: done
3308			} );
3309	} );
3310
3311
3312	/*!
3313	 * jQuery UI Effects Fold 1.12.1
3314	 * http://jqueryui.com
3315	 *
3316	 * Copyright jQuery Foundation and other contributors
3317	 * Released under the MIT license.
3318	 * http://jquery.org/license
3319	 */
3320
3321//>>label: Fold Effect
3322//>>group: Effects
3323//>>description: Folds an element first horizontally and then vertically.
3324//>>docs: http://api.jqueryui.com/fold-effect/
3325//>>demos: http://jqueryui.com/effect/
3326
3327
3328
3329	var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) {
3330
3331		// Create element
3332		var element = $( this ),
3333			mode = options.mode,
3334			show = mode === "show",
3335			hide = mode === "hide",
3336			size = options.size || 15,
3337			percent = /([0-9]+)%/.exec( size ),
3338			horizFirst = !!options.horizFirst,
3339			ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ],
3340			duration = options.duration / 2,
3341
3342			placeholder = $.effects.createPlaceholder( element ),
3343
3344			start = element.cssClip(),
3345			animation1 = { clip: $.extend( {}, start ) },
3346			animation2 = { clip: $.extend( {}, start ) },
3347
3348			distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ],
3349
3350			queuelen = element.queue().length;
3351
3352		if ( percent ) {
3353			size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
3354		}
3355		animation1.clip[ ref[ 0 ] ] = size;
3356		animation2.clip[ ref[ 0 ] ] = size;
3357		animation2.clip[ ref[ 1 ] ] = 0;
3358
3359		if ( show ) {
3360			element.cssClip( animation2.clip );
3361			if ( placeholder ) {
3362				placeholder.css( $.effects.clipToBox( animation2 ) );
3363			}
3364
3365			animation2.clip = start;
3366		}
3367
3368		// Animate
3369		element
3370			.queue( function( next ) {
3371				if ( placeholder ) {
3372					placeholder
3373						.animate( $.effects.clipToBox( animation1 ), duration, options.easing )
3374						.animate( $.effects.clipToBox( animation2 ), duration, options.easing );
3375				}
3376
3377				next();
3378			} )
3379			.animate( animation1, duration, options.easing )
3380			.animate( animation2, duration, options.easing )
3381			.queue( done );
3382
3383		$.effects.unshift( element, queuelen, 4 );
3384	} );
3385
3386
3387	/*!
3388	 * jQuery UI Effects Highlight 1.12.1
3389	 * http://jqueryui.com
vendor: 5,826 bytes, lines 3390-3581
3390	 *
3391	 * Copyright jQuery Foundation and other contributors
3392	 * Released under the MIT license.
3393	 * http://jquery.org/license
3394	 */
3395
3396//>>label: Highlight Effect
3397//>>group: Effects
3398//>>description: Highlights the background of an element in a defined color for a custom duration.
3399//>>docs: http://api.jqueryui.com/highlight-effect/
3400//>>demos: http://jqueryui.com/effect/
3401
3402
3403
3404	var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) {
3405		var element = $( this ),
3406			animation = {
3407				backgroundColor: element.css( "backgroundColor" )
3408			};
3409
3410		if ( options.mode === "hide" ) {
3411			animation.opacity = 0;
3412		}
3413
3414		$.effects.saveStyle( element );
3415
3416		element
3417			.css( {
3418				backgroundImage: "none",
3419				backgroundColor: options.color || "#ffff99"
3420			} )
3421			.animate( animation, {
3422				queue: false,
3423				duration: options.duration,
3424				easing: options.easing,
3425				complete: done
3426			} );
3427	} );
3428
3429
3430	/*!
3431	 * jQuery UI Effects Size 1.12.1
3432	 * http://jqueryui.com
3433	 *
3434	 * Copyright jQuery Foundation and other contributors
3435	 * Released under the MIT license.
3436	 * http://jquery.org/license
3437	 */
3438
3439//>>label: Size Effect
3440//>>group: Effects
3441//>>description: Resize an element to a specified width and height.
3442//>>docs: http://api.jqueryui.com/size-effect/
3443//>>demos: http://jqueryui.com/effect/
3444
3445
3446
3447	var effectsEffectSize = $.effects.define( "size", function( options, done ) {
3448
3449		// Create element
3450		var baseline, factor, temp,
3451			element = $( this ),
3452
3453		// Copy for children
3454			cProps = [ "fontSize" ],
3455			vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
3456			hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
3457
3458		// Set options
3459			mode = options.mode,
3460			restore = mode !== "effect",
3461			scale = options.scale || "both",
3462			origin = options.origin || [ "middle", "center" ],
3463			position = element.css( "position" ),
3464			pos = element.position(),
3465			original = $.effects.scaledDimensions( element ),
3466			from = options.from || original,
3467			to = options.to || $.effects.scaledDimensions( element, 0 );
3468
3469		$.effects.createPlaceholder( element );
3470
3471		if ( mode === "show" ) {
3472			temp = from;
3473			from = to;
3474			to = temp;
3475		}
3476
3477		// Set scaling factor
3478		factor = {
3479			from: {
3480				y: from.height / original.height,
3481				x: from.width / original.width
3482			},
3483			to: {
3484				y: to.height / original.height,
3485				x: to.width / original.width
3486			}
3487		};
3488
3489		// Scale the css box
3490		if ( scale === "box" || scale === "both" ) {
3491
3492			// Vertical props scaling
3493			if ( factor.from.y !== factor.to.y ) {
3494				from = $.effects.setTransition( element, vProps, factor.from.y, from );
3495				to = $.effects.setTransition( element, vProps, factor.to.y, to );
3496			}
3497
3498			// Horizontal props scaling
3499			if ( factor.from.x !== factor.to.x ) {
3500				from = $.effects.setTransition( element, hProps, factor.from.x, from );
3501				to = $.effects.setTransition( element, hProps, factor.to.x, to );
3502			}
3503		}
3504
3505		// Scale the content
3506		if ( scale === "content" || scale === "both" ) {
3507
3508			// Vertical props scaling
3509			if ( factor.from.y !== factor.to.y ) {
3510				from = $.effects.setTransition( element, cProps, factor.from.y, from );
3511				to = $.effects.setTransition( element, cProps, factor.to.y, to );
3512			}
3513		}
3514
3515		// Adjust the position properties based on the provided origin points
3516		if ( origin ) {
3517			baseline = $.effects.getBaseline( origin, original );
3518			from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top;
3519			from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left;
3520			to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top;
3521			to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left;
3522		}
3523		element.css( from );
3524
3525		// Animate the children if desired
3526		if ( scale === "content" || scale === "both" ) {
3527
3528			vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps );
3529			hProps = hProps.concat( [ "marginLeft", "marginRight" ] );
3530
3531			// Only animate children with width attributes specified
3532			// TODO: is this right? should we include anything with css width specified as well
3533			element.find( "*[width]" ).each( function() {
3534				var child = $( this ),
3535					childOriginal = $.effects.scaledDimensions( child ),
3536					childFrom = {
3537						height: childOriginal.height * factor.from.y,
3538						width: childOriginal.width * factor.from.x,
3539						outerHeight: childOriginal.outerHeight * factor.from.y,
3540						outerWidth: childOriginal.outerWidth * factor.from.x
3541					},
3542					childTo = {
3543						height: childOriginal.height * factor.to.y,
3544						width: childOriginal.width * factor.to.x,
3545						outerHeight: childOriginal.height * factor.to.y,
3546						outerWidth: childOriginal.width * factor.to.x
3547					};
3548
3549				// Vertical props scaling
3550				if ( factor.from.y !== factor.to.y ) {
3551					childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom );
3552					childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo );
3553				}
3554
3555				// Horizontal props scaling
3556				if ( factor.from.x !== factor.to.x ) {
3557					childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom );
3558					childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo );
3559				}
3560
3561				if ( restore ) {
3562					$.effects.saveStyle( child );
3563				}
3564
3565				// Animate children
3566				child.css( childFrom );
3567				child.animate( childTo, options.duration, options.easing, function() {
3568
3569					// Restore children
3570					if ( restore ) {
3571						$.effects.restoreStyle( child );
3572					}
3573				} );
3574			} );
3575		}
3576
3577		// Animate
3578		element.animate( to, {
3579			queue: false,
3580			duration: options.duration,
3581			easing: options.easing,
vendor: 5,500 bytes, lines 3582-3787
3582			complete: function() {
3583
3584				var offset = element.offset();
3585
3586				if ( to.opacity === 0 ) {
3587					element.css( "opacity", from.opacity );
3588				}
3589
3590				if ( !restore ) {
3591					element
3592						.css( "position", position === "static" ? "relative" : position )
3593						.offset( offset );
3594
3595					// Need to save style here so that automatic style restoration
3596					// doesn't restore to the original styles from before the animation.
3597					$.effects.saveStyle( element );
3598				}
3599
3600				done();
3601			}
3602		} );
3603
3604	} );
3605
3606
3607	/*!
3608	 * jQuery UI Effects Scale 1.12.1
3609	 * http://jqueryui.com
3610	 *
3611	 * Copyright jQuery Foundation and other contributors
3612	 * Released under the MIT license.
3613	 * http://jquery.org/license
3614	 */
3615
3616//>>label: Scale Effect
3617//>>group: Effects
3618//>>description: Grows or shrinks an element and its content.
3619//>>docs: http://api.jqueryui.com/scale-effect/
3620//>>demos: http://jqueryui.com/effect/
3621
3622
3623
3624	var effectsEffectScale = $.effects.define( "scale", function( options, done ) {
3625
3626		// Create element
3627		var el = $( this ),
3628			mode = options.mode,
3629			percent = parseInt( options.percent, 10 ) ||
3630				( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ),
3631
3632			newOptions = $.extend( true, {
3633				from: $.effects.scaledDimensions( el ),
3634				to: $.effects.scaledDimensions( el, percent, options.direction || "both" ),
3635				origin: options.origin || [ "middle", "center" ]
3636			}, options );
3637
3638		// Fade option to support puff
3639		if ( options.fade ) {
3640			newOptions.from.opacity = 1;
3641			newOptions.to.opacity = 0;
3642		}
3643
3644		$.effects.effect.size.call( this, newOptions, done );
3645	} );
3646
3647
3648	/*!
3649	 * jQuery UI Effects Puff 1.12.1
3650	 * http://jqueryui.com
3651	 *
3652	 * Copyright jQuery Foundation and other contributors
3653	 * Released under the MIT license.
3654	 * http://jquery.org/license
3655	 */
3656
3657//>>label: Puff Effect
3658//>>group: Effects
3659//>>description: Creates a puff effect by scaling the element up and hiding it at the same time.
3660//>>docs: http://api.jqueryui.com/puff-effect/
3661//>>demos: http://jqueryui.com/effect/
3662
3663
3664
3665	var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) {
3666		var newOptions = $.extend( true, {}, options, {
3667			fade: true,
3668			percent: parseInt( options.percent, 10 ) || 150
3669		} );
3670
3671		$.effects.effect.scale.call( this, newOptions, done );
3672	} );
3673
3674
3675	/*!
3676	 * jQuery UI Effects Pulsate 1.12.1
3677	 * http://jqueryui.com
3678	 *
3679	 * Copyright jQuery Foundation and other contributors
3680	 * Released under the MIT license.
3681	 * http://jquery.org/license
3682	 */
3683
3684//>>label: Pulsate Effect
3685//>>group: Effects
3686//>>description: Pulsates an element n times by changing the opacity to zero and back.
3687//>>docs: http://api.jqueryui.com/pulsate-effect/
3688//>>demos: http://jqueryui.com/effect/
3689
3690
3691
3692	var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) {
3693		var element = $( this ),
3694			mode = options.mode,
3695			show = mode === "show",
3696			hide = mode === "hide",
3697			showhide = show || hide,
3698
3699		// Showing or hiding leaves off the "last" animation
3700			anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
3701			duration = options.duration / anims,
3702			animateTo = 0,
3703			i = 1,
3704			queuelen = element.queue().length;
3705
3706		if ( show || !element.is( ":visible" ) ) {
3707			element.css( "opacity", 0 ).show();
3708			animateTo = 1;
3709		}
3710
3711		// Anims - 1 opacity "toggles"
3712		for ( ; i < anims; i++ ) {
3713			element.animate( { opacity: animateTo }, duration, options.easing );
3714			animateTo = 1 - animateTo;
3715		}
3716
3717		element.animate( { opacity: animateTo }, duration, options.easing );
3718
3719		element.queue( done );
3720
3721		$.effects.unshift( element, queuelen, anims + 1 );
3722	} );
3723
3724
3725	/*!
3726	 * jQuery UI Effects Shake 1.12.1
3727	 * http://jqueryui.com
3728	 *
3729	 * Copyright jQuery Foundation and other contributors
3730	 * Released under the MIT license.
3731	 * http://jquery.org/license
3732	 */
3733
3734//>>label: Shake Effect
3735//>>group: Effects
3736//>>description: Shakes an element horizontally or vertically n times.
3737//>>docs: http://api.jqueryui.com/shake-effect/
3738//>>demos: http://jqueryui.com/effect/
3739
3740
3741
3742	var effectsEffectShake = $.effects.define( "shake", function( options, done ) {
3743
3744		var i = 1,
3745			element = $( this ),
3746			direction = options.direction || "left",
3747			distance = options.distance || 20,
3748			times = options.times || 3,
3749			anims = times * 2 + 1,
3750			speed = Math.round( options.duration / anims ),
3751			ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3752			positiveMotion = ( direction === "up" || direction === "left" ),
3753			animation = {},
3754			animation1 = {},
3755			animation2 = {},
3756
3757			queuelen = element.queue().length;
3758
3759		$.effects.createPlaceholder( element );
3760
3761		// Animation
3762		animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
3763		animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
3764		animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
3765
3766		// Animate
3767		element.animate( animation, speed, options.easing );
3768
3769		// Shakes
3770		for ( ; i < times; i++ ) {
3771			element
3772				.animate( animation1, speed, options.easing )
3773				.animate( animation2, speed, options.easing );
3774		}
3775
3776		element
3777			.animate( animation1, speed, options.easing )
3778			.animate( animation, speed / 2, options.easing )
3779			.queue( done );
3780
3781		$.effects.unshift( element, queuelen, anims + 1 );
3782	} );
3783
3784
3785	/*!
3786	 * jQuery UI Effects Slide 1.12.1
3787	 * http://jqueryui.com
vendor: 15,206 bytes, lines 3788-4351
3788	 *
3789	 * Copyright jQuery Foundation and other contributors
3790	 * Released under the MIT license.
3791	 * http://jquery.org/license
3792	 */
3793
3794//>>label: Slide Effect
3795//>>group: Effects
3796//>>description: Slides an element in and out of the viewport.
3797//>>docs: http://api.jqueryui.com/slide-effect/
3798//>>demos: http://jqueryui.com/effect/
3799
3800
3801
3802	var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) {
3803		var startClip, startRef,
3804			element = $( this ),
3805			map = {
3806				up: [ "bottom", "top" ],
3807				down: [ "top", "bottom" ],
3808				left: [ "right", "left" ],
3809				right: [ "left", "right" ]
3810			},
3811			mode = options.mode,
3812			direction = options.direction || "left",
3813			ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3814			positiveMotion = ( direction === "up" || direction === "left" ),
3815			distance = options.distance ||
3816				element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ),
3817			animation = {};
3818
3819		$.effects.createPlaceholder( element );
3820
3821		startClip = element.cssClip();
3822		startRef = element.position()[ ref ];
3823
3824		// Define hide animation
3825		animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef;
3826		animation.clip = element.cssClip();
3827		animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ];
3828
3829		// Reverse the animation if we're showing
3830		if ( mode === "show" ) {
3831			element.cssClip( animation.clip );
3832			element.css( ref, animation[ ref ] );
3833			animation.clip = startClip;
3834			animation[ ref ] = startRef;
3835		}
3836
3837		// Actually animate
3838		element.animate( animation, {
3839			queue: false,
3840			duration: options.duration,
3841			easing: options.easing,
3842			complete: done
3843		} );
3844	} );
3845
3846
3847	/*!
3848	 * jQuery UI Effects Transfer 1.12.1
3849	 * http://jqueryui.com
3850	 *
3851	 * Copyright jQuery Foundation and other contributors
3852	 * Released under the MIT license.
3853	 * http://jquery.org/license
3854	 */
3855
3856//>>label: Transfer Effect
3857//>>group: Effects
3858//>>description: Displays a transfer effect from one element to another.
3859//>>docs: http://api.jqueryui.com/transfer-effect/
3860//>>demos: http://jqueryui.com/effect/
3861
3862
3863
3864	var effect;
3865	if ( $.uiBackCompat !== false ) {
3866		effect = $.effects.define( "transfer", function( options, done ) {
3867			$( this ).transfer( options, done );
3868		} );
3869	}
3870	var effectsEffectTransfer = effect;
3871
3872
3873	/*!
3874	 * jQuery UI Focusable 1.12.1
3875	 * http://jqueryui.com
3876	 *
3877	 * Copyright jQuery Foundation and other contributors
3878	 * Released under the MIT license.
3879	 * http://jquery.org/license
3880	 */
3881
3882//>>label: :focusable Selector
3883//>>group: Core
3884//>>description: Selects elements which can be focused.
3885//>>docs: http://api.jqueryui.com/focusable-selector/
3886
3887
3888
3889// Selectors
3890	$.ui.focusable = function( element, hasTabindex ) {
3891		var map, mapName, img, focusableIfVisible, fieldset,
3892			nodeName = element.nodeName.toLowerCase();
3893
3894		if ( "area" === nodeName ) {
3895			map = element.parentNode;
3896			mapName = map.name;
3897			if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
3898				return false;
3899			}
3900			img = $( "img[usemap='#" + mapName + "']" );
3901			return img.length > 0 && img.is( ":visible" );
3902		}
3903
3904		if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) {
3905			focusableIfVisible = !element.disabled;
3906
3907			if ( focusableIfVisible ) {
3908
3909				// Form controls within a disabled fieldset are disabled.
3910				// However, controls within the fieldset's legend do not get disabled.
3911				// Since controls generally aren't placed inside legends, we skip
3912				// this portion of the check.
3913				fieldset = $( element ).closest( "fieldset" )[ 0 ];
3914				if ( fieldset ) {
3915					focusableIfVisible = !fieldset.disabled;
3916				}
3917			}
3918		} else if ( "a" === nodeName ) {
3919			focusableIfVisible = element.href || hasTabindex;
3920		} else {
3921			focusableIfVisible = hasTabindex;
3922		}
3923
3924		return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) );
3925	};
3926
3927// Support: IE 8 only
3928// IE 8 doesn't resolve inherit to visible/hidden for computed values
3929	function visible( element ) {
3930		var visibility = element.css( "visibility" );
3931		while ( visibility === "inherit" ) {
3932			element = element.parent();
3933			visibility = element.css( "visibility" );
3934		}
3935		return visibility !== "hidden";
3936	}
3937
3938	$.extend( $.expr[ ":" ], {
3939		focusable: function( element ) {
3940			return $.ui.focusable( element, $.attr( element, "tabindex" ) != null );
3941		}
3942	} );
3943
3944	var focusable = $.ui.focusable;
3945
3946
3947
3948
3949// Support: IE8 Only
3950// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop
3951// with a string, so we need to find the proper form.
3952	var form = $.fn.form = function() {
3953		return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form );
3954	};
3955
3956
3957	/*!
3958	 * jQuery UI Form Reset Mixin 1.12.1
3959	 * http://jqueryui.com
3960	 *
3961	 * Copyright jQuery Foundation and other contributors
3962	 * Released under the MIT license.
3963	 * http://jquery.org/license
3964	 */
3965
3966//>>label: Form Reset Mixin
3967//>>group: Core
3968//>>description: Refresh input widgets when their form is reset
3969//>>docs: http://api.jqueryui.com/form-reset-mixin/
3970
3971
3972
3973	var formResetMixin = $.ui.formResetMixin = {
3974		_formResetHandler: function() {
3975			var form = $( this );
3976
3977			// Wait for the form reset to actually happen before refreshing
3978			setTimeout( function() {
3979				var instances = form.data( "ui-form-reset-instances" );
3980				$.each( instances, function() {
3981					this.refresh();
3982				} );
3983			} );
3984		},
3985
3986		_bindFormResetHandler: function() {
3987			this.form = this.element.form();
3988			if ( !this.form.length ) {
3989				return;
3990			}
3991
3992			var instances = this.form.data( "ui-form-reset-instances" ) || [];
3993			if ( !instances.length ) {
3994
3995				// We don't use _on() here because we use a single event handler per form
3996				this.form.on( "reset.ui-form-reset", this._formResetHandler );
3997			}
3998			instances.push( this );
3999			this.form.data( "ui-form-reset-instances", instances );
4000		},
4001
4002		_unbindFormResetHandler: function() {
4003			if ( !this.form.length ) {
4004				return;
4005			}
4006
4007			var instances = this.form.data( "ui-form-reset-instances" );
4008			instances.splice( $.inArray( this, instances ), 1 );
4009			if ( instances.length ) {
4010				this.form.data( "ui-form-reset-instances", instances );
4011			} else {
4012				this.form
4013					.removeData( "ui-form-reset-instances" )
4014					.off( "reset.ui-form-reset" );
4015			}
4016		}
4017	};
4018
4019
4020	/*!
4021	 * jQuery UI Support for jQuery core 1.7.x 1.12.1
4022	 * http://jqueryui.com
4023	 *
4024	 * Copyright jQuery Foundation and other contributors
4025	 * Released under the MIT license.
4026	 * http://jquery.org/license
4027	 *
4028	 */
4029
4030//>>label: jQuery 1.7 Support
4031//>>group: Core
4032//>>description: Support version 1.7.x of jQuery core
4033
4034
4035
4036// Support: jQuery 1.7 only
4037// Not a great way to check versions, but since we only support 1.7+ and only
4038// need to detect <1.8, this is a simple check that should suffice. Checking
4039// for "1.7." would be a bit safer, but the version string is 1.7, not 1.7.0
4040// and we'll never reach 1.70.0 (if we do, we certainly won't be supporting
4041// 1.7 anymore). See #11197 for why we're not using feature detection.
4042	if ( $.fn.jquery.substring( 0, 3 ) === "1.7" ) {
4043
4044		// Setters for .innerWidth(), .innerHeight(), .outerWidth(), .outerHeight()
4045		// Unlike jQuery Core 1.8+, these only support numeric values to set the
4046		// dimensions in pixels
4047		$.each( [ "Width", "Height" ], function( i, name ) {
4048			var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
4049				type = name.toLowerCase(),
4050				orig = {
4051					innerWidth: $.fn.innerWidth,
4052					innerHeight: $.fn.innerHeight,
4053					outerWidth: $.fn.outerWidth,
4054					outerHeight: $.fn.outerHeight
4055				};
4056
4057			function reduce( elem, size, border, margin ) {
4058				$.each( side, function() {
4059					size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
4060					if ( border ) {
4061						size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
4062					}
4063					if ( margin ) {
4064						size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
4065					}
4066				} );
4067				return size;
4068			}
4069
4070			$.fn[ "inner" + name ] = function( size ) {
4071				if ( size === undefined ) {
4072					return orig[ "inner" + name ].call( this );
4073				}
4074
4075				return this.each( function() {
4076					$( this ).css( type, reduce( this, size ) + "px" );
4077				} );
4078			};
4079
4080			$.fn[ "outer" + name ] = function( size, margin ) {
4081				if ( typeof size !== "number" ) {
4082					return orig[ "outer" + name ].call( this, size );
4083				}
4084
4085				return this.each( function() {
4086					$( this ).css( type, reduce( this, size, true, margin ) + "px" );
4087				} );
4088			};
4089		} );
4090
4091		$.fn.addBack = function( selector ) {
4092			return this.add( selector == null ?
4093					this.prevObject : this.prevObject.filter( selector )
4094			);
4095		};
4096	}
4097
4098	;
4099	/*!
4100	 * jQuery UI Keycode 1.12.1
4101	 * http://jqueryui.com
4102	 *
4103	 * Copyright jQuery Foundation and other contributors
4104	 * Released under the MIT license.
4105	 * http://jquery.org/license
4106	 */
4107
4108//>>label: Keycode
4109//>>group: Core
4110//>>description: Provide keycodes as keynames
4111//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/
4112
4113
4114	var keycode = $.ui.keyCode = {
4115		BACKSPACE: 8,
4116		COMMA: 188,
4117		DELETE: 46,
4118		DOWN: 40,
4119		END: 35,
4120		ENTER: 13,
4121		ESCAPE: 27,
4122		HOME: 36,
4123		LEFT: 37,
4124		PAGE_DOWN: 34,
4125		PAGE_UP: 33,
4126		PERIOD: 190,
4127		RIGHT: 39,
4128		SPACE: 32,
4129		TAB: 9,
4130		UP: 38
4131	};
4132
4133
4134
4135
4136// Internal use only
4137	var escapeSelector = $.ui.escapeSelector = ( function() {
4138		var selectorEscape = /([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;
4139		return function( selector ) {
4140			return selector.replace( selectorEscape, "\\$1" );
4141		};
4142	} )();
4143
4144
4145	/*!
4146	 * jQuery UI Labels 1.12.1
4147	 * http://jqueryui.com
4148	 *
4149	 * Copyright jQuery Foundation and other contributors
4150	 * Released under the MIT license.
4151	 * http://jquery.org/license
4152	 */
4153
4154//>>label: labels
4155//>>group: Core
4156//>>description: Find all the labels associated with a given input
4157//>>docs: http://api.jqueryui.com/labels/
4158
4159
4160
4161	var labels = $.fn.labels = function() {
4162		var ancestor, selector, id, labels, ancestors;
4163
4164		// Check control.labels first
4165		if ( this[ 0 ].labels && this[ 0 ].labels.length ) {
4166			return this.pushStack( this[ 0 ].labels );
4167		}
4168
4169		// Support: IE <= 11, FF <= 37, Android <= 2.3 only
4170		// Above browsers do not support control.labels. Everything below is to support them
4171		// as well as document fragments. control.labels does not work on document fragments
4172		labels = this.eq( 0 ).parents( "label" );
4173
4174		// Look for the label based on the id
4175		id = this.attr( "id" );
4176		if ( id ) {
4177
4178			// We don't search against the document in case the element
4179			// is disconnected from the DOM
4180			ancestor = this.eq( 0 ).parents().last();
4181
4182			// Get a full set of top level ancestors
4183			ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() );
4184
4185			// Create a selector for the label based on the id
4186			selector = "label[for='" + $.ui.escapeSelector( id ) + "']";
4187
4188			labels = labels.add( ancestors.find( selector ).addBack( selector ) );
4189
4190		}
4191
4192		// Return whatever we have found for labels
4193		return this.pushStack( labels );
4194	};
4195
4196
4197	/*!
4198	 * jQuery UI Scroll Parent 1.12.1
4199	 * http://jqueryui.com
4200	 *
4201	 * Copyright jQuery Foundation and other contributors
4202	 * Released under the MIT license.
4203	 * http://jquery.org/license
4204	 */
4205
4206//>>label: scrollParent
4207//>>group: Core
4208//>>description: Get the closest ancestor element that is scrollable.
4209//>>docs: http://api.jqueryui.com/scrollParent/
4210
4211
4212
4213	var scrollParent = $.fn.scrollParent = function( includeHidden ) {
4214		var position = this.css( "position" ),
4215			excludeStaticParent = position === "absolute",
4216			overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
4217			scrollParent = this.parents().filter( function() {
4218				var parent = $( this );
4219				if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
4220					return false;
4221				}
4222				return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
4223					parent.css( "overflow-x" ) );
4224			} ).eq( 0 );
4225
4226		return position === "fixed" || !scrollParent.length ?
4227			$( this[ 0 ].ownerDocument || document ) :
4228			scrollParent;
4229	};
4230
4231
4232	/*!
4233	 * jQuery UI Tabbable 1.12.1
4234	 * http://jqueryui.com
4235	 *
4236	 * Copyright jQuery Foundation and other contributors
4237	 * Released under the MIT license.
4238	 * http://jquery.org/license
4239	 */
4240
4241//>>label: :tabbable Selector
4242//>>group: Core
4243//>>description: Selects elements which can be tabbed to.
4244//>>docs: http://api.jqueryui.com/tabbable-selector/
4245
4246
4247
4248	var tabbable = $.extend( $.expr[ ":" ], {
4249		tabbable: function( element ) {
4250			var tabIndex = $.attr( element, "tabindex" ),
4251				hasTabindex = tabIndex != null;
4252			return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex );
4253		}
4254	} );
4255
4256
4257	/*!
4258	 * jQuery UI Unique ID 1.12.1
4259	 * http://jqueryui.com
4260	 *
4261	 * Copyright jQuery Foundation and other contributors
4262	 * Released under the MIT license.
4263	 * http://jquery.org/license
4264	 */
4265
4266//>>label: uniqueId
4267//>>group: Core
4268//>>description: Functions to generate and remove uniqueId's
4269//>>docs: http://api.jqueryui.com/uniqueId/
4270
4271
4272
4273	var uniqueId = $.fn.extend( {
4274		uniqueId: ( function() {
4275			var uuid = 0;
4276
4277			return function() {
4278				return this.each( function() {
4279					if ( !this.id ) {
4280						this.id = "ui-id-" + ( ++uuid );
4281					}
4282				} );
4283			};
4284		} )(),
4285
4286		removeUniqueId: function() {
4287			return this.each( function() {
4288				if ( /^ui-id-\d+$/.test( this.id ) ) {
4289					$( this ).removeAttr( "id" );
4290				}
4291			} );
4292		}
4293	} );
4294
4295
4296	/*!
4297	 * jQuery UI Accordion 1.12.1
4298	 * http://jqueryui.com
4299	 *
4300	 * Copyright jQuery Foundation and other contributors
4301	 * Released under the MIT license.
4302	 * http://jquery.org/license
4303	 */
4304
4305//>>label: Accordion
4306//>>group: Widgets
4307// jscs:disable maximumLineLength
4308//>>description: Displays collapsible content panels for presenting information in a limited amount of space.
4309// jscs:enable maximumLineLength
4310//>>docs: http://api.jqueryui.com/accordion/
4311//>>demos: http://jqueryui.com/accordion/
4312//>>css.structure: ../../themes/base/core.css
4313//>>css.structure: ../../themes/base/accordion.css
4314//>>css.theme: ../../themes/base/theme.css
4315
4316
4317
4318	var widgetsAccordion = $.widget( "ui.accordion", {
4319		version: "1.12.1",
4320		options: {
4321			active: 0,
4322			animate: {},
4323			classes: {
4324				"ui-accordion-header": "ui-corner-top",
4325				"ui-accordion-header-collapsed": "ui-corner-all",
4326				"ui-accordion-content": "ui-corner-bottom"
4327			},
4328			collapsible: false,
4329			event: "click",
4330			header: "> li > :first-child, > :not(li):even",
4331			heightStyle: "auto",
4332			icons: {
4333				activeHeader: "ui-icon-triangle-1-s",
4334				header: "ui-icon-triangle-1-e"
4335			},
4336
4337			// Callbacks
4338			activate: null,
4339			beforeActivate: null
4340		},
4341
4342		hideProps: {
4343			borderTopWidth: "hide",
4344			borderBottomWidth: "hide",
4345			paddingTop: "hide",
4346			paddingBottom: "hide",
4347			height: "hide"
4348		},
4349
4350		showProps: {
4351			borderTopWidth: "show",
vendor: 5,433 bytes, lines 4352-4554
4352			borderBottomWidth: "show",
4353			paddingTop: "show",
4354			paddingBottom: "show",
4355			height: "show"
4356		},
4357
4358		_create: function() {
4359			var options = this.options;
4360
4361			this.prevShow = this.prevHide = $();
4362			this._addClass( "ui-accordion", "ui-widget ui-helper-reset" );
4363			this.element.attr( "role", "tablist" );
4364
4365			// Don't allow collapsible: false and active: false / null
4366			if ( !options.collapsible && ( options.active === false || options.active == null ) ) {
4367				options.active = 0;
4368			}
4369
4370			this._processPanels();
4371
4372			// handle negative values
4373			if ( options.active < 0 ) {
4374				options.active += this.headers.length;
4375			}
4376			this._refresh();
4377		},
4378
4379		_getCreateEventData: function() {
4380			return {
4381				header: this.active,
4382				panel: !this.active.length ? $() : this.active.next()
4383			};
4384		},
4385
4386		_createIcons: function() {
4387			var icon, children,
4388				icons = this.options.icons;
4389
4390			if ( icons ) {
4391				icon = $( "<span>" );
4392				this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header );
4393				icon.prependTo( this.headers );
4394				children = this.active.children( ".ui-accordion-header-icon" );
4395				this._removeClass( children, icons.header )
4396					._addClass( children, null, icons.activeHeader )
4397					._addClass( this.headers, "ui-accordion-icons" );
4398			}
4399		},
4400
4401		_destroyIcons: function() {
4402			this._removeClass( this.headers, "ui-accordion-icons" );
4403			this.headers.children( ".ui-accordion-header-icon" ).remove();
4404		},
4405
4406		_destroy: function() {
4407			var contents;
4408
4409			// Clean up main element
4410			this.element.removeAttr( "role" );
4411
4412			// Clean up headers
4413			this.headers
4414				.removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" )
4415				.removeUniqueId();
4416
4417			this._destroyIcons();
4418
4419			// Clean up content panels
4420			contents = this.headers.next()
4421				.css( "display", "" )
4422				.removeAttr( "role aria-hidden aria-labelledby" )
4423				.removeUniqueId();
4424
4425			if ( this.options.heightStyle !== "content" ) {
4426				contents.css( "height", "" );
4427			}
4428		},
4429
4430		_setOption: function( key, value ) {
4431			if ( key === "active" ) {
4432
4433				// _activate() will handle invalid values and update this.options
4434				this._activate( value );
4435				return;
4436			}
4437
4438			if ( key === "event" ) {
4439				if ( this.options.event ) {
4440					this._off( this.headers, this.options.event );
4441				}
4442				this._setupEvents( value );
4443			}
4444
4445			this._super( key, value );
4446
4447			// Setting collapsible: false while collapsed; open first panel
4448			if ( key === "collapsible" && !value && this.options.active === false ) {
4449				this._activate( 0 );
4450			}
4451
4452			if ( key === "icons" ) {
4453				this._destroyIcons();
4454				if ( value ) {
4455					this._createIcons();
4456				}
4457			}
4458		},
4459
4460		_setOptionDisabled: function( value ) {
4461			this._super( value );
4462
4463			this.element.attr( "aria-disabled", value );
4464
4465			// Support: IE8 Only
4466			// #5332 / #6059 - opacity doesn't cascade to positioned elements in IE
4467			// so we need to add the disabled class to the headers and panels
4468			this._toggleClass( null, "ui-state-disabled", !!value );
4469			this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled",
4470				!!value );
4471		},
4472
4473		_keydown: function( event ) {
4474			if ( event.altKey || event.ctrlKey ) {
4475				return;
4476			}
4477
4478			var keyCode = $.ui.keyCode,
4479				length = this.headers.length,
4480				currentIndex = this.headers.index( event.target ),
4481				toFocus = false;
4482
4483			switch ( event.keyCode ) {
4484				case keyCode.RIGHT:
4485				case keyCode.DOWN:
4486					toFocus = this.headers[ ( currentIndex + 1 ) % length ];
4487					break;
4488				case keyCode.LEFT:
4489				case keyCode.UP:
4490					toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
4491					break;
4492				case keyCode.SPACE:
4493				case keyCode.ENTER:
4494					this._eventHandler( event );
4495					break;
4496				case keyCode.HOME:
4497					toFocus = this.headers[ 0 ];
4498					break;
4499				case keyCode.END:
4500					toFocus = this.headers[ length - 1 ];
4501					break;
4502			}
4503
4504			if ( toFocus ) {
4505				$( event.target ).attr( "tabIndex", -1 );
4506				$( toFocus ).attr( "tabIndex", 0 );
4507				$( toFocus ).trigger( "focus" );
4508				event.preventDefault();
4509			}
4510		},
4511
4512		_panelKeyDown: function( event ) {
4513			if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
4514				$( event.currentTarget ).prev().trigger( "focus" );
4515			}
4516		},
4517
4518		refresh: function() {
4519			var options = this.options;
4520			this._processPanels();
4521
4522			// Was collapsed or no panel
4523			if ( ( options.active === false && options.collapsible === true ) ||
4524				!this.headers.length ) {
4525				options.active = false;
4526				this.active = $();
4527
4528				// active false only when collapsible is true
4529			} else if ( options.active === false ) {
4530				this._activate( 0 );
4531
4532				// was active, but active panel is gone
4533			} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
4534
4535				// all remaining panel are disabled
4536				if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) {
4537					options.active = false;
4538					this.active = $();
4539
4540					// activate previous panel
4541				} else {
4542					this._activate( Math.max( 0, options.active - 1 ) );
4543				}
4544
4545				// was active, active panel still exists
4546			} else {
4547
4548				// make sure active index is correct
4549				options.active = this.headers.index( this.active );
4550			}
4551
4552			this._destroyIcons();
4553
4554			this._refresh();
vendor: 19,370 bytes, lines 4555-5227
4555		},
4556
4557		_processPanels: function() {
4558			var prevHeaders = this.headers,
4559				prevPanels = this.panels;
4560
4561			this.headers = this.element.find( this.options.header );
4562			this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed",
4563				"ui-state-default" );
4564
4565			this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide();
4566			this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" );
4567
4568			// Avoid memory leaks (#10056)
4569			if ( prevPanels ) {
4570				this._off( prevHeaders.not( this.headers ) );
4571				this._off( prevPanels.not( this.panels ) );
4572			}
4573		},
4574
4575		_refresh: function() {
4576			var maxHeight,
4577				options = this.options,
4578				heightStyle = options.heightStyle,
4579				parent = this.element.parent();
4580
4581			this.active = this._findActive( options.active );
4582			this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" )
4583				._removeClass( this.active, "ui-accordion-header-collapsed" );
4584			this._addClass( this.active.next(), "ui-accordion-content-active" );
4585			this.active.next().show();
4586
4587			this.headers
4588				.attr( "role", "tab" )
4589				.each( function() {
4590					var header = $( this ),
4591						headerId = header.uniqueId().attr( "id" ),
4592						panel = header.next(),
4593						panelId = panel.uniqueId().attr( "id" );
4594					header.attr( "aria-controls", panelId );
4595					panel.attr( "aria-labelledby", headerId );
4596				} )
4597				.next()
4598				.attr( "role", "tabpanel" );
4599
4600			this.headers
4601				.not( this.active )
4602				.attr( {
4603					"aria-selected": "false",
4604					"aria-expanded": "false",
4605					tabIndex: -1
4606				} )
4607				.next()
4608				.attr( {
4609					"aria-hidden": "true"
4610				} )
4611				.hide();
4612
4613			// Make sure at least one header is in the tab order
4614			if ( !this.active.length ) {
4615				this.headers.eq( 0 ).attr( "tabIndex", 0 );
4616			} else {
4617				this.active.attr( {
4618					"aria-selected": "true",
4619					"aria-expanded": "true",
4620					tabIndex: 0
4621				} )
4622					.next()
4623					.attr( {
4624						"aria-hidden": "false"
4625					} );
4626			}
4627
4628			this._createIcons();
4629
4630			this._setupEvents( options.event );
4631
4632			if ( heightStyle === "fill" ) {
4633				maxHeight = parent.height();
4634				this.element.siblings( ":visible" ).each( function() {
4635					var elem = $( this ),
4636						position = elem.css( "position" );
4637
4638					if ( position === "absolute" || position === "fixed" ) {
4639						return;
4640					}
4641					maxHeight -= elem.outerHeight( true );
4642				} );
4643
4644				this.headers.each( function() {
4645					maxHeight -= $( this ).outerHeight( true );
4646				} );
4647
4648				this.headers.next()
4649					.each( function() {
4650						$( this ).height( Math.max( 0, maxHeight -
4651							$( this ).innerHeight() + $( this ).height() ) );
4652					} )
4653					.css( "overflow", "auto" );
4654			} else if ( heightStyle === "auto" ) {
4655				maxHeight = 0;
4656				this.headers.next()
4657					.each( function() {
4658						var isVisible = $( this ).is( ":visible" );
4659						if ( !isVisible ) {
4660							$( this ).show();
4661						}
4662						maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
4663						if ( !isVisible ) {
4664							$( this ).hide();
4665						}
4666					} )
4667					.height( maxHeight );
4668			}
4669		},
4670
4671		_activate: function( index ) {
4672			var active = this._findActive( index )[ 0 ];
4673
4674			// Trying to activate the already active panel
4675			if ( active === this.active[ 0 ] ) {
4676				return;
4677			}
4678
4679			// Trying to collapse, simulate a click on the currently active header
4680			active = active || this.active[ 0 ];
4681
4682			this._eventHandler( {
4683				target: active,
4684				currentTarget: active,
4685				preventDefault: $.noop
4686			} );
4687		},
4688
4689		_findActive: function( selector ) {
4690			return typeof selector === "number" ? this.headers.eq( selector ) : $();
4691		},
4692
4693		_setupEvents: function( event ) {
4694			var events = {
4695				keydown: "_keydown"
4696			};
4697			if ( event ) {
4698				$.each( event.split( " " ), function( index, eventName ) {
4699					events[ eventName ] = "_eventHandler";
4700				} );
4701			}
4702
4703			this._off( this.headers.add( this.headers.next() ) );
4704			this._on( this.headers, events );
4705			this._on( this.headers.next(), { keydown: "_panelKeyDown" } );
4706			this._hoverable( this.headers );
4707			this._focusable( this.headers );
4708		},
4709
4710		_eventHandler: function( event ) {
4711			var activeChildren, clickedChildren,
4712				options = this.options,
4713				active = this.active,
4714				clicked = $( event.currentTarget ),
4715				clickedIsActive = clicked[ 0 ] === active[ 0 ],
4716				collapsing = clickedIsActive && options.collapsible,
4717				toShow = collapsing ? $() : clicked.next(),
4718				toHide = active.next(),
4719				eventData = {
4720					oldHeader: active,
4721					oldPanel: toHide,
4722					newHeader: collapsing ? $() : clicked,
4723					newPanel: toShow
4724				};
4725
4726			event.preventDefault();
4727
4728			if (
4729
4730				// click on active header, but not collapsible
4731			( clickedIsActive && !options.collapsible ) ||
4732
4733				// allow canceling activation
4734			( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
4735				return;
4736			}
4737
4738			options.active = collapsing ? false : this.headers.index( clicked );
4739
4740			// When the call to ._toggle() comes after the class changes
4741			// it causes a very odd bug in IE 8 (see #6720)
4742			this.active = clickedIsActive ? $() : clicked;
4743			this._toggle( eventData );
4744
4745			// Switch classes
4746			// corner classes on the previously active header stay after the animation
4747			this._removeClass( active, "ui-accordion-header-active", "ui-state-active" );
4748			if ( options.icons ) {
4749				activeChildren = active.children( ".ui-accordion-header-icon" );
4750				this._removeClass( activeChildren, null, options.icons.activeHeader )
4751					._addClass( activeChildren, null, options.icons.header );
4752			}
4753
4754			if ( !clickedIsActive ) {
4755				this._removeClass( clicked, "ui-accordion-header-collapsed" )
4756					._addClass( clicked, "ui-accordion-header-active", "ui-state-active" );
4757				if ( options.icons ) {
4758					clickedChildren = clicked.children( ".ui-accordion-header-icon" );
4759					this._removeClass( clickedChildren, null, options.icons.header )
4760						._addClass( clickedChildren, null, options.icons.activeHeader );
4761				}
4762
4763				this._addClass( clicked.next(), "ui-accordion-content-active" );
4764			}
4765		},
4766
4767		_toggle: function( data ) {
4768			var toShow = data.newPanel,
4769				toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
4770
4771			// Handle activating a panel during the animation for another activation
4772			this.prevShow.add( this.prevHide ).stop( true, true );
4773			this.prevShow = toShow;
4774			this.prevHide = toHide;
4775
4776			if ( this.options.animate ) {
4777				this._animate( toShow, toHide, data );
4778			} else {
4779				toHide.hide();
4780				toShow.show();
4781				this._toggleComplete( data );
4782			}
4783
4784			toHide.attr( {
4785				"aria-hidden": "true"
4786			} );
4787			toHide.prev().attr( {
4788				"aria-selected": "false",
4789				"aria-expanded": "false"
4790			} );
4791
4792			// if we're switching panels, remove the old header from the tab order
4793			// if we're opening from collapsed state, remove the previous header from the tab order
4794			// if we're collapsing, then keep the collapsing header in the tab order
4795			if ( toShow.length && toHide.length ) {
4796				toHide.prev().attr( {
4797					"tabIndex": -1,
4798					"aria-expanded": "false"
4799				} );
4800			} else if ( toShow.length ) {
4801				this.headers.filter( function() {
4802					return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
4803				} )
4804					.attr( "tabIndex", -1 );
4805			}
4806
4807			toShow
4808				.attr( "aria-hidden", "false" )
4809				.prev()
4810				.attr( {
4811					"aria-selected": "true",
4812					"aria-expanded": "true",
4813					tabIndex: 0
4814				} );
4815		},
4816
4817		_animate: function( toShow, toHide, data ) {
4818			var total, easing, duration,
4819				that = this,
4820				adjust = 0,
4821				boxSizing = toShow.css( "box-sizing" ),
4822				down = toShow.length &&
4823					( !toHide.length || ( toShow.index() < toHide.index() ) ),
4824				animate = this.options.animate || {},
4825				options = down && animate.down || animate,
4826				complete = function() {
4827					that._toggleComplete( data );
4828				};
4829
4830			if ( typeof options === "number" ) {
4831				duration = options;
4832			}
4833			if ( typeof options === "string" ) {
4834				easing = options;
4835			}
4836
4837			// fall back from options to animation in case of partial down settings
4838			easing = easing || options.easing || animate.easing;
4839			duration = duration || options.duration || animate.duration;
4840
4841			if ( !toHide.length ) {
4842				return toShow.animate( this.showProps, duration, easing, complete );
4843			}
4844			if ( !toShow.length ) {
4845				return toHide.animate( this.hideProps, duration, easing, complete );
4846			}
4847
4848			total = toShow.show().outerHeight();
4849			toHide.animate( this.hideProps, {
4850				duration: duration,
4851				easing: easing,
4852				step: function( now, fx ) {
4853					fx.now = Math.round( now );
4854				}
4855			} );
4856			toShow
4857				.hide()
4858				.animate( this.showProps, {
4859					duration: duration,
4860					easing: easing,
4861					complete: complete,
4862					step: function( now, fx ) {
4863						fx.now = Math.round( now );
4864						if ( fx.prop !== "height" ) {
4865							if ( boxSizing === "content-box" ) {
4866								adjust += fx.now;
4867							}
4868						} else if ( that.options.heightStyle !== "content" ) {
4869							fx.now = Math.round( total - toHide.outerHeight() - adjust );
4870							adjust = 0;
4871						}
4872					}
4873				} );
4874		},
4875
4876		_toggleComplete: function( data ) {
4877			var toHide = data.oldPanel,
4878				prev = toHide.prev();
4879
4880			this._removeClass( toHide, "ui-accordion-content-active" );
4881			this._removeClass( prev, "ui-accordion-header-active" )
4882				._addClass( prev, "ui-accordion-header-collapsed" );
4883
4884			// Work around for rendering bug in IE (#5421)
4885			if ( toHide.length ) {
4886				toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
4887			}
4888			this._trigger( "activate", null, data );
4889		}
4890	} );
4891
4892
4893
4894	var safeActiveElement = $.ui.safeActiveElement = function( document ) {
4895		var activeElement;
4896
4897		// Support: IE 9 only
4898		// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
4899		try {
4900			activeElement = document.activeElement;
4901		} catch ( error ) {
4902			activeElement = document.body;
4903		}
4904
4905		// Support: IE 9 - 11 only
4906		// IE may return null instead of an element
4907		// Interestingly, this only seems to occur when NOT in an iframe
4908		if ( !activeElement ) {
4909			activeElement = document.body;
4910		}
4911
4912		// Support: IE 11 only
4913		// IE11 returns a seemingly empty object in some cases when accessing
4914		// document.activeElement from an <iframe>
4915		if ( !activeElement.nodeName ) {
4916			activeElement = document.body;
4917		}
4918
4919		return activeElement;
4920	};
4921
4922
4923	/*!
4924	 * jQuery UI Menu 1.12.1
4925	 * http://jqueryui.com
4926	 *
4927	 * Copyright jQuery Foundation and other contributors
4928	 * Released under the MIT license.
4929	 * http://jquery.org/license
4930	 */
4931
4932//>>label: Menu
4933//>>group: Widgets
4934//>>description: Creates nestable menus.
4935//>>docs: http://api.jqueryui.com/menu/
4936//>>demos: http://jqueryui.com/menu/
4937//>>css.structure: ../../themes/base/core.css
4938//>>css.structure: ../../themes/base/menu.css
4939//>>css.theme: ../../themes/base/theme.css
4940
4941
4942
4943	var widgetsMenu = $.widget( "ui.menu", {
4944		version: "1.12.1",
4945		defaultElement: "<ul>",
4946		delay: 300,
4947		options: {
4948			icons: {
4949				submenu: "ui-icon-caret-1-e"
4950			},
4951			items: "> *",
4952			menus: "ul",
4953			position: {
4954				my: "left top",
4955				at: "right top"
4956			},
4957			role: "menu",
4958
4959			// Callbacks
4960			blur: null,
4961			focus: null,
4962			select: null
4963		},
4964
4965		_create: function() {
4966			this.activeMenu = this.element;
4967
4968			// Flag used to prevent firing of the click handler
4969			// as the event bubbles up through nested menus
4970			this.mouseHandled = false;
4971			this.element
4972				.uniqueId()
4973				.attr( {
4974					role: this.options.role,
4975					tabIndex: 0
4976				} );
4977
4978			this._addClass( "ui-menu", "ui-widget ui-widget-content" );
4979			this._on( {
4980
4981				// Prevent focus from sticking to links inside menu after clicking
4982				// them (focus should always stay on UL during navigation).
4983				"mousedown .ui-menu-item": function( event ) {
4984					event.preventDefault();
4985				},
4986				"click .ui-menu-item": function( event ) {
4987					var target = $( event.target );
4988					var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
4989					if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
4990						this.select( event );
4991
4992						// Only set the mouseHandled flag if the event will bubble, see #9469.
4993						if ( !event.isPropagationStopped() ) {
4994							this.mouseHandled = true;
4995						}
4996
4997						// Open submenu on click
4998						if ( target.has( ".ui-menu" ).length ) {
4999							this.expand( event );
5000						} else if ( !this.element.is( ":focus" ) &&
5001							active.closest( ".ui-menu" ).length ) {
5002
5003							// Redirect focus to the menu
5004							this.element.trigger( "focus", [ true ] );
5005
5006							// If the active item is on the top level, let it stay active.
5007							// Otherwise, blur the active item since it is no longer visible.
5008							if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
5009								clearTimeout( this.timer );
5010							}
5011						}
5012					}
5013				},
5014				"mouseenter .ui-menu-item": function( event ) {
5015
5016					// Ignore mouse events while typeahead is active, see #10458.
5017					// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
5018					// is over an item in the menu
5019					if ( this.previousFilter ) {
5020						return;
5021					}
5022
5023					var actualTarget = $( event.target ).closest( ".ui-menu-item" ),
5024						target = $( event.currentTarget );
5025
5026					// Ignore bubbled events on parent items, see #11641
5027					if ( actualTarget[ 0 ] !== target[ 0 ] ) {
5028						return;
5029					}
5030
5031					// Remove ui-state-active class from siblings of the newly focused menu item
5032					// to avoid a jump caused by adjacent elements both having a class with a border
5033					this._removeClass( target.siblings().children( ".ui-state-active" ),
5034						null, "ui-state-active" );
5035					this.focus( event, target );
5036				},
5037				mouseleave: "collapseAll",
5038				"mouseleave .ui-menu": "collapseAll",
5039				focus: function( event, keepActiveItem ) {
5040
5041					// If there's already an active item, keep it active
5042					// If not, activate the first item
5043					var item = this.active || this.element.find( this.options.items ).eq( 0 );
5044
5045					if ( !keepActiveItem ) {
5046						this.focus( event, item );
5047					}
5048				},
5049				blur: function( event ) {
5050					this._delay( function() {
5051						var notContained = !$.contains(
5052							this.element[ 0 ],
5053							$.ui.safeActiveElement( this.document[ 0 ] )
5054						);
5055						if ( notContained ) {
5056							this.collapseAll( event );
5057						}
5058					} );
5059				},
5060				keydown: "_keydown"
5061			} );
5062
5063			this.refresh();
5064
5065			// Clicks outside of a menu collapse any open menus
5066			this._on( this.document, {
5067				click: function( event ) {
5068					if ( this._closeOnDocumentClick( event ) ) {
5069						this.collapseAll( event );
5070					}
5071
5072					// Reset the mouseHandled flag
5073					this.mouseHandled = false;
5074				}
5075			} );
5076		},
5077
5078		_destroy: function() {
5079			var items = this.element.find( ".ui-menu-item" )
5080					.removeAttr( "role aria-disabled" ),
5081				submenus = items.children( ".ui-menu-item-wrapper" )
5082					.removeUniqueId()
5083					.removeAttr( "tabIndex role aria-haspopup" );
5084
5085			// Destroy (sub)menus
5086			this.element
5087				.removeAttr( "aria-activedescendant" )
5088				.find( ".ui-menu" ).addBack()
5089				.removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " +
5090				"tabIndex" )
5091				.removeUniqueId()
5092				.show();
5093
5094			submenus.children().each( function() {
5095				var elem = $( this );
5096				if ( elem.data( "ui-menu-submenu-caret" ) ) {
5097					elem.remove();
5098				}
5099			} );
5100		},
5101
5102		_keydown: function( event ) {
5103			var match, prev, character, skip,
5104				preventDefault = true;
5105
5106			switch ( event.keyCode ) {
5107				case $.ui.keyCode.PAGE_UP:
5108					this.previousPage( event );
5109					break;
5110				case $.ui.keyCode.PAGE_DOWN:
5111					this.nextPage( event );
5112					break;
5113				case $.ui.keyCode.HOME:
5114					this._move( "first", "first", event );
5115					break;
5116				case $.ui.keyCode.END:
5117					this._move( "last", "last", event );
5118					break;
5119				case $.ui.keyCode.UP:
5120					this.previous( event );
5121					break;
5122				case $.ui.keyCode.DOWN:
5123					this.next( event );
5124					break;
5125				case $.ui.keyCode.LEFT:
5126					this.collapse( event );
5127					break;
5128				case $.ui.keyCode.RIGHT:
5129					if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
5130						this.expand( event );
5131					}
5132					break;
5133				case $.ui.keyCode.ENTER:
5134				case $.ui.keyCode.SPACE:
5135					this._activate( event );
5136					break;
5137				case $.ui.keyCode.ESCAPE:
5138					this.collapse( event );
5139					break;
5140				default:
5141					preventDefault = false;
5142					prev = this.previousFilter || "";
5143					skip = false;
5144
5145					// Support number pad values
5146					character = event.keyCode >= 96 && event.keyCode <= 105 ?
5147						( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode );
5148
5149					clearTimeout( this.filterTimer );
5150
5151					if ( character === prev ) {
5152						skip = true;
5153					} else {
5154						character = prev + character;
5155					}
5156
5157					match = this._filterMenuItems( character );
5158					match = skip && match.index( this.active.next() ) !== -1 ?
5159						this.active.nextAll( ".ui-menu-item" ) :
5160						match;
5161
5162					// If no matches on the current filter, reset to the last character pressed
5163					// to move down the menu to the first item that starts with that character
5164					if ( !match.length ) {
5165						character = String.fromCharCode( event.keyCode );
5166						match = this._filterMenuItems( character );
5167					}
5168
5169					if ( match.length ) {
5170						this.focus( event, match );
5171						this.previousFilter = character;
5172						this.filterTimer = this._delay( function() {
5173							delete this.previousFilter;
5174						}, 1000 );
5175					} else {
5176						delete this.previousFilter;
5177					}
5178			}
5179
5180			if ( preventDefault ) {
5181				event.preventDefault();
5182			}
5183		},
5184
5185		_activate: function( event ) {
5186			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
5187				if ( this.active.children( "[aria-haspopup='true']" ).length ) {
5188					this.expand( event );
5189				} else {
5190					this.select( event );
5191				}
5192			}
5193		},
5194
5195		refresh: function() {
5196			var menus, items, newSubmenus, newItems, newWrappers,
5197				that = this,
5198				icon = this.options.icons.submenu,
5199				submenus = this.element.find( this.options.menus );
5200
5201			this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length );
5202
5203			// Initialize nested menus
5204			newSubmenus = submenus.filter( ":not(.ui-menu)" )
5205				.hide()
5206				.attr( {
5207					role: this.options.role,
5208					"aria-hidden": "true",
5209					"aria-expanded": "false"
5210				} )
5211				.each( function() {
5212					var menu = $( this ),
5213						item = menu.prev(),
5214						submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true );
5215
5216					that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon );
5217					item
5218						.attr( "aria-haspopup", "true" )
5219						.prepend( submenuCaret );
5220					menu.attr( "aria-labelledby", item.attr( "id" ) );
5221				} );
5222
5223			this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" );
5224
5225			menus = submenus.add( this.element );
5226			items = menus.find( this.options.items );
5227
vendor: 4,840 bytes, lines 5228-5390
5228			// Initialize menu-items containing spaces and/or dashes only as dividers
5229			items.not( ".ui-menu-item" ).each( function() {
5230				var item = $( this );
5231				if ( that._isDivider( item ) ) {
5232					that._addClass( item, "ui-menu-divider", "ui-widget-content" );
5233				}
5234			} );
5235
5236			// Don't refresh list items that are already adapted
5237			newItems = items.not( ".ui-menu-item, .ui-menu-divider" );
5238			newWrappers = newItems.children()
5239				.not( ".ui-menu" )
5240				.uniqueId()
5241				.attr( {
5242					tabIndex: -1,
5243					role: this._itemRole()
5244				} );
5245			this._addClass( newItems, "ui-menu-item" )
5246				._addClass( newWrappers, "ui-menu-item-wrapper" );
5247
5248			// Add aria-disabled attribute to any disabled menu item
5249			items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
5250
5251			// If the active item has been removed, blur the menu
5252			if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
5253				this.blur();
5254			}
5255		},
5256
5257		_itemRole: function() {
5258			return {
5259				menu: "menuitem",
5260				listbox: "option"
5261			}[ this.options.role ];
5262		},
5263
5264		_setOption: function( key, value ) {
5265			if ( key === "icons" ) {
5266				var icons = this.element.find( ".ui-menu-icon" );
5267				this._removeClass( icons, null, this.options.icons.submenu )
5268					._addClass( icons, null, value.submenu );
5269			}
5270			this._super( key, value );
5271		},
5272
5273		_setOptionDisabled: function( value ) {
5274			this._super( value );
5275
5276			this.element.attr( "aria-disabled", String( value ) );
5277			this._toggleClass( null, "ui-state-disabled", !!value );
5278		},
5279
5280		focus: function( event, item ) {
5281			var nested, focused, activeParent;
5282			this.blur( event, event && event.type === "focus" );
5283
5284			this._scrollIntoView( item );
5285
5286			this.active = item.first();
5287
5288			focused = this.active.children( ".ui-menu-item-wrapper" );
5289			this._addClass( focused, null, "ui-state-active" );
5290
5291			// Only update aria-activedescendant if there's a role
5292			// otherwise we assume focus is managed elsewhere
5293			if ( this.options.role ) {
5294				this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
5295			}
5296
5297			// Highlight active parent menu item, if any
5298			activeParent = this.active
5299				.parent()
5300				.closest( ".ui-menu-item" )
5301				.children( ".ui-menu-item-wrapper" );
5302			this._addClass( activeParent, null, "ui-state-active" );
5303
5304			if ( event && event.type === "keydown" ) {
5305				this._close();
5306			} else {
5307				this.timer = this._delay( function() {
5308					this._close();
5309				}, this.delay );
5310			}
5311
5312			nested = item.children( ".ui-menu" );
5313			if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
5314				this._startOpening( nested );
5315			}
5316			this.activeMenu = item.parent();
5317
5318			this._trigger( "focus", event, { item: item } );
5319		},
5320
5321		_scrollIntoView: function( item ) {
5322			var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
5323			if ( this._hasScroll() ) {
5324				borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0;
5325				paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0;
5326				offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
5327				scroll = this.activeMenu.scrollTop();
5328				elementHeight = this.activeMenu.height();
5329				itemHeight = item.outerHeight();
5330
5331				if ( offset < 0 ) {
5332					this.activeMenu.scrollTop( scroll + offset );
5333				} else if ( offset + itemHeight > elementHeight ) {
5334					this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
5335				}
5336			}
5337		},
5338
5339		blur: function( event, fromFocus ) {
5340			if ( !fromFocus ) {
5341				clearTimeout( this.timer );
5342			}
5343
5344			if ( !this.active ) {
5345				return;
5346			}
5347
5348			this._removeClass( this.active.children( ".ui-menu-item-wrapper" ),
5349				null, "ui-state-active" );
5350
5351			this._trigger( "blur", event, { item: this.active } );
5352			this.active = null;
5353		},
5354
5355		_startOpening: function( submenu ) {
5356			clearTimeout( this.timer );
5357
5358			// Don't open if already open fixes a Firefox bug that caused a .5 pixel
5359			// shift in the submenu position when mousing over the caret icon
5360			if ( submenu.attr( "aria-hidden" ) !== "true" ) {
5361				return;
5362			}
5363
5364			this.timer = this._delay( function() {
5365				this._close();
5366				this._open( submenu );
5367			}, this.delay );
5368		},
5369
5370		_open: function( submenu ) {
5371			var position = $.extend( {
5372				of: this.active
5373			}, this.options.position );
5374
5375			clearTimeout( this.timer );
5376			this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
5377				.hide()
5378				.attr( "aria-hidden", "true" );
5379
5380			submenu
5381				.show()
5382				.removeAttr( "aria-hidden" )
5383				.attr( "aria-expanded", "true" )
5384				.position( position );
5385		},
5386
5387		collapseAll: function( event, all ) {
5388			clearTimeout( this.timer );
5389			this.timer = this._delay( function() {
5390
vendor: 50,871 bytes, lines 5391-7167
5391				// If we were passed an event, look for the submenu that contains the event
5392				var currentMenu = all ? this.element :
5393					$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
5394
5395				// If we found no valid submenu ancestor, use the main menu to close all
5396				// sub menus anyway
5397				if ( !currentMenu.length ) {
5398					currentMenu = this.element;
5399				}
5400
5401				this._close( currentMenu );
5402
5403				this.blur( event );
5404
5405				// Work around active item staying active after menu is blurred
5406				this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" );
5407
5408				this.activeMenu = currentMenu;
5409			}, this.delay );
5410		},
5411
5412		// With no arguments, closes the currently active menu - if nothing is active
5413		// it closes all menus.  If passed an argument, it will search for menus BELOW
5414		_close: function( startMenu ) {
5415			if ( !startMenu ) {
5416				startMenu = this.active ? this.active.parent() : this.element;
5417			}
5418
5419			startMenu.find( ".ui-menu" )
5420				.hide()
5421				.attr( "aria-hidden", "true" )
5422				.attr( "aria-expanded", "false" );
5423		},
5424
5425		_closeOnDocumentClick: function( event ) {
5426			return !$( event.target ).closest( ".ui-menu" ).length;
5427		},
5428
5429		_isDivider: function( item ) {
5430
5431			// Match hyphen, em dash, en dash
5432			return !/[^\-\u2014\u2013\s]/.test( item.text() );
5433		},
5434
5435		collapse: function( event ) {
5436			var newItem = this.active &&
5437				this.active.parent().closest( ".ui-menu-item", this.element );
5438			if ( newItem && newItem.length ) {
5439				this._close();
5440				this.focus( event, newItem );
5441			}
5442		},
5443
5444		expand: function( event ) {
5445			var newItem = this.active &&
5446				this.active
5447					.children( ".ui-menu " )
5448					.find( this.options.items )
5449					.first();
5450
5451			if ( newItem && newItem.length ) {
5452				this._open( newItem.parent() );
5453
5454				// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
5455				this._delay( function() {
5456					this.focus( event, newItem );
5457				} );
5458			}
5459		},
5460
5461		next: function( event ) {
5462			this._move( "next", "first", event );
5463		},
5464
5465		previous: function( event ) {
5466			this._move( "prev", "last", event );
5467		},
5468
5469		isFirstItem: function() {
5470			return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
5471		},
5472
5473		isLastItem: function() {
5474			return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
5475		},
5476
5477		_move: function( direction, filter, event ) {
5478			var next;
5479			if ( this.active ) {
5480				if ( direction === "first" || direction === "last" ) {
5481					next = this.active
5482						[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
5483						.eq( -1 );
5484				} else {
5485					next = this.active
5486						[ direction + "All" ]( ".ui-menu-item" )
5487						.eq( 0 );
5488				}
5489			}
5490			if ( !next || !next.length || !this.active ) {
5491				next = this.activeMenu.find( this.options.items )[ filter ]();
5492			}
5493
5494			this.focus( event, next );
5495		},
5496
5497		nextPage: function( event ) {
5498			var item, base, height;
5499
5500			if ( !this.active ) {
5501				this.next( event );
5502				return;
5503			}
5504			if ( this.isLastItem() ) {
5505				return;
5506			}
5507			if ( this._hasScroll() ) {
5508				base = this.active.offset().top;
5509				height = this.element.height();
5510				this.active.nextAll( ".ui-menu-item" ).each( function() {
5511					item = $( this );
5512					return item.offset().top - base - height < 0;
5513				} );
5514
5515				this.focus( event, item );
5516			} else {
5517				this.focus( event, this.activeMenu.find( this.options.items )
5518					[ !this.active ? "first" : "last" ]() );
5519			}
5520		},
5521
5522		previousPage: function( event ) {
5523			var item, base, height;
5524			if ( !this.active ) {
5525				this.next( event );
5526				return;
5527			}
5528			if ( this.isFirstItem() ) {
5529				return;
5530			}
5531			if ( this._hasScroll() ) {
5532				base = this.active.offset().top;
5533				height = this.element.height();
5534				this.active.prevAll( ".ui-menu-item" ).each( function() {
5535					item = $( this );
5536					return item.offset().top - base + height > 0;
5537				} );
5538
5539				this.focus( event, item );
5540			} else {
5541				this.focus( event, this.activeMenu.find( this.options.items ).first() );
5542			}
5543		},
5544
5545		_hasScroll: function() {
5546			return this.element.outerHeight() < this.element.prop( "scrollHeight" );
5547		},
5548
5549		select: function( event ) {
5550
5551			// TODO: It should never be possible to not have an active item at this
5552			// point, but the tests don't trigger mouseenter before click.
5553			this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
5554			var ui = { item: this.active };
5555			if ( !this.active.has( ".ui-menu" ).length ) {
5556				this.collapseAll( event, true );
5557			}
5558			this._trigger( "select", event, ui );
5559		},
5560
5561		_filterMenuItems: function( character ) {
5562			var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
5563				regex = new RegExp( "^" + escapedCharacter, "i" );
5564
5565			return this.activeMenu
5566				.find( this.options.items )
5567
5568				// Only match on items, not dividers or other content (#10571)
5569				.filter( ".ui-menu-item" )
5570				.filter( function() {
5571					return regex.test(
5572						$.trim( $( this ).children( ".ui-menu-item-wrapper" ).text() ) );
5573				} );
5574		}
5575	} );
5576
5577
5578	/*!
5579	 * jQuery UI Autocomplete 1.12.1
5580	 * http://jqueryui.com
5581	 *
5582	 * Copyright jQuery Foundation and other contributors
5583	 * Released under the MIT license.
5584	 * http://jquery.org/license
5585	 */
5586
5587//>>label: Autocomplete
5588//>>group: Widgets
5589//>>description: Lists suggested words as the user is typing.
5590//>>docs: http://api.jqueryui.com/autocomplete/
5591//>>demos: http://jqueryui.com/autocomplete/
5592//>>css.structure: ../../themes/base/core.css
5593//>>css.structure: ../../themes/base/autocomplete.css
5594//>>css.theme: ../../themes/base/theme.css
5595
5596
5597
5598	$.widget( "ui.autocomplete", {
5599		version: "1.12.1",
5600		defaultElement: "<input>",
5601		options: {
5602			appendTo: null,
5603			autoFocus: false,
5604			delay: 300,
5605			minLength: 1,
5606			position: {
5607				my: "left top",
5608				at: "left bottom",
5609				collision: "none"
5610			},
5611			source: null,
5612
5613			// Callbacks
5614			change: null,
5615			close: null,
5616			focus: null,
5617			open: null,
5618			response: null,
5619			search: null,
5620			select: null
5621		},
5622
5623		requestIndex: 0,
5624		pending: 0,
5625
5626		_create: function() {
5627
5628			// Some browsers only repeat keydown events, not keypress events,
5629			// so we use the suppressKeyPress flag to determine if we've already
5630			// handled the keydown event. #7269
5631			// Unfortunately the code for & in keypress is the same as the up arrow,
5632			// so we use the suppressKeyPressRepeat flag to avoid handling keypress
5633			// events when we know the keydown event was used to modify the
5634			// search term. #7799
5635			var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
5636				nodeName = this.element[ 0 ].nodeName.toLowerCase(),
5637				isTextarea = nodeName === "textarea",
5638				isInput = nodeName === "input";
5639
5640			// Textareas are always multi-line
5641			// Inputs are always single-line, even if inside a contentEditable element
5642			// IE also treats inputs as contentEditable
5643			// All other element types are determined by whether or not they're contentEditable
5644			this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element );
5645
5646			this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
5647			this.isNewMenu = true;
5648
5649			this._addClass( "ui-autocomplete-input" );
5650			this.element.attr( "autocomplete", "off" );
5651
5652			this._on( this.element, {
5653				keydown: function( event ) {
5654					if ( this.element.prop( "readOnly" ) ) {
5655						suppressKeyPress = true;
5656						suppressInput = true;
5657						suppressKeyPressRepeat = true;
5658						return;
5659					}
5660
5661					suppressKeyPress = false;
5662					suppressInput = false;
5663					suppressKeyPressRepeat = false;
5664					var keyCode = $.ui.keyCode;
5665					switch ( event.keyCode ) {
5666						case keyCode.PAGE_UP:
5667							suppressKeyPress = true;
5668							this._move( "previousPage", event );
5669							break;
5670						case keyCode.PAGE_DOWN:
5671							suppressKeyPress = true;
5672							this._move( "nextPage", event );
5673							break;
5674						case keyCode.UP:
5675							suppressKeyPress = true;
5676							this._keyEvent( "previous", event );
5677							break;
5678						case keyCode.DOWN:
5679							suppressKeyPress = true;
5680							this._keyEvent( "next", event );
5681							break;
5682						case keyCode.ENTER:
5683
5684							// when menu is open and has focus
5685							if ( this.menu.active ) {
5686
5687								// #6055 - Opera still allows the keypress to occur
5688								// which causes forms to submit
5689								suppressKeyPress = true;
5690								event.preventDefault();
5691								this.menu.select( event );
5692							}
5693							break;
5694						case keyCode.TAB:
5695							if ( this.menu.active ) {
5696								this.menu.select( event );
5697							}
5698							break;
5699						case keyCode.ESCAPE:
5700							if ( this.menu.element.is( ":visible" ) ) {
5701								if ( !this.isMultiLine ) {
5702									this._value( this.term );
5703								}
5704								this.close( event );
5705
5706								// Different browsers have different default behavior for escape
5707								// Single press can mean undo or clear
5708								// Double press in IE means clear the whole form
5709								event.preventDefault();
5710							}
5711							break;
5712						default:
5713							suppressKeyPressRepeat = true;
5714
5715							// search timeout should be triggered before the input value is changed
5716							this._searchTimeout( event );
5717							break;
5718					}
5719				},
5720				keypress: function( event ) {
5721					if ( suppressKeyPress ) {
5722						suppressKeyPress = false;
5723						if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
5724							event.preventDefault();
5725						}
5726						return;
5727					}
5728					if ( suppressKeyPressRepeat ) {
5729						return;
5730					}
5731
5732					// Replicate some key handlers to allow them to repeat in Firefox and Opera
5733					var keyCode = $.ui.keyCode;
5734					switch ( event.keyCode ) {
5735						case keyCode.PAGE_UP:
5736							this._move( "previousPage", event );
5737							break;
5738						case keyCode.PAGE_DOWN:
5739							this._move( "nextPage", event );
5740							break;
5741						case keyCode.UP:
5742							this._keyEvent( "previous", event );
5743							break;
5744						case keyCode.DOWN:
5745							this._keyEvent( "next", event );
5746							break;
5747					}
5748				},
5749				input: function( event ) {
5750					if ( suppressInput ) {
5751						suppressInput = false;
5752						event.preventDefault();
5753						return;
5754					}
5755					this._searchTimeout( event );
5756				},
5757				focus: function() {
5758					this.selectedItem = null;
5759					this.previous = this._value();
5760				},
5761				blur: function( event ) {
5762					if ( this.cancelBlur ) {
5763						delete this.cancelBlur;
5764						return;
5765					}
5766
5767					clearTimeout( this.searching );
5768					this.close( event );
5769					this._change( event );
5770				}
5771			} );
5772
5773			this._initSource();
5774			this.menu = $( "<ul>" )
5775				.appendTo( this._appendTo() )
5776				.menu( {
5777
5778					// disable ARIA support, the live region takes care of that
5779					role: null
5780				} )
5781				.hide()
5782				.menu( "instance" );
5783
5784			this._addClass( this.menu.element, "ui-autocomplete", "ui-front" );
5785			this._on( this.menu.element, {
5786				mousedown: function( event ) {
5787
5788					// prevent moving focus out of the text field
5789					event.preventDefault();
5790
5791					// IE doesn't prevent moving focus even with event.preventDefault()
5792					// so we set a flag to know when we should ignore the blur event
5793					this.cancelBlur = true;
5794					this._delay( function() {
5795						delete this.cancelBlur;
5796
5797						// Support: IE 8 only
5798						// Right clicking a menu item or selecting text from the menu items will
5799						// result in focus moving out of the input. However, we've already received
5800						// and ignored the blur event because of the cancelBlur flag set above. So
5801						// we restore focus to ensure that the menu closes properly based on the user's
5802						// next actions.
5803						if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
5804							this.element.trigger( "focus" );
5805						}
5806					} );
5807				},
5808				menufocus: function( event, ui ) {
5809					var label, item;
5810
5811					// support: Firefox
5812					// Prevent accidental activation of menu items in Firefox (#7024 #9118)
5813					if ( this.isNewMenu ) {
5814						this.isNewMenu = false;
5815						if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
5816							this.menu.blur();
5817
5818							this.document.one( "mousemove", function() {
5819								$( event.target ).trigger( event.originalEvent );
5820							} );
5821
5822							return;
5823						}
5824					}
5825
5826					item = ui.item.data( "ui-autocomplete-item" );
5827					if ( false !== this._trigger( "focus", event, { item: item } ) ) {
5828
5829						// use value to match what will end up in the input, if it was a key event
5830						if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
5831							this._value( item.value );
5832						}
5833					}
5834
5835					// Announce the value in the liveRegion
5836					label = ui.item.attr( "aria-label" ) || item.value;
5837					if ( label && $.trim( label ).length ) {
5838						this.liveRegion.children().hide();
5839						$( "<div>" ).text( label ).appendTo( this.liveRegion );
5840					}
5841				},
5842				menuselect: function( event, ui ) {
5843					var item = ui.item.data( "ui-autocomplete-item" ),
5844						previous = this.previous;
5845
5846					// Only trigger when focus was lost (click on menu)
5847					if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
5848						this.element.trigger( "focus" );
5849						this.previous = previous;
5850
5851						// #6109 - IE triggers two focus events and the second
5852						// is asynchronous, so we need to reset the previous
5853						// term synchronously and asynchronously :-(
5854						this._delay( function() {
5855							this.previous = previous;
5856							this.selectedItem = item;
5857						} );
5858					}
5859
5860					if ( false !== this._trigger( "select", event, { item: item } ) ) {
5861						this._value( item.value );
5862					}
5863
5864					// reset the term after the select event
5865					// this allows custom select handling to work properly
5866					this.term = this._value();
5867
5868					this.close( event );
5869					this.selectedItem = item;
5870				}
5871			} );
5872
5873			this.liveRegion = $( "<div>", {
5874				role: "status",
5875				"aria-live": "assertive",
5876				"aria-relevant": "additions"
5877			} )
5878				.appendTo( this.document[ 0 ].body );
5879
5880			this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
5881
5882			// Turning off autocomplete prevents the browser from remembering the
5883			// value when navigating through history, so we re-enable autocomplete
5884			// if the page is unloaded before the widget is destroyed. #7790
5885			this._on( this.window, {
5886				beforeunload: function() {
5887					this.element.removeAttr( "autocomplete" );
5888				}
5889			} );
5890		},
5891
5892		_destroy: function() {
5893			clearTimeout( this.searching );
5894			this.element.removeAttr( "autocomplete" );
5895			this.menu.element.remove();
5896			this.liveRegion.remove();
5897		},
5898
5899		_setOption: function( key, value ) {
5900			this._super( key, value );
5901			if ( key === "source" ) {
5902				this._initSource();
5903			}
5904			if ( key === "appendTo" ) {
5905				this.menu.element.appendTo( this._appendTo() );
5906			}
5907			if ( key === "disabled" && value && this.xhr ) {
5908				this.xhr.abort();
5909			}
5910		},
5911
5912		_isEventTargetInWidget: function( event ) {
5913			var menuElement = this.menu.element[ 0 ];
5914
5915			return event.target === this.element[ 0 ] ||
5916				event.target === menuElement ||
5917				$.contains( menuElement, event.target );
5918		},
5919
5920		_closeOnClickOutside: function( event ) {
5921			if ( !this._isEventTargetInWidget( event ) ) {
5922				this.close();
5923			}
5924		},
5925
5926		_appendTo: function() {
5927			var element = this.options.appendTo;
5928
5929			if ( element ) {
5930				element = element.jquery || element.nodeType ?
5931					$( element ) :
5932					this.document.find( element ).eq( 0 );
5933			}
5934
5935			if ( !element || !element[ 0 ] ) {
5936				element = this.element.closest( ".ui-front, dialog" );
5937			}
5938
5939			if ( !element.length ) {
5940				element = this.document[ 0 ].body;
5941			}
5942
5943			return element;
5944		},
5945
5946		_initSource: function() {
5947			var array, url,
5948				that = this;
5949			if ( $.isArray( this.options.source ) ) {
5950				array = this.options.source;
5951				this.source = function( request, response ) {
5952					response( $.ui.autocomplete.filter( array, request.term ) );
5953				};
5954			} else if ( typeof this.options.source === "string" ) {
5955				url = this.options.source;
5956				this.source = function( request, response ) {
5957					if ( that.xhr ) {
5958						that.xhr.abort();
5959					}
5960					that.xhr = $.ajax( {
5961						url: url,
5962						data: request,
5963						dataType: "json",
5964						success: function( data ) {
5965							response( data );
5966						},
5967						error: function() {
5968							response( [] );
5969						}
5970					} );
5971				};
5972			} else {
5973				this.source = this.options.source;
5974			}
5975		},
5976
5977		_searchTimeout: function( event ) {
5978			clearTimeout( this.searching );
5979			this.searching = this._delay( function() {
5980
5981				// Search if the value has changed, or if the user retypes the same value (see #7434)
5982				var equalValues = this.term === this._value(),
5983					menuVisible = this.menu.element.is( ":visible" ),
5984					modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
5985
5986				if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
5987					this.selectedItem = null;
5988					this.search( null, event );
5989				}
5990			}, this.options.delay );
5991		},
5992
5993		search: function( value, event ) {
5994			value = value != null ? value : this._value();
5995
5996			// Always save the actual value, not the one passed as an argument
5997			this.term = this._value();
5998
5999			if ( value.length < this.options.minLength ) {
6000				return this.close( event );
6001			}
6002
6003			if ( this._trigger( "search", event ) === false ) {
6004				return;
6005			}
6006
6007			return this._search( value );
6008		},
6009
6010		_search: function( value ) {
6011			this.pending++;
6012			this._addClass( "ui-autocomplete-loading" );
6013			this.cancelSearch = false;
6014
6015			this.source( { term: value }, this._response() );
6016		},
6017
6018		_response: function() {
6019			var index = ++this.requestIndex;
6020
6021			return $.proxy( function( content ) {
6022				if ( index === this.requestIndex ) {
6023					this.__response( content );
6024				}
6025
6026				this.pending--;
6027				if ( !this.pending ) {
6028					this._removeClass( "ui-autocomplete-loading" );
6029				}
6030			}, this );
6031		},
6032
6033		__response: function( content ) {
6034			if ( content ) {
6035				content = this._normalize( content );
6036			}
6037			this._trigger( "response", null, { content: content } );
6038			if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
6039				this._suggest( content );
6040				this._trigger( "open" );
6041			} else {
6042
6043				// use ._close() instead of .close() so we don't cancel future searches
6044				this._close();
6045			}
6046		},
6047
6048		close: function( event ) {
6049			this.cancelSearch = true;
6050			this._close( event );
6051		},
6052
6053		_close: function( event ) {
6054
6055			// Remove the handler that closes the menu on outside clicks
6056			this._off( this.document, "mousedown" );
6057
6058			if ( this.menu.element.is( ":visible" ) ) {
6059				this.menu.element.hide();
6060				this.menu.blur();
6061				this.isNewMenu = true;
6062				this._trigger( "close", event );
6063			}
6064		},
6065
6066		_change: function( event ) {
6067			if ( this.previous !== this._value() ) {
6068				this._trigger( "change", event, { item: this.selectedItem } );
6069			}
6070		},
6071
6072		_normalize: function( items ) {
6073
6074			// assume all items have the right format when the first item is complete
6075			if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
6076				return items;
6077			}
6078			return $.map( items, function( item ) {
6079				if ( typeof item === "string" ) {
6080					return {
6081						label: item,
6082						value: item
6083					};
6084				}
6085				return $.extend( {}, item, {
6086					label: item.label || item.value,
6087					value: item.value || item.label
6088				} );
6089			} );
6090		},
6091
6092		_suggest: function( items ) {
6093			var ul = this.menu.element.empty();
6094			this._renderMenu( ul, items );
6095			this.isNewMenu = true;
6096			this.menu.refresh();
6097
6098			// Size and position menu
6099			ul.show();
6100			this._resizeMenu();
6101			ul.position( $.extend( {
6102				of: this.element
6103			}, this.options.position ) );
6104
6105			if ( this.options.autoFocus ) {
6106				this.menu.next();
6107			}
6108
6109			// Listen for interactions outside of the widget (#6642)
6110			this._on( this.document, {
6111				mousedown: "_closeOnClickOutside"
6112			} );
6113		},
6114
6115		_resizeMenu: function() {
6116			var ul = this.menu.element;
6117			ul.outerWidth( Math.max(
6118
6119				// Firefox wraps long text (possibly a rounding bug)
6120				// so we add 1px to avoid the wrapping (#7513)
6121				ul.width( "" ).outerWidth() + 1,
6122				this.element.outerWidth()
6123			) );
6124		},
6125
6126		_renderMenu: function( ul, items ) {
6127			var that = this;
6128			$.each( items, function( index, item ) {
6129				that._renderItemData( ul, item );
6130			} );
6131		},
6132
6133		_renderItemData: function( ul, item ) {
6134			return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
6135		},
6136
6137		_renderItem: function( ul, item ) {
6138			return $( "<li>" )
6139				.append( $( "<div>" ).text( item.label ) )
6140				.appendTo( ul );
6141		},
6142
6143		_move: function( direction, event ) {
6144			if ( !this.menu.element.is( ":visible" ) ) {
6145				this.search( null, event );
6146				return;
6147			}
6148			if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
6149				this.menu.isLastItem() && /^next/.test( direction ) ) {
6150
6151				if ( !this.isMultiLine ) {
6152					this._value( this.term );
6153				}
6154
6155				this.menu.blur();
6156				return;
6157			}
6158			this.menu[ direction ]( event );
6159		},
6160
6161		widget: function() {
6162			return this.menu.element;
6163		},
6164
6165		_value: function() {
6166			return this.valueMethod.apply( this.element, arguments );
6167		},
6168
6169		_keyEvent: function( keyEvent, event ) {
6170			if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
6171				this._move( keyEvent, event );
6172
6173				// Prevents moving cursor to beginning/end of the text field in some browsers
6174				event.preventDefault();
6175			}
6176		},
6177
6178		// Support: Chrome <=50
6179		// We should be able to just use this.element.prop( "isContentEditable" )
6180		// but hidden elements always report false in Chrome.
6181		// https://code.google.com/p/chromium/issues/detail?id=313082
6182		_isContentEditable: function( element ) {
6183			if ( !element.length ) {
6184				return false;
6185			}
6186
6187			var editable = element.prop( "contentEditable" );
6188
6189			if ( editable === "inherit" ) {
6190				return this._isContentEditable( element.parent() );
6191			}
6192
6193			return editable === "true";
6194		}
6195	} );
6196
6197	$.extend( $.ui.autocomplete, {
6198		escapeRegex: function( value ) {
6199			return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
6200		},
6201		filter: function( array, term ) {
6202			var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
6203			return $.grep( array, function( value ) {
6204				return matcher.test( value.label || value.value || value );
6205			} );
6206		}
6207	} );
6208
6209// Live region extension, adding a `messages` option
6210// NOTE: This is an experimental API. We are still investigating
6211// a full solution for string manipulation and internationalization.
6212	$.widget( "ui.autocomplete", $.ui.autocomplete, {
6213		options: {
6214			messages: {
6215				noResults: "No search results.",
6216				results: function( amount ) {
6217					return amount + ( amount > 1 ? " results are" : " result is" ) +
6218						" available, use up and down arrow keys to navigate.";
6219				}
6220			}
6221		},
6222
6223		__response: function( content ) {
6224			var message;
6225			this._superApply( arguments );
6226			if ( this.options.disabled || this.cancelSearch ) {
6227				return;
6228			}
6229			if ( content && content.length ) {
6230				message = this.options.messages.results( content.length );
6231			} else {
6232				message = this.options.messages.noResults;
6233			}
6234			this.liveRegion.children().hide();
6235			$( "<div>" ).text( message ).appendTo( this.liveRegion );
6236		}
6237	} );
6238
6239	var widgetsAutocomplete = $.ui.autocomplete;
6240
6241
6242	/*!
6243	 * jQuery UI Controlgroup 1.12.1
6244	 * http://jqueryui.com
6245	 *
6246	 * Copyright jQuery Foundation and other contributors
6247	 * Released under the MIT license.
6248	 * http://jquery.org/license
6249	 */
6250
6251//>>label: Controlgroup
6252//>>group: Widgets
6253//>>description: Visually groups form control widgets
6254//>>docs: http://api.jqueryui.com/controlgroup/
6255//>>demos: http://jqueryui.com/controlgroup/
6256//>>css.structure: ../../themes/base/core.css
6257//>>css.structure: ../../themes/base/controlgroup.css
6258//>>css.theme: ../../themes/base/theme.css
6259
6260
6261	var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g;
6262
6263	var widgetsControlgroup = $.widget( "ui.controlgroup", {
6264		version: "1.12.1",
6265		defaultElement: "<div>",
6266		options: {
6267			direction: "horizontal",
6268			disabled: null,
6269			onlyVisible: true,
6270			items: {
6271				"button": "input[type=button], input[type=submit], input[type=reset], button, a",
6272				"controlgroupLabel": ".ui-controlgroup-label",
6273				"checkboxradio": "input[type='checkbox'], input[type='radio']",
6274				"selectmenu": "select",
6275				"spinner": ".ui-spinner-input"
6276			}
6277		},
6278
6279		_create: function() {
6280			this._enhance();
6281		},
6282
6283		// To support the enhanced option in jQuery Mobile, we isolate DOM manipulation
6284		_enhance: function() {
6285			this.element.attr( "role", "toolbar" );
6286			this.refresh();
6287		},
6288
6289		_destroy: function() {
6290			this._callChildMethod( "destroy" );
6291			this.childWidgets.removeData( "ui-controlgroup-data" );
6292			this.element.removeAttr( "role" );
6293			if ( this.options.items.controlgroupLabel ) {
6294				this.element
6295					.find( this.options.items.controlgroupLabel )
6296					.find( ".ui-controlgroup-label-contents" )
6297					.contents().unwrap();
6298			}
6299		},
6300
6301		_initWidgets: function() {
6302			var that = this,
6303				childWidgets = [];
6304
6305			// First we iterate over each of the items options
6306			$.each( this.options.items, function( widget, selector ) {
6307				var labels;
6308				var options = {};
6309
6310				// Make sure the widget has a selector set
6311				if ( !selector ) {
6312					return;
6313				}
6314
6315				if ( widget === "controlgroupLabel" ) {
6316					labels = that.element.find( selector );
6317					labels.each( function() {
6318						var element = $( this );
6319
6320						if ( element.children( ".ui-controlgroup-label-contents" ).length ) {
6321							return;
6322						}
6323						element.contents()
6324							.wrapAll( "<span class='ui-controlgroup-label-contents'></span>" );
6325					} );
6326					that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" );
6327					childWidgets = childWidgets.concat( labels.get() );
6328					return;
6329				}
6330
6331				// Make sure the widget actually exists
6332				if ( !$.fn[ widget ] ) {
6333					return;
6334				}
6335
6336				// We assume everything is in the middle to start because we can't determine
6337				// first / last elements until all enhancments are done.
6338				if ( that[ "_" + widget + "Options" ] ) {
6339					options = that[ "_" + widget + "Options" ]( "middle" );
6340				} else {
6341					options = { classes: {} };
6342				}
6343
6344				// Find instances of this widget inside controlgroup and init them
6345				that.element
6346					.find( selector )
6347					.each( function() {
6348						var element = $( this );
6349						var instance = element[ widget ]( "instance" );
6350
6351						// We need to clone the default options for this type of widget to avoid
6352						// polluting the variable options which has a wider scope than a single widget.
6353						var instanceOptions = $.widget.extend( {}, options );
6354
6355						// If the button is the child of a spinner ignore it
6356						// TODO: Find a more generic solution
6357						if ( widget === "button" && element.parent( ".ui-spinner" ).length ) {
6358							return;
6359						}
6360
6361						// Create the widget if it doesn't exist
6362						if ( !instance ) {
6363							instance = element[ widget ]()[ widget ]( "instance" );
6364						}
6365						if ( instance ) {
6366							instanceOptions.classes =
6367								that._resolveClassesValues( instanceOptions.classes, instance );
6368						}
6369						element[ widget ]( instanceOptions );
6370
6371						// Store an instance of the controlgroup to be able to reference
6372						// from the outermost element for changing options and refresh
6373						var widgetElement = element[ widget ]( "widget" );
6374						$.data( widgetElement[ 0 ], "ui-controlgroup-data",
6375							instance ? instance : element[ widget ]( "instance" ) );
6376
6377						childWidgets.push( widgetElement[ 0 ] );
6378					} );
6379			} );
6380
6381			this.childWidgets = $( $.unique( childWidgets ) );
6382			this._addClass( this.childWidgets, "ui-controlgroup-item" );
6383		},
6384
6385		_callChildMethod: function( method ) {
6386			this.childWidgets.each( function() {
6387				var element = $( this ),
6388					data = element.data( "ui-controlgroup-data" );
6389				if ( data && data[ method ] ) {
6390					data[ method ]();
6391				}
6392			} );
6393		},
6394
6395		_updateCornerClass: function( element, position ) {
6396			var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all";
6397			var add = this._buildSimpleOptions( position, "label" ).classes.label;
6398
6399			this._removeClass( element, null, remove );
6400			this._addClass( element, null, add );
6401		},
6402
6403		_buildSimpleOptions: function( position, key ) {
6404			var direction = this.options.direction === "vertical";
6405			var result = {
6406				classes: {}
6407			};
6408			result.classes[ key ] = {
6409				"middle": "",
6410				"first": "ui-corner-" + ( direction ? "top" : "left" ),
6411				"last": "ui-corner-" + ( direction ? "bottom" : "right" ),
6412				"only": "ui-corner-all"
6413			}[ position ];
6414
6415			return result;
6416		},
6417
6418		_spinnerOptions: function( position ) {
6419			var options = this._buildSimpleOptions( position, "ui-spinner" );
6420
6421			options.classes[ "ui-spinner-up" ] = "";
6422			options.classes[ "ui-spinner-down" ] = "";
6423
6424			return options;
6425		},
6426
6427		_buttonOptions: function( position ) {
6428			return this._buildSimpleOptions( position, "ui-button" );
6429		},
6430
6431		_checkboxradioOptions: function( position ) {
6432			return this._buildSimpleOptions( position, "ui-checkboxradio-label" );
6433		},
6434
6435		_selectmenuOptions: function( position ) {
6436			var direction = this.options.direction === "vertical";
6437			return {
6438				width: direction ? "auto" : false,
6439				classes: {
6440					middle: {
6441						"ui-selectmenu-button-open": "",
6442						"ui-selectmenu-button-closed": ""
6443					},
6444					first: {
6445						"ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ),
6446						"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" )
6447					},
6448					last: {
6449						"ui-selectmenu-button-open": direction ? "" : "ui-corner-tr",
6450						"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" )
6451					},
6452					only: {
6453						"ui-selectmenu-button-open": "ui-corner-top",
6454						"ui-selectmenu-button-closed": "ui-corner-all"
6455					}
6456
6457				}[ position ]
6458			};
6459		},
6460
6461		_resolveClassesValues: function( classes, instance ) {
6462			var result = {};
6463			$.each( classes, function( key ) {
6464				var current = instance.options.classes[ key ] || "";
6465				current = $.trim( current.replace( controlgroupCornerRegex, "" ) );
6466				result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " );
6467			} );
6468			return result;
6469		},
6470
6471		_setOption: function( key, value ) {
6472			if ( key === "direction" ) {
6473				this._removeClass( "ui-controlgroup-" + this.options.direction );
6474			}
6475
6476			this._super( key, value );
6477			if ( key === "disabled" ) {
6478				this._callChildMethod( value ? "disable" : "enable" );
6479				return;
6480			}
6481
6482			this.refresh();
6483		},
6484
6485		refresh: function() {
6486			var children,
6487				that = this;
6488
6489			this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction );
6490
6491			if ( this.options.direction === "horizontal" ) {
6492				this._addClass( null, "ui-helper-clearfix" );
6493			}
6494			this._initWidgets();
6495
6496			children = this.childWidgets;
6497
6498			// We filter here because we need to track all childWidgets not just the visible ones
6499			if ( this.options.onlyVisible ) {
6500				children = children.filter( ":visible" );
6501			}
6502
6503			if ( children.length ) {
6504
6505				// We do this last because we need to make sure all enhancment is done
6506				// before determining first and last
6507				$.each( [ "first", "last" ], function( index, value ) {
6508					var instance = children[ value ]().data( "ui-controlgroup-data" );
6509
6510					if ( instance && that[ "_" + instance.widgetName + "Options" ] ) {
6511						var options = that[ "_" + instance.widgetName + "Options" ](
6512							children.length === 1 ? "only" : value
6513						);
6514						options.classes = that._resolveClassesValues( options.classes, instance );
6515						instance.element[ instance.widgetName ]( options );
6516					} else {
6517						that._updateCornerClass( children[ value ](), value );
6518					}
6519				} );
6520
6521				// Finally call the refresh method on each of the child widgets.
6522				this._callChildMethod( "refresh" );
6523			}
6524		}
6525	} );
6526
6527	/*!
6528	 * jQuery UI Checkboxradio 1.12.1
6529	 * http://jqueryui.com
6530	 *
6531	 * Copyright jQuery Foundation and other contributors
6532	 * Released under the MIT license.
6533	 * http://jquery.org/license
6534	 */
6535
6536//>>label: Checkboxradio
6537//>>group: Widgets
6538//>>description: Enhances a form with multiple themeable checkboxes or radio buttons.
6539//>>docs: http://api.jqueryui.com/checkboxradio/
6540//>>demos: http://jqueryui.com/checkboxradio/
6541//>>css.structure: ../../themes/base/core.css
6542//>>css.structure: ../../themes/base/button.css
6543//>>css.structure: ../../themes/base/checkboxradio.css
6544//>>css.theme: ../../themes/base/theme.css
6545
6546
6547
6548	$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
6549		version: "1.12.1",
6550		options: {
6551			disabled: null,
6552			label: null,
6553			icon: true,
6554			classes: {
6555				"ui-checkboxradio-label": "ui-corner-all",
6556				"ui-checkboxradio-icon": "ui-corner-all"
6557			}
6558		},
6559
6560		_getCreateOptions: function() {
6561			var disabled, labels;
6562			var that = this;
6563			var options = this._super() || {};
6564
6565			// We read the type here, because it makes more sense to throw a element type error first,
6566			// rather then the error for lack of a label. Often if its the wrong type, it
6567			// won't have a label (e.g. calling on a div, btn, etc)
6568			this._readType();
6569
6570			labels = this.element.labels();
6571
6572			// If there are multiple labels, use the last one
6573			this.label = $( labels[ labels.length - 1 ] );
6574			if ( !this.label.length ) {
6575				$.error( "No label found for checkboxradio widget" );
6576			}
6577
6578			this.originalLabel = "";
6579
6580			// We need to get the label text but this may also need to make sure it does not contain the
6581			// input itself.
6582			this.label.contents().not( this.element[ 0 ] ).each( function() {
6583
6584				// The label contents could be text, html, or a mix. We concat each element to get a
6585				// string representation of the label, without the input as part of it.
6586				that.originalLabel += this.nodeType === 3 ? $( this ).text() : this.outerHTML;
6587			} );
6588
6589			// Set the label option if we found label text
6590			if ( this.originalLabel ) {
6591				options.label = this.originalLabel;
6592			}
6593
6594			disabled = this.element[ 0 ].disabled;
6595			if ( disabled != null ) {
6596				options.disabled = disabled;
6597			}
6598			return options;
6599		},
6600
6601		_create: function() {
6602			var checked = this.element[ 0 ].checked;
6603
6604			this._bindFormResetHandler();
6605
6606			if ( this.options.disabled == null ) {
6607				this.options.disabled = this.element[ 0 ].disabled;
6608			}
6609
6610			this._setOption( "disabled", this.options.disabled );
6611			this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" );
6612			this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" );
6613
6614			if ( this.type === "radio" ) {
6615				this._addClass( this.label, "ui-checkboxradio-radio-label" );
6616			}
6617
6618			if ( this.options.label && this.options.label !== this.originalLabel ) {
6619				this._updateLabel();
6620			} else if ( this.originalLabel ) {
6621				this.options.label = this.originalLabel;
6622			}
6623
6624			this._enhance();
6625
6626			if ( checked ) {
6627				this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" );
6628				if ( this.icon ) {
6629					this._addClass( this.icon, null, "ui-state-hover" );
6630				}
6631			}
6632
6633			this._on( {
6634				change: "_toggleClasses",
6635				focus: function() {
6636					this._addClass( this.label, null, "ui-state-focus ui-visual-focus" );
6637				},
6638				blur: function() {
6639					this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" );
6640				}
6641			} );
6642		},
6643
6644		_readType: function() {
6645			var nodeName = this.element[ 0 ].nodeName.toLowerCase();
6646			this.type = this.element[ 0 ].type;
6647			if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) {
6648				$.error( "Can't create checkboxradio on element.nodeName=" + nodeName +
6649					" and element.type=" + this.type );
6650			}
6651		},
6652
6653		// Support jQuery Mobile enhanced option
6654		_enhance: function() {
6655			this._updateIcon( this.element[ 0 ].checked );
6656		},
6657
6658		widget: function() {
6659			return this.label;
6660		},
6661
6662		_getRadioGroup: function() {
6663			var group;
6664			var name = this.element[ 0 ].name;
6665			var nameSelector = "input[name='" + $.ui.escapeSelector( name ) + "']";
6666
6667			if ( !name ) {
6668				return $( [] );
6669			}
6670
6671			if ( this.form.length ) {
6672				group = $( this.form[ 0 ].elements ).filter( nameSelector );
6673			} else {
6674
6675				// Not inside a form, check all inputs that also are not inside a form
6676				group = $( nameSelector ).filter( function() {
6677					return $( this ).form().length === 0;
6678				} );
6679			}
6680
6681			return group.not( this.element );
6682		},
6683
6684		_toggleClasses: function() {
6685			var checked = this.element[ 0 ].checked;
6686			this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
6687
6688			if ( this.options.icon && this.type === "checkbox" ) {
6689				this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked )
6690					._toggleClass( this.icon, null, "ui-icon-blank", !checked );
6691			}
6692
6693			if ( this.type === "radio" ) {
6694				this._getRadioGroup()
6695					.each( function() {
6696						var instance = $( this ).checkboxradio( "instance" );
6697
6698						if ( instance ) {
6699							instance._removeClass( instance.label,
6700								"ui-checkboxradio-checked", "ui-state-active" );
6701						}
6702					} );
6703			}
6704		},
6705
6706		_destroy: function() {
6707			this._unbindFormResetHandler();
6708
6709			if ( this.icon ) {
6710				this.icon.remove();
6711				this.iconSpace.remove();
6712			}
6713		},
6714
6715		_setOption: function( key, value ) {
6716
6717			// We don't allow the value to be set to nothing
6718			if ( key === "label" && !value ) {
6719				return;
6720			}
6721
6722			this._super( key, value );
6723
6724			if ( key === "disabled" ) {
6725				this._toggleClass( this.label, null, "ui-state-disabled", value );
6726				this.element[ 0 ].disabled = value;
6727
6728				// Don't refresh when setting disabled
6729				return;
6730			}
6731			this.refresh();
6732		},
6733
6734		_updateIcon: function( checked ) {
6735			var toAdd = "ui-icon ui-icon-background ";
6736
6737			if ( this.options.icon ) {
6738				if ( !this.icon ) {
6739					this.icon = $( "<span>" );
6740					this.iconSpace = $( "<span> </span>" );
6741					this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" );
6742				}
6743
6744				if ( this.type === "checkbox" ) {
6745					toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank";
6746					this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" );
6747				} else {
6748					toAdd += "ui-icon-blank";
6749				}
6750				this._addClass( this.icon, "ui-checkboxradio-icon", toAdd );
6751				if ( !checked ) {
6752					this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" );
6753				}
6754				this.icon.prependTo( this.label ).after( this.iconSpace );
6755			} else if ( this.icon !== undefined ) {
6756				this.icon.remove();
6757				this.iconSpace.remove();
6758				delete this.icon;
6759			}
6760		},
6761
6762		_updateLabel: function() {
6763
6764			// Remove the contents of the label ( minus the icon, icon space, and input )
6765			var contents = this.label.contents().not( this.element[ 0 ] );
6766			if ( this.icon ) {
6767				contents = contents.not( this.icon[ 0 ] );
6768			}
6769			if ( this.iconSpace ) {
6770				contents = contents.not( this.iconSpace[ 0 ] );
6771			}
6772			contents.remove();
6773
6774			this.label.append( this.options.label );
6775		},
6776
6777		refresh: function() {
6778			var checked = this.element[ 0 ].checked,
6779				isDisabled = this.element[ 0 ].disabled;
6780
6781			this._updateIcon( checked );
6782			this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
6783			if ( this.options.label !== null ) {
6784				this._updateLabel();
6785			}
6786
6787			if ( isDisabled !== this.options.disabled ) {
6788				this._setOptions( { "disabled": isDisabled } );
6789			}
6790		}
6791
6792	} ] );
6793
6794	var widgetsCheckboxradio = $.ui.checkboxradio;
6795
6796
6797	/*!
6798	 * jQuery UI Button 1.12.1
6799	 * http://jqueryui.com
6800	 *
6801	 * Copyright jQuery Foundation and other contributors
6802	 * Released under the MIT license.
6803	 * http://jquery.org/license
6804	 */
6805
6806//>>label: Button
6807//>>group: Widgets
6808//>>description: Enhances a form with themeable buttons.
6809//>>docs: http://api.jqueryui.com/button/
6810//>>demos: http://jqueryui.com/button/
6811//>>css.structure: ../../themes/base/core.css
6812//>>css.structure: ../../themes/base/button.css
6813//>>css.theme: ../../themes/base/theme.css
6814
6815
6816
6817	$.widget( "ui.button", {
6818		version: "1.12.1",
6819		defaultElement: "<button>",
6820		options: {
6821			classes: {
6822				"ui-button": "ui-corner-all"
6823			},
6824			disabled: null,
6825			icon: null,
6826			iconPosition: "beginning",
6827			label: null,
6828			showLabel: true
6829		},
6830
6831		_getCreateOptions: function() {
6832			var disabled,
6833
6834			// This is to support cases like in jQuery Mobile where the base widget does have
6835			// an implementation of _getCreateOptions
6836				options = this._super() || {};
6837
6838			this.isInput = this.element.is( "input" );
6839
6840			disabled = this.element[ 0 ].disabled;
6841			if ( disabled != null ) {
6842				options.disabled = disabled;
6843			}
6844
6845			this.originalLabel = this.isInput ? this.element.val() : this.element.html();
6846			if ( this.originalLabel ) {
6847				options.label = this.originalLabel;
6848			}
6849
6850			return options;
6851		},
6852
6853		_create: function() {
6854			if ( !this.option.showLabel & !this.options.icon ) {
6855				this.options.showLabel = true;
6856			}
6857
6858			// We have to check the option again here even though we did in _getCreateOptions,
6859			// because null may have been passed on init which would override what was set in
6860			// _getCreateOptions
6861			if ( this.options.disabled == null ) {
6862				this.options.disabled = this.element[ 0 ].disabled || false;
6863			}
6864
6865			this.hasTitle = !!this.element.attr( "title" );
6866
6867			// Check to see if the label needs to be set or if its already correct
6868			if ( this.options.label && this.options.label !== this.originalLabel ) {
6869				if ( this.isInput ) {
6870					this.element.val( this.options.label );
6871				} else {
6872					this.element.html( this.options.label );
6873				}
6874			}
6875			this._addClass( "ui-button", "ui-widget" );
6876			this._setOption( "disabled", this.options.disabled );
6877			this._enhance();
6878
6879			if ( this.element.is( "a" ) ) {
6880				this._on( {
6881					"keyup": function( event ) {
6882						if ( event.keyCode === $.ui.keyCode.SPACE ) {
6883							event.preventDefault();
6884
6885							// Support: PhantomJS <= 1.9, IE 8 Only
6886							// If a native click is available use it so we actually cause navigation
6887							// otherwise just trigger a click event
6888							if ( this.element[ 0 ].click ) {
6889								this.element[ 0 ].click();
6890							} else {
6891								this.element.trigger( "click" );
6892							}
6893						}
6894					}
6895				} );
6896			}
6897		},
6898
6899		_enhance: function() {
6900			if ( !this.element.is( "button" ) ) {
6901				this.element.attr( "role", "button" );
6902			}
6903
6904			if ( this.options.icon ) {
6905				this._updateIcon( "icon", this.options.icon );
6906				this._updateTooltip();
6907			}
6908		},
6909
6910		_updateTooltip: function() {
6911			this.title = this.element.attr( "title" );
6912
6913			if ( !this.options.showLabel && !this.title ) {
6914				this.element.attr( "title", this.options.label );
6915			}
6916		},
6917
6918		_updateIcon: function( option, value ) {
6919			var icon = option !== "iconPosition",
6920				position = icon ? this.options.iconPosition : value,
6921				displayBlock = position === "top" || position === "bottom";
6922
6923			// Create icon
6924			if ( !this.icon ) {
6925				this.icon = $( "<span>" );
6926
6927				this._addClass( this.icon, "ui-button-icon", "ui-icon" );
6928
6929				if ( !this.options.showLabel ) {
6930					this._addClass( "ui-button-icon-only" );
6931				}
6932			} else if ( icon ) {
6933
6934				// If we are updating the icon remove the old icon class
6935				this._removeClass( this.icon, null, this.options.icon );
6936			}
6937
6938			// If we are updating the icon add the new icon class
6939			if ( icon ) {
6940				this._addClass( this.icon, null, value );
6941			}
6942
6943			this._attachIcon( position );
6944
6945			// If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove
6946			// the iconSpace if there is one.
6947			if ( displayBlock ) {
6948				this._addClass( this.icon, null, "ui-widget-icon-block" );
6949				if ( this.iconSpace ) {
6950					this.iconSpace.remove();
6951				}
6952			} else {
6953
6954				// Position is beginning or end so remove the ui-widget-icon-block class and add the
6955				// space if it does not exist
6956				if ( !this.iconSpace ) {
6957					this.iconSpace = $( "<span> </span>" );
6958					this._addClass( this.iconSpace, "ui-button-icon-space" );
6959				}
6960				this._removeClass( this.icon, null, "ui-wiget-icon-block" );
6961				this._attachIconSpace( position );
6962			}
6963		},
6964
6965		_destroy: function() {
6966			this.element.removeAttr( "role" );
6967
6968			if ( this.icon ) {
6969				this.icon.remove();
6970			}
6971			if ( this.iconSpace ) {
6972				this.iconSpace.remove();
6973			}
6974			if ( !this.hasTitle ) {
6975				this.element.removeAttr( "title" );
6976			}
6977		},
6978
6979		_attachIconSpace: function( iconPosition ) {
6980			this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace );
6981		},
6982
6983		_attachIcon: function( iconPosition ) {
6984			this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon );
6985		},
6986
6987		_setOptions: function( options ) {
6988			var newShowLabel = options.showLabel === undefined ?
6989					this.options.showLabel :
6990					options.showLabel,
6991				newIcon = options.icon === undefined ? this.options.icon : options.icon;
6992
6993			if ( !newShowLabel && !newIcon ) {
6994				options.showLabel = true;
6995			}
6996			this._super( options );
6997		},
6998
6999		_setOption: function( key, value ) {
7000			if ( key === "icon" ) {
7001				if ( value ) {
7002					this._updateIcon( key, value );
7003				} else if ( this.icon ) {
7004					this.icon.remove();
7005					if ( this.iconSpace ) {
7006						this.iconSpace.remove();
7007					}
7008				}
7009			}
7010
7011			if ( key === "iconPosition" ) {
7012				this._updateIcon( key, value );
7013			}
7014
7015			// Make sure we can't end up with a button that has neither text nor icon
7016			if ( key === "showLabel" ) {
7017				this._toggleClass( "ui-button-icon-only", null, !value );
7018				this._updateTooltip();
7019			}
7020
7021			if ( key === "label" ) {
7022				if ( this.isInput ) {
7023					this.element.val( value );
7024				} else {
7025
7026					// If there is an icon, append it, else nothing then append the value
7027					// this avoids removal of the icon when setting label text
7028					this.element.html( value );
7029					if ( this.icon ) {
7030						this._attachIcon( this.options.iconPosition );
7031						this._attachIconSpace( this.options.iconPosition );
7032					}
7033				}
7034			}
7035
7036			this._super( key, value );
7037
7038			if ( key === "disabled" ) {
7039				this._toggleClass( null, "ui-state-disabled", value );
7040				this.element[ 0 ].disabled = value;
7041				if ( value ) {
7042					this.element.blur();
7043				}
7044			}
7045		},
7046
7047		refresh: function() {
7048
7049			// Make sure to only check disabled if its an element that supports this otherwise
7050			// check for the disabled class to determine state
7051			var isDisabled = this.element.is( "input, button" ) ?
7052				this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" );
7053
7054			if ( isDisabled !== this.options.disabled ) {
7055				this._setOptions( { disabled: isDisabled } );
7056			}
7057
7058			this._updateTooltip();
7059		}
7060	} );
7061
7062// DEPRECATED
7063	if ( $.uiBackCompat !== false ) {
7064
7065		// Text and Icons options
7066		$.widget( "ui.button", $.ui.button, {
7067			options: {
7068				text: true,
7069				icons: {
7070					primary: null,
7071					secondary: null
7072				}
7073			},
7074
7075			_create: function() {
7076				if ( this.options.showLabel && !this.options.text ) {
7077					this.options.showLabel = this.options.text;
7078				}
7079				if ( !this.options.showLabel && this.options.text ) {
7080					this.options.text = this.options.showLabel;
7081				}
7082				if ( !this.options.icon && ( this.options.icons.primary ||
7083					this.options.icons.secondary ) ) {
7084					if ( this.options.icons.primary ) {
7085						this.options.icon = this.options.icons.primary;
7086					} else {
7087						this.options.icon = this.options.icons.secondary;
7088						this.options.iconPosition = "end";
7089					}
7090				} else if ( this.options.icon ) {
7091					this.options.icons.primary = this.options.icon;
7092				}
7093				this._super();
7094			},
7095
7096			_setOption: function( key, value ) {
7097				if ( key === "text" ) {
7098					this._super( "showLabel", value );
7099					return;
7100				}
7101				if ( key === "showLabel" ) {
7102					this.options.text = value;
7103				}
7104				if ( key === "icon" ) {
7105					this.options.icons.primary = value;
7106				}
7107				if ( key === "icons" ) {
7108					if ( value.primary ) {
7109						this._super( "icon", value.primary );
7110						this._super( "iconPosition", "beginning" );
7111					} else if ( value.secondary ) {
7112						this._super( "icon", value.secondary );
7113						this._super( "iconPosition", "end" );
7114					}
7115				}
7116				this._superApply( arguments );
7117			}
7118		} );
7119
7120		$.fn.button = ( function( orig ) {
7121			return function() {
7122				if ( !this.length || ( this.length && this[ 0 ].tagName !== "INPUT" ) ||
7123					( this.length && this[ 0 ].tagName === "INPUT" && (
7124						this.attr( "type" ) !== "checkbox" && this.attr( "type" ) !== "radio"
7125					) ) ) {
7126					return orig.apply( this, arguments );
7127				}
7128				if ( !$.ui.checkboxradio ) {
7129					$.error( "Checkboxradio widget missing" );
7130				}
7131				if ( arguments.length === 0 ) {
7132					return this.checkboxradio( {
7133						"icon": false
7134					} );
7135				}
7136				return this.checkboxradio.apply( this, arguments );
7137			};
7138		} )( $.fn.button );
7139
7140		$.fn.buttonset = function() {
7141			if ( !$.ui.controlgroup ) {
7142				$.error( "Controlgroup widget missing" );
7143			}
7144			if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) {
7145				return this.controlgroup.apply( this,
7146					[ arguments[ 0 ], "items.button", arguments[ 2 ] ] );
7147			}
7148			if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) {
7149				return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] );
7150			}
7151			if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) {
7152				arguments[ 0 ].items = {
7153					button: arguments[ 0 ].items
7154				};
7155			}
7156			return this.controlgroup.apply( this, arguments );
7157		};
7158	}
7159
7160	var widgetsButton = $.ui.button;
7161
7162
7163// jscs:disable maximumLineLength
7164	/* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
7165	/*!
7166	 * jQuery UI Datepicker 1.12.1
7167	 * http://jqueryui.com
vendor: 4,615 bytes, lines 7168-7254
7168	 *
7169	 * Copyright jQuery Foundation and other contributors
7170	 * Released under the MIT license.
7171	 * http://jquery.org/license
7172	 */
7173
7174//>>label: Datepicker
7175//>>group: Widgets
7176//>>description: Displays a calendar from an input or inline for selecting dates.
7177//>>docs: http://api.jqueryui.com/datepicker/
7178//>>demos: http://jqueryui.com/datepicker/
7179//>>css.structure: ../../themes/base/core.css
7180//>>css.structure: ../../themes/base/datepicker.css
7181//>>css.theme: ../../themes/base/theme.css
7182
7183
7184
7185	$.extend( $.ui, { datepicker: { version: "1.12.1" } } );
7186
7187	var datepicker_instActive;
7188
7189	function datepicker_getZindex( elem ) {
7190		var position, value;
7191		while ( elem.length && elem[ 0 ] !== document ) {
7192
7193			// Ignore z-index if position is set to a value where z-index is ignored by the browser
7194			// This makes behavior of this function consistent across browsers
7195			// WebKit always returns auto if the element is positioned
7196			position = elem.css( "position" );
7197			if ( position === "absolute" || position === "relative" || position === "fixed" ) {
7198
7199				// IE returns 0 when zIndex is not specified
7200				// other browsers return a string
7201				// we ignore the case of nested elements with an explicit value of 0
7202				// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
7203				value = parseInt( elem.css( "zIndex" ), 10 );
7204				if ( !isNaN( value ) && value !== 0 ) {
7205					return value;
7206				}
7207			}
7208			elem = elem.parent();
7209		}
7210
7211		return 0;
7212	}
7213	/* Date picker manager.
7214	 Use the singleton instance of this class, $.datepicker, to interact with the date picker.
7215	 Settings for (groups of) date pickers are maintained in an instance object,
7216	 allowing multiple different settings on the same page. */
7217
7218	function Datepicker() {
7219		this._curInst = null; // The current instance in use
7220		this._keyEvent = false; // If the last event was a key event
7221		this._disabledInputs = []; // List of date picker inputs that have been disabled
7222		this._datepickerShowing = false; // True if the popup picker is showing , false if not
7223		this._inDialog = false; // True if showing within a "dialog", false if not
7224		this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
7225		this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
7226		this._appendClass = "ui-datepicker-append"; // The name of the append marker class
7227		this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
7228		this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
7229		this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
7230		this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
7231		this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
7232		this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
7233		this.regional = []; // Available regional settings, indexed by language code
7234		this.regional[ "" ] = { // Default regional settings
7235			closeText: "Done", // Display text for close link
7236			prevText: "Prev", // Display text for previous month link
7237			nextText: "Next", // Display text for next month link
7238			currentText: "Today", // Display text for current month link
7239			monthNames: [ "January","February","March","April","May","June",
7240				"July","August","September","October","November","December" ], // Names of months for drop-down and formatting
7241			monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting
7242			dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting
7243			dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting
7244			dayNamesMin: [ "Su","Mo","Tu","We","Th","Fr","Sa" ], // Column headings for days starting at Sunday
7245			weekHeader: "Wk", // Column header for week of the year
7246			dateFormat: "mm/dd/yy", // See format options on parseDate
7247			firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
7248			isRTL: false, // True if right-to-left language, false if left-to-right
7249			showMonthAfterYear: false, // True if the year select precedes month, false for month then year
7250			yearSuffix: "" // Additional text to append to the year in the month headers
7251		};
7252		this._defaults = { // Global defaults for all the date picker instances
7253			showOn: "focus", // "focus" for popup on focus,
7254			// "button" for trigger button, or "both" for either
vendor: 6,039 bytes, lines 7255-7363
7255			showAnim: "fadeIn", // Name of jQuery animation for popup
7256			showOptions: {}, // Options for enhanced animations
7257			defaultDate: null, // Used when field is blank: actual date,
7258			// +/-number for offset from today, null for today
7259			appendText: "", // Display text following the input box, e.g. showing the format
7260			buttonText: "...", // Text for trigger button
7261			buttonImage: "", // URL for trigger button image
7262			buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
7263			hideIfNoPrevNext: false, // True to hide next/previous month links
7264			// if not applicable, false to just disable them
7265			navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
7266			gotoCurrent: false, // True if today link goes back to current selection instead
7267			changeMonth: false, // True if month can be selected directly, false if only prev/next
7268			changeYear: false, // True if year can be selected directly, false if only prev/next
7269			yearRange: "c-10:c+10", // Range of years to display in drop-down,
7270			// either relative to today's year (-nn:+nn), relative to currently displayed year
7271			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
7272			showOtherMonths: false, // True to show dates in other months, false to leave blank
7273			selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
7274			showWeek: false, // True to show week of the year, false to not show it
7275			calculateWeek: this.iso8601Week, // How to calculate the week of the year,
7276			// takes a Date and returns the number of the week for it
7277			shortYearCutoff: "+10", // Short year values < this are in the current century,
7278			// > this are in the previous century,
7279			// string value starting with "+" for current year + value
7280			minDate: null, // The earliest selectable date, or null for no limit
7281			maxDate: null, // The latest selectable date, or null for no limit
7282			duration: "fast", // Duration of display/closure
7283			beforeShowDay: null, // Function that takes a date and returns an array with
7284			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
7285			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
7286			beforeShow: null, // Function that takes an input field and
7287			// returns a set of custom settings for the date picker
7288			onSelect: null, // Define a callback function when a date is selected
7289			onChangeMonthYear: null, // Define a callback function when the month or year is changed
7290			onClose: null, // Define a callback function when the datepicker is closed
7291			numberOfMonths: 1, // Number of months to show at a time
7292			showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
7293			stepMonths: 1, // Number of months to step back/forward
7294			stepBigMonths: 12, // Number of months to step back/forward for the big links
7295			altField: "", // Selector for an alternate field to store selected dates into
7296			altFormat: "", // The date format to use for the alternate field
7297			constrainInput: true, // The input is constrained by the current date format
7298			showButtonPanel: false, // True to show button panel, false to not show it
7299			autoSize: false, // True to size the input for the date format, false to leave as is
7300			disabled: false // The initial disabled state
7301		};
7302		$.extend( this._defaults, this.regional[ "" ] );
7303		this.regional.en = $.extend( true, {}, this.regional[ "" ] );
7304		this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
7305		this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) );
7306	}
7307
7308	$.extend( Datepicker.prototype, {
7309		/* Class name added to elements to indicate already configured with a date picker. */
7310		markerClassName: "hasDatepicker",
7311
7312		//Keep track of the maximum number of rows displayed (see #7043)
7313		maxRows: 4,
7314
7315		// TODO rename to "widget" when switching to widget factory
7316		_widgetDatepicker: function() {
7317			return this.dpDiv;
7318		},
7319
7320		/* Override the default settings for all instances of the date picker.
7321		 * @param  settings  object - the new settings to use as defaults (anonymous object)
7322		 * @return the manager object
7323		 */
7324		setDefaults: function( settings ) {
7325			datepicker_extendRemove( this._defaults, settings || {} );
7326			return this;
7327		},
7328
7329		/* Attach the date picker to a jQuery selection.
7330		 * @param  target	element - the target input field or division or span
7331		 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
7332		 */
7333		_attachDatepicker: function( target, settings ) {
7334			var nodeName, inline, inst;
7335			nodeName = target.nodeName.toLowerCase();
7336			inline = ( nodeName === "div" || nodeName === "span" );
7337			if ( !target.id ) {
7338				this.uuid += 1;
7339				target.id = "dp" + this.uuid;
7340			}
7341			inst = this._newInst( $( target ), inline );
7342			inst.settings = $.extend( {}, settings || {} );
7343			if ( nodeName === "input" ) {
7344				this._connectDatepicker( target, inst );
7345			} else if ( inline ) {
7346				this._inlineDatepicker( target, inst );
7347			}
7348		},
7349
7350		/* Create a new instance object. */
7351		_newInst: function( target, inline ) {
7352			var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars
7353			return { id: id, input: target, // associated target
7354				selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
7355				drawMonth: 0, drawYear: 0, // month being drawn
7356				inline: inline, // is datepicker inline or not
7357				dpDiv: ( !inline ? this.dpDiv : // presentation div
7358					datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) };
7359		},
7360
7361		/* Attach the date picker to an input field. */
7362		_connectDatepicker: function( target, inst ) {
7363			var input = $( target );
vendor: 4,069 bytes, lines 7364-7473
7364			inst.append = $( [] );
7365			inst.trigger = $( [] );
7366			if ( input.hasClass( this.markerClassName ) ) {
7367				return;
7368			}
7369			this._attachments( input, inst );
7370			input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ).
7371				on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp );
7372			this._autoSize( inst );
7373			$.data( target, "datepicker", inst );
7374
7375			//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
7376			if ( inst.settings.disabled ) {
7377				this._disableDatepicker( target );
7378			}
7379		},
7380
7381		/* Make attachments based on settings. */
7382		_attachments: function( input, inst ) {
7383			var showOn, buttonText, buttonImage,
7384				appendText = this._get( inst, "appendText" ),
7385				isRTL = this._get( inst, "isRTL" );
7386
7387			if ( inst.append ) {
7388				inst.append.remove();
7389			}
7390			if ( appendText ) {
7391				inst.append = $( "<span class='" + this._appendClass + "'>" + appendText + "</span>" );
7392				input[ isRTL ? "before" : "after" ]( inst.append );
7393			}
7394
7395			input.off( "focus", this._showDatepicker );
7396
7397			if ( inst.trigger ) {
7398				inst.trigger.remove();
7399			}
7400
7401			showOn = this._get( inst, "showOn" );
7402			if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field
7403				input.on( "focus", this._showDatepicker );
7404			}
7405			if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked
7406				buttonText = this._get( inst, "buttonText" );
7407				buttonImage = this._get( inst, "buttonImage" );
7408				inst.trigger = $( this._get( inst, "buttonImageOnly" ) ?
7409					$( "<img/>" ).addClass( this._triggerClass ).
7410						attr( { src: buttonImage, alt: buttonText, title: buttonText } ) :
7411					$( "<button type='button'></button>" ).addClass( this._triggerClass ).
7412						html( !buttonImage ? buttonText : $( "<img/>" ).attr(
7413							{ src:buttonImage, alt:buttonText, title:buttonText } ) ) );
7414				input[ isRTL ? "before" : "after" ]( inst.trigger );
7415				inst.trigger.on( "click", function() {
7416					if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) {
7417						$.datepicker._hideDatepicker();
7418					} else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) {
7419						$.datepicker._hideDatepicker();
7420						$.datepicker._showDatepicker( input[ 0 ] );
7421					} else {
7422						$.datepicker._showDatepicker( input[ 0 ] );
7423					}
7424					return false;
7425				} );
7426			}
7427		},
7428
7429		/* Apply the maximum length for the date format. */
7430		_autoSize: function( inst ) {
7431			if ( this._get( inst, "autoSize" ) && !inst.inline ) {
7432				var findMax, max, maxI, i,
7433					date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits
7434					dateFormat = this._get( inst, "dateFormat" );
7435
7436				if ( dateFormat.match( /[DM]/ ) ) {
7437					findMax = function( names ) {
7438						max = 0;
7439						maxI = 0;
7440						for ( i = 0; i < names.length; i++ ) {
7441							if ( names[ i ].length > max ) {
7442								max = names[ i ].length;
7443								maxI = i;
7444							}
7445						}
7446						return maxI;
7447					};
7448					date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ?
7449						"monthNames" : "monthNamesShort" ) ) ) );
7450					date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ?
7451							"dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() );
7452				}
7453				inst.input.attr( "size", this._formatDate( inst, date ).length );
7454			}
7455		},
7456
7457		/* Attach an inline date picker to a div. */
7458		_inlineDatepicker: function( target, inst ) {
7459			var divSpan = $( target );
7460			if ( divSpan.hasClass( this.markerClassName ) ) {
7461				return;
7462			}
7463			divSpan.addClass( this.markerClassName ).append( inst.dpDiv );
7464			$.data( target, "datepicker", inst );
7465			this._setDate( inst, this._getDefaultDate( inst ), true );
7466			this._updateDatepicker( inst );
7467			this._updateAlternate( inst );
7468
7469			//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7470			if ( inst.settings.disabled ) {
7471				this._disableDatepicker( target );
7472			}
7473
vendor: 3,104 bytes, lines 7474-7545
7474			// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7475			// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7476			inst.dpDiv.css( "display", "block" );
7477		},
7478
7479		/* Pop-up the date picker in a "dialog" box.
7480		 * @param  input element - ignored
7481		 * @param  date	string or Date - the initial date to display
7482		 * @param  onSelect  function - the function to call when a date is selected
7483		 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
7484		 * @param  pos int[2] - coordinates for the dialog's position within the screen or
7485		 *					event - with x/y coordinates or
7486		 *					leave empty for default (screen centre)
7487		 * @return the manager object
7488		 */
7489		_dialogDatepicker: function( input, date, onSelect, settings, pos ) {
7490			var id, browserWidth, browserHeight, scrollX, scrollY,
7491				inst = this._dialogInst; // internal instance
7492
7493			if ( !inst ) {
7494				this.uuid += 1;
7495				id = "dp" + this.uuid;
7496				this._dialogInput = $( "<input type='text' id='" + id +
7497					"' style='position: absolute; top: -100px; width: 0px;'/>" );
7498				this._dialogInput.on( "keydown", this._doKeyDown );
7499				$( "body" ).append( this._dialogInput );
7500				inst = this._dialogInst = this._newInst( this._dialogInput, false );
7501				inst.settings = {};
7502				$.data( this._dialogInput[ 0 ], "datepicker", inst );
7503			}
7504			datepicker_extendRemove( inst.settings, settings || {} );
7505			date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date );
7506			this._dialogInput.val( date );
7507
7508			this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null );
7509			if ( !this._pos ) {
7510				browserWidth = document.documentElement.clientWidth;
7511				browserHeight = document.documentElement.clientHeight;
7512				scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7513				scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7514				this._pos = // should use actual width/height below
7515					[ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ];
7516			}
7517
7518			// Move input on screen for focus, but hidden behind dialog
7519			this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" );
7520			inst.settings.onSelect = onSelect;
7521			this._inDialog = true;
7522			this.dpDiv.addClass( this._dialogClass );
7523			this._showDatepicker( this._dialogInput[ 0 ] );
7524			if ( $.blockUI ) {
7525				$.blockUI( this.dpDiv );
7526			}
7527			$.data( this._dialogInput[ 0 ], "datepicker", inst );
7528			return this;
7529		},
7530
7531		/* Detach a datepicker from its control.
7532		 * @param  target	element - the target input field or division or span
7533		 */
7534		_destroyDatepicker: function( target ) {
7535			var nodeName,
7536				$target = $( target ),
7537				inst = $.data( target, "datepicker" );
7538
7539			if ( !$target.hasClass( this.markerClassName ) ) {
7540				return;
7541			}
7542
7543			nodeName = target.nodeName.toLowerCase();
7544			$.removeData( target, "datepicker" );
7545			if ( nodeName === "input" ) {
vendor: 12,339 bytes, lines 7546-7886
7546				inst.append.remove();
7547				inst.trigger.remove();
7548				$target.removeClass( this.markerClassName ).
7549					off( "focus", this._showDatepicker ).
7550					off( "keydown", this._doKeyDown ).
7551					off( "keypress", this._doKeyPress ).
7552					off( "keyup", this._doKeyUp );
7553			} else if ( nodeName === "div" || nodeName === "span" ) {
7554				$target.removeClass( this.markerClassName ).empty();
7555			}
7556
7557			if ( datepicker_instActive === inst ) {
7558				datepicker_instActive = null;
7559			}
7560		},
7561
7562		/* Enable the date picker to a jQuery selection.
7563		 * @param  target	element - the target input field or division or span
7564		 */
7565		_enableDatepicker: function( target ) {
7566			var nodeName, inline,
7567				$target = $( target ),
7568				inst = $.data( target, "datepicker" );
7569
7570			if ( !$target.hasClass( this.markerClassName ) ) {
7571				return;
7572			}
7573
7574			nodeName = target.nodeName.toLowerCase();
7575			if ( nodeName === "input" ) {
7576				target.disabled = false;
7577				inst.trigger.filter( "button" ).
7578					each( function() { this.disabled = false; } ).end().
7579					filter( "img" ).css( { opacity: "1.0", cursor: "" } );
7580			} else if ( nodeName === "div" || nodeName === "span" ) {
7581				inline = $target.children( "." + this._inlineClass );
7582				inline.children().removeClass( "ui-state-disabled" );
7583				inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
7584					prop( "disabled", false );
7585			}
7586			this._disabledInputs = $.map( this._disabledInputs,
7587				function( value ) { return ( value === target ? null : value ); } ); // delete entry
7588		},
7589
7590		/* Disable the date picker to a jQuery selection.
7591		 * @param  target	element - the target input field or division or span
7592		 */
7593		_disableDatepicker: function( target ) {
7594			var nodeName, inline,
7595				$target = $( target ),
7596				inst = $.data( target, "datepicker" );
7597
7598			if ( !$target.hasClass( this.markerClassName ) ) {
7599				return;
7600			}
7601
7602			nodeName = target.nodeName.toLowerCase();
7603			if ( nodeName === "input" ) {
7604				target.disabled = true;
7605				inst.trigger.filter( "button" ).
7606					each( function() { this.disabled = true; } ).end().
7607					filter( "img" ).css( { opacity: "0.5", cursor: "default" } );
7608			} else if ( nodeName === "div" || nodeName === "span" ) {
7609				inline = $target.children( "." + this._inlineClass );
7610				inline.children().addClass( "ui-state-disabled" );
7611				inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
7612					prop( "disabled", true );
7613			}
7614			this._disabledInputs = $.map( this._disabledInputs,
7615				function( value ) { return ( value === target ? null : value ); } ); // delete entry
7616			this._disabledInputs[ this._disabledInputs.length ] = target;
7617		},
7618
7619		/* Is the first field in a jQuery collection disabled as a datepicker?
7620		 * @param  target	element - the target input field or division or span
7621		 * @return boolean - true if disabled, false if enabled
7622		 */
7623		_isDisabledDatepicker: function( target ) {
7624			if ( !target ) {
7625				return false;
7626			}
7627			for ( var i = 0; i < this._disabledInputs.length; i++ ) {
7628				if ( this._disabledInputs[ i ] === target ) {
7629					return true;
7630				}
7631			}
7632			return false;
7633		},
7634
7635		/* Retrieve the instance data for the target control.
7636		 * @param  target  element - the target input field or division or span
7637		 * @return  object - the associated instance data
7638		 * @throws  error if a jQuery problem getting data
7639		 */
7640		_getInst: function( target ) {
7641			try {
7642				return $.data( target, "datepicker" );
7643			}
7644			catch ( err ) {
7645				throw "Missing instance data for this datepicker";
7646			}
7647		},
7648
7649		/* Update or retrieve the settings for a date picker attached to an input field or division.
7650		 * @param  target  element - the target input field or division or span
7651		 * @param  name	object - the new settings to update or
7652		 *				string - the name of the setting to change or retrieve,
7653		 *				when retrieving also "all" for all instance settings or
7654		 *				"defaults" for all global defaults
7655		 * @param  value   any - the new value for the setting
7656		 *				(omit if above is an object or to retrieve a value)
7657		 */
7658		_optionDatepicker: function( target, name, value ) {
7659			var settings, date, minDate, maxDate,
7660				inst = this._getInst( target );
7661
7662			if ( arguments.length === 2 && typeof name === "string" ) {
7663				return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) :
7664					( inst ? ( name === "all" ? $.extend( {}, inst.settings ) :
7665						this._get( inst, name ) ) : null ) );
7666			}
7667
7668			settings = name || {};
7669			if ( typeof name === "string" ) {
7670				settings = {};
7671				settings[ name ] = value;
7672			}
7673
7674			if ( inst ) {
7675				if ( this._curInst === inst ) {
7676					this._hideDatepicker();
7677				}
7678
7679				date = this._getDateDatepicker( target, true );
7680				minDate = this._getMinMaxDate( inst, "min" );
7681				maxDate = this._getMinMaxDate( inst, "max" );
7682				datepicker_extendRemove( inst.settings, settings );
7683
7684				// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
7685				if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) {
7686					inst.settings.minDate = this._formatDate( inst, minDate );
7687				}
7688				if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) {
7689					inst.settings.maxDate = this._formatDate( inst, maxDate );
7690				}
7691				if ( "disabled" in settings ) {
7692					if ( settings.disabled ) {
7693						this._disableDatepicker( target );
7694					} else {
7695						this._enableDatepicker( target );
7696					}
7697				}
7698				this._attachments( $( target ), inst );
7699				this._autoSize( inst );
7700				this._setDate( inst, date );
7701				this._updateAlternate( inst );
7702				this._updateDatepicker( inst );
7703			}
7704		},
7705
7706		// Change method deprecated
7707		_changeDatepicker: function( target, name, value ) {
7708			this._optionDatepicker( target, name, value );
7709		},
7710
7711		/* Redraw the date picker attached to an input field or division.
7712		 * @param  target  element - the target input field or division or span
7713		 */
7714		_refreshDatepicker: function( target ) {
7715			var inst = this._getInst( target );
7716			if ( inst ) {
7717				this._updateDatepicker( inst );
7718			}
7719		},
7720
7721		/* Set the dates for a jQuery selection.
7722		 * @param  target element - the target input field or division or span
7723		 * @param  date	Date - the new date
7724		 */
7725		_setDateDatepicker: function( target, date ) {
7726			var inst = this._getInst( target );
7727			if ( inst ) {
7728				this._setDate( inst, date );
7729				this._updateDatepicker( inst );
7730				this._updateAlternate( inst );
7731			}
7732		},
7733
7734		/* Get the date(s) for the first entry in a jQuery selection.
7735		 * @param  target element - the target input field or division or span
7736		 * @param  noDefault boolean - true if no default date is to be used
7737		 * @return Date - the current date
7738		 */
7739		_getDateDatepicker: function( target, noDefault ) {
7740			var inst = this._getInst( target );
7741			if ( inst && !inst.inline ) {
7742				this._setDateFromField( inst, noDefault );
7743			}
7744			return ( inst ? this._getDate( inst ) : null );
7745		},
7746
7747		/* Handle keystrokes. */
7748		_doKeyDown: function( event ) {
7749			var onSelect, dateStr, sel,
7750				inst = $.datepicker._getInst( event.target ),
7751				handled = true,
7752				isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" );
7753
7754			inst._keyEvent = true;
7755			if ( $.datepicker._datepickerShowing ) {
7756				switch ( event.keyCode ) {
7757					case 9: $.datepicker._hideDatepicker();
7758						handled = false;
7759						break; // hide on tab out
7760					case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." +
7761						$.datepicker._currentClass + ")", inst.dpDiv );
7762						if ( sel[ 0 ] ) {
7763							$.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] );
7764						}
7765
7766						onSelect = $.datepicker._get( inst, "onSelect" );
7767						if ( onSelect ) {
7768							dateStr = $.datepicker._formatDate( inst );
7769
7770							// Trigger custom callback
7771							onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );
7772						} else {
7773							$.datepicker._hideDatepicker();
7774						}
7775
7776						return false; // don't submit the form
7777					case 27: $.datepicker._hideDatepicker();
7778						break; // hide on escape
7779					case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7780						-$.datepicker._get( inst, "stepBigMonths" ) :
7781						-$.datepicker._get( inst, "stepMonths" ) ), "M" );
7782						break; // previous month/year on page up/+ ctrl
7783					case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7784						+$.datepicker._get( inst, "stepBigMonths" ) :
7785						+$.datepicker._get( inst, "stepMonths" ) ), "M" );
7786						break; // next month/year on page down/+ ctrl
7787					case 35: if ( event.ctrlKey || event.metaKey ) {
7788						$.datepicker._clearDate( event.target );
7789					}
7790						handled = event.ctrlKey || event.metaKey;
7791						break; // clear on ctrl or command +end
7792					case 36: if ( event.ctrlKey || event.metaKey ) {
7793						$.datepicker._gotoToday( event.target );
7794					}
7795						handled = event.ctrlKey || event.metaKey;
7796						break; // current on ctrl or command +home
7797					case 37: if ( event.ctrlKey || event.metaKey ) {
7798						$.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" );
7799					}
7800						handled = event.ctrlKey || event.metaKey;
7801
7802						// -1 day on ctrl or command +left
7803						if ( event.originalEvent.altKey ) {
7804							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7805								-$.datepicker._get( inst, "stepBigMonths" ) :
7806								-$.datepicker._get( inst, "stepMonths" ) ), "M" );
7807						}
7808
7809						// next month/year on alt +left on Mac
7810						break;
7811					case 38: if ( event.ctrlKey || event.metaKey ) {
7812						$.datepicker._adjustDate( event.target, -7, "D" );
7813					}
7814						handled = event.ctrlKey || event.metaKey;
7815						break; // -1 week on ctrl or command +up
7816					case 39: if ( event.ctrlKey || event.metaKey ) {
7817						$.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" );
7818					}
7819						handled = event.ctrlKey || event.metaKey;
7820
7821						// +1 day on ctrl or command +right
7822						if ( event.originalEvent.altKey ) {
7823							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7824								+$.datepicker._get( inst, "stepBigMonths" ) :
7825								+$.datepicker._get( inst, "stepMonths" ) ), "M" );
7826						}
7827
7828						// next month/year on alt +right
7829						break;
7830					case 40: if ( event.ctrlKey || event.metaKey ) {
7831						$.datepicker._adjustDate( event.target, +7, "D" );
7832					}
7833						handled = event.ctrlKey || event.metaKey;
7834						break; // +1 week on ctrl or command +down
7835					default: handled = false;
7836				}
7837			} else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home
7838				$.datepicker._showDatepicker( this );
7839			} else {
7840				handled = false;
7841			}
7842
7843			if ( handled ) {
7844				event.preventDefault();
7845				event.stopPropagation();
7846			}
7847		},
7848
7849		/* Filter entered characters - based on date format. */
7850		_doKeyPress: function( event ) {
7851			var chars, chr,
7852				inst = $.datepicker._getInst( event.target );
7853
7854			if ( $.datepicker._get( inst, "constrainInput" ) ) {
7855				chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) );
7856				chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode );
7857				return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 );
7858			}
7859		},
7860
7861		/* Synchronise manual entry and field/alternate field. */
7862		_doKeyUp: function( event ) {
7863			var date,
7864				inst = $.datepicker._getInst( event.target );
7865
7866			if ( inst.input.val() !== inst.lastVal ) {
7867				try {
7868					date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
7869						( inst.input ? inst.input.val() : null ),
7870						$.datepicker._getFormatConfig( inst ) );
7871
7872					if ( date ) { // only if valid
7873						$.datepicker._setDateFromField( inst );
7874						$.datepicker._updateAlternate( inst );
7875						$.datepicker._updateDatepicker( inst );
7876					}
7877				}
7878				catch ( err ) {
7879				}
7880			}
7881			return true;
7882		},
7883
7884		/* Pop-up the date picker for a given input field.
7885		 * If false returned from beforeShow event handler do not show.
7886		 * @param  input  element - the input field attached to the date picker or
vendor: 4,479 bytes, lines 7887-8008
7887		 *					event - if triggered by focus
7888		 */
7889		_showDatepicker: function( input ) {
7890			input = input.target || input;
7891			if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger
7892				input = $( "input", input.parentNode )[ 0 ];
7893			}
7894
7895			if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here
7896				return;
7897			}
7898
7899			var inst, beforeShow, beforeShowSettings, isFixed,
7900				offset, showAnim, duration;
7901
7902			inst = $.datepicker._getInst( input );
7903			if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) {
7904				$.datepicker._curInst.dpDiv.stop( true, true );
7905				if ( inst && $.datepicker._datepickerShowing ) {
7906					$.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] );
7907				}
7908			}
7909
7910			beforeShow = $.datepicker._get( inst, "beforeShow" );
7911			beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {};
7912			if ( beforeShowSettings === false ) {
7913				return;
7914			}
7915			datepicker_extendRemove( inst.settings, beforeShowSettings );
7916
7917			inst.lastVal = null;
7918			$.datepicker._lastInput = input;
7919			$.datepicker._setDateFromField( inst );
7920
7921			if ( $.datepicker._inDialog ) { // hide cursor
7922				input.value = "";
7923			}
7924			if ( !$.datepicker._pos ) { // position below input
7925				$.datepicker._pos = $.datepicker._findPos( input );
7926				$.datepicker._pos[ 1 ] += input.offsetHeight; // add the height
7927			}
7928
7929			isFixed = false;
7930			$( input ).parents().each( function() {
7931				isFixed |= $( this ).css( "position" ) === "fixed";
7932				return !isFixed;
7933			} );
7934
7935			offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] };
7936			$.datepicker._pos = null;
7937
7938			//to avoid flashes on Firefox
7939			inst.dpDiv.empty();
7940
7941			// determine sizing offscreen
7942			inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } );
7943			$.datepicker._updateDatepicker( inst );
7944
7945			// fix width for dynamic number of date pickers
7946			// and adjust position before showing
7947			offset = $.datepicker._checkOffset( inst, offset, isFixed );
7948			inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ?
7949				"static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none",
7950				left: offset.left + "px", top: offset.top + "px" } );
7951
7952			if ( !inst.inline ) {
7953				showAnim = $.datepicker._get( inst, "showAnim" );
7954				duration = $.datepicker._get( inst, "duration" );
7955				inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
7956				$.datepicker._datepickerShowing = true;
7957
7958				if ( $.effects && $.effects.effect[ showAnim ] ) {
7959					inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration );
7960				} else {
7961					inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null );
7962				}
7963
7964				if ( $.datepicker._shouldFocusInput( inst ) ) {
7965					inst.input.trigger( "focus" );
7966				}
7967
7968				$.datepicker._curInst = inst;
7969			}
7970		},
7971
7972		/* Generate the date picker content. */
7973		_updateDatepicker: function( inst ) {
7974			this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
7975			datepicker_instActive = inst; // for delegate hover events
7976			inst.dpDiv.empty().append( this._generateHTML( inst ) );
7977			this._attachHandlers( inst );
7978
7979			var origyearshtml,
7980				numMonths = this._getNumberOfMonths( inst ),
7981				cols = numMonths[ 1 ],
7982				width = 17,
7983				activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
7984
7985			if ( activeCell.length > 0 ) {
7986				datepicker_handleMouseover.apply( activeCell.get( 0 ) );
7987			}
7988
7989			inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" );
7990			if ( cols > 1 ) {
7991				inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" );
7992			}
7993			inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) +
7994			"Class" ]( "ui-datepicker-multi" );
7995			inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) +
7996			"Class" ]( "ui-datepicker-rtl" );
7997
7998			if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
7999				inst.input.trigger( "focus" );
8000			}
8001
8002			// Deffered render of the years select (to avoid flashes on Firefox)
8003			if ( inst.yearshtml ) {
8004				origyearshtml = inst.yearshtml;
8005				setTimeout( function() {
8006
8007					//assure that inst.yearshtml didn't change.
8008					if ( origyearshtml === inst.yearshtml && inst.yearshtml ) {
vendor: 5,765 bytes, lines 8009-8165
8009						inst.dpDiv.find( "select.ui-datepicker-year:first" ).replaceWith( inst.yearshtml );
8010					}
8011					origyearshtml = inst.yearshtml = null;
8012				}, 0 );
8013			}
8014		},
8015
8016		// #6694 - don't focus the input if it's already focused
8017		// this breaks the change event in IE
8018		// Support: IE and jQuery <1.9
8019		_shouldFocusInput: function( inst ) {
8020			return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
8021		},
8022
8023		/* Check positioning to remain on screen. */
8024		_checkOffset: function( inst, offset, isFixed ) {
8025			var dpWidth = inst.dpDiv.outerWidth(),
8026				dpHeight = inst.dpDiv.outerHeight(),
8027				inputWidth = inst.input ? inst.input.outerWidth() : 0,
8028				inputHeight = inst.input ? inst.input.outerHeight() : 0,
8029				viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ),
8030				viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() );
8031
8032			offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 );
8033			offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0;
8034			offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0;
8035
8036			// Now check if datepicker is showing outside window viewport - move to a better place if so.
8037			offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ?
8038				Math.abs( offset.left + dpWidth - viewWidth ) : 0 );
8039			offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ?
8040				Math.abs( dpHeight + inputHeight ) : 0 );
8041
8042			return offset;
8043		},
8044
8045		/* Find an object's position on the screen. */
8046		_findPos: function( obj ) {
8047			var position,
8048				inst = this._getInst( obj ),
8049				isRTL = this._get( inst, "isRTL" );
8050
8051			while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden( obj ) ) ) {
8052				obj = obj[ isRTL ? "previousSibling" : "nextSibling" ];
8053			}
8054
8055			position = $( obj ).offset();
8056			return [ position.left, position.top ];
8057		},
8058
8059		/* Hide the date picker from view.
8060		 * @param  input  element - the input field attached to the date picker
8061		 */
8062		_hideDatepicker: function( input ) {
8063			var showAnim, duration, postProcess, onClose,
8064				inst = this._curInst;
8065
8066			if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) {
8067				return;
8068			}
8069
8070			if ( this._datepickerShowing ) {
8071				showAnim = this._get( inst, "showAnim" );
8072				duration = this._get( inst, "duration" );
8073				postProcess = function() {
8074					$.datepicker._tidyDialog( inst );
8075				};
8076
8077				// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
8078				if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
8079					inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess );
8080				} else {
8081					inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" :
8082						( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess );
8083				}
8084
8085				if ( !showAnim ) {
8086					postProcess();
8087				}
8088				this._datepickerShowing = false;
8089
8090				onClose = this._get( inst, "onClose" );
8091				if ( onClose ) {
8092					onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] );
8093				}
8094
8095				this._lastInput = null;
8096				if ( this._inDialog ) {
8097					this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } );
8098					if ( $.blockUI ) {
8099						$.unblockUI();
8100						$( "body" ).append( this.dpDiv );
8101					}
8102				}
8103				this._inDialog = false;
8104			}
8105		},
8106
8107		/* Tidy up after a dialog display. */
8108		_tidyDialog: function( inst ) {
8109			inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" );
8110		},
8111
8112		/* Close date picker if clicked elsewhere. */
8113		_checkExternalClick: function( event ) {
8114			if ( !$.datepicker._curInst ) {
8115				return;
8116			}
8117
8118			var $target = $( event.target ),
8119				inst = $.datepicker._getInst( $target[ 0 ] );
8120
8121			if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId &&
8122				$target.parents( "#" + $.datepicker._mainDivId ).length === 0 &&
8123				!$target.hasClass( $.datepicker.markerClassName ) &&
8124				!$target.closest( "." + $.datepicker._triggerClass ).length &&
8125				$.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) ||
8126				( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) {
8127				$.datepicker._hideDatepicker();
8128			}
8129		},
8130
8131		/* Adjust one of the date sub-fields. */
8132		_adjustDate: function( id, offset, period ) {
8133			var target = $( id ),
8134				inst = this._getInst( target[ 0 ] );
8135
8136			if ( this._isDisabledDatepicker( target[ 0 ] ) ) {
8137				return;
8138			}
8139			this._adjustInstDate( inst, offset +
8140				( period === "M" ? this._get( inst, "showCurrentAtPos" ) : 0 ), // undo positioning
8141				period );
8142			this._updateDatepicker( inst );
8143		},
8144
8145		/* Action for current link. */
8146		_gotoToday: function( id ) {
8147			var date,
8148				target = $( id ),
8149				inst = this._getInst( target[ 0 ] );
8150
8151			if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) {
8152				inst.selectedDay = inst.currentDay;
8153				inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8154				inst.drawYear = inst.selectedYear = inst.currentYear;
8155			} else {
8156				date = new Date();
8157				inst.selectedDay = date.getDate();
8158				inst.drawMonth = inst.selectedMonth = date.getMonth();
8159				inst.drawYear = inst.selectedYear = date.getFullYear();
8160			}
8161			this._notifyChange( inst );
8162			this._adjustDate( target );
8163		},
8164
8165		/* Action for selecting a new month/year. */
vendor: 4,819 bytes, lines 8166-8297
8166		_selectMonthYear: function( id, select, period ) {
8167			var target = $( id ),
8168				inst = this._getInst( target[ 0 ] );
8169
8170			inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] =
8171				inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] =
8172					parseInt( select.options[ select.selectedIndex ].value, 10 );
8173
8174			this._notifyChange( inst );
8175			this._adjustDate( target );
8176		},
8177
8178		/* Action for selecting a day. */
8179		_selectDay: function( id, month, year, td ) {
8180			var inst,
8181				target = $( id );
8182
8183			if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) {
8184				return;
8185			}
8186
8187			inst = this._getInst( target[ 0 ] );
8188			inst.selectedDay = inst.currentDay = $( "a", td ).html();
8189			inst.selectedMonth = inst.currentMonth = month;
8190			inst.selectedYear = inst.currentYear = year;
8191			this._selectDate( id, this._formatDate( inst,
8192				inst.currentDay, inst.currentMonth, inst.currentYear ) );
8193		},
8194
8195		/* Erase the input field and hide the date picker. */
8196		_clearDate: function( id ) {
8197			var target = $( id );
8198			this._selectDate( target, "" );
8199		},
8200
8201		/* Update the input field with the selected date. */
8202		_selectDate: function( id, dateStr ) {
8203			var onSelect,
8204				target = $( id ),
8205				inst = this._getInst( target[ 0 ] );
8206
8207			dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) );
8208			if ( inst.input ) {
8209				inst.input.val( dateStr );
8210			}
8211			this._updateAlternate( inst );
8212
8213			onSelect = this._get( inst, "onSelect" );
8214			if ( onSelect ) {
8215				onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );  // trigger custom callback
8216			} else if ( inst.input ) {
8217				inst.input.trigger( "change" ); // fire the change event
8218			}
8219
8220			if ( inst.inline ) {
8221				this._updateDatepicker( inst );
8222			} else {
8223				this._hideDatepicker();
8224				this._lastInput = inst.input[ 0 ];
8225				if ( typeof( inst.input[ 0 ] ) !== "object" ) {
8226					inst.input.trigger( "focus" ); // restore focus
8227				}
8228				this._lastInput = null;
8229			}
8230		},
8231
8232		/* Update any alternate field to synchronise with the main field. */
8233		_updateAlternate: function( inst ) {
8234			var altFormat, date, dateStr,
8235				altField = this._get( inst, "altField" );
8236
8237			if ( altField ) { // update alternate field too
8238				altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" );
8239				date = this._getDate( inst );
8240				dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) );
8241				$( altField ).val( dateStr );
8242			}
8243		},
8244
8245		/* Set as beforeShowDay function to prevent selection of weekends.
8246		 * @param  date  Date - the date to customise
8247		 * @return [boolean, string] - is this date selectable?, what is its CSS class?
8248		 */
8249		noWeekends: function( date ) {
8250			var day = date.getDay();
8251			return [ ( day > 0 && day < 6 ), "" ];
8252		},
8253
8254		/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
8255		 * @param  date  Date - the date to get the week for
8256		 * @return  number - the number of the week within the year that contains this date
8257		 */
8258		iso8601Week: function( date ) {
8259			var time,
8260				checkDate = new Date( date.getTime() );
8261
8262			// Find Thursday of this week starting on Monday
8263			checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) );
8264
8265			time = checkDate.getTime();
8266			checkDate.setMonth( 0 ); // Compare with Jan 1
8267			checkDate.setDate( 1 );
8268			return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1;
8269		},
8270
8271		/* Parse a string value into a date object.
8272		 * See formatDate below for the possible formats.
8273		 *
8274		 * @param  format string - the expected format of the date
8275		 * @param  value string - the date in the above format
8276		 * @param  settings Object - attributes include:
8277		 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
8278		 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
8279		 *					dayNames		string[7] - names of the days from Sunday (optional)
8280		 *					monthNamesShort string[12] - abbreviated names of the months (optional)
8281		 *					monthNames		string[12] - names of the months (optional)
8282		 * @return  Date - the extracted date value or null if value is blank
8283		 */
8284		parseDate: function( format, value, settings ) {
8285			if ( format == null || value == null ) {
8286				throw "Invalid arguments";
8287			}
8288
8289			value = ( typeof value === "object" ? value.toString() : value + "" );
8290			if ( value === "" ) {
8291				return null;
8292			}
8293
8294			var iFormat, dim, extra,
8295				iValue = 0,
8296				shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff,
8297				shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp 
vendor: 13,978 bytes, lines 8297-8729
8297:
8298				new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ),
8299				dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
8300				dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
8301				monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
8302				monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
8303				year = -1,
8304				month = -1,
8305				day = -1,
8306				doy = -1,
8307				literal = false,
8308				date,
8309
8310			// Check whether a format character is doubled
8311				lookAhead = function( match ) {
8312					var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8313					if ( matches ) {
8314						iFormat++;
8315					}
8316					return matches;
8317				},
8318
8319			// Extract a number from the string value
8320				getNumber = function( match ) {
8321					var isDoubled = lookAhead( match ),
8322						size = ( match === "@" ? 14 : ( match === "!" ? 20 :
8323							( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ),
8324						minSize = ( match === "y" ? size : 1 ),
8325						digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ),
8326						num = value.substring( iValue ).match( digits );
8327					if ( !num ) {
8328						throw "Missing number at position " + iValue;
8329					}
8330					iValue += num[ 0 ].length;
8331					return parseInt( num[ 0 ], 10 );
8332				},
8333
8334			// Extract a name from the string value and convert to an index
8335				getName = function( match, shortNames, longNames ) {
8336					var index = -1,
8337						names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) {
8338							return [ [ k, v ] ];
8339						} ).sort( function( a, b ) {
8340							return -( a[ 1 ].length - b[ 1 ].length );
8341						} );
8342
8343					$.each( names, function( i, pair ) {
8344						var name = pair[ 1 ];
8345						if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) {
8346							index = pair[ 0 ];
8347							iValue += name.length;
8348							return false;
8349						}
8350					} );
8351					if ( index !== -1 ) {
8352						return index + 1;
8353					} else {
8354						throw "Unknown name at position " + iValue;
8355					}
8356				},
8357
8358			// Confirm that a literal character matches the string value
8359				checkLiteral = function() {
8360					if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) {
8361						throw "Unexpected literal at position " + iValue;
8362					}
8363					iValue++;
8364				};
8365
8366			for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8367				if ( literal ) {
8368					if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8369						literal = false;
8370					} else {
8371						checkLiteral();
8372					}
8373				} else {
8374					switch ( format.charAt( iFormat ) ) {
8375						case "d":
8376							day = getNumber( "d" );
8377							break;
8378						case "D":
8379							getName( "D", dayNamesShort, dayNames );
8380							break;
8381						case "o":
8382							doy = getNumber( "o" );
8383							break;
8384						case "m":
8385							month = getNumber( "m" );
8386							break;
8387						case "M":
8388							month = getName( "M", monthNamesShort, monthNames );
8389							break;
8390						case "y":
8391							year = getNumber( "y" );
8392							break;
8393						case "@":
8394							date = new Date( getNumber( "@" ) );
8395							year = date.getFullYear();
8396							month = date.getMonth() + 1;
8397							day = date.getDate();
8398							break;
8399						case "!":
8400							date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 );
8401							year = date.getFullYear();
8402							month = date.getMonth() + 1;
8403							day = date.getDate();
8404							break;
8405						case "'":
8406							if ( lookAhead( "'" ) ) {
8407								checkLiteral();
8408							} else {
8409								literal = true;
8410							}
8411							break;
8412						default:
8413							checkLiteral();
8414					}
8415				}
8416			}
8417
8418			if ( iValue < value.length ) {
8419				extra = value.substr( iValue );
8420				if ( !/^\s+/.test( extra ) ) {
8421					throw "Extra/unparsed characters found in date: " + extra;
8422				}
8423			}
8424
8425			if ( year === -1 ) {
8426				year = new Date().getFullYear();
8427			} else if ( year < 100 ) {
8428				year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8429					( year <= shortYearCutoff ? 0 : -100 );
8430			}
8431
8432			if ( doy > -1 ) {
8433				month = 1;
8434				day = doy;
8435				do {
8436					dim = this._getDaysInMonth( year, month - 1 );
8437					if ( day <= dim ) {
8438						break;
8439					}
8440					month++;
8441					day -= dim;
8442				} while ( true );
8443			}
8444
8445			date = this._daylightSavingAdjust( new Date( year, month - 1, day ) );
8446			if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) {
8447				throw "Invalid date"; // E.g. 31/02/00
8448			}
8449			return date;
8450		},
8451
8452		/* Standard date formats. */
8453		ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
8454		COOKIE: "D, dd M yy",
8455		ISO_8601: "yy-mm-dd",
8456		RFC_822: "D, d M y",
8457		RFC_850: "DD, dd-M-y",
8458		RFC_1036: "D, d M y",
8459		RFC_1123: "D, d M yy",
8460		RFC_2822: "D, d M yy",
8461		RSS: "D, d M y", // RFC 822
8462		TICKS: "!",
8463		TIMESTAMP: "@",
8464		W3C: "yy-mm-dd", // ISO 8601
8465
8466		_ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) +
8467		Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ),
8468
8469		/* Format a date object into a string value.
8470		 * The format can be combinations of the following:
8471		 * d  - day of month (no leading zero)
8472		 * dd - day of month (two digit)
8473		 * o  - day of year (no leading zeros)
8474		 * oo - day of year (three digit)
8475		 * D  - day name short
8476		 * DD - day name long
8477		 * m  - month of year (no leading zero)
8478		 * mm - month of year (two digit)
8479		 * M  - month name short
8480		 * MM - month name long
8481		 * y  - year (two digit)
8482		 * yy - year (four digit)
8483		 * @ - Unix timestamp (ms since 01/01/1970)
8484		 * ! - Windows ticks (100ns since 01/01/0001)
8485		 * "..." - literal text
8486		 * '' - single quote
8487		 *
8488		 * @param  format string - the desired format of the date
8489		 * @param  date Date - the date value to format
8490		 * @param  settings Object - attributes include:
8491		 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
8492		 *					dayNames		string[7] - names of the days from Sunday (optional)
8493		 *					monthNamesShort string[12] - abbreviated names of the months (optional)
8494		 *					monthNames		string[12] - names of the months (optional)
8495		 * @return  string - the date in the above format
8496		 */
8497		formatDate: function( format, date, settings ) {
8498			if ( !date ) {
8499				return "";
8500			}
8501
8502			var iFormat,
8503				dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
8504				dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
8505				monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
8506				monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
8507
8508			// Check whether a format character is doubled
8509				lookAhead = function( match ) {
8510					var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8511					if ( matches ) {
8512						iFormat++;
8513					}
8514					return matches;
8515				},
8516
8517			// Format a number, with leading zero if necessary
8518				formatNumber = function( match, value, len ) {
8519					var num = "" + value;
8520					if ( lookAhead( match ) ) {
8521						while ( num.length < len ) {
8522							num = "0" + num;
8523						}
8524					}
8525					return num;
8526				},
8527
8528			// Format a name, short or long as requested
8529				formatName = function( match, value, shortNames, longNames ) {
8530					return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] );
8531				},
8532				output = "",
8533				literal = false;
8534
8535			if ( date ) {
8536				for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8537					if ( literal ) {
8538						if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8539							literal = false;
8540						} else {
8541							output += format.charAt( iFormat );
8542						}
8543					} else {
8544						switch ( format.charAt( iFormat ) ) {
8545							case "d":
8546								output += formatNumber( "d", date.getDate(), 2 );
8547								break;
8548							case "D":
8549								output += formatName( "D", date.getDay(), dayNamesShort, dayNames );
8550								break;
8551							case "o":
8552								output += formatNumber( "o",
8553									Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 );
8554								break;
8555							case "m":
8556								output += formatNumber( "m", date.getMonth() + 1, 2 );
8557								break;
8558							case "M":
8559								output += formatName( "M", date.getMonth(), monthNamesShort, monthNames );
8560								break;
8561							case "y":
8562								output += ( lookAhead( "y" ) ? date.getFullYear() :
8563								( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 );
8564								break;
8565							case "@":
8566								output += date.getTime();
8567								break;
8568							case "!":
8569								output += date.getTime() * 10000 + this._ticksTo1970;
8570								break;
8571							case "'":
8572								if ( lookAhead( "'" ) ) {
8573									output += "'";
8574								} else {
8575									literal = true;
8576								}
8577								break;
8578							default:
8579								output += format.charAt( iFormat );
8580						}
8581					}
8582				}
8583			}
8584			return output;
8585		},
8586
8587		/* Extract all possible characters from the date format. */
8588		_possibleChars: function( format ) {
8589			var iFormat,
8590				chars = "",
8591				literal = false,
8592
8593			// Check whether a format character is doubled
8594				lookAhead = function( match ) {
8595					var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8596					if ( matches ) {
8597						iFormat++;
8598					}
8599					return matches;
8600				};
8601
8602			for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8603				if ( literal ) {
8604					if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8605						literal = false;
8606					} else {
8607						chars += format.charAt( iFormat );
8608					}
8609				} else {
8610					switch ( format.charAt( iFormat ) ) {
8611						case "d": case "m": case "y": case "@":
8612						chars += "0123456789";
8613						break;
8614						case "D": case "M":
8615						return null; // Accept anything
8616						case "'":
8617							if ( lookAhead( "'" ) ) {
8618								chars += "'";
8619							} else {
8620								literal = true;
8621							}
8622							break;
8623						default:
8624							chars += format.charAt( iFormat );
8625					}
8626				}
8627			}
8628			return chars;
8629		},
8630
8631		/* Get a setting value, defaulting if necessary. */
8632		_get: function( inst, name ) {
8633			return inst.settings[ name ] !== undefined ?
8634				inst.settings[ name ] : this._defaults[ name ];
8635		},
8636
8637		/* Parse existing date and initialise date picker. */
8638		_setDateFromField: function( inst, noDefault ) {
8639			if ( inst.input.val() === inst.lastVal ) {
8640				return;
8641			}
8642
8643			var dateFormat = this._get( inst, "dateFormat" ),
8644				dates = inst.lastVal = inst.input ? inst.input.val() : null,
8645				defaultDate = this._getDefaultDate( inst ),
8646				date = defaultDate,
8647				settings = this._getFormatConfig( inst );
8648
8649			try {
8650				date = this.parseDate( dateFormat, dates, settings ) || defaultDate;
8651			} catch ( event ) {
8652				dates = ( noDefault ? "" : dates );
8653			}
8654			inst.selectedDay = date.getDate();
8655			inst.drawMonth = inst.selectedMonth = date.getMonth();
8656			inst.drawYear = inst.selectedYear = date.getFullYear();
8657			inst.currentDay = ( dates ? date.getDate() : 0 );
8658			inst.currentMonth = ( dates ? date.getMonth() : 0 );
8659			inst.currentYear = ( dates ? date.getFullYear() : 0 );
8660			this._adjustInstDate( inst );
8661		},
8662
8663		/* Retrieve the default date shown on opening. */
8664		_getDefaultDate: function( inst ) {
8665			return this._restrictMinMax( inst,
8666				this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) );
8667		},
8668
8669		/* A date may be specified as an exact value or a relative one. */
8670		_determineDate: function( inst, date, defaultDate ) {
8671			var offsetNumeric = function( offset ) {
8672					var date = new Date();
8673					date.setDate( date.getDate() + offset );
8674					return date;
8675				},
8676				offsetString = function( offset ) {
8677					try {
8678						return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
8679							offset, $.datepicker._getFormatConfig( inst ) );
8680					}
8681					catch ( e ) {
8682
8683						// Ignore
8684					}
8685
8686					var date = ( offset.toLowerCase().match( /^c/ ) ?
8687								$.datepicker._getDate( inst ) : null ) || new Date(),
8688						year = date.getFullYear(),
8689						month = date.getMonth(),
8690						day = date.getDate(),
8691						pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
8692						matches = pattern.exec( offset );
8693
8694					while ( matches ) {
8695						switch ( matches[ 2 ] || "d" ) {
8696							case "d" : case "D" :
8697							day += parseInt( matches[ 1 ], 10 ); break;
8698							case "w" : case "W" :
8699							day += parseInt( matches[ 1 ], 10 ) * 7; break;
8700							case "m" : case "M" :
8701							month += parseInt( matches[ 1 ], 10 );
8702							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
8703							break;
8704							case "y": case "Y" :
8705							year += parseInt( matches[ 1 ], 10 );
8706							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
8707							break;
8708						}
8709						matches = pattern.exec( offset );
8710					}
8711					return new Date( year, month, day );
8712				},
8713				newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) :
8714					( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) );
8715
8716			newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate );
8717			if ( newDate ) {
8718				newDate.setHours( 0 );
8719				newDate.setMinutes( 0 );
8720				newDate.setSeconds( 0 );
8721				newDate.setMilliseconds( 0 );
8722			}
8723			return this._daylightSavingAdjust( newDate );
8724		},
8725
8726		/* Handle switch to/from daylight saving.
8727		 * Hours may be non-zero on daylight saving cut-over:
8728		 * > 12 when midnight changeover, but then cannot generate
8729		 * midnight datetime, so jump to 1AM, otherwise reset.
vendor: 32,244 bytes, lines 8730-9521
8730		 * @param  date  (Date) the date to check
8731		 * @return  (Date) the corrected date
8732		 */
8733		_daylightSavingAdjust: function( date ) {
8734			if ( !date ) {
8735				return null;
8736			}
8737			date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 );
8738			return date;
8739		},
8740
8741		/* Set the date(s) directly. */
8742		_setDate: function( inst, date, noChange ) {
8743			var clear = !date,
8744				origMonth = inst.selectedMonth,
8745				origYear = inst.selectedYear,
8746				newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) );
8747
8748			inst.selectedDay = inst.currentDay = newDate.getDate();
8749			inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
8750			inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
8751			if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) {
8752				this._notifyChange( inst );
8753			}
8754			this._adjustInstDate( inst );
8755			if ( inst.input ) {
8756				inst.input.val( clear ? "" : this._formatDate( inst ) );
8757			}
8758		},
8759
8760		/* Retrieve the date(s) directly. */
8761		_getDate: function( inst ) {
8762			var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null :
8763				this._daylightSavingAdjust( new Date(
8764					inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
8765			return startDate;
8766		},
8767
8768		/* Attach the onxxx handlers.  These are declared statically so
8769		 * they work with static code transformers like Caja.
8770		 */
8771		_attachHandlers: function( inst ) {
8772			var stepMonths = this._get( inst, "stepMonths" ),
8773				id = "#" + inst.id.replace( /\\\\/g, "\\" );
8774			inst.dpDiv.find( "[data-handler]" ).map( function() {
8775				var handler = {
8776					prev: function() {
8777						$.datepicker._adjustDate( id, -stepMonths, "M" );
8778					},
8779					next: function() {
8780						$.datepicker._adjustDate( id, +stepMonths, "M" );
8781					},
8782					hide: function() {
8783						$.datepicker._hideDatepicker();
8784					},
8785					today: function() {
8786						$.datepicker._gotoToday( id );
8787					},
8788					selectDay: function() {
8789						$.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this );
8790						return false;
8791					},
8792					selectMonth: function() {
8793						$.datepicker._selectMonthYear( id, this, "M" );
8794						return false;
8795					},
8796					selectYear: function() {
8797						$.datepicker._selectMonthYear( id, this, "Y" );
8798						return false;
8799					}
8800				};
8801				$( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] );
8802			} );
8803		},
8804
8805		/* Generate the HTML for the current state of the date picker. */
8806		_generateHTML: function( inst ) {
8807			var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
8808				controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
8809				monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
8810				selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
8811				cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
8812				printDate, dRow, tbody, daySettings, otherMonth, unselectable,
8813				tempDate = new Date(),
8814				today = this._daylightSavingAdjust(
8815					new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time
8816				isRTL = this._get( inst, "isRTL" ),
8817				showButtonPanel = this._get( inst, "showButtonPanel" ),
8818				hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ),
8819				navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ),
8820				numMonths = this._getNumberOfMonths( inst ),
8821				showCurrentAtPos = this._get( inst, "showCurrentAtPos" ),
8822				stepMonths = this._get( inst, "stepMonths" ),
8823				isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ),
8824				currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) :
8825					new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ),
8826				minDate = this._getMinMaxDate( inst, "min" ),
8827				maxDate = this._getMinMaxDate( inst, "max" ),
8828				drawMonth = inst.drawMonth - showCurrentAtPos,
8829				drawYear = inst.drawYear;
8830
8831			if ( drawMonth < 0 ) {
8832				drawMonth += 12;
8833				drawYear--;
8834			}
8835			if ( maxDate ) {
8836				maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(),
8837					maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) );
8838				maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw );
8839				while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) {
8840					drawMonth--;
8841					if ( drawMonth < 0 ) {
8842						drawMonth = 11;
8843						drawYear--;
8844					}
8845				}
8846			}
8847			inst.drawMonth = drawMonth;
8848			inst.drawYear = drawYear;
8849
8850			prevText = this._get( inst, "prevText" );
8851			prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText,
8852				this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ),
8853				this._getFormatConfig( inst ) ) );
8854
8855			prev = ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ?
8856			"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
8857			" title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" :
8858				( hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" ) );
8859
8860			nextText = this._get( inst, "nextText" );
8861			nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText,
8862				this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ),
8863				this._getFormatConfig( inst ) ) );
8864
8865			next = ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ?
8866			"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
8867			" title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" :
8868				( hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" ) );
8869
8870			currentText = this._get( inst, "currentText" );
8871			gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today );
8872			currentText = ( !navigationAsDateFormat ? currentText :
8873				this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) );
8874
8875			controls = ( !inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" +
8876			this._get( inst, "closeText" ) + "</button>" : "" );
8877
8878			buttonPanel = ( showButtonPanel ) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + ( isRTL ? controls : "" ) +
8879			( this._isInRange( inst, gotoDate ) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" +
8880			">" + currentText + "</button>" : "" ) + ( isRTL ? "" : controls ) + "</div>" : "";
8881
8882			firstDay = parseInt( this._get( inst, "firstDay" ), 10 );
8883			firstDay = ( isNaN( firstDay ) ? 0 : firstDay );
8884
8885			showWeek = this._get( inst, "showWeek" );
8886			dayNames = this._get( inst, "dayNames" );
8887			dayNamesMin = this._get( inst, "dayNamesMin" );
8888			monthNames = this._get( inst, "monthNames" );
8889			monthNamesShort = this._get( inst, "monthNamesShort" );
8890			beforeShowDay = this._get( inst, "beforeShowDay" );
8891			showOtherMonths = this._get( inst, "showOtherMonths" );
8892			selectOtherMonths = this._get( inst, "selectOtherMonths" );
8893			defaultDate = this._getDefaultDate( inst );
8894			html = "";
8895
8896			for ( row = 0; row < numMonths[ 0 ]; row++ ) {
8897				group = "";
8898				this.maxRows = 4;
8899				for ( col = 0; col < numMonths[ 1 ]; col++ ) {
8900					selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) );
8901					cornerClass = " ui-corner-all";
8902					calender = "";
8903					if ( isMultiMonth ) {
8904						calender += "<div class='ui-datepicker-group";
8905						if ( numMonths[ 1 ] > 1 ) {
8906							switch ( col ) {
8907								case 0: calender += " ui-datepicker-group-first";
8908									cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break;
8909								case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last";
8910									cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break;
8911								default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
8912							}
8913						}
8914						calender += "'>";
8915					}
8916					calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
8917						( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) +
8918						( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) +
8919						this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate,
8920							row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers
8921						"</div><table class='ui-datepicker-calendar'><thead>" +
8922						"<tr>";
8923					thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" );
8924					for ( dow = 0; dow < 7; dow++ ) { // days of the week
8925						day = ( dow + firstDay ) % 7;
8926						thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" +
8927							"<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>";
8928					}
8929					calender += thead + "</tr></thead><tbody>";
8930					daysInMonth = this._getDaysInMonth( drawYear, drawMonth );
8931					if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) {
8932						inst.selectedDay = Math.min( inst.selectedDay, daysInMonth );
8933					}
8934					leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7;
8935					curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate
8936					numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043)
8937					this.maxRows = numRows;
8938					printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) );
8939					for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows
8940						calender += "<tr>";
8941						tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
8942						this._get( inst, "calculateWeek" )( printDate ) + "</td>" );
8943						for ( dow = 0; dow < 7; dow++ ) { // create date picker days
8944							daySettings = ( beforeShowDay ?
8945								beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] );
8946							otherMonth = ( printDate.getMonth() !== drawMonth );
8947							unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] ||
8948								( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate );
8949							tbody += "<td class='" +
8950								( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends
8951								( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months
8952								( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key
8953								( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ?
8954
8955									// or defaultDate is current printedDate and defaultDate is selectedDate
8956								" " + this._dayOverClass : "" ) + // highlight selected day
8957								( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) +  // highlight unselectable days
8958								( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates
8959								( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day
8960								( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different)
8961								( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "&#39;" ) + "'" : "" ) + // cell title
8962								( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions
8963								( otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
8964									( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
8965									( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) +
8966									( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day
8967									( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months
8968									"' href='#'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date
8969							printDate.setDate( printDate.getDate() + 1 );
8970							printDate = this._daylightSavingAdjust( printDate );
8971						}
8972						calender += tbody + "</tr>";
8973					}
8974					drawMonth++;
8975					if ( drawMonth > 11 ) {
8976						drawMonth = 0;
8977						drawYear++;
8978					}
8979					calender += "</tbody></table>" + ( isMultiMonth ? "</div>" +
8980						( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" );
8981					group += calender;
8982				}
8983				html += group;
8984			}
8985			html += buttonPanel;
8986			inst._keyEvent = false;
8987			return html;
8988		},
8989
8990		/* Generate the month and year header. */
8991		_generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate,
8992											secondary, monthNames, monthNamesShort ) {
8993
8994			var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
8995				changeMonth = this._get( inst, "changeMonth" ),
8996				changeYear = this._get( inst, "changeYear" ),
8997				showMonthAfterYear = this._get( inst, "showMonthAfterYear" ),
8998				html = "<div class='ui-datepicker-title'>",
8999				monthHtml = "";
9000
9001			// Month selection
9002			if ( secondary || !changeMonth ) {
9003				monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>";
9004			} else {
9005				inMinYear = ( minDate && minDate.getFullYear() === drawYear );
9006				inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear );
9007				monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
9008				for ( month = 0; month < 12; month++ ) {
9009					if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) {
9010						monthHtml += "<option value='" + month + "'" +
9011							( month === drawMonth ? " selected='selected'" : "" ) +
9012							">" + monthNamesShort[ month ] + "</option>";
9013					}
9014				}
9015				monthHtml += "</select>";
9016			}
9017
9018			if ( !showMonthAfterYear ) {
9019				html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" );
9020			}
9021
9022			// Year selection
9023			if ( !inst.yearshtml ) {
9024				inst.yearshtml = "";
9025				if ( secondary || !changeYear ) {
9026					html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
9027				} else {
9028
9029					// determine range of years to display
9030					years = this._get( inst, "yearRange" ).split( ":" );
9031					thisYear = new Date().getFullYear();
9032					determineYear = function( value ) {
9033						var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) :
9034							( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) :
9035								parseInt( value, 10 ) ) );
9036						return ( isNaN( year ) ? thisYear : year );
9037					};
9038					year = determineYear( years[ 0 ] );
9039					endYear = Math.max( year, determineYear( years[ 1 ] || "" ) );
9040					year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year );
9041					endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear );
9042					inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
9043					for ( ; year <= endYear; year++ ) {
9044						inst.yearshtml += "<option value='" + year + "'" +
9045							( year === drawYear ? " selected='selected'" : "" ) +
9046							">" + year + "</option>";
9047					}
9048					inst.yearshtml += "</select>";
9049
9050					html += inst.yearshtml;
9051					inst.yearshtml = null;
9052				}
9053			}
9054
9055			html += this._get( inst, "yearSuffix" );
9056			if ( showMonthAfterYear ) {
9057				html += ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" ) + monthHtml;
9058			}
9059			html += "</div>"; // Close datepicker_header
9060			return html;
9061		},
9062
9063		/* Adjust one of the date sub-fields. */
9064		_adjustInstDate: function( inst, offset, period ) {
9065			var year = inst.selectedYear + ( period === "Y" ? offset : 0 ),
9066				month = inst.selectedMonth + ( period === "M" ? offset : 0 ),
9067				day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ),
9068				date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) );
9069
9070			inst.selectedDay = date.getDate();
9071			inst.drawMonth = inst.selectedMonth = date.getMonth();
9072			inst.drawYear = inst.selectedYear = date.getFullYear();
9073			if ( period === "M" || period === "Y" ) {
9074				this._notifyChange( inst );
9075			}
9076		},
9077
9078		/* Ensure a date is within any min/max bounds. */
9079		_restrictMinMax: function( inst, date ) {
9080			var minDate = this._getMinMaxDate( inst, "min" ),
9081				maxDate = this._getMinMaxDate( inst, "max" ),
9082				newDate = ( minDate && date < minDate ? minDate : date );
9083			return ( maxDate && newDate > maxDate ? maxDate : newDate );
9084		},
9085
9086		/* Notify change of month/year. */
9087		_notifyChange: function( inst ) {
9088			var onChange = this._get( inst, "onChangeMonthYear" );
9089			if ( onChange ) {
9090				onChange.apply( ( inst.input ? inst.input[ 0 ] : null ),
9091					[ inst.selectedYear, inst.selectedMonth + 1, inst ] );
9092			}
9093		},
9094
9095		/* Determine the number of months to show. */
9096		_getNumberOfMonths: function( inst ) {
9097			var numMonths = this._get( inst, "numberOfMonths" );
9098			return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) );
9099		},
9100
9101		/* Determine the current maximum date - ensure no time components are set. */
9102		_getMinMaxDate: function( inst, minMax ) {
9103			return this._determineDate( inst, this._get( inst, minMax + "Date" ), null );
9104		},
9105
9106		/* Find the number of days in a given month. */
9107		_getDaysInMonth: function( year, month ) {
9108			return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate();
9109		},
9110
9111		/* Find the day of the week of the first of a month. */
9112		_getFirstDayOfMonth: function( year, month ) {
9113			return new Date( year, month, 1 ).getDay();
9114		},
9115
9116		/* Determines if we should allow a "next/prev" month display change. */
9117		_canAdjustMonth: function( inst, offset, curYear, curMonth ) {
9118			var numMonths = this._getNumberOfMonths( inst ),
9119				date = this._daylightSavingAdjust( new Date( curYear,
9120					curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) );
9121
9122			if ( offset < 0 ) {
9123				date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) );
9124			}
9125			return this._isInRange( inst, date );
9126		},
9127
9128		/* Is the given date in the accepted range? */
9129		_isInRange: function( inst, date ) {
9130			var yearSplit, currentYear,
9131				minDate = this._getMinMaxDate( inst, "min" ),
9132				maxDate = this._getMinMaxDate( inst, "max" ),
9133				minYear = null,
9134				maxYear = null,
9135				years = this._get( inst, "yearRange" );
9136			if ( years ) {
9137				yearSplit = years.split( ":" );
9138				currentYear = new Date().getFullYear();
9139				minYear = parseInt( yearSplit[ 0 ], 10 );
9140				maxYear = parseInt( yearSplit[ 1 ], 10 );
9141				if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) {
9142					minYear += currentYear;
9143				}
9144				if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) {
9145					maxYear += currentYear;
9146				}
9147			}
9148
9149			return ( ( !minDate || date.getTime() >= minDate.getTime() ) &&
9150			( !maxDate || date.getTime() <= maxDate.getTime() ) &&
9151			( !minYear || date.getFullYear() >= minYear ) &&
9152			( !maxYear || date.getFullYear() <= maxYear ) );
9153		},
9154
9155		/* Provide the configuration settings for formatting/parsing. */
9156		_getFormatConfig: function( inst ) {
9157			var shortYearCutoff = this._get( inst, "shortYearCutoff" );
9158			shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff :
9159			new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) );
9160			return { shortYearCutoff: shortYearCutoff,
9161				dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ),
9162				monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) };
9163		},
9164
9165		/* Format the given date for display. */
9166		_formatDate: function( inst, day, month, year ) {
9167			if ( !day ) {
9168				inst.currentDay = inst.selectedDay;
9169				inst.currentMonth = inst.selectedMonth;
9170				inst.currentYear = inst.selectedYear;
9171			}
9172			var date = ( day ? ( typeof day === "object" ? day :
9173				this._daylightSavingAdjust( new Date( year, month, day ) ) ) :
9174				this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
9175			return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) );
9176		}
9177	} );
9178
9179	/*
9180	 * Bind hover events for datepicker elements.
9181	 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9182	 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9183	 */
9184	function datepicker_bindHover( dpDiv ) {
9185		var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
9186		return dpDiv.on( "mouseout", selector, function() {
9187			$( this ).removeClass( "ui-state-hover" );
9188			if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
9189				$( this ).removeClass( "ui-datepicker-prev-hover" );
9190			}
9191			if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
9192				$( this ).removeClass( "ui-datepicker-next-hover" );
9193			}
9194		} )
9195			.on( "mouseover", selector, datepicker_handleMouseover );
9196	}
9197
9198	function datepicker_handleMouseover() {
9199		if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) {
9200			$( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" );
9201			$( this ).addClass( "ui-state-hover" );
9202			if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
9203				$( this ).addClass( "ui-datepicker-prev-hover" );
9204			}
9205			if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
9206				$( this ).addClass( "ui-datepicker-next-hover" );
9207			}
9208		}
9209	}
9210
9211	/* jQuery extend now ignores nulls! */
9212	function datepicker_extendRemove( target, props ) {
9213		$.extend( target, props );
9214		for ( var name in props ) {
9215			if ( props[ name ] == null ) {
9216				target[ name ] = props[ name ];
9217			}
9218		}
9219		return target;
9220	}
9221
9222	/* Invoke the datepicker functionality.
9223	 @param  options  string - a command, optionally followed by additional parameters or
9224	 Object - settings for attaching new datepicker functionality
9225	 @return  jQuery object */
9226	$.fn.datepicker = function( options ) {
9227
9228		/* Verify an empty collection wasn't passed - Fixes #6976 */
9229		if ( !this.length ) {
9230			return this;
9231		}
9232
9233		/* Initialise the date picker. */
9234		if ( !$.datepicker.initialized ) {
9235			$( document ).on( "mousedown", $.datepicker._checkExternalClick );
9236			$.datepicker.initialized = true;
9237		}
9238
9239		/* Append datepicker main container to body if not exist. */
9240		if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) {
9241			$( "body" ).append( $.datepicker.dpDiv );
9242		}
9243
9244		var otherArgs = Array.prototype.slice.call( arguments, 1 );
9245		if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) {
9246			return $.datepicker[ "_" + options + "Datepicker" ].
9247				apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
9248		}
9249		if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) {
9250			return $.datepicker[ "_" + options + "Datepicker" ].
9251				apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
9252		}
9253		return this.each( function() {
9254			typeof options === "string" ?
9255				$.datepicker[ "_" + options + "Datepicker" ].
9256					apply( $.datepicker, [ this ].concat( otherArgs ) ) :
9257				$.datepicker._attachDatepicker( this, options );
9258		} );
9259	};
9260
9261	$.datepicker = new Datepicker(); // singleton instance
9262	$.datepicker.initialized = false;
9263	$.datepicker.uuid = new Date().getTime();
9264	$.datepicker.version = "1.12.1";
9265
9266	var widgetsDatepicker = $.datepicker;
9267
9268
9269
9270
9271// This file is deprecated
9272	var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
9273
9274	/*!
9275	 * jQuery UI Mouse 1.12.1
9276	 * http://jqueryui.com
9277	 *
9278	 * Copyright jQuery Foundation and other contributors
9279	 * Released under the MIT license.
9280	 * http://jquery.org/license
9281	 */
9282
9283//>>label: Mouse
9284//>>group: Widgets
9285//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
9286//>>docs: http://api.jqueryui.com/mouse/
9287
9288
9289
9290	var mouseHandled = false;
9291	$( document ).on( "mouseup", function() {
9292		mouseHandled = false;
9293	} );
9294
9295	var widgetsMouse = $.widget( "ui.mouse", {
9296		version: "1.12.1",
9297		options: {
9298			cancel: "input, textarea, button, select, option",
9299			distance: 1,
9300			delay: 0
9301		},
9302		_mouseInit: function() {
9303			var that = this;
9304
9305			this.element
9306				.on( "mousedown." + this.widgetName, function( event ) {
9307					return that._mouseDown( event );
9308				} )
9309				.on( "click." + this.widgetName, function( event ) {
9310					if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
9311						$.removeData( event.target, that.widgetName + ".preventClickEvent" );
9312						event.stopImmediatePropagation();
9313						return false;
9314					}
9315				} );
9316
9317			this.started = false;
9318		},
9319
9320		// TODO: make sure destroying one instance of mouse doesn't mess with
9321		// other instances of mouse
9322		_mouseDestroy: function() {
9323			this.element.off( "." + this.widgetName );
9324			if ( this._mouseMoveDelegate ) {
9325				this.document
9326					.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9327					.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
9328			}
9329		},
9330
9331		_mouseDown: function( event ) {
9332
9333			// don't let more than one widget handle mouseStart
9334			if ( mouseHandled ) {
9335				return;
9336			}
9337
9338			this._mouseMoved = false;
9339
9340			// We may have missed mouseup (out of window)
9341			( this._mouseStarted && this._mouseUp( event ) );
9342
9343			this._mouseDownEvent = event;
9344
9345			var that = this,
9346				btnIsLeft = ( event.which === 1 ),
9347
9348			// event.target.nodeName works around a bug in IE 8 with
9349			// disabled inputs (#7620)
9350				elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
9351					$( event.target ).closest( this.options.cancel ).length : false );
9352			if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
9353				return true;
9354			}
9355
9356			this.mouseDelayMet = !this.options.delay;
9357			if ( !this.mouseDelayMet ) {
9358				this._mouseDelayTimer = setTimeout( function() {
9359					that.mouseDelayMet = true;
9360				}, this.options.delay );
9361			}
9362
9363			if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
9364				this._mouseStarted = ( this._mouseStart( event ) !== false );
9365				if ( !this._mouseStarted ) {
9366					event.preventDefault();
9367					return true;
9368				}
9369			}
9370
9371			// Click event may never have fired (Gecko & Opera)
9372			if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
9373				$.removeData( event.target, this.widgetName + ".preventClickEvent" );
9374			}
9375
9376			// These delegates are required to keep context
9377			this._mouseMoveDelegate = function( event ) {
9378				return that._mouseMove( event );
9379			};
9380			this._mouseUpDelegate = function( event ) {
9381				return that._mouseUp( event );
9382			};
9383
9384			this.document
9385				.on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9386				.on( "mouseup." + this.widgetName, this._mouseUpDelegate );
9387
9388			event.preventDefault();
9389
9390			mouseHandled = true;
9391			return true;
9392		},
9393
9394		_mouseMove: function( event ) {
9395
9396			// Only check for mouseups outside the document if you've moved inside the document
9397			// at least once. This prevents the firing of mouseup in the case of IE<9, which will
9398			// fire a mousemove event if content is placed under the cursor. See #7778
9399			// Support: IE <9
9400			if ( this._mouseMoved ) {
9401
9402				// IE mouseup check - mouseup happened when mouse was out of window
9403				if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
9404					!event.button ) {
9405					return this._mouseUp( event );
9406
9407					// Iframe mouseup check - mouseup occurred in another document
9408				} else if ( !event.which ) {
9409
9410					// Support: Safari <=8 - 9
9411					// Safari sets which to 0 if you press any of the following keys
9412					// during a drag (#14461)
9413					if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
9414						event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
9415						this.ignoreMissingWhich = true;
9416					} else if ( !this.ignoreMissingWhich ) {
9417						return this._mouseUp( event );
9418					}
9419				}
9420			}
9421
9422			if ( event.which || event.button ) {
9423				this._mouseMoved = true;
9424			}
9425
9426			if ( this._mouseStarted ) {
9427				this._mouseDrag( event );
9428				return event.preventDefault();
9429			}
9430
9431			if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
9432				this._mouseStarted =
9433					( this._mouseStart( this._mouseDownEvent, event ) !== false );
9434				( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) );
9435			}
9436
9437			return !this._mouseStarted;
9438		},
9439
9440		_mouseUp: function( event ) {
9441			this.document
9442				.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9443				.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
9444
9445			if ( this._mouseStarted ) {
9446				this._mouseStarted = false;
9447
9448				if ( event.target === this._mouseDownEvent.target ) {
9449					$.data( event.target, this.widgetName + ".preventClickEvent", true );
9450				}
9451
9452				this._mouseStop( event );
9453			}
9454
9455			if ( this._mouseDelayTimer ) {
9456				clearTimeout( this._mouseDelayTimer );
9457				delete this._mouseDelayTimer;
9458			}
9459
9460			this.ignoreMissingWhich = false;
9461			mouseHandled = false;
9462			event.preventDefault();
9463		},
9464
9465		_mouseDistanceMet: function( event ) {
9466			return ( Math.max(
9467					Math.abs( this._mouseDownEvent.pageX - event.pageX ),
9468					Math.abs( this._mouseDownEvent.pageY - event.pageY )
9469				) >= this.options.distance
9470			);
9471		},
9472
9473		_mouseDelayMet: function( /* event */ ) {
9474			return this.mouseDelayMet;
9475		},
9476
9477		// These are placeholder methods, to be overriden by extending plugin
9478		_mouseStart: function( /* event */ ) {},
9479		_mouseDrag: function( /* event */ ) {},
9480		_mouseStop: function( /* event */ ) {},
9481		_mouseCapture: function( /* event */ ) { return true; }
9482	} );
9483
9484
9485
9486
9487// $.ui.plugin is deprecated. Use $.widget() extensions instead.
9488	var plugin = $.ui.plugin = {
9489		add: function( module, option, set ) {
9490			var i,
9491				proto = $.ui[ module ].prototype;
9492			for ( i in set ) {
9493				proto.plugins[ i ] = proto.plugins[ i ] || [];
9494				proto.plugins[ i ].push( [ option, set[ i ] ] );
9495			}
9496		},
9497		call: function( instance, name, args, allowDisconnected ) {
9498			var i,
9499				set = instance.plugins[ name ];
9500
9501			if ( !set ) {
9502				return;
9503			}
9504
9505			if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
9506				instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
9507				return;
9508			}
9509
9510			for ( i = 0; i < set.length; i++ ) {
9511				if ( instance.options[ set[ i ][ 0 ] ] ) {
9512					set[ i ][ 1 ].apply( instance.element, args );
9513				}
9514			}
9515		}
9516	};
9517
9518
9519
9520	var safeBlur = $.ui.safeBlur = function( element ) {
9521
vendor: 4,545 bytes, lines 9522-9701
9522		// Support: IE9 - 10 only
9523		// If the <body> is blurred, IE will switch windows, see #9420
9524		if ( element && element.nodeName.toLowerCase() !== "body" ) {
9525			$( element ).trigger( "blur" );
9526		}
9527	};
9528
9529
9530	/*!
9531	 * jQuery UI Draggable 1.12.1
9532	 * http://jqueryui.com
9533	 *
9534	 * Copyright jQuery Foundation and other contributors
9535	 * Released under the MIT license.
9536	 * http://jquery.org/license
9537	 */
9538
9539//>>label: Draggable
9540//>>group: Interactions
9541//>>description: Enables dragging functionality for any element.
9542//>>docs: http://api.jqueryui.com/draggable/
9543//>>demos: http://jqueryui.com/draggable/
9544//>>css.structure: ../../themes/base/draggable.css
9545
9546
9547
9548	$.widget( "ui.draggable", $.ui.mouse, {
9549		version: "1.12.1",
9550		widgetEventPrefix: "drag",
9551		options: {
9552			addClasses: true,
9553			appendTo: "parent",
9554			axis: false,
9555			connectToSortable: false,
9556			containment: false,
9557			cursor: "auto",
9558			cursorAt: false,
9559			grid: false,
9560			handle: false,
9561			helper: "original",
9562			iframeFix: false,
9563			opacity: false,
9564			refreshPositions: false,
9565			revert: false,
9566			revertDuration: 500,
9567			scope: "default",
9568			scroll: true,
9569			scrollSensitivity: 20,
9570			scrollSpeed: 20,
9571			snap: false,
9572			snapMode: "both",
9573			snapTolerance: 20,
9574			stack: false,
9575			zIndex: false,
9576
9577			// Callbacks
9578			drag: null,
9579			start: null,
9580			stop: null
9581		},
9582		_create: function() {
9583
9584			if ( this.options.helper === "original" ) {
9585				this._setPositionRelative();
9586			}
9587			if ( this.options.addClasses ) {
9588				this._addClass( "ui-draggable" );
9589			}
9590			this._setHandleClassName();
9591
9592			this._mouseInit();
9593		},
9594
9595		_setOption: function( key, value ) {
9596			this._super( key, value );
9597			if ( key === "handle" ) {
9598				this._removeHandleClassName();
9599				this._setHandleClassName();
9600			}
9601		},
9602
9603		_destroy: function() {
9604			if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
9605				this.destroyOnClear = true;
9606				return;
9607			}
9608			this._removeHandleClassName();
9609			this._mouseDestroy();
9610		},
9611
9612		_mouseCapture: function( event ) {
9613			var o = this.options;
9614
9615			// Among others, prevent a drag on a resizable-handle
9616			if ( this.helper || o.disabled ||
9617				$( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
9618				return false;
9619			}
9620
9621			//Quit if we're not on a valid handle
9622			this.handle = this._getHandle( event );
9623			if ( !this.handle ) {
9624				return false;
9625			}
9626
9627			this._blurActiveElement( event );
9628
9629			this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
9630
9631			return true;
9632
9633		},
9634
9635		_blockFrames: function( selector ) {
9636			this.iframeBlocks = this.document.find( selector ).map( function() {
9637				var iframe = $( this );
9638
9639				return $( "<div>" )
9640					.css( "position", "absolute" )
9641					.appendTo( iframe.parent() )
9642					.outerWidth( iframe.outerWidth() )
9643					.outerHeight( iframe.outerHeight() )
9644					.offset( iframe.offset() )[ 0 ];
9645			} );
9646		},
9647
9648		_unblockFrames: function() {
9649			if ( this.iframeBlocks ) {
9650				this.iframeBlocks.remove();
9651				delete this.iframeBlocks;
9652			}
9653		},
9654
9655		_blurActiveElement: function( event ) {
9656			var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
9657				target = $( event.target );
9658
9659			// Don't blur if the event occurred on an element that is within
9660			// the currently focused element
9661			// See #10527, #12472
9662			if ( target.closest( activeElement ).length ) {
9663				return;
9664			}
9665
9666			// Blur any element that currently has focus, see #4261
9667			$.ui.safeBlur( activeElement );
9668		},
9669
9670		_mouseStart: function( event ) {
9671
9672			var o = this.options;
9673
9674			//Create and append the visible helper
9675			this.helper = this._createHelper( event );
9676
9677			this._addClass( this.helper, "ui-draggable-dragging" );
9678
9679			//Cache the helper size
9680			this._cacheHelperProportions();
9681
9682			//If ddmanager is used for droppables, set the global draggable
9683			if ( $.ui.ddmanager ) {
9684				$.ui.ddmanager.current = this;
9685			}
9686
9687			/*
9688			 * - Position generation -
9689			 * This block generates everything position related - it's the core of draggables.
9690			 */
9691
9692			//Cache the margins of the original element
9693			this._cacheMargins();
9694
9695			//Store the helper's css position
9696			this.cssPosition = this.helper.css( "position" );
9697			this.scrollParent = this.helper.scrollParent( true );
9698			this.offsetParent = this.helper.offsetParent();
9699			this.hasFixedAncestor = this.helper.parents().filter( function() {
9700					return $( this ).css( "position" ) === "fixed";
9701				} ).length > 0;
vendor: 5,560 bytes, lines 9702-9894
9702
9703			//The element's absolute position on the page minus margins
9704			this.positionAbs = this.element.offset();
9705			this._refreshOffsets( event );
9706
9707			//Generate the original position
9708			this.originalPosition = this.position = this._generatePosition( event, false );
9709			this.originalPageX = event.pageX;
9710			this.originalPageY = event.pageY;
9711
9712			//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
9713			( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
9714
9715			//Set a containment if given in the options
9716			this._setContainment();
9717
9718			//Trigger event + callbacks
9719			if ( this._trigger( "start", event ) === false ) {
9720				this._clear();
9721				return false;
9722			}
9723
9724			//Recache the helper size
9725			this._cacheHelperProportions();
9726
9727			//Prepare the droppable offsets
9728			if ( $.ui.ddmanager && !o.dropBehaviour ) {
9729				$.ui.ddmanager.prepareOffsets( this, event );
9730			}
9731
9732			// Execute the drag once - this causes the helper not to be visible before getting its
9733			// correct position
9734			this._mouseDrag( event, true );
9735
9736			// If the ddmanager is used for droppables, inform the manager that dragging has started
9737			// (see #5003)
9738			if ( $.ui.ddmanager ) {
9739				$.ui.ddmanager.dragStart( this, event );
9740			}
9741
9742			return true;
9743		},
9744
9745		_refreshOffsets: function( event ) {
9746			this.offset = {
9747				top: this.positionAbs.top - this.margins.top,
9748				left: this.positionAbs.left - this.margins.left,
9749				scroll: false,
9750				parent: this._getParentOffset(),
9751				relative: this._getRelativeOffset()
9752			};
9753
9754			this.offset.click = {
9755				left: event.pageX - this.offset.left,
9756				top: event.pageY - this.offset.top
9757			};
9758		},
9759
9760		_mouseDrag: function( event, noPropagation ) {
9761
9762			// reset any necessary cached properties (see #5009)
9763			if ( this.hasFixedAncestor ) {
9764				this.offset.parent = this._getParentOffset();
9765			}
9766
9767			//Compute the helpers position
9768			this.position = this._generatePosition( event, true );
9769			this.positionAbs = this._convertPositionTo( "absolute" );
9770
9771			//Call plugins and callbacks and use the resulting position if something is returned
9772			if ( !noPropagation ) {
9773				var ui = this._uiHash();
9774				if ( this._trigger( "drag", event, ui ) === false ) {
9775					this._mouseUp( new $.Event( "mouseup", event ) );
9776					return false;
9777				}
9778				this.position = ui.position;
9779			}
9780
9781			this.helper[ 0 ].style.left = this.position.left + "px";
9782			this.helper[ 0 ].style.top = this.position.top + "px";
9783
9784			if ( $.ui.ddmanager ) {
9785				$.ui.ddmanager.drag( this, event );
9786			}
9787
9788			return false;
9789		},
9790
9791		_mouseStop: function( event ) {
9792
9793			//If we are using droppables, inform the manager about the drop
9794			var that = this,
9795				dropped = false;
9796			if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
9797				dropped = $.ui.ddmanager.drop( this, event );
9798			}
9799
9800			//if a drop comes from outside (a sortable)
9801			if ( this.dropped ) {
9802				dropped = this.dropped;
9803				this.dropped = false;
9804			}
9805
9806			if ( ( this.options.revert === "invalid" && !dropped ) ||
9807				( this.options.revert === "valid" && dropped ) ||
9808				this.options.revert === true || ( $.isFunction( this.options.revert ) &&
9809				this.options.revert.call( this.element, dropped ) )
9810			) {
9811				$( this.helper ).animate(
9812					this.originalPosition,
9813					parseInt( this.options.revertDuration, 10 ),
9814					function() {
9815						if ( that._trigger( "stop", event ) !== false ) {
9816							that._clear();
9817						}
9818					}
9819				);
9820			} else {
9821				if ( this._trigger( "stop", event ) !== false ) {
9822					this._clear();
9823				}
9824			}
9825
9826			return false;
9827		},
9828
9829		_mouseUp: function( event ) {
9830			this._unblockFrames();
9831
9832			// If the ddmanager is used for droppables, inform the manager that dragging has stopped
9833			// (see #5003)
9834			if ( $.ui.ddmanager ) {
9835				$.ui.ddmanager.dragStop( this, event );
9836			}
9837
9838			// Only need to focus if the event occurred on the draggable itself, see #10527
9839			if ( this.handleElement.is( event.target ) ) {
9840
9841				// The interaction is over; whether or not the click resulted in a drag,
9842				// focus the element
9843				this.element.trigger( "focus" );
9844			}
9845
9846			return $.ui.mouse.prototype._mouseUp.call( this, event );
9847		},
9848
9849		cancel: function() {
9850
9851			if ( this.helper.is( ".ui-draggable-dragging" ) ) {
9852				this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
9853			} else {
9854				this._clear();
9855			}
9856
9857			return this;
9858
9859		},
9860
9861		_getHandle: function( event ) {
9862			return this.options.handle ?
9863				!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
9864				true;
9865		},
9866
9867		_setHandleClassName: function() {
9868			this.handleElement = this.options.handle ?
9869				this.element.find( this.options.handle ) : this.element;
9870			this._addClass( this.handleElement, "ui-draggable-handle" );
9871		},
9872
9873		_removeHandleClassName: function() {
9874			this._removeClass( this.handleElement, "ui-draggable-handle" );
9875		},
9876
9877		_createHelper: function( event ) {
9878
9879			var o = this.options,
9880				helperIsFunction = $.isFunction( o.helper ),
9881				helper = helperIsFunction ?
9882					$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
9883					( o.helper === "clone" ?
9884						this.element.clone().removeAttr( "id" ) :
9885						this.element );
9886
9887			if ( !helper.parents( "body" ).length ) {
9888				helper.appendTo( ( o.appendTo === "parent" ?
9889					this.element[ 0 ].parentNode :
9890					o.appendTo ) );
9891			}
9892
9893			// Http://bugs.jqueryui.com/ticket/9446
9894			// a helper function can return the original element
vendor: 15,718 bytes, lines 9895-10387
9895			// which wouldn't have been set to relative in _create
9896			if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
9897				this._setPositionRelative();
9898			}
9899
9900			if ( helper[ 0 ] !== this.element[ 0 ] &&
9901				!( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
9902				helper.css( "position", "absolute" );
9903			}
9904
9905			return helper;
9906
9907		},
9908
9909		_setPositionRelative: function() {
9910			if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
9911				this.element[ 0 ].style.position = "relative";
9912			}
9913		},
9914
9915		_adjustOffsetFromHelper: function( obj ) {
9916			if ( typeof obj === "string" ) {
9917				obj = obj.split( " " );
9918			}
9919			if ( $.isArray( obj ) ) {
9920				obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
9921			}
9922			if ( "left" in obj ) {
9923				this.offset.click.left = obj.left + this.margins.left;
9924			}
9925			if ( "right" in obj ) {
9926				this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
9927			}
9928			if ( "top" in obj ) {
9929				this.offset.click.top = obj.top + this.margins.top;
9930			}
9931			if ( "bottom" in obj ) {
9932				this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
9933			}
9934		},
9935
9936		_isRootNode: function( element ) {
9937			return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
9938		},
9939
9940		_getParentOffset: function() {
9941
9942			//Get the offsetParent and cache its position
9943			var po = this.offsetParent.offset(),
9944				document = this.document[ 0 ];
9945
9946			// This is a special case where we need to modify a offset calculated on start, since the
9947			// following happened:
9948			// 1. The position of the helper is absolute, so it's position is calculated based on the
9949			// next positioned parent
9950			// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
9951			// the document, which means that the scroll is included in the initial calculation of the
9952			// offset of the parent, and never recalculated upon drag
9953			if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
9954				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
9955				po.left += this.scrollParent.scrollLeft();
9956				po.top += this.scrollParent.scrollTop();
9957			}
9958
9959			if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
9960				po = { top: 0, left: 0 };
9961			}
9962
9963			return {
9964				top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
9965				left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
9966			};
9967
9968		},
9969
9970		_getRelativeOffset: function() {
9971			if ( this.cssPosition !== "relative" ) {
9972				return { top: 0, left: 0 };
9973			}
9974
9975			var p = this.element.position(),
9976				scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
9977
9978			return {
9979				top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
9980				( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
9981				left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
9982				( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
9983			};
9984
9985		},
9986
9987		_cacheMargins: function() {
9988			this.margins = {
9989				left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
9990				top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
9991				right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
9992				bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
9993			};
9994		},
9995
9996		_cacheHelperProportions: function() {
9997			this.helperProportions = {
9998				width: this.helper.outerWidth(),
9999				height: this.helper.outerHeight()
10000			};
10001		},
10002
10003		_setContainment: function() {
10004
10005			var isUserScrollable, c, ce,
10006				o = this.options,
10007				document = this.document[ 0 ];
10008
10009			this.relativeContainer = null;
10010
10011			if ( !o.containment ) {
10012				this.containment = null;
10013				return;
10014			}
10015
10016			if ( o.containment === "window" ) {
10017				this.containment = [
10018					$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
10019					$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
10020					$( window ).scrollLeft() + $( window ).width() -
10021					this.helperProportions.width - this.margins.left,
10022					$( window ).scrollTop() +
10023					( $( window ).height() || document.body.parentNode.scrollHeight ) -
10024					this.helperProportions.height - this.margins.top
10025				];
10026				return;
10027			}
10028
10029			if ( o.containment === "document" ) {
10030				this.containment = [
10031					0,
10032					0,
10033					$( document ).width() - this.helperProportions.width - this.margins.left,
10034					( $( document ).height() || document.body.parentNode.scrollHeight ) -
10035					this.helperProportions.height - this.margins.top
10036				];
10037				return;
10038			}
10039
10040			if ( o.containment.constructor === Array ) {
10041				this.containment = o.containment;
10042				return;
10043			}
10044
10045			if ( o.containment === "parent" ) {
10046				o.containment = this.helper[ 0 ].parentNode;
10047			}
10048
10049			c = $( o.containment );
10050			ce = c[ 0 ];
10051
10052			if ( !ce ) {
10053				return;
10054			}
10055
10056			isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
10057
10058			this.containment = [
10059				( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
10060				( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
10061				( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
10062				( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
10063				( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
10064				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
10065				( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
10066				this.helperProportions.width -
10067				this.margins.left -
10068				this.margins.right,
10069				( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
10070				( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
10071				( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
10072				this.helperProportions.height -
10073				this.margins.top -
10074				this.margins.bottom
10075			];
10076			this.relativeContainer = c;
10077		},
10078
10079		_convertPositionTo: function( d, pos ) {
10080
10081			if ( !pos ) {
10082				pos = this.position;
10083			}
10084
10085			var mod = d === "absolute" ? 1 : -1,
10086				scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
10087
10088			return {
10089				top: (
10090
10091					// The absolute mouse position
10092					pos.top	+
10093
10094						// Only for relative positioned nodes: Relative offset from element to offset parent
10095					this.offset.relative.top * mod +
10096
10097						// The offsetParent's offset without borders (offset + border)
10098					this.offset.parent.top * mod -
10099					( ( this.cssPosition === "fixed" ?
10100						-this.offset.scroll.top :
10101						( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
10102				),
10103				left: (
10104
10105					// The absolute mouse position
10106					pos.left +
10107
10108						// Only for relative positioned nodes: Relative offset from element to offset parent
10109					this.offset.relative.left * mod +
10110
10111						// The offsetParent's offset without borders (offset + border)
10112					this.offset.parent.left * mod	-
10113					( ( this.cssPosition === "fixed" ?
10114						-this.offset.scroll.left :
10115						( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
10116				)
10117			};
10118
10119		},
10120
10121		_generatePosition: function( event, constrainPosition ) {
10122
10123			var containment, co, top, left,
10124				o = this.options,
10125				scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
10126				pageX = event.pageX,
10127				pageY = event.pageY;
10128
10129			// Cache the scroll
10130			if ( !scrollIsRootNode || !this.offset.scroll ) {
10131				this.offset.scroll = {
10132					top: this.scrollParent.scrollTop(),
10133					left: this.scrollParent.scrollLeft()
10134				};
10135			}
10136
10137			/*
10138			 * - Position constraining -
10139			 * Constrain the position to a mix of grid, containment.
10140			 */
10141
10142			// If we are not dragging yet, we won't check for options
10143			if ( constrainPosition ) {
10144				if ( this.containment ) {
10145					if ( this.relativeContainer ) {
10146						co = this.relativeContainer.offset();
10147						containment = [
10148							this.containment[ 0 ] + co.left,
10149							this.containment[ 1 ] + co.top,
10150							this.containment[ 2 ] + co.left,
10151							this.containment[ 3 ] + co.top
10152						];
10153					} else {
10154						containment = this.containment;
10155					}
10156
10157					if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
10158						pageX = containment[ 0 ] + this.offset.click.left;
10159					}
10160					if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
10161						pageY = containment[ 1 ] + this.offset.click.top;
10162					}
10163					if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
10164						pageX = containment[ 2 ] + this.offset.click.left;
10165					}
10166					if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
10167						pageY = containment[ 3 ] + this.offset.click.top;
10168					}
10169				}
10170
10171				if ( o.grid ) {
10172
10173					//Check for grid elements set to 0 to prevent divide by 0 error causing invalid
10174					// argument errors in IE (see ticket #6950)
10175					top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
10176						this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
10177					pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
10178					top - this.offset.click.top > containment[ 3 ] ) ?
10179						top :
10180						( ( top - this.offset.click.top >= containment[ 1 ] ) ?
10181						top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
10182
10183					left = o.grid[ 0 ] ? this.originalPageX +
10184					Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
10185						this.originalPageX;
10186					pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
10187					left - this.offset.click.left > containment[ 2 ] ) ?
10188						left :
10189						( ( left - this.offset.click.left >= containment[ 0 ] ) ?
10190						left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
10191				}
10192
10193				if ( o.axis === "y" ) {
10194					pageX = this.originalPageX;
10195				}
10196
10197				if ( o.axis === "x" ) {
10198					pageY = this.originalPageY;
10199				}
10200			}
10201
10202			return {
10203				top: (
10204
10205					// The absolute mouse position
10206					pageY -
10207
10208						// Click offset (relative to the element)
10209					this.offset.click.top -
10210
10211						// Only for relative positioned nodes: Relative offset from element to offset parent
10212					this.offset.relative.top -
10213
10214						// The offsetParent's offset without borders (offset + border)
10215					this.offset.parent.top +
10216					( this.cssPosition === "fixed" ?
10217						-this.offset.scroll.top :
10218						( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
10219				),
10220				left: (
10221
10222					// The absolute mouse position
10223					pageX -
10224
10225						// Click offset (relative to the element)
10226					this.offset.click.left -
10227
10228						// Only for relative positioned nodes: Relative offset from element to offset parent
10229					this.offset.relative.left -
10230
10231						// The offsetParent's offset without borders (offset + border)
10232					this.offset.parent.left +
10233					( this.cssPosition === "fixed" ?
10234						-this.offset.scroll.left :
10235						( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
10236				)
10237			};
10238
10239		},
10240
10241		_clear: function() {
10242			this._removeClass( this.helper, "ui-draggable-dragging" );
10243			if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
10244				this.helper.remove();
10245			}
10246			this.helper = null;
10247			this.cancelHelperRemoval = false;
10248			if ( this.destroyOnClear ) {
10249				this.destroy();
10250			}
10251		},
10252
10253		// From now on bulk stuff - mainly helpers
10254
10255		_trigger: function( type, event, ui ) {
10256			ui = ui || this._uiHash();
10257			$.ui.plugin.call( this, type, [ event, ui, this ], true );
10258
10259			// Absolute position and offset (see #6884 ) have to be recalculated after plugins
10260			if ( /^(drag|start|stop)/.test( type ) ) {
10261				this.positionAbs = this._convertPositionTo( "absolute" );
10262				ui.offset = this.positionAbs;
10263			}
10264			return $.Widget.prototype._trigger.call( this, type, event, ui );
10265		},
10266
10267		plugins: {},
10268
10269		_uiHash: function() {
10270			return {
10271				helper: this.helper,
10272				position: this.position,
10273				originalPosition: this.originalPosition,
10274				offset: this.positionAbs
10275			};
10276		}
10277
10278	} );
10279
10280	$.ui.plugin.add( "draggable", "connectToSortable", {
10281		start: function( event, ui, draggable ) {
10282			var uiSortable = $.extend( {}, ui, {
10283				item: draggable.element
10284			} );
10285
10286			draggable.sortables = [];
10287			$( draggable.options.connectToSortable ).each( function() {
10288				var sortable = $( this ).sortable( "instance" );
10289
10290				if ( sortable && !sortable.options.disabled ) {
10291					draggable.sortables.push( sortable );
10292
10293					// RefreshPositions is called at drag start to refresh the containerCache
10294					// which is used in drag. This ensures it's initialized and synchronized
10295					// with any changes that might have happened on the page since initialization.
10296					sortable.refreshPositions();
10297					sortable._trigger( "activate", event, uiSortable );
10298				}
10299			} );
10300		},
10301		stop: function( event, ui, draggable ) {
10302			var uiSortable = $.extend( {}, ui, {
10303				item: draggable.element
10304			} );
10305
10306			draggable.cancelHelperRemoval = false;
10307
10308			$.each( draggable.sortables, function() {
10309				var sortable = this;
10310
10311				if ( sortable.isOver ) {
10312					sortable.isOver = 0;
10313
10314					// Allow this sortable to handle removing the helper
10315					draggable.cancelHelperRemoval = true;
10316					sortable.cancelHelperRemoval = false;
10317
10318					// Use _storedCSS To restore properties in the sortable,
10319					// as this also handles revert (#9675) since the draggable
10320					// may have modified them in unexpected ways (#8809)
10321					sortable._storedCSS = {
10322						position: sortable.placeholder.css( "position" ),
10323						top: sortable.placeholder.css( "top" ),
10324						left: sortable.placeholder.css( "left" )
10325					};
10326
10327					sortable._mouseStop( event );
10328
10329					// Once drag has ended, the sortable should return to using
10330					// its original helper, not the shared helper from draggable
10331					sortable.options.helper = sortable.options._helper;
10332				} else {
10333
10334					// Prevent this Sortable from removing the helper.
10335					// However, don't set the draggable to remove the helper
10336					// either as another connected Sortable may yet handle the removal.
10337					sortable.cancelHelperRemoval = true;
10338
10339					sortable._trigger( "deactivate", event, uiSortable );
10340				}
10341			} );
10342		},
10343		drag: function( event, ui, draggable ) {
10344			$.each( draggable.sortables, function() {
10345				var innermostIntersecting = false,
10346					sortable = this;
10347
10348				// Copy over variables that sortable's _intersectsWith uses
10349				sortable.positionAbs = draggable.positionAbs;
10350				sortable.helperProportions = draggable.helperProportions;
10351				sortable.offset.click = draggable.offset.click;
10352
10353				if ( sortable._intersectsWith( sortable.containerCache ) ) {
10354					innermostIntersecting = true;
10355
10356					$.each( draggable.sortables, function() {
10357
10358						// Copy over variables that sortable's _intersectsWith uses
10359						this.positionAbs = draggable.positionAbs;
10360						this.helperProportions = draggable.helperProportions;
10361						this.offset.click = draggable.offset.click;
10362
10363						if ( this !== sortable &&
10364							this._intersectsWith( this.containerCache ) &&
10365							$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
10366							innermostIntersecting = false;
10367						}
10368
10369						return innermostIntersecting;
10370					} );
10371				}
10372
10373				if ( innermostIntersecting ) {
10374
10375					// If it intersects, we use a little isOver variable and set it once,
10376					// so that the move-in stuff gets fired only once.
10377					if ( !sortable.isOver ) {
10378						sortable.isOver = 1;
10379
10380						// Store draggable's parent in case we need to reappend to it later.
10381						draggable._parent = ui.helper.parent();
10382
10383						sortable.currentItem = ui.helper
10384							.appendTo( sortable.element )
10385							.data( "ui-sortable-item", true );
10386
10387						// Store helper option to later restore it
vendor: 11,730 bytes, lines 10388-10762
10388						sortable.options._helper = sortable.options.helper;
10389
10390						sortable.options.helper = function() {
10391							return ui.helper[ 0 ];
10392						};
10393
10394						// Fire the start events of the sortable with our passed browser event,
10395						// and our own helper (so it doesn't create a new one)
10396						event.target = sortable.currentItem[ 0 ];
10397						sortable._mouseCapture( event, true );
10398						sortable._mouseStart( event, true, true );
10399
10400						// Because the browser event is way off the new appended portlet,
10401						// modify necessary variables to reflect the changes
10402						sortable.offset.click.top = draggable.offset.click.top;
10403						sortable.offset.click.left = draggable.offset.click.left;
10404						sortable.offset.parent.left -= draggable.offset.parent.left -
10405							sortable.offset.parent.left;
10406						sortable.offset.parent.top -= draggable.offset.parent.top -
10407							sortable.offset.parent.top;
10408
10409						draggable._trigger( "toSortable", event );
10410
10411						// Inform draggable that the helper is in a valid drop zone,
10412						// used solely in the revert option to handle "valid/invalid".
10413						draggable.dropped = sortable.element;
10414
10415						// Need to refreshPositions of all sortables in the case that
10416						// adding to one sortable changes the location of the other sortables (#9675)
10417						$.each( draggable.sortables, function() {
10418							this.refreshPositions();
10419						} );
10420
10421						// Hack so receive/update callbacks work (mostly)
10422						draggable.currentItem = draggable.element;
10423						sortable.fromOutside = draggable;
10424					}
10425
10426					if ( sortable.currentItem ) {
10427						sortable._mouseDrag( event );
10428
10429						// Copy the sortable's position because the draggable's can potentially reflect
10430						// a relative position, while sortable is always absolute, which the dragged
10431						// element has now become. (#8809)
10432						ui.position = sortable.position;
10433					}
10434				} else {
10435
10436					// If it doesn't intersect with the sortable, and it intersected before,
10437					// we fake the drag stop of the sortable, but make sure it doesn't remove
10438					// the helper by using cancelHelperRemoval.
10439					if ( sortable.isOver ) {
10440
10441						sortable.isOver = 0;
10442						sortable.cancelHelperRemoval = true;
10443
10444						// Calling sortable's mouseStop would trigger a revert,
10445						// so revert must be temporarily false until after mouseStop is called.
10446						sortable.options._revert = sortable.options.revert;
10447						sortable.options.revert = false;
10448
10449						sortable._trigger( "out", event, sortable._uiHash( sortable ) );
10450						sortable._mouseStop( event, true );
10451
10452						// Restore sortable behaviors that were modfied
10453						// when the draggable entered the sortable area (#9481)
10454						sortable.options.revert = sortable.options._revert;
10455						sortable.options.helper = sortable.options._helper;
10456
10457						if ( sortable.placeholder ) {
10458							sortable.placeholder.remove();
10459						}
10460
10461						// Restore and recalculate the draggable's offset considering the sortable
10462						// may have modified them in unexpected ways. (#8809, #10669)
10463						ui.helper.appendTo( draggable._parent );
10464						draggable._refreshOffsets( event );
10465						ui.position = draggable._generatePosition( event, true );
10466
10467						draggable._trigger( "fromSortable", event );
10468
10469						// Inform draggable that the helper is no longer in a valid drop zone
10470						draggable.dropped = false;
10471
10472						// Need to refreshPositions of all sortables just in case removing
10473						// from one sortable changes the location of other sortables (#9675)
10474						$.each( draggable.sortables, function() {
10475							this.refreshPositions();
10476						} );
10477					}
10478				}
10479			} );
10480		}
10481	} );
10482
10483	$.ui.plugin.add( "draggable", "cursor", {
10484		start: function( event, ui, instance ) {
10485			var t = $( "body" ),
10486				o = instance.options;
10487
10488			if ( t.css( "cursor" ) ) {
10489				o._cursor = t.css( "cursor" );
10490			}
10491			t.css( "cursor", o.cursor );
10492		},
10493		stop: function( event, ui, instance ) {
10494			var o = instance.options;
10495			if ( o._cursor ) {
10496				$( "body" ).css( "cursor", o._cursor );
10497			}
10498		}
10499	} );
10500
10501	$.ui.plugin.add( "draggable", "opacity", {
10502		start: function( event, ui, instance ) {
10503			var t = $( ui.helper ),
10504				o = instance.options;
10505			if ( t.css( "opacity" ) ) {
10506				o._opacity = t.css( "opacity" );
10507			}
10508			t.css( "opacity", o.opacity );
10509		},
10510		stop: function( event, ui, instance ) {
10511			var o = instance.options;
10512			if ( o._opacity ) {
10513				$( ui.helper ).css( "opacity", o._opacity );
10514			}
10515		}
10516	} );
10517
10518	$.ui.plugin.add( "draggable", "scroll", {
10519		start: function( event, ui, i ) {
10520			if ( !i.scrollParentNotHidden ) {
10521				i.scrollParentNotHidden = i.helper.scrollParent( false );
10522			}
10523
10524			if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
10525				i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
10526				i.overflowOffset = i.scrollParentNotHidden.offset();
10527			}
10528		},
10529		drag: function( event, ui, i  ) {
10530
10531			var o = i.options,
10532				scrolled = false,
10533				scrollParent = i.scrollParentNotHidden[ 0 ],
10534				document = i.document[ 0 ];
10535
10536			if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
10537				if ( !o.axis || o.axis !== "x" ) {
10538					if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
10539						o.scrollSensitivity ) {
10540						scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
10541					} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
10542						scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
10543					}
10544				}
10545
10546				if ( !o.axis || o.axis !== "y" ) {
10547					if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
10548						o.scrollSensitivity ) {
10549						scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
10550					} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
10551						scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
10552					}
10553				}
10554
10555			} else {
10556
10557				if ( !o.axis || o.axis !== "x" ) {
10558					if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
10559						scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
10560					} else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
10561						o.scrollSensitivity ) {
10562						scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
10563					}
10564				}
10565
10566				if ( !o.axis || o.axis !== "y" ) {
10567					if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
10568						scrolled = $( document ).scrollLeft(
10569							$( document ).scrollLeft() - o.scrollSpeed
10570						);
10571					} else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
10572						o.scrollSensitivity ) {
10573						scrolled = $( document ).scrollLeft(
10574							$( document ).scrollLeft() + o.scrollSpeed
10575						);
10576					}
10577				}
10578
10579			}
10580
10581			if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
10582				$.ui.ddmanager.prepareOffsets( i, event );
10583			}
10584
10585		}
10586	} );
10587
10588	$.ui.plugin.add( "draggable", "snap", {
10589		start: function( event, ui, i ) {
10590
10591			var o = i.options;
10592
10593			i.snapElements = [];
10594
10595			$( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
10596				.each( function() {
10597					var $t = $( this ),
10598						$o = $t.offset();
10599					if ( this !== i.element[ 0 ] ) {
10600						i.snapElements.push( {
10601							item: this,
10602							width: $t.outerWidth(), height: $t.outerHeight(),
10603							top: $o.top, left: $o.left
10604						} );
10605					}
10606				} );
10607
10608		},
10609		drag: function( event, ui, inst ) {
10610
10611			var ts, bs, ls, rs, l, r, t, b, i, first,
10612				o = inst.options,
10613				d = o.snapTolerance,
10614				x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
10615				y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
10616
10617			for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
10618
10619				l = inst.snapElements[ i ].left - inst.margins.left;
10620				r = l + inst.snapElements[ i ].width;
10621				t = inst.snapElements[ i ].top - inst.margins.top;
10622				b = t + inst.snapElements[ i ].height;
10623
10624				if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
10625					!$.contains( inst.snapElements[ i ].item.ownerDocument,
10626						inst.snapElements[ i ].item ) ) {
10627					if ( inst.snapElements[ i ].snapping ) {
10628						( inst.options.snap.release &&
10629						inst.options.snap.release.call(
10630							inst.element,
10631							event,
10632							$.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
10633						) );
10634					}
10635					inst.snapElements[ i ].snapping = false;
10636					continue;
10637				}
10638
10639				if ( o.snapMode !== "inner" ) {
10640					ts = Math.abs( t - y2 ) <= d;
10641					bs = Math.abs( b - y1 ) <= d;
10642					ls = Math.abs( l - x2 ) <= d;
10643					rs = Math.abs( r - x1 ) <= d;
10644					if ( ts ) {
10645						ui.position.top = inst._convertPositionTo( "relative", {
10646							top: t - inst.helperProportions.height,
10647							left: 0
10648						} ).top;
10649					}
10650					if ( bs ) {
10651						ui.position.top = inst._convertPositionTo( "relative", {
10652							top: b,
10653							left: 0
10654						} ).top;
10655					}
10656					if ( ls ) {
10657						ui.position.left = inst._convertPositionTo( "relative", {
10658							top: 0,
10659							left: l - inst.helperProportions.width
10660						} ).left;
10661					}
10662					if ( rs ) {
10663						ui.position.left = inst._convertPositionTo( "relative", {
10664							top: 0,
10665							left: r
10666						} ).left;
10667					}
10668				}
10669
10670				first = ( ts || bs || ls || rs );
10671
10672				if ( o.snapMode !== "outer" ) {
10673					ts = Math.abs( t - y1 ) <= d;
10674					bs = Math.abs( b - y2 ) <= d;
10675					ls = Math.abs( l - x1 ) <= d;
10676					rs = Math.abs( r - x2 ) <= d;
10677					if ( ts ) {
10678						ui.position.top = inst._convertPositionTo( "relative", {
10679							top: t,
10680							left: 0
10681						} ).top;
10682					}
10683					if ( bs ) {
10684						ui.position.top = inst._convertPositionTo( "relative", {
10685							top: b - inst.helperProportions.height,
10686							left: 0
10687						} ).top;
10688					}
10689					if ( ls ) {
10690						ui.position.left = inst._convertPositionTo( "relative", {
10691							top: 0,
10692							left: l
10693						} ).left;
10694					}
10695					if ( rs ) {
10696						ui.position.left = inst._convertPositionTo( "relative", {
10697							top: 0,
10698							left: r - inst.helperProportions.width
10699						} ).left;
10700					}
10701				}
10702
10703				if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
10704					( inst.options.snap.snap &&
10705					inst.options.snap.snap.call(
10706						inst.element,
10707						event,
10708						$.extend( inst._uiHash(), {
10709							snapItem: inst.snapElements[ i ].item
10710						} ) ) );
10711				}
10712				inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
10713
10714			}
10715
10716		}
10717	} );
10718
10719	$.ui.plugin.add( "draggable", "stack", {
10720		start: function( event, ui, instance ) {
10721			var min,
10722				o = instance.options,
10723				group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
10724					return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
10725						( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
10726				} );
10727
10728			if ( !group.length ) { return; }
10729
10730			min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
10731			$( group ).each( function( i ) {
10732				$( this ).css( "zIndex", min + i );
10733			} );
10734			this.css( "zIndex", ( min + group.length ) );
10735		}
10736	} );
10737
10738	$.ui.plugin.add( "draggable", "zIndex", {
10739		start: function( event, ui, instance ) {
10740			var t = $( ui.helper ),
10741				o = instance.options;
10742
10743			if ( t.css( "zIndex" ) ) {
10744				o._zIndex = t.css( "zIndex" );
10745			}
10746			t.css( "zIndex", o.zIndex );
10747		},
10748		stop: function( event, ui, instance ) {
10749			var o = instance.options;
10750
10751			if ( o._zIndex ) {
10752				$( ui.helper ).css( "zIndex", o._zIndex );
10753			}
10754		}
10755	} );
10756
10757	var widgetsDraggable = $.ui.draggable;
10758
10759
10760	/*!
10761	 * jQuery UI Resizable 1.12.1
10762	 * http://jqueryui.com
vendor: 7,142 bytes, lines 10763-11041
10763	 *
10764	 * Copyright jQuery Foundation and other contributors
10765	 * Released under the MIT license.
10766	 * http://jquery.org/license
10767	 */
10768
10769//>>label: Resizable
10770//>>group: Interactions
10771//>>description: Enables resize functionality for any element.
10772//>>docs: http://api.jqueryui.com/resizable/
10773//>>demos: http://jqueryui.com/resizable/
10774//>>css.structure: ../../themes/base/core.css
10775//>>css.structure: ../../themes/base/resizable.css
10776//>>css.theme: ../../themes/base/theme.css
10777
10778
10779
10780	$.widget( "ui.resizable", $.ui.mouse, {
10781		version: "1.12.1",
10782		widgetEventPrefix: "resize",
10783		options: {
10784			alsoResize: false,
10785			animate: false,
10786			animateDuration: "slow",
10787			animateEasing: "swing",
10788			aspectRatio: false,
10789			autoHide: false,
10790			classes: {
10791				"ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se"
10792			},
10793			containment: false,
10794			ghost: false,
10795			grid: false,
10796			handles: "e,s,se",
10797			helper: false,
10798			maxHeight: null,
10799			maxWidth: null,
10800			minHeight: 10,
10801			minWidth: 10,
10802
10803			// See #7960
10804			zIndex: 90,
10805
10806			// Callbacks
10807			resize: null,
10808			start: null,
10809			stop: null
10810		},
10811
10812		_num: function( value ) {
10813			return parseFloat( value ) || 0;
10814		},
10815
10816		_isNumber: function( value ) {
10817			return !isNaN( parseFloat( value ) );
10818		},
10819
10820		_hasScroll: function( el, a ) {
10821
10822			if ( $( el ).css( "overflow" ) === "hidden" ) {
10823				return false;
10824			}
10825
10826			var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
10827				has = false;
10828
10829			if ( el[ scroll ] > 0 ) {
10830				return true;
10831			}
10832
10833			// TODO: determine which cases actually cause this to happen
10834			// if the element doesn't have the scroll set, see if it's possible to
10835			// set the scroll
10836			el[ scroll ] = 1;
10837			has = ( el[ scroll ] > 0 );
10838			el[ scroll ] = 0;
10839			return has;
10840		},
10841
10842		_create: function() {
10843
10844			var margins,
10845				o = this.options,
10846				that = this;
10847			this._addClass( "ui-resizable" );
10848
10849			$.extend( this, {
10850				_aspectRatio: !!( o.aspectRatio ),
10851				aspectRatio: o.aspectRatio,
10852				originalElement: this.element,
10853				_proportionallyResizeElements: [],
10854				_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
10855			} );
10856
10857			// Wrap the element if it cannot hold child nodes
10858			if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) {
10859
10860				this.element.wrap(
10861					$( "<div class='ui-wrapper' style='overflow: hidden;'></div>" ).css( {
10862						position: this.element.css( "position" ),
10863						width: this.element.outerWidth(),
10864						height: this.element.outerHeight(),
10865						top: this.element.css( "top" ),
10866						left: this.element.css( "left" )
10867					} )
10868				);
10869
10870				this.element = this.element.parent().data(
10871					"ui-resizable", this.element.resizable( "instance" )
10872				);
10873
10874				this.elementIsWrapper = true;
10875
10876				margins = {
10877					marginTop: this.originalElement.css( "marginTop" ),
10878					marginRight: this.originalElement.css( "marginRight" ),
10879					marginBottom: this.originalElement.css( "marginBottom" ),
10880					marginLeft: this.originalElement.css( "marginLeft" )
10881				};
10882
10883				this.element.css( margins );
10884				this.originalElement.css( "margin", 0 );
10885
10886				// support: Safari
10887				// Prevent Safari textarea resize
10888				this.originalResizeStyle = this.originalElement.css( "resize" );
10889				this.originalElement.css( "resize", "none" );
10890
10891				this._proportionallyResizeElements.push( this.originalElement.css( {
10892					position: "static",
10893					zoom: 1,
10894					display: "block"
10895				} ) );
10896
10897				// Support: IE9
10898				// avoid IE jump (hard set the margin)
10899				this.originalElement.css( margins );
10900
10901				this._proportionallyResize();
10902			}
10903
10904			this._setupHandles();
10905
10906			if ( o.autoHide ) {
10907				$( this.element )
10908					.on( "mouseenter", function() {
10909						if ( o.disabled ) {
10910							return;
10911						}
10912						that._removeClass( "ui-resizable-autohide" );
10913						that._handles.show();
10914					} )
10915					.on( "mouseleave", function() {
10916						if ( o.disabled ) {
10917							return;
10918						}
10919						if ( !that.resizing ) {
10920							that._addClass( "ui-resizable-autohide" );
10921							that._handles.hide();
10922						}
10923					} );
10924			}
10925
10926			this._mouseInit();
10927		},
10928
10929		_destroy: function() {
10930
10931			this._mouseDestroy();
10932
10933			var wrapper,
10934				_destroy = function( exp ) {
10935					$( exp )
10936						.removeData( "resizable" )
10937						.removeData( "ui-resizable" )
10938						.off( ".resizable" )
10939						.find( ".ui-resizable-handle" )
10940						.remove();
10941				};
10942
10943			// TODO: Unwrap at same DOM position
10944			if ( this.elementIsWrapper ) {
10945				_destroy( this.element );
10946				wrapper = this.element;
10947				this.originalElement.css( {
10948					position: wrapper.css( "position" ),
10949					width: wrapper.outerWidth(),
10950					height: wrapper.outerHeight(),
10951					top: wrapper.css( "top" ),
10952					left: wrapper.css( "left" )
10953				} ).insertAfter( wrapper );
10954				wrapper.remove();
10955			}
10956
10957			this.originalElement.css( "resize", this.originalResizeStyle );
10958			_destroy( this.originalElement );
10959
10960			return this;
10961		},
10962
10963		_setOption: function( key, value ) {
10964			this._super( key, value );
10965
10966			switch ( key ) {
10967				case "handles":
10968					this._removeHandles();
10969					this._setupHandles();
10970					break;
10971				default:
10972					break;
10973			}
10974		},
10975
10976		_setupHandles: function() {
10977			var o = this.options, handle, i, n, hname, axis, that = this;
10978			this.handles = o.handles ||
10979				( !$( ".ui-resizable-handle", this.element ).length ?
10980					"e,s,se" : {
10981					n: ".ui-resizable-n",
10982					e: ".ui-resizable-e",
10983					s: ".ui-resizable-s",
10984					w: ".ui-resizable-w",
10985					se: ".ui-resizable-se",
10986					sw: ".ui-resizable-sw",
10987					ne: ".ui-resizable-ne",
10988					nw: ".ui-resizable-nw"
10989				} );
10990
10991			this._handles = $();
10992			if ( this.handles.constructor === String ) {
10993
10994				if ( this.handles === "all" ) {
10995					this.handles = "n,e,s,w,se,sw,ne,nw";
10996				}
10997
10998				n = this.handles.split( "," );
10999				this.handles = {};
11000
11001				for ( i = 0; i < n.length; i++ ) {
11002
11003					handle = $.trim( n[ i ] );
11004					hname = "ui-resizable-" + handle;
11005					axis = $( "<div>" );
11006					this._addClass( axis, "ui-resizable-handle " + hname );
11007
11008					axis.css( { zIndex: o.zIndex } );
11009
11010					this.handles[ handle ] = ".ui-resizable-" + handle;
11011					this.element.append( axis );
11012				}
11013
11014			}
11015
11016			this._renderAxis = function( target ) {
11017
11018				var i, axis, padPos, padWrapper;
11019
11020				target = target || this.element;
11021
11022				for ( i in this.handles ) {
11023
11024					if ( this.handles[ i ].constructor === String ) {
11025						this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show();
11026					} else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
11027						this.handles[ i ] = $( this.handles[ i ] );
11028						this._on( this.handles[ i ], { "mousedown": that._mouseDown } );
11029					}
11030
11031					if ( this.elementIsWrapper &&
11032						this.originalElement[ 0 ]
11033							.nodeName
11034							.match( /^(textarea|input|select|button)$/i ) ) {
11035						axis = $( this.handles[ i ], this.element );
11036
11037						padWrapper = /sw|ne|nw|se|n|s/.test( i ) ?
11038							axis.outerHeight() :
11039							axis.outerWidth();
11040
11041						padPos = [ "padding",
vendor: 4,804 bytes, lines 11042-11222
11042							/ne|nw|n/.test( i ) ? "Top" :
11043								/se|sw|s/.test( i ) ? "Bottom" :
11044									/^e$/.test( i ) ? "Right" : "Left" ].join( "" );
11045
11046						target.css( padPos, padWrapper );
11047
11048						this._proportionallyResize();
11049					}
11050
11051					this._handles = this._handles.add( this.handles[ i ] );
11052				}
11053			};
11054
11055			// TODO: make renderAxis a prototype function
11056			this._renderAxis( this.element );
11057
11058			this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
11059			this._handles.disableSelection();
11060
11061			this._handles.on( "mouseover", function() {
11062				if ( !that.resizing ) {
11063					if ( this.className ) {
11064						axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i );
11065					}
11066					that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se";
11067				}
11068			} );
11069
11070			if ( o.autoHide ) {
11071				this._handles.hide();
11072				this._addClass( "ui-resizable-autohide" );
11073			}
11074		},
11075
11076		_removeHandles: function() {
11077			this._handles.remove();
11078		},
11079
11080		_mouseCapture: function( event ) {
11081			var i, handle,
11082				capture = false;
11083
11084			for ( i in this.handles ) {
11085				handle = $( this.handles[ i ] )[ 0 ];
11086				if ( handle === event.target || $.contains( handle, event.target ) ) {
11087					capture = true;
11088				}
11089			}
11090
11091			return !this.options.disabled && capture;
11092		},
11093
11094		_mouseStart: function( event ) {
11095
11096			var curleft, curtop, cursor,
11097				o = this.options,
11098				el = this.element;
11099
11100			this.resizing = true;
11101
11102			this._renderProxy();
11103
11104			curleft = this._num( this.helper.css( "left" ) );
11105			curtop = this._num( this.helper.css( "top" ) );
11106
11107			if ( o.containment ) {
11108				curleft += $( o.containment ).scrollLeft() || 0;
11109				curtop += $( o.containment ).scrollTop() || 0;
11110			}
11111
11112			this.offset = this.helper.offset();
11113			this.position = { left: curleft, top: curtop };
11114
11115			this.size = this._helper ? {
11116				width: this.helper.width(),
11117				height: this.helper.height()
11118			} : {
11119				width: el.width(),
11120				height: el.height()
11121			};
11122
11123			this.originalSize = this._helper ? {
11124				width: el.outerWidth(),
11125				height: el.outerHeight()
11126			} : {
11127				width: el.width(),
11128				height: el.height()
11129			};
11130
11131			this.sizeDiff = {
11132				width: el.outerWidth() - el.width(),
11133				height: el.outerHeight() - el.height()
11134			};
11135
11136			this.originalPosition = { left: curleft, top: curtop };
11137			this.originalMousePosition = { left: event.pageX, top: event.pageY };
11138
11139			this.aspectRatio = ( typeof o.aspectRatio === "number" ) ?
11140				o.aspectRatio :
11141				( ( this.originalSize.width / this.originalSize.height ) || 1 );
11142
11143			cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" );
11144			$( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor );
11145
11146			this._addClass( "ui-resizable-resizing" );
11147			this._propagate( "start", event );
11148			return true;
11149		},
11150
11151		_mouseDrag: function( event ) {
11152
11153			var data, props,
11154				smp = this.originalMousePosition,
11155				a = this.axis,
11156				dx = ( event.pageX - smp.left ) || 0,
11157				dy = ( event.pageY - smp.top ) || 0,
11158				trigger = this._change[ a ];
11159
11160			this._updatePrevProperties();
11161
11162			if ( !trigger ) {
11163				return false;
11164			}
11165
11166			data = trigger.apply( this, [ event, dx, dy ] );
11167
11168			this._updateVirtualBoundaries( event.shiftKey );
11169			if ( this._aspectRatio || event.shiftKey ) {
11170				data = this._updateRatio( data, event );
11171			}
11172
11173			data = this._respectSize( data, event );
11174
11175			this._updateCache( data );
11176
11177			this._propagate( "resize", event );
11178
11179			props = this._applyChanges();
11180
11181			if ( !this._helper && this._proportionallyResizeElements.length ) {
11182				this._proportionallyResize();
11183			}
11184
11185			if ( !$.isEmptyObject( props ) ) {
11186				this._updatePrevProperties();
11187				this._trigger( "resize", event, this.ui() );
11188				this._applyChanges();
11189			}
11190
11191			return false;
11192		},
11193
11194		_mouseStop: function( event ) {
11195
11196			this.resizing = false;
11197			var pr, ista, soffseth, soffsetw, s, left, top,
11198				o = this.options, that = this;
11199
11200			if ( this._helper ) {
11201
11202				pr = this._proportionallyResizeElements;
11203				ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName );
11204				soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height;
11205				soffsetw = ista ? 0 : that.sizeDiff.width;
11206
11207				s = {
11208					width: ( that.helper.width()  - soffsetw ),
11209					height: ( that.helper.height() - soffseth )
11210				};
11211				left = ( parseFloat( that.element.css( "left" ) ) +
11212					( that.position.left - that.originalPosition.left ) ) || null;
11213				top = ( parseFloat( that.element.css( "top" ) ) +
11214					( that.position.top - that.originalPosition.top ) ) || null;
11215
11216				if ( !o.animate ) {
11217					this.element.css( $.extend( s, { top: top, left: left } ) );
11218				}
11219
11220				that.helper.height( that.size.height );
11221				that.helper.width( that.size.width );
11222
vendor: 17,276 bytes, lines 11223-11852
11223				if ( this._helper && !o.animate ) {
11224					this._proportionallyResize();
11225				}
11226			}
11227
11228			$( "body" ).css( "cursor", "auto" );
11229
11230			this._removeClass( "ui-resizable-resizing" );
11231
11232			this._propagate( "stop", event );
11233
11234			if ( this._helper ) {
11235				this.helper.remove();
11236			}
11237
11238			return false;
11239
11240		},
11241
11242		_updatePrevProperties: function() {
11243			this.prevPosition = {
11244				top: this.position.top,
11245				left: this.position.left
11246			};
11247			this.prevSize = {
11248				width: this.size.width,
11249				height: this.size.height
11250			};
11251		},
11252
11253		_applyChanges: function() {
11254			var props = {};
11255
11256			if ( this.position.top !== this.prevPosition.top ) {
11257				props.top = this.position.top + "px";
11258			}
11259			if ( this.position.left !== this.prevPosition.left ) {
11260				props.left = this.position.left + "px";
11261			}
11262			if ( this.size.width !== this.prevSize.width ) {
11263				props.width = this.size.width + "px";
11264			}
11265			if ( this.size.height !== this.prevSize.height ) {
11266				props.height = this.size.height + "px";
11267			}
11268
11269			this.helper.css( props );
11270
11271			return props;
11272		},
11273
11274		_updateVirtualBoundaries: function( forceAspectRatio ) {
11275			var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
11276				o = this.options;
11277
11278			b = {
11279				minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0,
11280				maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity,
11281				minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0,
11282				maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity
11283			};
11284
11285			if ( this._aspectRatio || forceAspectRatio ) {
11286				pMinWidth = b.minHeight * this.aspectRatio;
11287				pMinHeight = b.minWidth / this.aspectRatio;
11288				pMaxWidth = b.maxHeight * this.aspectRatio;
11289				pMaxHeight = b.maxWidth / this.aspectRatio;
11290
11291				if ( pMinWidth > b.minWidth ) {
11292					b.minWidth = pMinWidth;
11293				}
11294				if ( pMinHeight > b.minHeight ) {
11295					b.minHeight = pMinHeight;
11296				}
11297				if ( pMaxWidth < b.maxWidth ) {
11298					b.maxWidth = pMaxWidth;
11299				}
11300				if ( pMaxHeight < b.maxHeight ) {
11301					b.maxHeight = pMaxHeight;
11302				}
11303			}
11304			this._vBoundaries = b;
11305		},
11306
11307		_updateCache: function( data ) {
11308			this.offset = this.helper.offset();
11309			if ( this._isNumber( data.left ) ) {
11310				this.position.left = data.left;
11311			}
11312			if ( this._isNumber( data.top ) ) {
11313				this.position.top = data.top;
11314			}
11315			if ( this._isNumber( data.height ) ) {
11316				this.size.height = data.height;
11317			}
11318			if ( this._isNumber( data.width ) ) {
11319				this.size.width = data.width;
11320			}
11321		},
11322
11323		_updateRatio: function( data ) {
11324
11325			var cpos = this.position,
11326				csize = this.size,
11327				a = this.axis;
11328
11329			if ( this._isNumber( data.height ) ) {
11330				data.width = ( data.height * this.aspectRatio );
11331			} else if ( this._isNumber( data.width ) ) {
11332				data.height = ( data.width / this.aspectRatio );
11333			}
11334
11335			if ( a === "sw" ) {
11336				data.left = cpos.left + ( csize.width - data.width );
11337				data.top = null;
11338			}
11339			if ( a === "nw" ) {
11340				data.top = cpos.top + ( csize.height - data.height );
11341				data.left = cpos.left + ( csize.width - data.width );
11342			}
11343
11344			return data;
11345		},
11346
11347		_respectSize: function( data ) {
11348
11349			var o = this._vBoundaries,
11350				a = this.axis,
11351				ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ),
11352				ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ),
11353				isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ),
11354				isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ),
11355				dw = this.originalPosition.left + this.originalSize.width,
11356				dh = this.originalPosition.top + this.originalSize.height,
11357				cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a );
11358			if ( isminw ) {
11359				data.width = o.minWidth;
11360			}
11361			if ( isminh ) {
11362				data.height = o.minHeight;
11363			}
11364			if ( ismaxw ) {
11365				data.width = o.maxWidth;
11366			}
11367			if ( ismaxh ) {
11368				data.height = o.maxHeight;
11369			}
11370
11371			if ( isminw && cw ) {
11372				data.left = dw - o.minWidth;
11373			}
11374			if ( ismaxw && cw ) {
11375				data.left = dw - o.maxWidth;
11376			}
11377			if ( isminh && ch ) {
11378				data.top = dh - o.minHeight;
11379			}
11380			if ( ismaxh && ch ) {
11381				data.top = dh - o.maxHeight;
11382			}
11383
11384			// Fixing jump error on top/left - bug #2330
11385			if ( !data.width && !data.height && !data.left && data.top ) {
11386				data.top = null;
11387			} else if ( !data.width && !data.height && !data.top && data.left ) {
11388				data.left = null;
11389			}
11390
11391			return data;
11392		},
11393
11394		_getPaddingPlusBorderDimensions: function( element ) {
11395			var i = 0,
11396				widths = [],
11397				borders = [
11398					element.css( "borderTopWidth" ),
11399					element.css( "borderRightWidth" ),
11400					element.css( "borderBottomWidth" ),
11401					element.css( "borderLeftWidth" )
11402				],
11403				paddings = [
11404					element.css( "paddingTop" ),
11405					element.css( "paddingRight" ),
11406					element.css( "paddingBottom" ),
11407					element.css( "paddingLeft" )
11408				];
11409
11410			for ( ; i < 4; i++ ) {
11411				widths[ i ] = ( parseFloat( borders[ i ] ) || 0 );
11412				widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 );
11413			}
11414
11415			return {
11416				height: widths[ 0 ] + widths[ 2 ],
11417				width: widths[ 1 ] + widths[ 3 ]
11418			};
11419		},
11420
11421		_proportionallyResize: function() {
11422
11423			if ( !this._proportionallyResizeElements.length ) {
11424				return;
11425			}
11426
11427			var prel,
11428				i = 0,
11429				element = this.helper || this.element;
11430
11431			for ( ; i < this._proportionallyResizeElements.length; i++ ) {
11432
11433				prel = this._proportionallyResizeElements[ i ];
11434
11435				// TODO: Seems like a bug to cache this.outerDimensions
11436				// considering that we are in a loop.
11437				if ( !this.outerDimensions ) {
11438					this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
11439				}
11440
11441				prel.css( {
11442					height: ( element.height() - this.outerDimensions.height ) || 0,
11443					width: ( element.width() - this.outerDimensions.width ) || 0
11444				} );
11445
11446			}
11447
11448		},
11449
11450		_renderProxy: function() {
11451
11452			var el = this.element, o = this.options;
11453			this.elementOffset = el.offset();
11454
11455			if ( this._helper ) {
11456
11457				this.helper = this.helper || $( "<div style='overflow:hidden;'></div>" );
11458
11459				this._addClass( this.helper, this._helper );
11460				this.helper.css( {
11461					width: this.element.outerWidth(),
11462					height: this.element.outerHeight(),
11463					position: "absolute",
11464					left: this.elementOffset.left + "px",
11465					top: this.elementOffset.top + "px",
11466					zIndex: ++o.zIndex //TODO: Don't modify option
11467				} );
11468
11469				this.helper
11470					.appendTo( "body" )
11471					.disableSelection();
11472
11473			} else {
11474				this.helper = this.element;
11475			}
11476
11477		},
11478
11479		_change: {
11480			e: function( event, dx ) {
11481				return { width: this.originalSize.width + dx };
11482			},
11483			w: function( event, dx ) {
11484				var cs = this.originalSize, sp = this.originalPosition;
11485				return { left: sp.left + dx, width: cs.width - dx };
11486			},
11487			n: function( event, dx, dy ) {
11488				var cs = this.originalSize, sp = this.originalPosition;
11489				return { top: sp.top + dy, height: cs.height - dy };
11490			},
11491			s: function( event, dx, dy ) {
11492				return { height: this.originalSize.height + dy };
11493			},
11494			se: function( event, dx, dy ) {
11495				return $.extend( this._change.s.apply( this, arguments ),
11496					this._change.e.apply( this, [ event, dx, dy ] ) );
11497			},
11498			sw: function( event, dx, dy ) {
11499				return $.extend( this._change.s.apply( this, arguments ),
11500					this._change.w.apply( this, [ event, dx, dy ] ) );
11501			},
11502			ne: function( event, dx, dy ) {
11503				return $.extend( this._change.n.apply( this, arguments ),
11504					this._change.e.apply( this, [ event, dx, dy ] ) );
11505			},
11506			nw: function( event, dx, dy ) {
11507				return $.extend( this._change.n.apply( this, arguments ),
11508					this._change.w.apply( this, [ event, dx, dy ] ) );
11509			}
11510		},
11511
11512		_propagate: function( n, event ) {
11513			$.ui.plugin.call( this, n, [ event, this.ui() ] );
11514			( n !== "resize" && this._trigger( n, event, this.ui() ) );
11515		},
11516
11517		plugins: {},
11518
11519		ui: function() {
11520			return {
11521				originalElement: this.originalElement,
11522				element: this.element,
11523				helper: this.helper,
11524				position: this.position,
11525				size: this.size,
11526				originalSize: this.originalSize,
11527				originalPosition: this.originalPosition
11528			};
11529		}
11530
11531	} );
11532
11533	/*
11534	 * Resizable Extensions
11535	 */
11536
11537	$.ui.plugin.add( "resizable", "animate", {
11538
11539		stop: function( event ) {
11540			var that = $( this ).resizable( "instance" ),
11541				o = that.options,
11542				pr = that._proportionallyResizeElements,
11543				ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ),
11544				soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height,
11545				soffsetw = ista ? 0 : that.sizeDiff.width,
11546				style = {
11547					width: ( that.size.width - soffsetw ),
11548					height: ( that.size.height - soffseth )
11549				},
11550				left = ( parseFloat( that.element.css( "left" ) ) +
11551					( that.position.left - that.originalPosition.left ) ) || null,
11552				top = ( parseFloat( that.element.css( "top" ) ) +
11553					( that.position.top - that.originalPosition.top ) ) || null;
11554
11555			that.element.animate(
11556				$.extend( style, top && left ? { top: top, left: left } : {} ), {
11557					duration: o.animateDuration,
11558					easing: o.animateEasing,
11559					step: function() {
11560
11561						var data = {
11562							width: parseFloat( that.element.css( "width" ) ),
11563							height: parseFloat( that.element.css( "height" ) ),
11564							top: parseFloat( that.element.css( "top" ) ),
11565							left: parseFloat( that.element.css( "left" ) )
11566						};
11567
11568						if ( pr && pr.length ) {
11569							$( pr[ 0 ] ).css( { width: data.width, height: data.height } );
11570						}
11571
11572						// Propagating resize, and updating values for each animation step
11573						that._updateCache( data );
11574						that._propagate( "resize", event );
11575
11576					}
11577				}
11578			);
11579		}
11580
11581	} );
11582
11583	$.ui.plugin.add( "resizable", "containment", {
11584
11585		start: function() {
11586			var element, p, co, ch, cw, width, height,
11587				that = $( this ).resizable( "instance" ),
11588				o = that.options,
11589				el = that.element,
11590				oc = o.containment,
11591				ce = ( oc instanceof $ ) ?
11592					oc.get( 0 ) :
11593					( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
11594
11595			if ( !ce ) {
11596				return;
11597			}
11598
11599			that.containerElement = $( ce );
11600
11601			if ( /document/.test( oc ) || oc === document ) {
11602				that.containerOffset = {
11603					left: 0,
11604					top: 0
11605				};
11606				that.containerPosition = {
11607					left: 0,
11608					top: 0
11609				};
11610
11611				that.parentData = {
11612					element: $( document ),
11613					left: 0,
11614					top: 0,
11615					width: $( document ).width(),
11616					height: $( document ).height() || document.body.parentNode.scrollHeight
11617				};
11618			} else {
11619				element = $( ce );
11620				p = [];
11621				$( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) {
11622					p[ i ] = that._num( element.css( "padding" + name ) );
11623				} );
11624
11625				that.containerOffset = element.offset();
11626				that.containerPosition = element.position();
11627				that.containerSize = {
11628					height: ( element.innerHeight() - p[ 3 ] ),
11629					width: ( element.innerWidth() - p[ 1 ] )
11630				};
11631
11632				co = that.containerOffset;
11633				ch = that.containerSize.height;
11634				cw = that.containerSize.width;
11635				width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
11636				height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
11637
11638				that.parentData = {
11639					element: ce,
11640					left: co.left,
11641					top: co.top,
11642					width: width,
11643					height: height
11644				};
11645			}
11646		},
11647
11648		resize: function( event ) {
11649			var woset, hoset, isParent, isOffsetRelative,
11650				that = $( this ).resizable( "instance" ),
11651				o = that.options,
11652				co = that.containerOffset,
11653				cp = that.position,
11654				pRatio = that._aspectRatio || event.shiftKey,
11655				cop = {
11656					top: 0,
11657					left: 0
11658				},
11659				ce = that.containerElement,
11660				continueResize = true;
11661
11662			if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
11663				cop = co;
11664			}
11665
11666			if ( cp.left < ( that._helper ? co.left : 0 ) ) {
11667				that.size.width = that.size.width +
11668					( that._helper ?
11669						( that.position.left - co.left ) :
11670						( that.position.left - cop.left ) );
11671
11672				if ( pRatio ) {
11673					that.size.height = that.size.width / that.aspectRatio;
11674					continueResize = false;
11675				}
11676				that.position.left = o.helper ? co.left : 0;
11677			}
11678
11679			if ( cp.top < ( that._helper ? co.top : 0 ) ) {
11680				that.size.height = that.size.height +
11681					( that._helper ?
11682						( that.position.top - co.top ) :
11683						that.position.top );
11684
11685				if ( pRatio ) {
11686					that.size.width = that.size.height * that.aspectRatio;
11687					continueResize = false;
11688				}
11689				that.position.top = that._helper ? co.top : 0;
11690			}
11691
11692			isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
11693			isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
11694
11695			if ( isParent && isOffsetRelative ) {
11696				that.offset.left = that.parentData.left + that.position.left;
11697				that.offset.top = that.parentData.top + that.position.top;
11698			} else {
11699				that.offset.left = that.element.offset().left;
11700				that.offset.top = that.element.offset().top;
11701			}
11702
11703			woset = Math.abs( that.sizeDiff.width +
11704				( that._helper ?
11705				that.offset.left - cop.left :
11706					( that.offset.left - co.left ) ) );
11707
11708			hoset = Math.abs( that.sizeDiff.height +
11709				( that._helper ?
11710				that.offset.top - cop.top :
11711					( that.offset.top - co.top ) ) );
11712
11713			if ( woset + that.size.width >= that.parentData.width ) {
11714				that.size.width = that.parentData.width - woset;
11715				if ( pRatio ) {
11716					that.size.height = that.size.width / that.aspectRatio;
11717					continueResize = false;
11718				}
11719			}
11720
11721			if ( hoset + that.size.height >= that.parentData.height ) {
11722				that.size.height = that.parentData.height - hoset;
11723				if ( pRatio ) {
11724					that.size.width = that.size.height * that.aspectRatio;
11725					continueResize = false;
11726				}
11727			}
11728
11729			if ( !continueResize ) {
11730				that.position.left = that.prevPosition.left;
11731				that.position.top = that.prevPosition.top;
11732				that.size.width = that.prevSize.width;
11733				that.size.height = that.prevSize.height;
11734			}
11735		},
11736
11737		stop: function() {
11738			var that = $( this ).resizable( "instance" ),
11739				o = that.options,
11740				co = that.containerOffset,
11741				cop = that.containerPosition,
11742				ce = that.containerElement,
11743				helper = $( that.helper ),
11744				ho = helper.offset(),
11745				w = helper.outerWidth() - that.sizeDiff.width,
11746				h = helper.outerHeight() - that.sizeDiff.height;
11747
11748			if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
11749				$( this ).css( {
11750					left: ho.left - cop.left - co.left,
11751					width: w,
11752					height: h
11753				} );
11754			}
11755
11756			if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
11757				$( this ).css( {
11758					left: ho.left - cop.left - co.left,
11759					width: w,
11760					height: h
11761				} );
11762			}
11763		}
11764	} );
11765
11766	$.ui.plugin.add( "resizable", "alsoResize", {
11767
11768		start: function() {
11769			var that = $( this ).resizable( "instance" ),
11770				o = that.options;
11771
11772			$( o.alsoResize ).each( function() {
11773				var el = $( this );
11774				el.data( "ui-resizable-alsoresize", {
11775					width: parseFloat( el.width() ), height: parseFloat( el.height() ),
11776					left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
11777				} );
11778			} );
11779		},
11780
11781		resize: function( event, ui ) {
11782			var that = $( this ).resizable( "instance" ),
11783				o = that.options,
11784				os = that.originalSize,
11785				op = that.originalPosition,
11786				delta = {
11787					height: ( that.size.height - os.height ) || 0,
11788					width: ( that.size.width - os.width ) || 0,
11789					top: ( that.position.top - op.top ) || 0,
11790					left: ( that.position.left - op.left ) || 0
11791				};
11792
11793			$( o.alsoResize ).each( function() {
11794				var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {},
11795					css = el.parents( ui.originalElement[ 0 ] ).length ?
11796						[ "width", "height" ] :
11797						[ "width", "height", "top", "left" ];
11798
11799				$.each( css, function( i, prop ) {
11800					var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 );
11801					if ( sum && sum >= 0 ) {
11802						style[ prop ] = sum || null;
11803					}
11804				} );
11805
11806				el.css( style );
11807			} );
11808		},
11809
11810		stop: function() {
11811			$( this ).removeData( "ui-resizable-alsoresize" );
11812		}
11813	} );
11814
11815	$.ui.plugin.add( "resizable", "ghost", {
11816
11817		start: function() {
11818
11819			var that = $( this ).resizable( "instance" ), cs = that.size;
11820
11821			that.ghost = that.originalElement.clone();
11822			that.ghost.css( {
11823				opacity: 0.25,
11824				display: "block",
11825				position: "relative",
11826				height: cs.height,
11827				width: cs.width,
11828				margin: 0,
11829				left: 0,
11830				top: 0
11831			} );
11832
11833			that._addClass( that.ghost, "ui-resizable-ghost" );
11834
11835			// DEPRECATED
11836			// TODO: remove after 1.12
11837			if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) {
11838
11839				// Ghost option
11840				that.ghost.addClass( this.options.ghost );
11841			}
11842
11843			that.ghost.appendTo( that.helper );
11844
11845		},
11846
11847		resize: function() {
11848			var that = $( this ).resizable( "instance" );
11849			if ( that.ghost ) {
11850				that.ghost.css( {
11851					position: "relative",
11852					height: that.size.height,
vendor: 5,137 bytes, lines 11853-12058
11853					width: that.size.width
11854				} );
11855			}
11856		},
11857
11858		stop: function() {
11859			var that = $( this ).resizable( "instance" );
11860			if ( that.ghost && that.helper ) {
11861				that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) );
11862			}
11863		}
11864
11865	} );
11866
11867	$.ui.plugin.add( "resizable", "grid", {
11868
11869		resize: function() {
11870			var outerDimensions,
11871				that = $( this ).resizable( "instance" ),
11872				o = that.options,
11873				cs = that.size,
11874				os = that.originalSize,
11875				op = that.originalPosition,
11876				a = that.axis,
11877				grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
11878				gridX = ( grid[ 0 ] || 1 ),
11879				gridY = ( grid[ 1 ] || 1 ),
11880				ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX,
11881				oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY,
11882				newWidth = os.width + ox,
11883				newHeight = os.height + oy,
11884				isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ),
11885				isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ),
11886				isMinWidth = o.minWidth && ( o.minWidth > newWidth ),
11887				isMinHeight = o.minHeight && ( o.minHeight > newHeight );
11888
11889			o.grid = grid;
11890
11891			if ( isMinWidth ) {
11892				newWidth += gridX;
11893			}
11894			if ( isMinHeight ) {
11895				newHeight += gridY;
11896			}
11897			if ( isMaxWidth ) {
11898				newWidth -= gridX;
11899			}
11900			if ( isMaxHeight ) {
11901				newHeight -= gridY;
11902			}
11903
11904			if ( /^(se|s|e)$/.test( a ) ) {
11905				that.size.width = newWidth;
11906				that.size.height = newHeight;
11907			} else if ( /^(ne)$/.test( a ) ) {
11908				that.size.width = newWidth;
11909				that.size.height = newHeight;
11910				that.position.top = op.top - oy;
11911			} else if ( /^(sw)$/.test( a ) ) {
11912				that.size.width = newWidth;
11913				that.size.height = newHeight;
11914				that.position.left = op.left - ox;
11915			} else {
11916				if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) {
11917					outerDimensions = that._getPaddingPlusBorderDimensions( this );
11918				}
11919
11920				if ( newHeight - gridY > 0 ) {
11921					that.size.height = newHeight;
11922					that.position.top = op.top - oy;
11923				} else {
11924					newHeight = gridY - outerDimensions.height;
11925					that.size.height = newHeight;
11926					that.position.top = op.top + os.height - newHeight;
11927				}
11928				if ( newWidth - gridX > 0 ) {
11929					that.size.width = newWidth;
11930					that.position.left = op.left - ox;
11931				} else {
11932					newWidth = gridX - outerDimensions.width;
11933					that.size.width = newWidth;
11934					that.position.left = op.left + os.width - newWidth;
11935				}
11936			}
11937		}
11938
11939	} );
11940
11941	var widgetsResizable = $.ui.resizable;
11942
11943
11944	/*!
11945	 * jQuery UI Dialog 1.12.1
11946	 * http://jqueryui.com
11947	 *
11948	 * Copyright jQuery Foundation and other contributors
11949	 * Released under the MIT license.
11950	 * http://jquery.org/license
11951	 */
11952
11953//>>label: Dialog
11954//>>group: Widgets
11955//>>description: Displays customizable dialog windows.
11956//>>docs: http://api.jqueryui.com/dialog/
11957//>>demos: http://jqueryui.com/dialog/
11958//>>css.structure: ../../themes/base/core.css
11959//>>css.structure: ../../themes/base/dialog.css
11960//>>css.theme: ../../themes/base/theme.css
11961
11962
11963
11964	$.widget( "ui.dialog", {
11965		version: "1.12.1",
11966		options: {
11967			appendTo: "body",
11968			autoOpen: true,
11969			buttons: [],
11970			classes: {
11971				"ui-dialog": "ui-corner-all",
11972				"ui-dialog-titlebar": "ui-corner-all"
11973			},
11974			closeOnEscape: true,
11975			closeText: "Close",
11976			draggable: true,
11977			hide: null,
11978			height: "auto",
11979			maxHeight: null,
11980			maxWidth: null,
11981			minHeight: 150,
11982			minWidth: 150,
11983			modal: false,
11984			position: {
11985				my: "center",
11986				at: "center",
11987				of: window,
11988				collision: "fit",
11989
11990				// Ensure the titlebar is always visible
11991				using: function( pos ) {
11992					var topOffset = $( this ).css( pos ).offset().top;
11993					if ( topOffset < 0 ) {
11994						$( this ).css( "top", pos.top - topOffset );
11995					}
11996				}
11997			},
11998			resizable: true,
11999			show: null,
12000			title: null,
12001			width: 300,
12002
12003			// Callbacks
12004			beforeClose: null,
12005			close: null,
12006			drag: null,
12007			dragStart: null,
12008			dragStop: null,
12009			focus: null,
12010			open: null,
12011			resize: null,
12012			resizeStart: null,
12013			resizeStop: null
12014		},
12015
12016		sizeRelatedOptions: {
12017			buttons: true,
12018			height: true,
12019			maxHeight: true,
12020			maxWidth: true,
12021			minHeight: true,
12022			minWidth: true,
12023			width: true
12024		},
12025
12026		resizableRelatedOptions: {
12027			maxHeight: true,
12028			maxWidth: true,
12029			minHeight: true,
12030			minWidth: true
12031		},
12032
12033		_create: function() {
12034			this.originalCss = {
12035				display: this.element[ 0 ].style.display,
12036				width: this.element[ 0 ].style.width,
12037				minHeight: this.element[ 0 ].style.minHeight,
12038				maxHeight: this.element[ 0 ].style.maxHeight,
12039				height: this.element[ 0 ].style.height
12040			};
12041			this.originalPosition = {
12042				parent: this.element.parent(),
12043				index: this.element.parent().children().index( this.element )
12044			};
12045			this.originalTitle = this.element.attr( "title" );
12046			if ( this.options.title == null && this.originalTitle != null ) {
12047				this.options.title = this.originalTitle;
12048			}
12049
12050			// Dialogs can't be disabled
12051			if ( this.options.disabled ) {
12052				this.options.disabled = false;
12053			}
12054
12055			this._createWrapper();
12056
12057			this.element
12058				.show()
vendor: 35,279 bytes, lines 12059-13342
12059				.removeAttr( "title" )
12060				.appendTo( this.uiDialog );
12061
12062			this._addClass( "ui-dialog-content", "ui-widget-content" );
12063
12064			this._createTitlebar();
12065			this._createButtonPane();
12066
12067			if ( this.options.draggable && $.fn.draggable ) {
12068				this._makeDraggable();
12069			}
12070			if ( this.options.resizable && $.fn.resizable ) {
12071				this._makeResizable();
12072			}
12073
12074			this._isOpen = false;
12075
12076			this._trackFocus();
12077		},
12078
12079		_init: function() {
12080			if ( this.options.autoOpen ) {
12081				this.open();
12082			}
12083		},
12084
12085		_appendTo: function() {
12086			var element = this.options.appendTo;
12087			if ( element && ( element.jquery || element.nodeType ) ) {
12088				return $( element );
12089			}
12090			return this.document.find( element || "body" ).eq( 0 );
12091		},
12092
12093		_destroy: function() {
12094			var next,
12095				originalPosition = this.originalPosition;
12096
12097			this._untrackInstance();
12098			this._destroyOverlay();
12099
12100			this.element
12101				.removeUniqueId()
12102				.css( this.originalCss )
12103
12104				// Without detaching first, the following becomes really slow
12105				.detach();
12106
12107			this.uiDialog.remove();
12108
12109			if ( this.originalTitle ) {
12110				this.element.attr( "title", this.originalTitle );
12111			}
12112
12113			next = originalPosition.parent.children().eq( originalPosition.index );
12114
12115			// Don't try to place the dialog next to itself (#8613)
12116			if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
12117				next.before( this.element );
12118			} else {
12119				originalPosition.parent.append( this.element );
12120			}
12121		},
12122
12123		widget: function() {
12124			return this.uiDialog;
12125		},
12126
12127		disable: $.noop,
12128		enable: $.noop,
12129
12130		close: function( event ) {
12131			var that = this;
12132
12133			if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
12134				return;
12135			}
12136
12137			this._isOpen = false;
12138			this._focusedElement = null;
12139			this._destroyOverlay();
12140			this._untrackInstance();
12141
12142			if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) {
12143
12144				// Hiding a focused element doesn't trigger blur in WebKit
12145				// so in case we have nothing to focus on, explicitly blur the active element
12146				// https://bugs.webkit.org/show_bug.cgi?id=47182
12147				$.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) );
12148			}
12149
12150			this._hide( this.uiDialog, this.options.hide, function() {
12151				that._trigger( "close", event );
12152			} );
12153		},
12154
12155		isOpen: function() {
12156			return this._isOpen;
12157		},
12158
12159		moveToTop: function() {
12160			this._moveToTop();
12161		},
12162
12163		_moveToTop: function( event, silent ) {
12164			var moved = false,
12165				zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() {
12166					return +$( this ).css( "z-index" );
12167				} ).get(),
12168				zIndexMax = Math.max.apply( null, zIndices );
12169
12170			if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
12171				this.uiDialog.css( "z-index", zIndexMax + 1 );
12172				moved = true;
12173			}
12174
12175			if ( moved && !silent ) {
12176				this._trigger( "focus", event );
12177			}
12178			return moved;
12179		},
12180
12181		open: function() {
12182			var that = this;
12183			if ( this._isOpen ) {
12184				if ( this._moveToTop() ) {
12185					this._focusTabbable();
12186				}
12187				return;
12188			}
12189
12190			this._isOpen = true;
12191			this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
12192
12193			this._size();
12194			this._position();
12195			this._createOverlay();
12196			this._moveToTop( null, true );
12197
12198			// Ensure the overlay is moved to the top with the dialog, but only when
12199			// opening. The overlay shouldn't move after the dialog is open so that
12200			// modeless dialogs opened after the modal dialog stack properly.
12201			if ( this.overlay ) {
12202				this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
12203			}
12204
12205			this._show( this.uiDialog, this.options.show, function() {
12206				that._focusTabbable();
12207				that._trigger( "focus" );
12208			} );
12209
12210			// Track the dialog immediately upon openening in case a focus event
12211			// somehow occurs outside of the dialog before an element inside the
12212			// dialog is focused (#10152)
12213			this._makeFocusTarget();
12214
12215			this._trigger( "open" );
12216		},
12217
12218		_focusTabbable: function() {
12219
12220			// Set focus to the first match:
12221			// 1. An element that was focused previously
12222			// 2. First element inside the dialog matching [autofocus]
12223			// 3. Tabbable element inside the content element
12224			// 4. Tabbable element inside the buttonpane
12225			// 5. The close button
12226			// 6. The dialog itself
12227			var hasFocus = this._focusedElement;
12228			if ( !hasFocus ) {
12229				hasFocus = this.element.find( "[autofocus]" );
12230			}
12231			if ( !hasFocus.length ) {
12232				hasFocus = this.element.find( ":tabbable" );
12233			}
12234			if ( !hasFocus.length ) {
12235				hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
12236			}
12237			if ( !hasFocus.length ) {
12238				hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
12239			}
12240			if ( !hasFocus.length ) {
12241				hasFocus = this.uiDialog;
12242			}
12243			hasFocus.eq( 0 ).trigger( "focus" );
12244		},
12245
12246		_keepFocus: function( event ) {
12247			function checkFocus() {
12248				var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
12249					isActive = this.uiDialog[ 0 ] === activeElement ||
12250						$.contains( this.uiDialog[ 0 ], activeElement );
12251				if ( !isActive ) {
12252					this._focusTabbable();
12253				}
12254			}
12255			event.preventDefault();
12256			checkFocus.call( this );
12257
12258			// support: IE
12259			// IE <= 8 doesn't prevent moving focus even with event.preventDefault()
12260			// so we check again later
12261			this._delay( checkFocus );
12262		},
12263
12264		_createWrapper: function() {
12265			this.uiDialog = $( "<div>" )
12266				.hide()
12267				.attr( {
12268
12269					// Setting tabIndex makes the div focusable
12270					tabIndex: -1,
12271					role: "dialog"
12272				} )
12273				.appendTo( this._appendTo() );
12274
12275			this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" );
12276			this._on( this.uiDialog, {
12277				keydown: function( event ) {
12278					if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
12279						event.keyCode === $.ui.keyCode.ESCAPE ) {
12280						event.preventDefault();
12281						this.close( event );
12282						return;
12283					}
12284
12285					// Prevent tabbing out of dialogs
12286					if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
12287						return;
12288					}
12289					var tabbables = this.uiDialog.find( ":tabbable" ),
12290						first = tabbables.filter( ":first" ),
12291						last = tabbables.filter( ":last" );
12292
12293					if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) &&
12294						!event.shiftKey ) {
12295						this._delay( function() {
12296							first.trigger( "focus" );
12297						} );
12298						event.preventDefault();
12299					} else if ( ( event.target === first[ 0 ] ||
12300						event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) {
12301						this._delay( function() {
12302							last.trigger( "focus" );
12303						} );
12304						event.preventDefault();
12305					}
12306				},
12307				mousedown: function( event ) {
12308					if ( this._moveToTop( event ) ) {
12309						this._focusTabbable();
12310					}
12311				}
12312			} );
12313
12314			// We assume that any existing aria-describedby attribute means
12315			// that the dialog content is marked up properly
12316			// otherwise we brute force the content as the description
12317			if ( !this.element.find( "[aria-describedby]" ).length ) {
12318				this.uiDialog.attr( {
12319					"aria-describedby": this.element.uniqueId().attr( "id" )
12320				} );
12321			}
12322		},
12323
12324		_createTitlebar: function() {
12325			var uiDialogTitle;
12326
12327			this.uiDialogTitlebar = $( "<div>" );
12328			this._addClass( this.uiDialogTitlebar,
12329				"ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" );
12330			this._on( this.uiDialogTitlebar, {
12331				mousedown: function( event ) {
12332
12333					// Don't prevent click on close button (#8838)
12334					// Focusing a dialog that is partially scrolled out of view
12335					// causes the browser to scroll it into view, preventing the click event
12336					if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
12337
12338						// Dialog isn't getting focus when dragging (#8063)
12339						this.uiDialog.trigger( "focus" );
12340					}
12341				}
12342			} );
12343
12344			// Support: IE
12345			// Use type="button" to prevent enter keypresses in textboxes from closing the
12346			// dialog in IE (#9312)
12347			this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
12348				.button( {
12349					label: $( "<a>" ).text( this.options.closeText ).html(),
12350					icon: "ui-icon-closethick",
12351					showLabel: false
12352				} )
12353				.appendTo( this.uiDialogTitlebar );
12354
12355			this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" );
12356			this._on( this.uiDialogTitlebarClose, {
12357				click: function( event ) {
12358					event.preventDefault();
12359					this.close( event );
12360				}
12361			} );
12362
12363			uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar );
12364			this._addClass( uiDialogTitle, "ui-dialog-title" );
12365			this._title( uiDialogTitle );
12366
12367			this.uiDialogTitlebar.prependTo( this.uiDialog );
12368
12369			this.uiDialog.attr( {
12370				"aria-labelledby": uiDialogTitle.attr( "id" )
12371			} );
12372		},
12373
12374		_title: function( title ) {
12375			if ( this.options.title ) {
12376				title.text( this.options.title );
12377			} else {
12378				title.html( "&#160;" );
12379			}
12380		},
12381
12382		_createButtonPane: function() {
12383			this.uiDialogButtonPane = $( "<div>" );
12384			this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane",
12385				"ui-widget-content ui-helper-clearfix" );
12386
12387			this.uiButtonSet = $( "<div>" )
12388				.appendTo( this.uiDialogButtonPane );
12389			this._addClass( this.uiButtonSet, "ui-dialog-buttonset" );
12390
12391			this._createButtons();
12392		},
12393
12394		_createButtons: function() {
12395			var that = this,
12396				buttons = this.options.buttons;
12397
12398			// If we already have a button pane, remove it
12399			this.uiDialogButtonPane.remove();
12400			this.uiButtonSet.empty();
12401
12402			if ( $.isEmptyObject( buttons ) || ( $.isArray( buttons ) && !buttons.length ) ) {
12403				this._removeClass( this.uiDialog, "ui-dialog-buttons" );
12404				return;
12405			}
12406
12407			$.each( buttons, function( name, props ) {
12408				var click, buttonOptions;
12409				props = $.isFunction( props ) ?
12410				{ click: props, text: name } :
12411					props;
12412
12413				// Default to a non-submitting button
12414				props = $.extend( { type: "button" }, props );
12415
12416				// Change the context for the click callback to be the main element
12417				click = props.click;
12418				buttonOptions = {
12419					icon: props.icon,
12420					iconPosition: props.iconPosition,
12421					showLabel: props.showLabel,
12422
12423					// Deprecated options
12424					icons: props.icons,
12425					text: props.text
12426				};
12427
12428				delete props.click;
12429				delete props.icon;
12430				delete props.iconPosition;
12431				delete props.showLabel;
12432
12433				// Deprecated options
12434				delete props.icons;
12435				if ( typeof props.text === "boolean" ) {
12436					delete props.text;
12437				}
12438
12439				$( "<button></button>", props )
12440					.button( buttonOptions )
12441					.appendTo( that.uiButtonSet )
12442					.on( "click", function() {
12443						click.apply( that.element[ 0 ], arguments );
12444					} );
12445			} );
12446			this._addClass( this.uiDialog, "ui-dialog-buttons" );
12447			this.uiDialogButtonPane.appendTo( this.uiDialog );
12448		},
12449
12450		_makeDraggable: function() {
12451			var that = this,
12452				options = this.options;
12453
12454			function filteredUi( ui ) {
12455				return {
12456					position: ui.position,
12457					offset: ui.offset
12458				};
12459			}
12460
12461			this.uiDialog.draggable( {
12462				cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
12463				handle: ".ui-dialog-titlebar",
12464				containment: "document",
12465				start: function( event, ui ) {
12466					that._addClass( $( this ), "ui-dialog-dragging" );
12467					that._blockFrames();
12468					that._trigger( "dragStart", event, filteredUi( ui ) );
12469				},
12470				drag: function( event, ui ) {
12471					that._trigger( "drag", event, filteredUi( ui ) );
12472				},
12473				stop: function( event, ui ) {
12474					var left = ui.offset.left - that.document.scrollLeft(),
12475						top = ui.offset.top - that.document.scrollTop();
12476
12477					options.position = {
12478						my: "left top",
12479						at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12480						"top" + ( top >= 0 ? "+" : "" ) + top,
12481						of: that.window
12482					};
12483					that._removeClass( $( this ), "ui-dialog-dragging" );
12484					that._unblockFrames();
12485					that._trigger( "dragStop", event, filteredUi( ui ) );
12486				}
12487			} );
12488		},
12489
12490		_makeResizable: function() {
12491			var that = this,
12492				options = this.options,
12493				handles = options.resizable,
12494
12495			// .ui-resizable has position: relative defined in the stylesheet
12496			// but dialogs have to use absolute or fixed positioning
12497				position = this.uiDialog.css( "position" ),
12498				resizeHandles = typeof handles === "string" ?
12499					handles :
12500					"n,e,s,w,se,sw,ne,nw";
12501
12502			function filteredUi( ui ) {
12503				return {
12504					originalPosition: ui.originalPosition,
12505					originalSize: ui.originalSize,
12506					position: ui.position,
12507					size: ui.size
12508				};
12509			}
12510
12511			this.uiDialog.resizable( {
12512				cancel: ".ui-dialog-content",
12513				containment: "document",
12514				alsoResize: this.element,
12515				maxWidth: options.maxWidth,
12516				maxHeight: options.maxHeight,
12517				minWidth: options.minWidth,
12518				minHeight: this._minHeight(),
12519				handles: resizeHandles,
12520				start: function( event, ui ) {
12521					that._addClass( $( this ), "ui-dialog-resizing" );
12522					that._blockFrames();
12523					that._trigger( "resizeStart", event, filteredUi( ui ) );
12524				},
12525				resize: function( event, ui ) {
12526					that._trigger( "resize", event, filteredUi( ui ) );
12527				},
12528				stop: function( event, ui ) {
12529					var offset = that.uiDialog.offset(),
12530						left = offset.left - that.document.scrollLeft(),
12531						top = offset.top - that.document.scrollTop();
12532
12533					options.height = that.uiDialog.height();
12534					options.width = that.uiDialog.width();
12535					options.position = {
12536						my: "left top",
12537						at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12538						"top" + ( top >= 0 ? "+" : "" ) + top,
12539						of: that.window
12540					};
12541					that._removeClass( $( this ), "ui-dialog-resizing" );
12542					that._unblockFrames();
12543					that._trigger( "resizeStop", event, filteredUi( ui ) );
12544				}
12545			} )
12546				.css( "position", position );
12547		},
12548
12549		_trackFocus: function() {
12550			this._on( this.widget(), {
12551				focusin: function( event ) {
12552					this._makeFocusTarget();
12553					this._focusedElement = $( event.target );
12554				}
12555			} );
12556		},
12557
12558		_makeFocusTarget: function() {
12559			this._untrackInstance();
12560			this._trackingInstances().unshift( this );
12561		},
12562
12563		_untrackInstance: function() {
12564			var instances = this._trackingInstances(),
12565				exists = $.inArray( this, instances );
12566			if ( exists !== -1 ) {
12567				instances.splice( exists, 1 );
12568			}
12569		},
12570
12571		_trackingInstances: function() {
12572			var instances = this.document.data( "ui-dialog-instances" );
12573			if ( !instances ) {
12574				instances = [];
12575				this.document.data( "ui-dialog-instances", instances );
12576			}
12577			return instances;
12578		},
12579
12580		_minHeight: function() {
12581			var options = this.options;
12582
12583			return options.height === "auto" ?
12584				options.minHeight :
12585				Math.min( options.minHeight, options.height );
12586		},
12587
12588		_position: function() {
12589
12590			// Need to show the dialog to get the actual offset in the position plugin
12591			var isVisible = this.uiDialog.is( ":visible" );
12592			if ( !isVisible ) {
12593				this.uiDialog.show();
12594			}
12595			this.uiDialog.position( this.options.position );
12596			if ( !isVisible ) {
12597				this.uiDialog.hide();
12598			}
12599		},
12600
12601		_setOptions: function( options ) {
12602			var that = this,
12603				resize = false,
12604				resizableOptions = {};
12605
12606			$.each( options, function( key, value ) {
12607				that._setOption( key, value );
12608
12609				if ( key in that.sizeRelatedOptions ) {
12610					resize = true;
12611				}
12612				if ( key in that.resizableRelatedOptions ) {
12613					resizableOptions[ key ] = value;
12614				}
12615			} );
12616
12617			if ( resize ) {
12618				this._size();
12619				this._position();
12620			}
12621			if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12622				this.uiDialog.resizable( "option", resizableOptions );
12623			}
12624		},
12625
12626		_setOption: function( key, value ) {
12627			var isDraggable, isResizable,
12628				uiDialog = this.uiDialog;
12629
12630			if ( key === "disabled" ) {
12631				return;
12632			}
12633
12634			this._super( key, value );
12635
12636			if ( key === "appendTo" ) {
12637				this.uiDialog.appendTo( this._appendTo() );
12638			}
12639
12640			if ( key === "buttons" ) {
12641				this._createButtons();
12642			}
12643
12644			if ( key === "closeText" ) {
12645				this.uiDialogTitlebarClose.button( {
12646
12647					// Ensure that we always pass a string
12648					label: $( "<a>" ).text( "" + this.options.closeText ).html()
12649				} );
12650			}
12651
12652			if ( key === "draggable" ) {
12653				isDraggable = uiDialog.is( ":data(ui-draggable)" );
12654				if ( isDraggable && !value ) {
12655					uiDialog.draggable( "destroy" );
12656				}
12657
12658				if ( !isDraggable && value ) {
12659					this._makeDraggable();
12660				}
12661			}
12662
12663			if ( key === "position" ) {
12664				this._position();
12665			}
12666
12667			if ( key === "resizable" ) {
12668
12669				// currently resizable, becoming non-resizable
12670				isResizable = uiDialog.is( ":data(ui-resizable)" );
12671				if ( isResizable && !value ) {
12672					uiDialog.resizable( "destroy" );
12673				}
12674
12675				// Currently resizable, changing handles
12676				if ( isResizable && typeof value === "string" ) {
12677					uiDialog.resizable( "option", "handles", value );
12678				}
12679
12680				// Currently non-resizable, becoming resizable
12681				if ( !isResizable && value !== false ) {
12682					this._makeResizable();
12683				}
12684			}
12685
12686			if ( key === "title" ) {
12687				this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
12688			}
12689		},
12690
12691		_size: function() {
12692
12693			// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
12694			// divs will both have width and height set, so we need to reset them
12695			var nonContentHeight, minContentHeight, maxContentHeight,
12696				options = this.options;
12697
12698			// Reset content sizing
12699			this.element.show().css( {
12700				width: "auto",
12701				minHeight: 0,
12702				maxHeight: "none",
12703				height: 0
12704			} );
12705
12706			if ( options.minWidth > options.width ) {
12707				options.width = options.minWidth;
12708			}
12709
12710			// Reset wrapper sizing
12711			// determine the height of all the non-content elements
12712			nonContentHeight = this.uiDialog.css( {
12713				height: "auto",
12714				width: options.width
12715			} )
12716				.outerHeight();
12717			minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
12718			maxContentHeight = typeof options.maxHeight === "number" ?
12719				Math.max( 0, options.maxHeight - nonContentHeight ) :
12720				"none";
12721
12722			if ( options.height === "auto" ) {
12723				this.element.css( {
12724					minHeight: minContentHeight,
12725					maxHeight: maxContentHeight,
12726					height: "auto"
12727				} );
12728			} else {
12729				this.element.height( Math.max( 0, options.height - nonContentHeight ) );
12730			}
12731
12732			if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12733				this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
12734			}
12735		},
12736
12737		_blockFrames: function() {
12738			this.iframeBlocks = this.document.find( "iframe" ).map( function() {
12739				var iframe = $( this );
12740
12741				return $( "<div>" )
12742					.css( {
12743						position: "absolute",
12744						width: iframe.outerWidth(),
12745						height: iframe.outerHeight()
12746					} )
12747					.appendTo( iframe.parent() )
12748					.offset( iframe.offset() )[ 0 ];
12749			} );
12750		},
12751
12752		_unblockFrames: function() {
12753			if ( this.iframeBlocks ) {
12754				this.iframeBlocks.remove();
12755				delete this.iframeBlocks;
12756			}
12757		},
12758
12759		_allowInteraction: function( event ) {
12760			if ( $( event.target ).closest( ".ui-dialog" ).length ) {
12761				return true;
12762			}
12763
12764			// TODO: Remove hack when datepicker implements
12765			// the .ui-front logic (#8989)
12766			return !!$( event.target ).closest( ".ui-datepicker" ).length;
12767		},
12768
12769		_createOverlay: function() {
12770			if ( !this.options.modal ) {
12771				return;
12772			}
12773
12774			// We use a delay in case the overlay is created from an
12775			// event that we're going to be cancelling (#2804)
12776			var isOpening = true;
12777			this._delay( function() {
12778				isOpening = false;
12779			} );
12780
12781			if ( !this.document.data( "ui-dialog-overlays" ) ) {
12782
12783				// Prevent use of anchors and inputs
12784				// Using _on() for an event handler shared across many instances is
12785				// safe because the dialogs stack and must be closed in reverse order
12786				this._on( this.document, {
12787					focusin: function( event ) {
12788						if ( isOpening ) {
12789							return;
12790						}
12791
12792						if ( !this._allowInteraction( event ) ) {
12793							event.preventDefault();
12794							this._trackingInstances()[ 0 ]._focusTabbable();
12795						}
12796					}
12797				} );
12798			}
12799
12800			this.overlay = $( "<div>" )
12801				.appendTo( this._appendTo() );
12802
12803			this._addClass( this.overlay, null, "ui-widget-overlay ui-front" );
12804			this._on( this.overlay, {
12805				mousedown: "_keepFocus"
12806			} );
12807			this.document.data( "ui-dialog-overlays",
12808				( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 );
12809		},
12810
12811		_destroyOverlay: function() {
12812			if ( !this.options.modal ) {
12813				return;
12814			}
12815
12816			if ( this.overlay ) {
12817				var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
12818
12819				if ( !overlays ) {
12820					this._off( this.document, "focusin" );
12821					this.document.removeData( "ui-dialog-overlays" );
12822				} else {
12823					this.document.data( "ui-dialog-overlays", overlays );
12824				}
12825
12826				this.overlay.remove();
12827				this.overlay = null;
12828			}
12829		}
12830	} );
12831
12832// DEPRECATED
12833// TODO: switch return back to widget declaration at top of file when this is removed
12834	if ( $.uiBackCompat !== false ) {
12835
12836		// Backcompat for dialogClass option
12837		$.widget( "ui.dialog", $.ui.dialog, {
12838			options: {
12839				dialogClass: ""
12840			},
12841			_createWrapper: function() {
12842				this._super();
12843				this.uiDialog.addClass( this.options.dialogClass );
12844			},
12845			_setOption: function( key, value ) {
12846				if ( key === "dialogClass" ) {
12847					this.uiDialog
12848						.removeClass( this.options.dialogClass )
12849						.addClass( value );
12850				}
12851				this._superApply( arguments );
12852			}
12853		} );
12854	}
12855
12856	var widgetsDialog = $.ui.dialog;
12857
12858
12859	/*!
12860	 * jQuery UI Droppable 1.12.1
12861	 * http://jqueryui.com
12862	 *
12863	 * Copyright jQuery Foundation and other contributors
12864	 * Released under the MIT license.
12865	 * http://jquery.org/license
12866	 */
12867
12868//>>label: Droppable
12869//>>group: Interactions
12870//>>description: Enables drop targets for draggable elements.
12871//>>docs: http://api.jqueryui.com/droppable/
12872//>>demos: http://jqueryui.com/droppable/
12873
12874
12875
12876	$.widget( "ui.droppable", {
12877		version: "1.12.1",
12878		widgetEventPrefix: "drop",
12879		options: {
12880			accept: "*",
12881			addClasses: true,
12882			greedy: false,
12883			scope: "default",
12884			tolerance: "intersect",
12885
12886			// Callbacks
12887			activate: null,
12888			deactivate: null,
12889			drop: null,
12890			out: null,
12891			over: null
12892		},
12893		_create: function() {
12894
12895			var proportions,
12896				o = this.options,
12897				accept = o.accept;
12898
12899			this.isover = false;
12900			this.isout = true;
12901
12902			this.accept = $.isFunction( accept ) ? accept : function( d ) {
12903				return d.is( accept );
12904			};
12905
12906			this.proportions = function( /* valueToWrite */ ) {
12907				if ( arguments.length ) {
12908
12909					// Store the droppable's proportions
12910					proportions = arguments[ 0 ];
12911				} else {
12912
12913					// Retrieve or derive the droppable's proportions
12914					return proportions ?
12915						proportions :
12916						proportions = {
12917							width: this.element[ 0 ].offsetWidth,
12918							height: this.element[ 0 ].offsetHeight
12919						};
12920				}
12921			};
12922
12923			this._addToManager( o.scope );
12924
12925			o.addClasses && this._addClass( "ui-droppable" );
12926
12927		},
12928
12929		_addToManager: function( scope ) {
12930
12931			// Add the reference and positions to the manager
12932			$.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
12933			$.ui.ddmanager.droppables[ scope ].push( this );
12934		},
12935
12936		_splice: function( drop ) {
12937			var i = 0;
12938			for ( ; i < drop.length; i++ ) {
12939				if ( drop[ i ] === this ) {
12940					drop.splice( i, 1 );
12941				}
12942			}
12943		},
12944
12945		_destroy: function() {
12946			var drop = $.ui.ddmanager.droppables[ this.options.scope ];
12947
12948			this._splice( drop );
12949		},
12950
12951		_setOption: function( key, value ) {
12952
12953			if ( key === "accept" ) {
12954				this.accept = $.isFunction( value ) ? value : function( d ) {
12955					return d.is( value );
12956				};
12957			} else if ( key === "scope" ) {
12958				var drop = $.ui.ddmanager.droppables[ this.options.scope ];
12959
12960				this._splice( drop );
12961				this._addToManager( value );
12962			}
12963
12964			this._super( key, value );
12965		},
12966
12967		_activate: function( event ) {
12968			var draggable = $.ui.ddmanager.current;
12969
12970			this._addActiveClass();
12971			if ( draggable ) {
12972				this._trigger( "activate", event, this.ui( draggable ) );
12973			}
12974		},
12975
12976		_deactivate: function( event ) {
12977			var draggable = $.ui.ddmanager.current;
12978
12979			this._removeActiveClass();
12980			if ( draggable ) {
12981				this._trigger( "deactivate", event, this.ui( draggable ) );
12982			}
12983		},
12984
12985		_over: function( event ) {
12986
12987			var draggable = $.ui.ddmanager.current;
12988
12989			// Bail if draggable and droppable are same element
12990			if ( !draggable || ( draggable.currentItem ||
12991				draggable.element )[ 0 ] === this.element[ 0 ] ) {
12992				return;
12993			}
12994
12995			if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
12996				draggable.element ) ) ) {
12997				this._addHoverClass();
12998				this._trigger( "over", event, this.ui( draggable ) );
12999			}
13000
13001		},
13002
13003		_out: function( event ) {
13004
13005			var draggable = $.ui.ddmanager.current;
13006
13007			// Bail if draggable and droppable are same element
13008			if ( !draggable || ( draggable.currentItem ||
13009				draggable.element )[ 0 ] === this.element[ 0 ] ) {
13010				return;
13011			}
13012
13013			if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
13014				draggable.element ) ) ) {
13015				this._removeHoverClass();
13016				this._trigger( "out", event, this.ui( draggable ) );
13017			}
13018
13019		},
13020
13021		_drop: function( event, custom ) {
13022
13023			var draggable = custom || $.ui.ddmanager.current,
13024				childrenIntersection = false;
13025
13026			// Bail if draggable and droppable are same element
13027			if ( !draggable || ( draggable.currentItem ||
13028				draggable.element )[ 0 ] === this.element[ 0 ] ) {
13029				return false;
13030			}
13031
13032			this.element
13033				.find( ":data(ui-droppable)" )
13034				.not( ".ui-draggable-dragging" )
13035				.each( function() {
13036					var inst = $( this ).droppable( "instance" );
13037					if (
13038						inst.options.greedy &&
13039						!inst.options.disabled &&
13040						inst.options.scope === draggable.options.scope &&
13041						inst.accept.call(
13042							inst.element[ 0 ], ( draggable.currentItem || draggable.element )
13043						) &&
13044						intersect(
13045							draggable,
13046							$.extend( inst, { offset: inst.element.offset() } ),
13047							inst.options.tolerance, event
13048						)
13049					) {
13050						childrenIntersection = true;
13051						return false; }
13052				} );
13053			if ( childrenIntersection ) {
13054				return false;
13055			}
13056
13057			if ( this.accept.call( this.element[ 0 ],
13058					( draggable.currentItem || draggable.element ) ) ) {
13059				this._removeActiveClass();
13060				this._removeHoverClass();
13061
13062				this._trigger( "drop", event, this.ui( draggable ) );
13063				return this.element;
13064			}
13065
13066			return false;
13067
13068		},
13069
13070		ui: function( c ) {
13071			return {
13072				draggable: ( c.currentItem || c.element ),
13073				helper: c.helper,
13074				position: c.position,
13075				offset: c.positionAbs
13076			};
13077		},
13078
13079		// Extension points just to make backcompat sane and avoid duplicating logic
13080		// TODO: Remove in 1.13 along with call to it below
13081		_addHoverClass: function() {
13082			this._addClass( "ui-droppable-hover" );
13083		},
13084
13085		_removeHoverClass: function() {
13086			this._removeClass( "ui-droppable-hover" );
13087		},
13088
13089		_addActiveClass: function() {
13090			this._addClass( "ui-droppable-active" );
13091		},
13092
13093		_removeActiveClass: function() {
13094			this._removeClass( "ui-droppable-active" );
13095		}
13096	} );
13097
13098	var intersect = $.ui.intersect = ( function() {
13099		function isOverAxis( x, reference, size ) {
13100			return ( x >= reference ) && ( x < ( reference + size ) );
13101		}
13102
13103		return function( draggable, droppable, toleranceMode, event ) {
13104
13105			if ( !droppable.offset ) {
13106				return false;
13107			}
13108
13109			var x1 = ( draggable.positionAbs ||
13110					draggable.position.absolute ).left + draggable.margins.left,
13111				y1 = ( draggable.positionAbs ||
13112					draggable.position.absolute ).top + draggable.margins.top,
13113				x2 = x1 + draggable.helperProportions.width,
13114				y2 = y1 + draggable.helperProportions.height,
13115				l = droppable.offset.left,
13116				t = droppable.offset.top,
13117				r = l + droppable.proportions().width,
13118				b = t + droppable.proportions().height;
13119
13120			switch ( toleranceMode ) {
13121				case "fit":
13122					return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
13123				case "intersect":
13124					return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
13125					x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
13126					t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
13127					y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
13128				case "pointer":
13129					return isOverAxis( event.pageY, t, droppable.proportions().height ) &&
13130						isOverAxis( event.pageX, l, droppable.proportions().width );
13131				case "touch":
13132					return (
13133							( y1 >= t && y1 <= b ) || // Top edge touching
13134							( y2 >= t && y2 <= b ) || // Bottom edge touching
13135							( y1 < t && y2 > b ) // Surrounded vertically
13136						) && (
13137							( x1 >= l && x1 <= r ) || // Left edge touching
13138							( x2 >= l && x2 <= r ) || // Right edge touching
13139							( x1 < l && x2 > r ) // Surrounded horizontally
13140						);
13141				default:
13142					return false;
13143			}
13144		};
13145	} )();
13146
13147	/*
13148	 This manager tracks offsets of draggables and droppables
13149	 */
13150	$.ui.ddmanager = {
13151		current: null,
13152		droppables: { "default": [] },
13153		prepareOffsets: function( t, event ) {
13154
13155			var i, j,
13156				m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
13157				type = event ? event.type : null, // workaround for #2317
13158				list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
13159
13160			droppablesLoop: for ( i = 0; i < m.length; i++ ) {
13161
13162				// No disabled and non-accepted
13163				if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ],
13164						( t.currentItem || t.element ) ) ) ) {
13165					continue;
13166				}
13167
13168				// Filter out elements in the current dragged item
13169				for ( j = 0; j < list.length; j++ ) {
13170					if ( list[ j ] === m[ i ].element[ 0 ] ) {
13171						m[ i ].proportions().height = 0;
13172						continue droppablesLoop;
13173					}
13174				}
13175
13176				m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
13177				if ( !m[ i ].visible ) {
13178					continue;
13179				}
13180
13181				// Activate the droppable if used directly from draggables
13182				if ( type === "mousedown" ) {
13183					m[ i ]._activate.call( m[ i ], event );
13184				}
13185
13186				m[ i ].offset = m[ i ].element.offset();
13187				m[ i ].proportions( {
13188					width: m[ i ].element[ 0 ].offsetWidth,
13189					height: m[ i ].element[ 0 ].offsetHeight
13190				} );
13191
13192			}
13193
13194		},
13195		drop: function( draggable, event ) {
13196
13197			var dropped = false;
13198
13199			// Create a copy of the droppables in case the list changes during the drop (#9116)
13200			$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
13201
13202				if ( !this.options ) {
13203					return;
13204				}
13205				if ( !this.options.disabled && this.visible &&
13206					intersect( draggable, this, this.options.tolerance, event ) ) {
13207					dropped = this._drop.call( this, event ) || dropped;
13208				}
13209
13210				if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ],
13211						( draggable.currentItem || draggable.element ) ) ) {
13212					this.isout = true;
13213					this.isover = false;
13214					this._deactivate.call( this, event );
13215				}
13216
13217			} );
13218			return dropped;
13219
13220		},
13221		dragStart: function( draggable, event ) {
13222
13223			// Listen for scrolling so that if the dragging causes scrolling the position of the
13224			// droppables can be recalculated (see #5003)
13225			draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() {
13226				if ( !draggable.options.refreshPositions ) {
13227					$.ui.ddmanager.prepareOffsets( draggable, event );
13228				}
13229			} );
13230		},
13231		drag: function( draggable, event ) {
13232
13233			// If you have a highly dynamic page, you might try this option. It renders positions
13234			// every time you move the mouse.
13235			if ( draggable.options.refreshPositions ) {
13236				$.ui.ddmanager.prepareOffsets( draggable, event );
13237			}
13238
13239			// Run through all droppables and check their positions based on specific tolerance options
13240			$.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
13241
13242				if ( this.options.disabled || this.greedyChild || !this.visible ) {
13243					return;
13244				}
13245
13246				var parentInstance, scope, parent,
13247					intersects = intersect( draggable, this, this.options.tolerance, event ),
13248					c = !intersects && this.isover ?
13249						"isout" :
13250						( intersects && !this.isover ? "isover" : null );
13251				if ( !c ) {
13252					return;
13253				}
13254
13255				if ( this.options.greedy ) {
13256
13257					// find droppable parents with same scope
13258					scope = this.options.scope;
13259					parent = this.element.parents( ":data(ui-droppable)" ).filter( function() {
13260						return $( this ).droppable( "instance" ).options.scope === scope;
13261					} );
13262
13263					if ( parent.length ) {
13264						parentInstance = $( parent[ 0 ] ).droppable( "instance" );
13265						parentInstance.greedyChild = ( c === "isover" );
13266					}
13267				}
13268
13269				// We just moved into a greedy child
13270				if ( parentInstance && c === "isover" ) {
13271					parentInstance.isover = false;
13272					parentInstance.isout = true;
13273					parentInstance._out.call( parentInstance, event );
13274				}
13275
13276				this[ c ] = true;
13277				this[ c === "isout" ? "isover" : "isout" ] = false;
13278				this[ c === "isover" ? "_over" : "_out" ].call( this, event );
13279
13280				// We just moved out of a greedy child
13281				if ( parentInstance && c === "isout" ) {
13282					parentInstance.isout = false;
13283					parentInstance.isover = true;
13284					parentInstance._over.call( parentInstance, event );
13285				}
13286			} );
13287
13288		},
13289		dragStop: function( draggable, event ) {
13290			draggable.element.parentsUntil( "body" ).off( "scroll.droppable" );
13291
13292			// Call prepareOffsets one final time since IE does not fire return scroll events when
13293			// overflow was caused by drag (see #5003)
13294			if ( !draggable.options.refreshPositions ) {
13295				$.ui.ddmanager.prepareOffsets( draggable, event );
13296			}
13297		}
13298	};
13299
13300// DEPRECATED
13301// TODO: switch return back to widget declaration at top of file when this is removed
13302	if ( $.uiBackCompat !== false ) {
13303
13304		// Backcompat for activeClass and hoverClass options
13305		$.widget( "ui.droppable", $.ui.droppable, {
13306			options: {
13307				hoverClass: false,
13308				activeClass: false
13309			},
13310			_addActiveClass: function() {
13311				this._super();
13312				if ( this.options.activeClass ) {
13313					this.element.addClass( this.options.activeClass );
13314				}
13315			},
13316			_removeActiveClass: function() {
13317				this._super();
13318				if ( this.options.activeClass ) {
13319					this.element.removeClass( this.options.activeClass );
13320				}
13321			},
13322			_addHoverClass: function() {
13323				this._super();
13324				if ( this.options.hoverClass ) {
13325					this.element.addClass( this.options.hoverClass );
13326				}
13327			},
13328			_removeHoverClass: function() {
13329				this._super();
13330				if ( this.options.hoverClass ) {
13331					this.element.removeClass( this.options.hoverClass );
13332				}
13333			}
13334		} );
13335	}
13336
13337	var widgetsDroppable = $.ui.droppable;
13338
13339
13340	/*!
13341	 * jQuery UI Progressbar 1.12.1
13342	 * http://jqueryui.com
vendor: 12,556 bytes, lines 13343-13801
13343	 *
13344	 * Copyright jQuery Foundation and other contributors
13345	 * Released under the MIT license.
13346	 * http://jquery.org/license
13347	 */
13348
13349//>>label: Progressbar
13350//>>group: Widgets
13351// jscs:disable maximumLineLength
13352//>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators.
13353// jscs:enable maximumLineLength
13354//>>docs: http://api.jqueryui.com/progressbar/
13355//>>demos: http://jqueryui.com/progressbar/
13356//>>css.structure: ../../themes/base/core.css
13357//>>css.structure: ../../themes/base/progressbar.css
13358//>>css.theme: ../../themes/base/theme.css
13359
13360
13361
13362	var widgetsProgressbar = $.widget( "ui.progressbar", {
13363		version: "1.12.1",
13364		options: {
13365			classes: {
13366				"ui-progressbar": "ui-corner-all",
13367				"ui-progressbar-value": "ui-corner-left",
13368				"ui-progressbar-complete": "ui-corner-right"
13369			},
13370			max: 100,
13371			value: 0,
13372
13373			change: null,
13374			complete: null
13375		},
13376
13377		min: 0,
13378
13379		_create: function() {
13380
13381			// Constrain initial value
13382			this.oldValue = this.options.value = this._constrainedValue();
13383
13384			this.element.attr( {
13385
13386				// Only set static values; aria-valuenow and aria-valuemax are
13387				// set inside _refreshValue()
13388				role: "progressbar",
13389				"aria-valuemin": this.min
13390			} );
13391			this._addClass( "ui-progressbar", "ui-widget ui-widget-content" );
13392
13393			this.valueDiv = $( "<div>" ).appendTo( this.element );
13394			this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" );
13395			this._refreshValue();
13396		},
13397
13398		_destroy: function() {
13399			this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" );
13400
13401			this.valueDiv.remove();
13402		},
13403
13404		value: function( newValue ) {
13405			if ( newValue === undefined ) {
13406				return this.options.value;
13407			}
13408
13409			this.options.value = this._constrainedValue( newValue );
13410			this._refreshValue();
13411		},
13412
13413		_constrainedValue: function( newValue ) {
13414			if ( newValue === undefined ) {
13415				newValue = this.options.value;
13416			}
13417
13418			this.indeterminate = newValue === false;
13419
13420			// Sanitize value
13421			if ( typeof newValue !== "number" ) {
13422				newValue = 0;
13423			}
13424
13425			return this.indeterminate ? false :
13426				Math.min( this.options.max, Math.max( this.min, newValue ) );
13427		},
13428
13429		_setOptions: function( options ) {
13430
13431			// Ensure "value" option is set after other values (like max)
13432			var value = options.value;
13433			delete options.value;
13434
13435			this._super( options );
13436
13437			this.options.value = this._constrainedValue( value );
13438			this._refreshValue();
13439		},
13440
13441		_setOption: function( key, value ) {
13442			if ( key === "max" ) {
13443
13444				// Don't allow a max less than min
13445				value = Math.max( this.min, value );
13446			}
13447			this._super( key, value );
13448		},
13449
13450		_setOptionDisabled: function( value ) {
13451			this._super( value );
13452
13453			this.element.attr( "aria-disabled", value );
13454			this._toggleClass( null, "ui-state-disabled", !!value );
13455		},
13456
13457		_percentage: function() {
13458			return this.indeterminate ?
13459				100 :
13460			100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
13461		},
13462
13463		_refreshValue: function() {
13464			var value = this.options.value,
13465				percentage = this._percentage();
13466
13467			this.valueDiv
13468				.toggle( this.indeterminate || value > this.min )
13469				.width( percentage.toFixed( 0 ) + "%" );
13470
13471			this
13472				._toggleClass( this.valueDiv, "ui-progressbar-complete", null,
13473				value === this.options.max )
13474				._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate );
13475
13476			if ( this.indeterminate ) {
13477				this.element.removeAttr( "aria-valuenow" );
13478				if ( !this.overlayDiv ) {
13479					this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv );
13480					this._addClass( this.overlayDiv, "ui-progressbar-overlay" );
13481				}
13482			} else {
13483				this.element.attr( {
13484					"aria-valuemax": this.options.max,
13485					"aria-valuenow": value
13486				} );
13487				if ( this.overlayDiv ) {
13488					this.overlayDiv.remove();
13489					this.overlayDiv = null;
13490				}
13491			}
13492
13493			if ( this.oldValue !== value ) {
13494				this.oldValue = value;
13495				this._trigger( "change" );
13496			}
13497			if ( value === this.options.max ) {
13498				this._trigger( "complete" );
13499			}
13500		}
13501	} );
13502
13503
13504	/*!
13505	 * jQuery UI Selectable 1.12.1
13506	 * http://jqueryui.com
13507	 *
13508	 * Copyright jQuery Foundation and other contributors
13509	 * Released under the MIT license.
13510	 * http://jquery.org/license
13511	 */
13512
13513//>>label: Selectable
13514//>>group: Interactions
13515//>>description: Allows groups of elements to be selected with the mouse.
13516//>>docs: http://api.jqueryui.com/selectable/
13517//>>demos: http://jqueryui.com/selectable/
13518//>>css.structure: ../../themes/base/selectable.css
13519
13520
13521
13522	var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, {
13523		version: "1.12.1",
13524		options: {
13525			appendTo: "body",
13526			autoRefresh: true,
13527			distance: 0,
13528			filter: "*",
13529			tolerance: "touch",
13530
13531			// Callbacks
13532			selected: null,
13533			selecting: null,
13534			start: null,
13535			stop: null,
13536			unselected: null,
13537			unselecting: null
13538		},
13539		_create: function() {
13540			var that = this;
13541
13542			this._addClass( "ui-selectable" );
13543
13544			this.dragged = false;
13545
13546			// Cache selectee children based on filter
13547			this.refresh = function() {
13548				that.elementPos = $( that.element[ 0 ] ).offset();
13549				that.selectees = $( that.options.filter, that.element[ 0 ] );
13550				that._addClass( that.selectees, "ui-selectee" );
13551				that.selectees.each( function() {
13552					var $this = $( this ),
13553						selecteeOffset = $this.offset(),
13554						pos = {
13555							left: selecteeOffset.left - that.elementPos.left,
13556							top: selecteeOffset.top - that.elementPos.top
13557						};
13558					$.data( this, "selectable-item", {
13559						element: this,
13560						$element: $this,
13561						left: pos.left,
13562						top: pos.top,
13563						right: pos.left + $this.outerWidth(),
13564						bottom: pos.top + $this.outerHeight(),
13565						startselected: false,
13566						selected: $this.hasClass( "ui-selected" ),
13567						selecting: $this.hasClass( "ui-selecting" ),
13568						unselecting: $this.hasClass( "ui-unselecting" )
13569					} );
13570				} );
13571			};
13572			this.refresh();
13573
13574			this._mouseInit();
13575
13576			this.helper = $( "<div>" );
13577			this._addClass( this.helper, "ui-selectable-helper" );
13578		},
13579
13580		_destroy: function() {
13581			this.selectees.removeData( "selectable-item" );
13582			this._mouseDestroy();
13583		},
13584
13585		_mouseStart: function( event ) {
13586			var that = this,
13587				options = this.options;
13588
13589			this.opos = [ event.pageX, event.pageY ];
13590			this.elementPos = $( this.element[ 0 ] ).offset();
13591
13592			if ( this.options.disabled ) {
13593				return;
13594			}
13595
13596			this.selectees = $( options.filter, this.element[ 0 ] );
13597
13598			this._trigger( "start", event );
13599
13600			$( options.appendTo ).append( this.helper );
13601
13602			// position helper (lasso)
13603			this.helper.css( {
13604				"left": event.pageX,
13605				"top": event.pageY,
13606				"width": 0,
13607				"height": 0
13608			} );
13609
13610			if ( options.autoRefresh ) {
13611				this.refresh();
13612			}
13613
13614			this.selectees.filter( ".ui-selected" ).each( function() {
13615				var selectee = $.data( this, "selectable-item" );
13616				selectee.startselected = true;
13617				if ( !event.metaKey && !event.ctrlKey ) {
13618					that._removeClass( selectee.$element, "ui-selected" );
13619					selectee.selected = false;
13620					that._addClass( selectee.$element, "ui-unselecting" );
13621					selectee.unselecting = true;
13622
13623					// selectable UNSELECTING callback
13624					that._trigger( "unselecting", event, {
13625						unselecting: selectee.element
13626					} );
13627				}
13628			} );
13629
13630			$( event.target ).parents().addBack().each( function() {
13631				var doSelect,
13632					selectee = $.data( this, "selectable-item" );
13633				if ( selectee ) {
13634					doSelect = ( !event.metaKey && !event.ctrlKey ) ||
13635						!selectee.$element.hasClass( "ui-selected" );
13636					that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
13637						._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
13638					selectee.unselecting = !doSelect;
13639					selectee.selecting = doSelect;
13640					selectee.selected = doSelect;
13641
13642					// selectable (UN)SELECTING callback
13643					if ( doSelect ) {
13644						that._trigger( "selecting", event, {
13645							selecting: selectee.element
13646						} );
13647					} else {
13648						that._trigger( "unselecting", event, {
13649							unselecting: selectee.element
13650						} );
13651					}
13652					return false;
13653				}
13654			} );
13655
13656		},
13657
13658		_mouseDrag: function( event ) {
13659
13660			this.dragged = true;
13661
13662			if ( this.options.disabled ) {
13663				return;
13664			}
13665
13666			var tmp,
13667				that = this,
13668				options = this.options,
13669				x1 = this.opos[ 0 ],
13670				y1 = this.opos[ 1 ],
13671				x2 = event.pageX,
13672				y2 = event.pageY;
13673
13674			if ( x1 > x2 ) { tmp = x2; x2 = x1; x1 = tmp; }
13675			if ( y1 > y2 ) { tmp = y2; y2 = y1; y1 = tmp; }
13676			this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
13677
13678			this.selectees.each( function() {
13679				var selectee = $.data( this, "selectable-item" ),
13680					hit = false,
13681					offset = {};
13682
13683				//prevent helper from being selected if appendTo: selectable
13684				if ( !selectee || selectee.element === that.element[ 0 ] ) {
13685					return;
13686				}
13687
13688				offset.left   = selectee.left   + that.elementPos.left;
13689				offset.right  = selectee.right  + that.elementPos.left;
13690				offset.top    = selectee.top    + that.elementPos.top;
13691				offset.bottom = selectee.bottom + that.elementPos.top;
13692
13693				if ( options.tolerance === "touch" ) {
13694					hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
13695					offset.bottom < y1 ) );
13696				} else if ( options.tolerance === "fit" ) {
13697					hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
13698					offset.bottom < y2 );
13699				}
13700
13701				if ( hit ) {
13702
13703					// SELECT
13704					if ( selectee.selected ) {
13705						that._removeClass( selectee.$element, "ui-selected" );
13706						selectee.selected = false;
13707					}
13708					if ( selectee.unselecting ) {
13709						that._removeClass( selectee.$element, "ui-unselecting" );
13710						selectee.unselecting = false;
13711					}
13712					if ( !selectee.selecting ) {
13713						that._addClass( selectee.$element, "ui-selecting" );
13714						selectee.selecting = true;
13715
13716						// selectable SELECTING callback
13717						that._trigger( "selecting", event, {
13718							selecting: selectee.element
13719						} );
13720					}
13721				} else {
13722
13723					// UNSELECT
13724					if ( selectee.selecting ) {
13725						if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
13726							that._removeClass( selectee.$element, "ui-selecting" );
13727							selectee.selecting = false;
13728							that._addClass( selectee.$element, "ui-selected" );
13729							selectee.selected = true;
13730						} else {
13731							that._removeClass( selectee.$element, "ui-selecting" );
13732							selectee.selecting = false;
13733							if ( selectee.startselected ) {
13734								that._addClass( selectee.$element, "ui-unselecting" );
13735								selectee.unselecting = true;
13736							}
13737
13738							// selectable UNSELECTING callback
13739							that._trigger( "unselecting", event, {
13740								unselecting: selectee.element
13741							} );
13742						}
13743					}
13744					if ( selectee.selected ) {
13745						if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
13746							that._removeClass( selectee.$element, "ui-selected" );
13747							selectee.selected = false;
13748
13749							that._addClass( selectee.$element, "ui-unselecting" );
13750							selectee.unselecting = true;
13751
13752							// selectable UNSELECTING callback
13753							that._trigger( "unselecting", event, {
13754								unselecting: selectee.element
13755							} );
13756						}
13757					}
13758				}
13759			} );
13760
13761			return false;
13762		},
13763
13764		_mouseStop: function( event ) {
13765			var that = this;
13766
13767			this.dragged = false;
13768
13769			$( ".ui-unselecting", this.element[ 0 ] ).each( function() {
13770				var selectee = $.data( this, "selectable-item" );
13771				that._removeClass( selectee.$element, "ui-unselecting" );
13772				selectee.unselecting = false;
13773				selectee.startselected = false;
13774				that._trigger( "unselected", event, {
13775					unselected: selectee.element
13776				} );
13777			} );
13778			$( ".ui-selecting", this.element[ 0 ] ).each( function() {
13779				var selectee = $.data( this, "selectable-item" );
13780				that._removeClass( selectee.$element, "ui-selecting" )
13781					._addClass( selectee.$element, "ui-selected" );
13782				selectee.selecting = false;
13783				selectee.selected = true;
13784				selectee.startselected = true;
13785				that._trigger( "selected", event, {
13786					selected: selectee.element
13787				} );
13788			} );
13789			this._trigger( "stop", event );
13790
13791			this.helper.remove();
13792
13793			return false;
13794		}
13795
13796	} );
13797
13798
13799	/*!
13800	 * jQuery UI Selectmenu 1.12.1
13801	 * http://jqueryui.com
vendor: 5,706 bytes, lines 13802-14008
13802	 *
13803	 * Copyright jQuery Foundation and other contributors
13804	 * Released under the MIT license.
13805	 * http://jquery.org/license
13806	 */
13807
13808//>>label: Selectmenu
13809//>>group: Widgets
13810// jscs:disable maximumLineLength
13811//>>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.
13812// jscs:enable maximumLineLength
13813//>>docs: http://api.jqueryui.com/selectmenu/
13814//>>demos: http://jqueryui.com/selectmenu/
13815//>>css.structure: ../../themes/base/core.css
13816//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css
13817//>>css.theme: ../../themes/base/theme.css
13818
13819
13820
13821	var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
13822		version: "1.12.1",
13823		defaultElement: "<select>",
13824		options: {
13825			appendTo: null,
13826			classes: {
13827				"ui-selectmenu-button-open": "ui-corner-top",
13828				"ui-selectmenu-button-closed": "ui-corner-all"
13829			},
13830			disabled: null,
13831			icons: {
13832				button: "ui-icon-triangle-1-s"
13833			},
13834			position: {
13835				my: "left top",
13836				at: "left bottom",
13837				collision: "none"
13838			},
13839			width: false,
13840
13841			// Callbacks
13842			change: null,
13843			close: null,
13844			focus: null,
13845			open: null,
13846			select: null
13847		},
13848
13849		_create: function() {
13850			var selectmenuId = this.element.uniqueId().attr( "id" );
13851			this.ids = {
13852				element: selectmenuId,
13853				button: selectmenuId + "-button",
13854				menu: selectmenuId + "-menu"
13855			};
13856
13857			this._drawButton();
13858			this._drawMenu();
13859			this._bindFormResetHandler();
13860
13861			this._rendered = false;
13862			this.menuItems = $();
13863		},
13864
13865		_drawButton: function() {
13866			var icon,
13867				that = this,
13868				item = this._parseOption(
13869					this.element.find( "option:selected" ),
13870					this.element[ 0 ].selectedIndex
13871				);
13872
13873			// Associate existing label with the new button
13874			this.labels = this.element.labels().attr( "for", this.ids.button );
13875			this._on( this.labels, {
13876				click: function( event ) {
13877					this.button.focus();
13878					event.preventDefault();
13879				}
13880			} );
13881
13882			// Hide original select element
13883			this.element.hide();
13884
13885			// Create button
13886			this.button = $( "<span>", {
13887				tabindex: this.options.disabled ? -1 : 0,
13888				id: this.ids.button,
13889				role: "combobox",
13890				"aria-expanded": "false",
13891				"aria-autocomplete": "list",
13892				"aria-owns": this.ids.menu,
13893				"aria-haspopup": "true",
13894				title: this.element.attr( "title" )
13895			} )
13896				.insertAfter( this.element );
13897
13898			this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed",
13899				"ui-button ui-widget" );
13900
13901			icon = $( "<span>" ).appendTo( this.button );
13902			this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button );
13903			this.buttonItem = this._renderButtonItem( item )
13904				.appendTo( this.button );
13905
13906			if ( this.options.width !== false ) {
13907				this._resizeButton();
13908			}
13909
13910			this._on( this.button, this._buttonEvents );
13911			this.button.one( "focusin", function() {
13912
13913				// Delay rendering the menu items until the button receives focus.
13914				// The menu may have already been rendered via a programmatic open.
13915				if ( !that._rendered ) {
13916					that._refreshMenu();
13917				}
13918			} );
13919		},
13920
13921		_drawMenu: function() {
13922			var that = this;
13923
13924			// Create menu
13925			this.menu = $( "<ul>", {
13926				"aria-hidden": "true",
13927				"aria-labelledby": this.ids.button,
13928				id: this.ids.menu
13929			} );
13930
13931			// Wrap menu
13932			this.menuWrap = $( "<div>" ).append( this.menu );
13933			this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" );
13934			this.menuWrap.appendTo( this._appendTo() );
13935
13936			// Initialize menu widget
13937			this.menuInstance = this.menu
13938				.menu( {
13939					classes: {
13940						"ui-menu": "ui-corner-bottom"
13941					},
13942					role: "listbox",
13943					select: function( event, ui ) {
13944						event.preventDefault();
13945
13946						// Support: IE8
13947						// If the item was selected via a click, the text selection
13948						// will be destroyed in IE
13949						that._setSelection();
13950
13951						that._select( ui.item.data( "ui-selectmenu-item" ), event );
13952					},
13953					focus: function( event, ui ) {
13954						var item = ui.item.data( "ui-selectmenu-item" );
13955
13956						// Prevent inital focus from firing and check if its a newly focused item
13957						if ( that.focusIndex != null && item.index !== that.focusIndex ) {
13958							that._trigger( "focus", event, { item: item } );
13959							if ( !that.isOpen ) {
13960								that._select( item, event );
13961							}
13962						}
13963						that.focusIndex = item.index;
13964
13965						that.button.attr( "aria-activedescendant",
13966							that.menuItems.eq( item.index ).attr( "id" ) );
13967					}
13968				} )
13969				.menu( "instance" );
13970
13971			// Don't close the menu on mouseleave
13972			this.menuInstance._off( this.menu, "mouseleave" );
13973
13974			// Cancel the menu's collapseAll on document click
13975			this.menuInstance._closeOnDocumentClick = function() {
13976				return false;
13977			};
13978
13979			// Selects often contain empty items, but never contain dividers
13980			this.menuInstance._isDivider = function() {
13981				return false;
13982			};
13983		},
13984
13985		refresh: function() {
13986			this._refreshMenu();
13987			this.buttonItem.replaceWith(
13988				this.buttonItem = this._renderButtonItem(
13989
13990					// Fall back to an empty object in case there are no options
13991					this._getSelectedItem().data( "ui-selectmenu-item" ) || {}
13992				)
13993			);
13994			if ( this.options.width === null ) {
13995				this._resizeButton();
13996			}
13997		},
13998
13999		_refreshMenu: function() {
14000			var item,
14001				options = this.element.find( "option" );
14002
14003			this.menu.empty();
14004
14005			this._parseOptions( options );
14006			this._renderMenu( this.menu, this.items );
14007
14008			this.menuInstance.refresh();
vendor: 10,144 bytes, lines 14009-14416
14009			this.menuItems = this.menu.find( "li" )
14010				.not( ".ui-selectmenu-optgroup" )
14011				.find( ".ui-menu-item-wrapper" );
14012
14013			this._rendered = true;
14014
14015			if ( !options.length ) {
14016				return;
14017			}
14018
14019			item = this._getSelectedItem();
14020
14021			// Update the menu to have the correct item focused
14022			this.menuInstance.focus( null, item );
14023			this._setAria( item.data( "ui-selectmenu-item" ) );
14024
14025			// Set disabled state
14026			this._setOption( "disabled", this.element.prop( "disabled" ) );
14027		},
14028
14029		open: function( event ) {
14030			if ( this.options.disabled ) {
14031				return;
14032			}
14033
14034			// If this is the first time the menu is being opened, render the items
14035			if ( !this._rendered ) {
14036				this._refreshMenu();
14037			} else {
14038
14039				// Menu clears focus on close, reset focus to selected item
14040				this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" );
14041				this.menuInstance.focus( null, this._getSelectedItem() );
14042			}
14043
14044			// If there are no options, don't open the menu
14045			if ( !this.menuItems.length ) {
14046				return;
14047			}
14048
14049			this.isOpen = true;
14050			this._toggleAttr();
14051			this._resizeMenu();
14052			this._position();
14053
14054			this._on( this.document, this._documentClick );
14055
14056			this._trigger( "open", event );
14057		},
14058
14059		_position: function() {
14060			this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
14061		},
14062
14063		close: function( event ) {
14064			if ( !this.isOpen ) {
14065				return;
14066			}
14067
14068			this.isOpen = false;
14069			this._toggleAttr();
14070
14071			this.range = null;
14072			this._off( this.document );
14073
14074			this._trigger( "close", event );
14075		},
14076
14077		widget: function() {
14078			return this.button;
14079		},
14080
14081		menuWidget: function() {
14082			return this.menu;
14083		},
14084
14085		_renderButtonItem: function( item ) {
14086			var buttonItem = $( "<span>" );
14087
14088			this._setText( buttonItem, item.label );
14089			this._addClass( buttonItem, "ui-selectmenu-text" );
14090
14091			return buttonItem;
14092		},
14093
14094		_renderMenu: function( ul, items ) {
14095			var that = this,
14096				currentOptgroup = "";
14097
14098			$.each( items, function( index, item ) {
14099				var li;
14100
14101				if ( item.optgroup !== currentOptgroup ) {
14102					li = $( "<li>", {
14103						text: item.optgroup
14104					} );
14105					that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" +
14106						( item.element.parent( "optgroup" ).prop( "disabled" ) ?
14107							" ui-state-disabled" :
14108							"" ) );
14109
14110					li.appendTo( ul );
14111
14112					currentOptgroup = item.optgroup;
14113				}
14114
14115				that._renderItemData( ul, item );
14116			} );
14117		},
14118
14119		_renderItemData: function( ul, item ) {
14120			return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
14121		},
14122
14123		_renderItem: function( ul, item ) {
14124			var li = $( "<li>" ),
14125				wrapper = $( "<div>", {
14126					title: item.element.attr( "title" )
14127				} );
14128
14129			if ( item.disabled ) {
14130				this._addClass( li, null, "ui-state-disabled" );
14131			}
14132			this._setText( wrapper, item.label );
14133
14134			return li.append( wrapper ).appendTo( ul );
14135		},
14136
14137		_setText: function( element, value ) {
14138			if ( value ) {
14139				element.text( value );
14140			} else {
14141				element.html( "&#160;" );
14142			}
14143		},
14144
14145		_move: function( direction, event ) {
14146			var item, next,
14147				filter = ".ui-menu-item";
14148
14149			if ( this.isOpen ) {
14150				item = this.menuItems.eq( this.focusIndex ).parent( "li" );
14151			} else {
14152				item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
14153				filter += ":not(.ui-state-disabled)";
14154			}
14155
14156			if ( direction === "first" || direction === "last" ) {
14157				next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
14158			} else {
14159				next = item[ direction + "All" ]( filter ).eq( 0 );
14160			}
14161
14162			if ( next.length ) {
14163				this.menuInstance.focus( event, next );
14164			}
14165		},
14166
14167		_getSelectedItem: function() {
14168			return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
14169		},
14170
14171		_toggle: function( event ) {
14172			this[ this.isOpen ? "close" : "open" ]( event );
14173		},
14174
14175		_setSelection: function() {
14176			var selection;
14177
14178			if ( !this.range ) {
14179				return;
14180			}
14181
14182			if ( window.getSelection ) {
14183				selection = window.getSelection();
14184				selection.removeAllRanges();
14185				selection.addRange( this.range );
14186
14187				// Support: IE8
14188			} else {
14189				this.range.select();
14190			}
14191
14192			// Support: IE
14193			// Setting the text selection kills the button focus in IE, but
14194			// restoring the focus doesn't kill the selection.
14195			this.button.focus();
14196		},
14197
14198		_documentClick: {
14199			mousedown: function( event ) {
14200				if ( !this.isOpen ) {
14201					return;
14202				}
14203
14204				if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" +
14205						$.ui.escapeSelector( this.ids.button ) ).length ) {
14206					this.close( event );
14207				}
14208			}
14209		},
14210
14211		_buttonEvents: {
14212
14213			// Prevent text selection from being reset when interacting with the selectmenu (#10144)
14214			mousedown: function() {
14215				var selection;
14216
14217				if ( window.getSelection ) {
14218					selection = window.getSelection();
14219					if ( selection.rangeCount ) {
14220						this.range = selection.getRangeAt( 0 );
14221					}
14222
14223					// Support: IE8
14224				} else {
14225					this.range = document.selection.createRange();
14226				}
14227			},
14228
14229			click: function( event ) {
14230				this._setSelection();
14231				this._toggle( event );
14232			},
14233
14234			keydown: function( event ) {
14235				var preventDefault = true;
14236				switch ( event.keyCode ) {
14237					case $.ui.keyCode.TAB:
14238					case $.ui.keyCode.ESCAPE:
14239						this.close( event );
14240						preventDefault = false;
14241						break;
14242					case $.ui.keyCode.ENTER:
14243						if ( this.isOpen ) {
14244							this._selectFocusedItem( event );
14245						}
14246						break;
14247					case $.ui.keyCode.UP:
14248						if ( event.altKey ) {
14249							this._toggle( event );
14250						} else {
14251							this._move( "prev", event );
14252						}
14253						break;
14254					case $.ui.keyCode.DOWN:
14255						if ( event.altKey ) {
14256							this._toggle( event );
14257						} else {
14258							this._move( "next", event );
14259						}
14260						break;
14261					case $.ui.keyCode.SPACE:
14262						if ( this.isOpen ) {
14263							this._selectFocusedItem( event );
14264						} else {
14265							this._toggle( event );
14266						}
14267						break;
14268					case $.ui.keyCode.LEFT:
14269						this._move( "prev", event );
14270						break;
14271					case $.ui.keyCode.RIGHT:
14272						this._move( "next", event );
14273						break;
14274					case $.ui.keyCode.HOME:
14275					case $.ui.keyCode.PAGE_UP:
14276						this._move( "first", event );
14277						break;
14278					case $.ui.keyCode.END:
14279					case $.ui.keyCode.PAGE_DOWN:
14280						this._move( "last", event );
14281						break;
14282					default:
14283						this.menu.trigger( event );
14284						preventDefault = false;
14285				}
14286
14287				if ( preventDefault ) {
14288					event.preventDefault();
14289				}
14290			}
14291		},
14292
14293		_selectFocusedItem: function( event ) {
14294			var item = this.menuItems.eq( this.focusIndex ).parent( "li" );
14295			if ( !item.hasClass( "ui-state-disabled" ) ) {
14296				this._select( item.data( "ui-selectmenu-item" ), event );
14297			}
14298		},
14299
14300		_select: function( item, event ) {
14301			var oldIndex = this.element[ 0 ].selectedIndex;
14302
14303			// Change native select element
14304			this.element[ 0 ].selectedIndex = item.index;
14305			this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) );
14306			this._setAria( item );
14307			this._trigger( "select", event, { item: item } );
14308
14309			if ( item.index !== oldIndex ) {
14310				this._trigger( "change", event, { item: item } );
14311			}
14312
14313			this.close( event );
14314		},
14315
14316		_setAria: function( item ) {
14317			var id = this.menuItems.eq( item.index ).attr( "id" );
14318
14319			this.button.attr( {
14320				"aria-labelledby": id,
14321				"aria-activedescendant": id
14322			} );
14323			this.menu.attr( "aria-activedescendant", id );
14324		},
14325
14326		_setOption: function( key, value ) {
14327			if ( key === "icons" ) {
14328				var icon = this.button.find( "span.ui-icon" );
14329				this._removeClass( icon, null, this.options.icons.button )
14330					._addClass( icon, null, value.button );
14331			}
14332
14333			this._super( key, value );
14334
14335			if ( key === "appendTo" ) {
14336				this.menuWrap.appendTo( this._appendTo() );
14337			}
14338
14339			if ( key === "width" ) {
14340				this._resizeButton();
14341			}
14342		},
14343
14344		_setOptionDisabled: function( value ) {
14345			this._super( value );
14346
14347			this.menuInstance.option( "disabled", value );
14348			this.button.attr( "aria-disabled", value );
14349			this._toggleClass( this.button, null, "ui-state-disabled", value );
14350
14351			this.element.prop( "disabled", value );
14352			if ( value ) {
14353				this.button.attr( "tabindex", -1 );
14354				this.close();
14355			} else {
14356				this.button.attr( "tabindex", 0 );
14357			}
14358		},
14359
14360		_appendTo: function() {
14361			var element = this.options.appendTo;
14362
14363			if ( element ) {
14364				element = element.jquery || element.nodeType ?
14365					$( element ) :
14366					this.document.find( element ).eq( 0 );
14367			}
14368
14369			if ( !element || !element[ 0 ] ) {
14370				element = this.element.closest( ".ui-front, dialog" );
14371			}
14372
14373			if ( !element.length ) {
14374				element = this.document[ 0 ].body;
14375			}
14376
14377			return element;
14378		},
14379
14380		_toggleAttr: function() {
14381			this.button.attr( "aria-expanded", this.isOpen );
14382
14383			// We can't use two _toggleClass() calls here, because we need to make sure
14384			// we always remove classes first and add them second, otherwise if both classes have the
14385			// same theme class, it will be removed after we add it.
14386			this._removeClass( this.button, "ui-selectmenu-button-" +
14387				( this.isOpen ? "closed" : "open" ) )
14388				._addClass( this.button, "ui-selectmenu-button-" +
14389				( this.isOpen ? "open" : "closed" ) )
14390				._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen );
14391
14392			this.menu.attr( "aria-hidden", !this.isOpen );
14393		},
14394
14395		_resizeButton: function() {
14396			var width = this.options.width;
14397
14398			// For `width: false`, just remove inline style and stop
14399			if ( width === false ) {
14400				this.button.css( "width", "" );
14401				return;
14402			}
14403
14404			// For `width: null`, match the width of the original element
14405			if ( width === null ) {
14406				width = this.element.show().outerWidth();
14407				this.element.hide();
14408			}
14409
14410			this.button.outerWidth( width );
14411		},
14412
14413		_resizeMenu: function() {
14414			this.menu.outerWidth( Math.max(
14415				this.button.outerWidth(),
14416
vendor: 5,557 bytes, lines 14417-14630
14417				// Support: IE10
14418				// IE10 wraps long text (possibly a rounding bug)
14419				// so we add 1px to avoid the wrapping
14420				this.menu.width( "" ).outerWidth() + 1
14421			) );
14422		},
14423
14424		_getCreateOptions: function() {
14425			var options = this._super();
14426
14427			options.disabled = this.element.prop( "disabled" );
14428
14429			return options;
14430		},
14431
14432		_parseOptions: function( options ) {
14433			var that = this,
14434				data = [];
14435			options.each( function( index, item ) {
14436				data.push( that._parseOption( $( item ), index ) );
14437			} );
14438			this.items = data;
14439		},
14440
14441		_parseOption: function( option, index ) {
14442			var optgroup = option.parent( "optgroup" );
14443
14444			return {
14445				element: option,
14446				index: index,
14447				value: option.val(),
14448				label: option.text(),
14449				optgroup: optgroup.attr( "label" ) || "",
14450				disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
14451			};
14452		},
14453
14454		_destroy: function() {
14455			this._unbindFormResetHandler();
14456			this.menuWrap.remove();
14457			this.button.remove();
14458			this.element.show();
14459			this.element.removeUniqueId();
14460			this.labels.attr( "for", this.ids.element );
14461		}
14462	} ] );
14463
14464
14465	/*!
14466	 * jQuery UI Slider 1.12.1
14467	 * http://jqueryui.com
14468	 *
14469	 * Copyright jQuery Foundation and other contributors
14470	 * Released under the MIT license.
14471	 * http://jquery.org/license
14472	 */
14473
14474//>>label: Slider
14475//>>group: Widgets
14476//>>description: Displays a flexible slider with ranges and accessibility via keyboard.
14477//>>docs: http://api.jqueryui.com/slider/
14478//>>demos: http://jqueryui.com/slider/
14479//>>css.structure: ../../themes/base/core.css
14480//>>css.structure: ../../themes/base/slider.css
14481//>>css.theme: ../../themes/base/theme.css
14482
14483
14484
14485	var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, {
14486		version: "1.12.1",
14487		widgetEventPrefix: "slide",
14488
14489		options: {
14490			animate: false,
14491			classes: {
14492				"ui-slider": "ui-corner-all",
14493				"ui-slider-handle": "ui-corner-all",
14494
14495				// Note: ui-widget-header isn't the most fittingly semantic framework class for this
14496				// element, but worked best visually with a variety of themes
14497				"ui-slider-range": "ui-corner-all ui-widget-header"
14498			},
14499			distance: 0,
14500			max: 100,
14501			min: 0,
14502			orientation: "horizontal",
14503			range: false,
14504			step: 1,
14505			value: 0,
14506			values: null,
14507
14508			// Callbacks
14509			change: null,
14510			slide: null,
14511			start: null,
14512			stop: null
14513		},
14514
14515		// Number of pages in a slider
14516		// (how many times can you page up/down to go through the whole range)
14517		numPages: 5,
14518
14519		_create: function() {
14520			this._keySliding = false;
14521			this._mouseSliding = false;
14522			this._animateOff = true;
14523			this._handleIndex = null;
14524			this._detectOrientation();
14525			this._mouseInit();
14526			this._calculateNewMax();
14527
14528			this._addClass( "ui-slider ui-slider-" + this.orientation,
14529				"ui-widget ui-widget-content" );
14530
14531			this._refresh();
14532
14533			this._animateOff = false;
14534		},
14535
14536		_refresh: function() {
14537			this._createRange();
14538			this._createHandles();
14539			this._setupEvents();
14540			this._refreshValue();
14541		},
14542
14543		_createHandles: function() {
14544			var i, handleCount,
14545				options = this.options,
14546				existingHandles = this.element.find( ".ui-slider-handle" ),
14547				handle = "<span tabindex='0'></span>",
14548				handles = [];
14549
14550			handleCount = ( options.values && options.values.length ) || 1;
14551
14552			if ( existingHandles.length > handleCount ) {
14553				existingHandles.slice( handleCount ).remove();
14554				existingHandles = existingHandles.slice( 0, handleCount );
14555			}
14556
14557			for ( i = existingHandles.length; i < handleCount; i++ ) {
14558				handles.push( handle );
14559			}
14560
14561			this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
14562
14563			this._addClass( this.handles, "ui-slider-handle", "ui-state-default" );
14564
14565			this.handle = this.handles.eq( 0 );
14566
14567			this.handles.each( function( i ) {
14568				$( this )
14569					.data( "ui-slider-handle-index", i )
14570					.attr( "tabIndex", 0 );
14571			} );
14572		},
14573
14574		_createRange: function() {
14575			var options = this.options;
14576
14577			if ( options.range ) {
14578				if ( options.range === true ) {
14579					if ( !options.values ) {
14580						options.values = [ this._valueMin(), this._valueMin() ];
14581					} else if ( options.values.length && options.values.length !== 2 ) {
14582						options.values = [ options.values[ 0 ], options.values[ 0 ] ];
14583					} else if ( $.isArray( options.values ) ) {
14584						options.values = options.values.slice( 0 );
14585					}
14586				}
14587
14588				if ( !this.range || !this.range.length ) {
14589					this.range = $( "<div>" )
14590						.appendTo( this.element );
14591
14592					this._addClass( this.range, "ui-slider-range" );
14593				} else {
14594					this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" );
14595
14596					// Handle range switching from true to min/max
14597					this.range.css( {
14598						"left": "",
14599						"bottom": ""
14600					} );
14601				}
14602				if ( options.range === "min" || options.range === "max" ) {
14603					this._addClass( this.range, "ui-slider-range-" + options.range );
14604				}
14605			} else {
14606				if ( this.range ) {
14607					this.range.remove();
14608				}
14609				this.range = null;
14610			}
14611		},
14612
14613		_setupEvents: function() {
14614			this._off( this.handles );
14615			this._on( this.handles, this._handleEvents );
14616			this._hoverable( this.handles );
14617			this._focusable( this.handles );
14618		},
14619
14620		_destroy: function() {
14621			this.handles.remove();
14622			if ( this.range ) {
14623				this.range.remove();
14624			}
14625
14626			this._mouseDestroy();
14627		},
14628
14629		_mouseCapture: function( event ) {
14630			var position, normValue, distance, closestHandle, index, allowed, offset, mou
vendor: 16,247 bytes, lines 14630-15203
14630seOverHandle,
14631				that = this,
14632				o = this.options;
14633
14634			if ( o.disabled ) {
14635				return false;
14636			}
14637
14638			this.elementSize = {
14639				width: this.element.outerWidth(),
14640				height: this.element.outerHeight()
14641			};
14642			this.elementOffset = this.element.offset();
14643
14644			position = { x: event.pageX, y: event.pageY };
14645			normValue = this._normValueFromMouse( position );
14646			distance = this._valueMax() - this._valueMin() + 1;
14647			this.handles.each( function( i ) {
14648				var thisDistance = Math.abs( normValue - that.values( i ) );
14649				if ( ( distance > thisDistance ) ||
14650					( distance === thisDistance &&
14651					( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) {
14652					distance = thisDistance;
14653					closestHandle = $( this );
14654					index = i;
14655				}
14656			} );
14657
14658			allowed = this._start( event, index );
14659			if ( allowed === false ) {
14660				return false;
14661			}
14662			this._mouseSliding = true;
14663
14664			this._handleIndex = index;
14665
14666			this._addClass( closestHandle, null, "ui-state-active" );
14667			closestHandle.trigger( "focus" );
14668
14669			offset = closestHandle.offset();
14670			mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
14671			this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
14672				left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
14673				top: event.pageY - offset.top -
14674				( closestHandle.height() / 2 ) -
14675				( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) -
14676				( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) +
14677				( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 )
14678			};
14679
14680			if ( !this.handles.hasClass( "ui-state-hover" ) ) {
14681				this._slide( event, index, normValue );
14682			}
14683			this._animateOff = true;
14684			return true;
14685		},
14686
14687		_mouseStart: function() {
14688			return true;
14689		},
14690
14691		_mouseDrag: function( event ) {
14692			var position = { x: event.pageX, y: event.pageY },
14693				normValue = this._normValueFromMouse( position );
14694
14695			this._slide( event, this._handleIndex, normValue );
14696
14697			return false;
14698		},
14699
14700		_mouseStop: function( event ) {
14701			this._removeClass( this.handles, null, "ui-state-active" );
14702			this._mouseSliding = false;
14703
14704			this._stop( event, this._handleIndex );
14705			this._change( event, this._handleIndex );
14706
14707			this._handleIndex = null;
14708			this._clickOffset = null;
14709			this._animateOff = false;
14710
14711			return false;
14712		},
14713
14714		_detectOrientation: function() {
14715			this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
14716		},
14717
14718		_normValueFromMouse: function( position ) {
14719			var pixelTotal,
14720				pixelMouse,
14721				percentMouse,
14722				valueTotal,
14723				valueMouse;
14724
14725			if ( this.orientation === "horizontal" ) {
14726				pixelTotal = this.elementSize.width;
14727				pixelMouse = position.x - this.elementOffset.left -
14728					( this._clickOffset ? this._clickOffset.left : 0 );
14729			} else {
14730				pixelTotal = this.elementSize.height;
14731				pixelMouse = position.y - this.elementOffset.top -
14732					( this._clickOffset ? this._clickOffset.top : 0 );
14733			}
14734
14735			percentMouse = ( pixelMouse / pixelTotal );
14736			if ( percentMouse > 1 ) {
14737				percentMouse = 1;
14738			}
14739			if ( percentMouse < 0 ) {
14740				percentMouse = 0;
14741			}
14742			if ( this.orientation === "vertical" ) {
14743				percentMouse = 1 - percentMouse;
14744			}
14745
14746			valueTotal = this._valueMax() - this._valueMin();
14747			valueMouse = this._valueMin() + percentMouse * valueTotal;
14748
14749			return this._trimAlignValue( valueMouse );
14750		},
14751
14752		_uiHash: function( index, value, values ) {
14753			var uiHash = {
14754				handle: this.handles[ index ],
14755				handleIndex: index,
14756				value: value !== undefined ? value : this.value()
14757			};
14758
14759			if ( this._hasMultipleValues() ) {
14760				uiHash.value = value !== undefined ? value : this.values( index );
14761				uiHash.values = values || this.values();
14762			}
14763
14764			return uiHash;
14765		},
14766
14767		_hasMultipleValues: function() {
14768			return this.options.values && this.options.values.length;
14769		},
14770
14771		_start: function( event, index ) {
14772			return this._trigger( "start", event, this._uiHash( index ) );
14773		},
14774
14775		_slide: function( event, index, newVal ) {
14776			var allowed, otherVal,
14777				currentValue = this.value(),
14778				newValues = this.values();
14779
14780			if ( this._hasMultipleValues() ) {
14781				otherVal = this.values( index ? 0 : 1 );
14782				currentValue = this.values( index );
14783
14784				if ( this.options.values.length === 2 && this.options.range === true ) {
14785					newVal =  index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal );
14786				}
14787
14788				newValues[ index ] = newVal;
14789			}
14790
14791			if ( newVal === currentValue ) {
14792				return;
14793			}
14794
14795			allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) );
14796
14797			// A slide can be canceled by returning false from the slide callback
14798			if ( allowed === false ) {
14799				return;
14800			}
14801
14802			if ( this._hasMultipleValues() ) {
14803				this.values( index, newVal );
14804			} else {
14805				this.value( newVal );
14806			}
14807		},
14808
14809		_stop: function( event, index ) {
14810			this._trigger( "stop", event, this._uiHash( index ) );
14811		},
14812
14813		_change: function( event, index ) {
14814			if ( !this._keySliding && !this._mouseSliding ) {
14815
14816				//store the last changed value index for reference when handles overlap
14817				this._lastChangedValue = index;
14818				this._trigger( "change", event, this._uiHash( index ) );
14819			}
14820		},
14821
14822		value: function( newValue ) {
14823			if ( arguments.length ) {
14824				this.options.value = this._trimAlignValue( newValue );
14825				this._refreshValue();
14826				this._change( null, 0 );
14827				return;
14828			}
14829
14830			return this._value();
14831		},
14832
14833		values: function( index, newValue ) {
14834			var vals,
14835				newValues,
14836				i;
14837
14838			if ( arguments.length > 1 ) {
14839				this.options.values[ index ] = this._trimAlignValue( newValue );
14840				this._refreshValue();
14841				this._change( null, index );
14842				return;
14843			}
14844
14845			if ( arguments.length ) {
14846				if ( $.isArray( arguments[ 0 ] ) ) {
14847					vals = this.options.values;
14848					newValues = arguments[ 0 ];
14849					for ( i = 0; i < vals.length; i += 1 ) {
14850						vals[ i ] = this._trimAlignValue( newValues[ i ] );
14851						this._change( null, i );
14852					}
14853					this._refreshValue();
14854				} else {
14855					if ( this._hasMultipleValues() ) {
14856						return this._values( index );
14857					} else {
14858						return this.value();
14859					}
14860				}
14861			} else {
14862				return this._values();
14863			}
14864		},
14865
14866		_setOption: function( key, value ) {
14867			var i,
14868				valsLength = 0;
14869
14870			if ( key === "range" && this.options.range === true ) {
14871				if ( value === "min" ) {
14872					this.options.value = this._values( 0 );
14873					this.options.values = null;
14874				} else if ( value === "max" ) {
14875					this.options.value = this._values( this.options.values.length - 1 );
14876					this.options.values = null;
14877				}
14878			}
14879
14880			if ( $.isArray( this.options.values ) ) {
14881				valsLength = this.options.values.length;
14882			}
14883
14884			this._super( key, value );
14885
14886			switch ( key ) {
14887				case "orientation":
14888					this._detectOrientation();
14889					this._removeClass( "ui-slider-horizontal ui-slider-vertical" )
14890						._addClass( "ui-slider-" + this.orientation );
14891					this._refreshValue();
14892					if ( this.options.range ) {
14893						this._refreshRange( value );
14894					}
14895
14896					// Reset positioning from previous orientation
14897					this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
14898					break;
14899				case "value":
14900					this._animateOff = true;
14901					this._refreshValue();
14902					this._change( null, 0 );
14903					this._animateOff = false;
14904					break;
14905				case "values":
14906					this._animateOff = true;
14907					this._refreshValue();
14908
14909					// Start from the last handle to prevent unreachable handles (#9046)
14910					for ( i = valsLength - 1; i >= 0; i-- ) {
14911						this._change( null, i );
14912					}
14913					this._animateOff = false;
14914					break;
14915				case "step":
14916				case "min":
14917				case "max":
14918					this._animateOff = true;
14919					this._calculateNewMax();
14920					this._refreshValue();
14921					this._animateOff = false;
14922					break;
14923				case "range":
14924					this._animateOff = true;
14925					this._refresh();
14926					this._animateOff = false;
14927					break;
14928			}
14929		},
14930
14931		_setOptionDisabled: function( value ) {
14932			this._super( value );
14933
14934			this._toggleClass( null, "ui-state-disabled", !!value );
14935		},
14936
14937		//internal value getter
14938		// _value() returns value trimmed by min and max, aligned by step
14939		_value: function() {
14940			var val = this.options.value;
14941			val = this._trimAlignValue( val );
14942
14943			return val;
14944		},
14945
14946		//internal values getter
14947		// _values() returns array of values trimmed by min and max, aligned by step
14948		// _values( index ) returns single value trimmed by min and max, aligned by step
14949		_values: function( index ) {
14950			var val,
14951				vals,
14952				i;
14953
14954			if ( arguments.length ) {
14955				val = this.options.values[ index ];
14956				val = this._trimAlignValue( val );
14957
14958				return val;
14959			} else if ( this._hasMultipleValues() ) {
14960
14961				// .slice() creates a copy of the array
14962				// this copy gets trimmed by min and max and then returned
14963				vals = this.options.values.slice();
14964				for ( i = 0; i < vals.length; i += 1 ) {
14965					vals[ i ] = this._trimAlignValue( vals[ i ] );
14966				}
14967
14968				return vals;
14969			} else {
14970				return [];
14971			}
14972		},
14973
14974		// Returns the step-aligned value that val is closest to, between (inclusive) min and max
14975		_trimAlignValue: function( val ) {
14976			if ( val <= this._valueMin() ) {
14977				return this._valueMin();
14978			}
14979			if ( val >= this._valueMax() ) {
14980				return this._valueMax();
14981			}
14982			var step = ( this.options.step > 0 ) ? this.options.step : 1,
14983				valModStep = ( val - this._valueMin() ) % step,
14984				alignValue = val - valModStep;
14985
14986			if ( Math.abs( valModStep ) * 2 >= step ) {
14987				alignValue += ( valModStep > 0 ) ? step : ( -step );
14988			}
14989
14990			// Since JavaScript has problems with large floats, round
14991			// the final value to 5 digits after the decimal point (see #4124)
14992			return parseFloat( alignValue.toFixed( 5 ) );
14993		},
14994
14995		_calculateNewMax: function() {
14996			var max = this.options.max,
14997				min = this._valueMin(),
14998				step = this.options.step,
14999				aboveMin = Math.round( ( max - min ) / step ) * step;
15000			max = aboveMin + min;
15001			if ( max > this.options.max ) {
15002
15003				//If max is not divisible by step, rounding off may increase its value
15004				max -= step;
15005			}
15006			this.max = parseFloat( max.toFixed( this._precision() ) );
15007		},
15008
15009		_precision: function() {
15010			var precision = this._precisionOf( this.options.step );
15011			if ( this.options.min !== null ) {
15012				precision = Math.max( precision, this._precisionOf( this.options.min ) );
15013			}
15014			return precision;
15015		},
15016
15017		_precisionOf: function( num ) {
15018			var str = num.toString(),
15019				decimal = str.indexOf( "." );
15020			return decimal === -1 ? 0 : str.length - decimal - 1;
15021		},
15022
15023		_valueMin: function() {
15024			return this.options.min;
15025		},
15026
15027		_valueMax: function() {
15028			return this.max;
15029		},
15030
15031		_refreshRange: function( orientation ) {
15032			if ( orientation === "vertical" ) {
15033				this.range.css( { "width": "", "left": "" } );
15034			}
15035			if ( orientation === "horizontal" ) {
15036				this.range.css( { "height": "", "bottom": "" } );
15037			}
15038		},
15039
15040		_refreshValue: function() {
15041			var lastValPercent, valPercent, value, valueMin, valueMax,
15042				oRange = this.options.range,
15043				o = this.options,
15044				that = this,
15045				animate = ( !this._animateOff ) ? o.animate : false,
15046				_set = {};
15047
15048			if ( this._hasMultipleValues() ) {
15049				this.handles.each( function( i ) {
15050					valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() -
15051						that._valueMin() ) * 100;
15052					_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
15053					$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
15054					if ( that.options.range === true ) {
15055						if ( that.orientation === "horizontal" ) {
15056							if ( i === 0 ) {
15057								that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15058									left: valPercent + "%"
15059								}, o.animate );
15060							}
15061							if ( i === 1 ) {
15062								that.range[ animate ? "animate" : "css" ]( {
15063									width: ( valPercent - lastValPercent ) + "%"
15064								}, {
15065									queue: false,
15066									duration: o.animate
15067								} );
15068							}
15069						} else {
15070							if ( i === 0 ) {
15071								that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15072									bottom: ( valPercent ) + "%"
15073								}, o.animate );
15074							}
15075							if ( i === 1 ) {
15076								that.range[ animate ? "animate" : "css" ]( {
15077									height: ( valPercent - lastValPercent ) + "%"
15078								}, {
15079									queue: false,
15080									duration: o.animate
15081								} );
15082							}
15083						}
15084					}
15085					lastValPercent = valPercent;
15086				} );
15087			} else {
15088				value = this.value();
15089				valueMin = this._valueMin();
15090				valueMax = this._valueMax();
15091				valPercent = ( valueMax !== valueMin ) ?
15092				( value - valueMin ) / ( valueMax - valueMin ) * 100 :
15093					0;
15094				_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
15095				this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
15096
15097				if ( oRange === "min" && this.orientation === "horizontal" ) {
15098					this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15099						width: valPercent + "%"
15100					}, o.animate );
15101				}
15102				if ( oRange === "max" && this.orientation === "horizontal" ) {
15103					this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15104						width: ( 100 - valPercent ) + "%"
15105					}, o.animate );
15106				}
15107				if ( oRange === "min" && this.orientation === "vertical" ) {
15108					this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15109						height: valPercent + "%"
15110					}, o.animate );
15111				}
15112				if ( oRange === "max" && this.orientation === "vertical" ) {
15113					this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15114						height: ( 100 - valPercent ) + "%"
15115					}, o.animate );
15116				}
15117			}
15118		},
15119
15120		_handleEvents: {
15121			keydown: function( event ) {
15122				var allowed, curVal, newVal, step,
15123					index = $( event.target ).data( "ui-slider-handle-index" );
15124
15125				switch ( event.keyCode ) {
15126					case $.ui.keyCode.HOME:
15127					case $.ui.keyCode.END:
15128					case $.ui.keyCode.PAGE_UP:
15129					case $.ui.keyCode.PAGE_DOWN:
15130					case $.ui.keyCode.UP:
15131					case $.ui.keyCode.RIGHT:
15132					case $.ui.keyCode.DOWN:
15133					case $.ui.keyCode.LEFT:
15134						event.preventDefault();
15135						if ( !this._keySliding ) {
15136							this._keySliding = true;
15137							this._addClass( $( event.target ), null, "ui-state-active" );
15138							allowed = this._start( event, index );
15139							if ( allowed === false ) {
15140								return;
15141							}
15142						}
15143						break;
15144				}
15145
15146				step = this.options.step;
15147				if ( this._hasMultipleValues() ) {
15148					curVal = newVal = this.values( index );
15149				} else {
15150					curVal = newVal = this.value();
15151				}
15152
15153				switch ( event.keyCode ) {
15154					case $.ui.keyCode.HOME:
15155						newVal = this._valueMin();
15156						break;
15157					case $.ui.keyCode.END:
15158						newVal = this._valueMax();
15159						break;
15160					case $.ui.keyCode.PAGE_UP:
15161						newVal = this._trimAlignValue(
15162							curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
15163						);
15164						break;
15165					case $.ui.keyCode.PAGE_DOWN:
15166						newVal = this._trimAlignValue(
15167							curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) );
15168						break;
15169					case $.ui.keyCode.UP:
15170					case $.ui.keyCode.RIGHT:
15171						if ( curVal === this._valueMax() ) {
15172							return;
15173						}
15174						newVal = this._trimAlignValue( curVal + step );
15175						break;
15176					case $.ui.keyCode.DOWN:
15177					case $.ui.keyCode.LEFT:
15178						if ( curVal === this._valueMin() ) {
15179							return;
15180						}
15181						newVal = this._trimAlignValue( curVal - step );
15182						break;
15183				}
15184
15185				this._slide( event, index, newVal );
15186			},
15187			keyup: function( event ) {
15188				var index = $( event.target ).data( "ui-slider-handle-index" );
15189
15190				if ( this._keySliding ) {
15191					this._keySliding = false;
15192					this._stop( event, index );
15193					this._change( event, index );
15194					this._removeClass( $( event.target ), null, "ui-state-active" );
15195				}
15196			}
15197		}
15198	} );
15199
15200
15201	/*!
15202	 * jQuery UI Sortable 1.12.1
15203	 * http://jqueryui.com
vendor: 11,622 bytes, lines 15204-15604
15204	 *
15205	 * Copyright jQuery Foundation and other contributors
15206	 * Released under the MIT license.
15207	 * http://jquery.org/license
15208	 */
15209
15210//>>label: Sortable
15211//>>group: Interactions
15212//>>description: Enables items in a list to be sorted using the mouse.
15213//>>docs: http://api.jqueryui.com/sortable/
15214//>>demos: http://jqueryui.com/sortable/
15215//>>css.structure: ../../themes/base/sortable.css
15216
15217
15218
15219	var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, {
15220		version: "1.12.1",
15221		widgetEventPrefix: "sort",
15222		ready: false,
15223		options: {
15224			appendTo: "parent",
15225			axis: false,
15226			connectWith: false,
15227			containment: false,
15228			cursor: "auto",
15229			cursorAt: false,
15230			dropOnEmpty: true,
15231			forcePlaceholderSize: false,
15232			forceHelperSize: false,
15233			grid: false,
15234			handle: false,
15235			helper: "original",
15236			items: "> *",
15237			opacity: false,
15238			placeholder: false,
15239			revert: false,
15240			scroll: true,
15241			scrollSensitivity: 20,
15242			scrollSpeed: 20,
15243			scope: "default",
15244			tolerance: "intersect",
15245			zIndex: 1000,
15246
15247			// Callbacks
15248			activate: null,
15249			beforeStop: null,
15250			change: null,
15251			deactivate: null,
15252			out: null,
15253			over: null,
15254			receive: null,
15255			remove: null,
15256			sort: null,
15257			start: null,
15258			stop: null,
15259			update: null
15260		},
15261
15262		_isOverAxis: function( x, reference, size ) {
15263			return ( x >= reference ) && ( x < ( reference + size ) );
15264		},
15265
15266		_isFloating: function( item ) {
15267			return ( /left|right/ ).test( item.css( "float" ) ) ||
15268				( /inline|table-cell/ ).test( item.css( "display" ) );
15269		},
15270
15271		_create: function() {
15272			this.containerCache = {};
15273			this._addClass( "ui-sortable" );
15274
15275			//Get the items
15276			this.refresh();
15277
15278			//Let's determine the parent's offset
15279			this.offset = this.element.offset();
15280
15281			//Initialize mouse events for interaction
15282			this._mouseInit();
15283
15284			this._setHandleClassName();
15285
15286			//We're ready to go
15287			this.ready = true;
15288
15289		},
15290
15291		_setOption: function( key, value ) {
15292			this._super( key, value );
15293
15294			if ( key === "handle" ) {
15295				this._setHandleClassName();
15296			}
15297		},
15298
15299		_setHandleClassName: function() {
15300			var that = this;
15301			this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" );
15302			$.each( this.items, function() {
15303				that._addClass(
15304					this.instance.options.handle ?
15305						this.item.find( this.instance.options.handle ) :
15306						this.item,
15307					"ui-sortable-handle"
15308				);
15309			} );
15310		},
15311
15312		_destroy: function() {
15313			this._mouseDestroy();
15314
15315			for ( var i = this.items.length - 1; i >= 0; i-- ) {
15316				this.items[ i ].item.removeData( this.widgetName + "-item" );
15317			}
15318
15319			return this;
15320		},
15321
15322		_mouseCapture: function( event, overrideHandle ) {
15323			var currentItem = null,
15324				validHandle = false,
15325				that = this;
15326
15327			if ( this.reverting ) {
15328				return false;
15329			}
15330
15331			if ( this.options.disabled || this.options.type === "static" ) {
15332				return false;
15333			}
15334
15335			//We have to refresh the items data once first
15336			this._refreshItems( event );
15337
15338			//Find out if the clicked node (or one of its parents) is a actual item in this.items
15339			$( event.target ).parents().each( function() {
15340				if ( $.data( this, that.widgetName + "-item" ) === that ) {
15341					currentItem = $( this );
15342					return false;
15343				}
15344			} );
15345			if ( $.data( event.target, that.widgetName + "-item" ) === that ) {
15346				currentItem = $( event.target );
15347			}
15348
15349			if ( !currentItem ) {
15350				return false;
15351			}
15352			if ( this.options.handle && !overrideHandle ) {
15353				$( this.options.handle, currentItem ).find( "*" ).addBack().each( function() {
15354					if ( this === event.target ) {
15355						validHandle = true;
15356					}
15357				} );
15358				if ( !validHandle ) {
15359					return false;
15360				}
15361			}
15362
15363			this.currentItem = currentItem;
15364			this._removeCurrentsFromItems();
15365			return true;
15366
15367		},
15368
15369		_mouseStart: function( event, overrideHandle, noActivation ) {
15370
15371			var i, body,
15372				o = this.options;
15373
15374			this.currentContainer = this;
15375
15376			//We only need to call refreshPositions, because the refreshItems call has been moved to
15377			// mouseCapture
15378			this.refreshPositions();
15379
15380			//Create and append the visible helper
15381			this.helper = this._createHelper( event );
15382
15383			//Cache the helper size
15384			this._cacheHelperProportions();
15385
15386			/*
15387			 * - Position generation -
15388			 * This block generates everything position related - it's the core of draggables.
15389			 */
15390
15391			//Cache the margins of the original element
15392			this._cacheMargins();
15393
15394			//Get the next scrolling parent
15395			this.scrollParent = this.helper.scrollParent();
15396
15397			//The element's absolute position on the page minus margins
15398			this.offset = this.currentItem.offset();
15399			this.offset = {
15400				top: this.offset.top - this.margins.top,
15401				left: this.offset.left - this.margins.left
15402			};
15403
15404			$.extend( this.offset, {
15405				click: { //Where the click happened, relative to the element
15406					left: event.pageX - this.offset.left,
15407					top: event.pageY - this.offset.top
15408				},
15409				parent: this._getParentOffset(),
15410
15411				// This is a relative to absolute position minus the actual position calculation -
15412				// only used for relative positioned helper
15413				relative: this._getRelativeOffset()
15414			} );
15415
15416			// Only after we got the offset, we can change the helper's position to absolute
15417			// TODO: Still need to figure out a way to make relative sorting possible
15418			this.helper.css( "position", "absolute" );
15419			this.cssPosition = this.helper.css( "position" );
15420
15421			//Generate the original position
15422			this.originalPosition = this._generatePosition( event );
15423			this.originalPageX = event.pageX;
15424			this.originalPageY = event.pageY;
15425
15426			//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
15427			( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
15428
15429			//Cache the former DOM position
15430			this.domPosition = {
15431				prev: this.currentItem.prev()[ 0 ],
15432				parent: this.currentItem.parent()[ 0 ]
15433			};
15434
15435			// If the helper is not the original, hide the original so it's not playing any role during
15436			// the drag, won't cause anything bad this way
15437			if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
15438				this.currentItem.hide();
15439			}
15440
15441			//Create the placeholder
15442			this._createPlaceholder();
15443
15444			//Set a containment if given in the options
15445			if ( o.containment ) {
15446				this._setContainment();
15447			}
15448
15449			if ( o.cursor && o.cursor !== "auto" ) { // cursor option
15450				body = this.document.find( "body" );
15451
15452				// Support: IE
15453				this.storedCursor = body.css( "cursor" );
15454				body.css( "cursor", o.cursor );
15455
15456				this.storedStylesheet =
15457					$( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body );
15458			}
15459
15460			if ( o.opacity ) { // opacity option
15461				if ( this.helper.css( "opacity" ) ) {
15462					this._storedOpacity = this.helper.css( "opacity" );
15463				}
15464				this.helper.css( "opacity", o.opacity );
15465			}
15466
15467			if ( o.zIndex ) { // zIndex option
15468				if ( this.helper.css( "zIndex" ) ) {
15469					this._storedZIndex = this.helper.css( "zIndex" );
15470				}
15471				this.helper.css( "zIndex", o.zIndex );
15472			}
15473
15474			//Prepare scrolling
15475			if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
15476				this.scrollParent[ 0 ].tagName !== "HTML" ) {
15477				this.overflowOffset = this.scrollParent.offset();
15478			}
15479
15480			//Call callbacks
15481			this._trigger( "start", event, this._uiHash() );
15482
15483			//Recache the helper size
15484			if ( !this._preserveHelperProportions ) {
15485				this._cacheHelperProportions();
15486			}
15487
15488			//Post "activate" events to possible containers
15489			if ( !noActivation ) {
15490				for ( i = this.containers.length - 1; i >= 0; i-- ) {
15491					this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
15492				}
15493			}
15494
15495			//Prepare possible droppables
15496			if ( $.ui.ddmanager ) {
15497				$.ui.ddmanager.current = this;
15498			}
15499
15500			if ( $.ui.ddmanager && !o.dropBehaviour ) {
15501				$.ui.ddmanager.prepareOffsets( this, event );
15502			}
15503
15504			this.dragging = true;
15505
15506			this._addClass( this.helper, "ui-sortable-helper" );
15507
15508			// Execute the drag once - this causes the helper not to be visiblebefore getting its
15509			// correct position
15510			this._mouseDrag( event );
15511			return true;
15512
15513		},
15514
15515		_mouseDrag: function( event ) {
15516			var i, item, itemElement, intersection,
15517				o = this.options,
15518				scrolled = false;
15519
15520			//Compute the helpers position
15521			this.position = this._generatePosition( event );
15522			this.positionAbs = this._convertPositionTo( "absolute" );
15523
15524			if ( !this.lastPositionAbs ) {
15525				this.lastPositionAbs = this.positionAbs;
15526			}
15527
15528			//Do scrolling
15529			if ( this.options.scroll ) {
15530				if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
15531					this.scrollParent[ 0 ].tagName !== "HTML" ) {
15532
15533					if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -
15534						event.pageY < o.scrollSensitivity ) {
15535						this.scrollParent[ 0 ].scrollTop =
15536							scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;
15537					} else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {
15538						this.scrollParent[ 0 ].scrollTop =
15539							scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;
15540					}
15541
15542					if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -
15543						event.pageX < o.scrollSensitivity ) {
15544						this.scrollParent[ 0 ].scrollLeft = scrolled =
15545							this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;
15546					} else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {
15547						this.scrollParent[ 0 ].scrollLeft = scrolled =
15548							this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;
15549					}
15550
15551				} else {
15552
15553					if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {
15554						scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );
15555					} else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <
15556						o.scrollSensitivity ) {
15557						scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );
15558					}
15559
15560					if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {
15561						scrolled = this.document.scrollLeft(
15562							this.document.scrollLeft() - o.scrollSpeed
15563						);
15564					} else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <
15565						o.scrollSensitivity ) {
15566						scrolled = this.document.scrollLeft(
15567							this.document.scrollLeft() + o.scrollSpeed
15568						);
15569					}
15570
15571				}
15572
15573				if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
15574					$.ui.ddmanager.prepareOffsets( this, event );
15575				}
15576			}
15577
15578			//Regenerate the absolute position used for position checks
15579			this.positionAbs = this._convertPositionTo( "absolute" );
15580
15581			//Set the helper position
15582			if ( !this.options.axis || this.options.axis !== "y" ) {
15583				this.helper[ 0 ].style.left = this.position.left + "px";
15584			}
15585			if ( !this.options.axis || this.options.axis !== "x" ) {
15586				this.helper[ 0 ].style.top = this.position.top + "px";
15587			}
15588
15589			//Rearrange
15590			for ( i = this.items.length - 1; i >= 0; i-- ) {
15591
15592				//Cache variables and intersection, continue if no intersection
15593				item = this.items[ i ];
15594				itemElement = item.item[ 0 ];
15595				intersection = this._intersectsWithPointer( item );
15596				if ( !intersection ) {
15597					continue;
15598				}
15599
15600				// Only put the placeholder inside the current Container, skip all
15601				// items from other containers. This works because when moving
15602				// an item from one container to another the
15603				// currentContainer is switched before the placeholder is moved.
15604				//
vendor: 4,783 bytes, lines 15605-15784
15605				// Without this, moving items in "sub-sortables" can cause
15606				// the placeholder to jitter between the outer and inner container.
15607				if ( item.instance !== this.currentContainer ) {
15608					continue;
15609				}
15610
15611				// Cannot intersect with itself
15612				// no useless actions that have been done before
15613				// no action if the item moved is the parent of the item checked
15614				if ( itemElement !== this.currentItem[ 0 ] &&
15615					this.placeholder[ intersection === 1 ? "next" : "prev" ]()[ 0 ] !== itemElement &&
15616					!$.contains( this.placeholder[ 0 ], itemElement ) &&
15617					( this.options.type === "semi-dynamic" ?
15618							!$.contains( this.element[ 0 ], itemElement ) :
15619							true
15620					)
15621				) {
15622
15623					this.direction = intersection === 1 ? "down" : "up";
15624
15625					if ( this.options.tolerance === "pointer" || this._intersectsWithSides( item ) ) {
15626						this._rearrange( event, item );
15627					} else {
15628						break;
15629					}
15630
15631					this._trigger( "change", event, this._uiHash() );
15632					break;
15633				}
15634			}
15635
15636			//Post events to containers
15637			this._contactContainers( event );
15638
15639			//Interconnect with droppables
15640			if ( $.ui.ddmanager ) {
15641				$.ui.ddmanager.drag( this, event );
15642			}
15643
15644			//Call callbacks
15645			this._trigger( "sort", event, this._uiHash() );
15646
15647			this.lastPositionAbs = this.positionAbs;
15648			return false;
15649
15650		},
15651
15652		_mouseStop: function( event, noPropagation ) {
15653
15654			if ( !event ) {
15655				return;
15656			}
15657
15658			//If we are using droppables, inform the manager about the drop
15659			if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
15660				$.ui.ddmanager.drop( this, event );
15661			}
15662
15663			if ( this.options.revert ) {
15664				var that = this,
15665					cur = this.placeholder.offset(),
15666					axis = this.options.axis,
15667					animation = {};
15668
15669				if ( !axis || axis === "x" ) {
15670					animation.left = cur.left - this.offset.parent.left - this.margins.left +
15671						( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
15672								0 :
15673								this.offsetParent[ 0 ].scrollLeft
15674						);
15675				}
15676				if ( !axis || axis === "y" ) {
15677					animation.top = cur.top - this.offset.parent.top - this.margins.top +
15678						( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
15679								0 :
15680								this.offsetParent[ 0 ].scrollTop
15681						);
15682				}
15683				this.reverting = true;
15684				$( this.helper ).animate(
15685					animation,
15686					parseInt( this.options.revert, 10 ) || 500,
15687					function() {
15688						that._clear( event );
15689					}
15690				);
15691			} else {
15692				this._clear( event, noPropagation );
15693			}
15694
15695			return false;
15696
15697		},
15698
15699		cancel: function() {
15700
15701			if ( this.dragging ) {
15702
15703				this._mouseUp( new $.Event( "mouseup", { target: null } ) );
15704
15705				if ( this.options.helper === "original" ) {
15706					this.currentItem.css( this._storedCSS );
15707					this._removeClass( this.currentItem, "ui-sortable-helper" );
15708				} else {
15709					this.currentItem.show();
15710				}
15711
15712				//Post deactivating events to containers
15713				for ( var i = this.containers.length - 1; i >= 0; i-- ) {
15714					this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) );
15715					if ( this.containers[ i ].containerCache.over ) {
15716						this.containers[ i ]._trigger( "out", null, this._uiHash( this ) );
15717						this.containers[ i ].containerCache.over = 0;
15718					}
15719				}
15720
15721			}
15722
15723			if ( this.placeholder ) {
15724
15725				//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
15726				// it unbinds ALL events from the original node!
15727				if ( this.placeholder[ 0 ].parentNode ) {
15728					this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
15729				}
15730				if ( this.options.helper !== "original" && this.helper &&
15731					this.helper[ 0 ].parentNode ) {
15732					this.helper.remove();
15733				}
15734
15735				$.extend( this, {
15736					helper: null,
15737					dragging: false,
15738					reverting: false,
15739					_noFinalSort: null
15740				} );
15741
15742				if ( this.domPosition.prev ) {
15743					$( this.domPosition.prev ).after( this.currentItem );
15744				} else {
15745					$( this.domPosition.parent ).prepend( this.currentItem );
15746				}
15747			}
15748
15749			return this;
15750
15751		},
15752
15753		serialize: function( o ) {
15754
15755			var items = this._getItemsAsjQuery( o && o.connected ),
15756				str = [];
15757			o = o || {};
15758
15759			$( items ).each( function() {
15760				var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" )
15761					.match( o.expression || ( /(.+)[\-=_](.+)/ ) );
15762				if ( res ) {
15763					str.push(
15764						( o.key || res[ 1 ] + "[]" ) +
15765						"=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );
15766				}
15767			} );
15768
15769			if ( !str.length && o.key ) {
15770				str.push( o.key + "=" );
15771			}
15772
15773			return str.join( "&" );
15774
15775		},
15776
15777		toArray: function( o ) {
15778
15779			var items = this._getItemsAsjQuery( o && o.connected ),
15780				ret = [];
15781
15782			o = o || {};
15783
15784			items.each( function() {
vendor: 32,055 bytes, lines 15785-16737
15785				ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" );
15786			} );
15787			return ret;
15788
15789		},
15790
15791		/* Be careful with the following core functions */
15792		_intersectsWith: function( item ) {
15793
15794			var x1 = this.positionAbs.left,
15795				x2 = x1 + this.helperProportions.width,
15796				y1 = this.positionAbs.top,
15797				y2 = y1 + this.helperProportions.height,
15798				l = item.left,
15799				r = l + item.width,
15800				t = item.top,
15801				b = t + item.height,
15802				dyClick = this.offset.click.top,
15803				dxClick = this.offset.click.left,
15804				isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t &&
15805					( y1 + dyClick ) < b ),
15806				isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l &&
15807					( x1 + dxClick ) < r ),
15808				isOverElement = isOverElementHeight && isOverElementWidth;
15809
15810			if ( this.options.tolerance === "pointer" ||
15811				this.options.forcePointerForContainers ||
15812				( this.options.tolerance !== "pointer" &&
15813				this.helperProportions[ this.floating ? "width" : "height" ] >
15814				item[ this.floating ? "width" : "height" ] )
15815			) {
15816				return isOverElement;
15817			} else {
15818
15819				return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half
15820				x2 - ( this.helperProportions.width / 2 ) < r && // Left Half
15821				t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half
15822				y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half
15823
15824			}
15825		},
15826
15827		_intersectsWithPointer: function( item ) {
15828			var verticalDirection, horizontalDirection,
15829				isOverElementHeight = ( this.options.axis === "x" ) ||
15830					this._isOverAxis(
15831						this.positionAbs.top + this.offset.click.top, item.top, item.height ),
15832				isOverElementWidth = ( this.options.axis === "y" ) ||
15833					this._isOverAxis(
15834						this.positionAbs.left + this.offset.click.left, item.left, item.width ),
15835				isOverElement = isOverElementHeight && isOverElementWidth;
15836
15837			if ( !isOverElement ) {
15838				return false;
15839			}
15840
15841			verticalDirection = this._getDragVerticalDirection();
15842			horizontalDirection = this._getDragHorizontalDirection();
15843
15844			return this.floating ?
15845				( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 )
15846				: ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) );
15847
15848		},
15849
15850		_intersectsWithSides: function( item ) {
15851
15852			var isOverBottomHalf = this._isOverAxis( this.positionAbs.top +
15853					this.offset.click.top, item.top + ( item.height / 2 ), item.height ),
15854				isOverRightHalf = this._isOverAxis( this.positionAbs.left +
15855					this.offset.click.left, item.left + ( item.width / 2 ), item.width ),
15856				verticalDirection = this._getDragVerticalDirection(),
15857				horizontalDirection = this._getDragHorizontalDirection();
15858
15859			if ( this.floating && horizontalDirection ) {
15860				return ( ( horizontalDirection === "right" && isOverRightHalf ) ||
15861				( horizontalDirection === "left" && !isOverRightHalf ) );
15862			} else {
15863				return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) ||
15864					( verticalDirection === "up" && !isOverBottomHalf ) );
15865			}
15866
15867		},
15868
15869		_getDragVerticalDirection: function() {
15870			var delta = this.positionAbs.top - this.lastPositionAbs.top;
15871			return delta !== 0 && ( delta > 0 ? "down" : "up" );
15872		},
15873
15874		_getDragHorizontalDirection: function() {
15875			var delta = this.positionAbs.left - this.lastPositionAbs.left;
15876			return delta !== 0 && ( delta > 0 ? "right" : "left" );
15877		},
15878
15879		refresh: function( event ) {
15880			this._refreshItems( event );
15881			this._setHandleClassName();
15882			this.refreshPositions();
15883			return this;
15884		},
15885
15886		_connectWith: function() {
15887			var options = this.options;
15888			return options.connectWith.constructor === String ?
15889				[ options.connectWith ] :
15890				options.connectWith;
15891		},
15892
15893		_getItemsAsjQuery: function( connected ) {
15894
15895			var i, j, cur, inst,
15896				items = [],
15897				queries = [],
15898				connectWith = this._connectWith();
15899
15900			if ( connectWith && connected ) {
15901				for ( i = connectWith.length - 1; i >= 0; i-- ) {
15902					cur = $( connectWith[ i ], this.document[ 0 ] );
15903					for ( j = cur.length - 1; j >= 0; j-- ) {
15904						inst = $.data( cur[ j ], this.widgetFullName );
15905						if ( inst && inst !== this && !inst.options.disabled ) {
15906							queries.push( [ $.isFunction( inst.options.items ) ?
15907								inst.options.items.call( inst.element ) :
15908								$( inst.options.items, inst.element )
15909									.not( ".ui-sortable-helper" )
15910									.not( ".ui-sortable-placeholder" ), inst ] );
15911						}
15912					}
15913				}
15914			}
15915
15916			queries.push( [ $.isFunction( this.options.items ) ?
15917				this.options.items
15918					.call( this.element, null, { options: this.options, item: this.currentItem } ) :
15919				$( this.options.items, this.element )
15920					.not( ".ui-sortable-helper" )
15921					.not( ".ui-sortable-placeholder" ), this ] );
15922
15923			function addItems() {
15924				items.push( this );
15925			}
15926			for ( i = queries.length - 1; i >= 0; i-- ) {
15927				queries[ i ][ 0 ].each( addItems );
15928			}
15929
15930			return $( items );
15931
15932		},
15933
15934		_removeCurrentsFromItems: function() {
15935
15936			var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" );
15937
15938			this.items = $.grep( this.items, function( item ) {
15939				for ( var j = 0; j < list.length; j++ ) {
15940					if ( list[ j ] === item.item[ 0 ] ) {
15941						return false;
15942					}
15943				}
15944				return true;
15945			} );
15946
15947		},
15948
15949		_refreshItems: function( event ) {
15950
15951			this.items = [];
15952			this.containers = [ this ];
15953
15954			var i, j, cur, inst, targetData, _queries, item, queriesLength,
15955				items = this.items,
15956				queries = [ [ $.isFunction( this.options.items ) ?
15957					this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :
15958					$( this.options.items, this.element ), this ] ],
15959				connectWith = this._connectWith();
15960
15961			//Shouldn't be run the first time through due to massive slow-down
15962			if ( connectWith && this.ready ) {
15963				for ( i = connectWith.length - 1; i >= 0; i-- ) {
15964					cur = $( connectWith[ i ], this.document[ 0 ] );
15965					for ( j = cur.length - 1; j >= 0; j-- ) {
15966						inst = $.data( cur[ j ], this.widgetFullName );
15967						if ( inst && inst !== this && !inst.options.disabled ) {
15968							queries.push( [ $.isFunction( inst.options.items ) ?
15969								inst.options.items
15970									.call( inst.element[ 0 ], event, { item: this.currentItem } ) :
15971								$( inst.options.items, inst.element ), inst ] );
15972							this.containers.push( inst );
15973						}
15974					}
15975				}
15976			}
15977
15978			for ( i = queries.length - 1; i >= 0; i-- ) {
15979				targetData = queries[ i ][ 1 ];
15980				_queries = queries[ i ][ 0 ];
15981
15982				for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {
15983					item = $( _queries[ j ] );
15984
15985					// Data for target checking (mouse manager)
15986					item.data( this.widgetName + "-item", targetData );
15987
15988					items.push( {
15989						item: item,
15990						instance: targetData,
15991						width: 0, height: 0,
15992						left: 0, top: 0
15993					} );
15994				}
15995			}
15996
15997		},
15998
15999		refreshPositions: function( fast ) {
16000
16001			// Determine whether items are being displayed horizontally
16002			this.floating = this.items.length ?
16003			this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
16004				false;
16005
16006			//This has to be redone because due to the item being moved out/into the offsetParent,
16007			// the offsetParent's position will change
16008			if ( this.offsetParent && this.helper ) {
16009				this.offset.parent = this._getParentOffset();
16010			}
16011
16012			var i, item, t, p;
16013
16014			for ( i = this.items.length - 1; i >= 0; i-- ) {
16015				item = this.items[ i ];
16016
16017				//We ignore calculating positions of all connected containers when we're not over them
16018				if ( item.instance !== this.currentContainer && this.currentContainer &&
16019					item.item[ 0 ] !== this.currentItem[ 0 ] ) {
16020					continue;
16021				}
16022
16023				t = this.options.toleranceElement ?
16024					$( this.options.toleranceElement, item.item ) :
16025					item.item;
16026
16027				if ( !fast ) {
16028					item.width = t.outerWidth();
16029					item.height = t.outerHeight();
16030				}
16031
16032				p = t.offset();
16033				item.left = p.left;
16034				item.top = p.top;
16035			}
16036
16037			if ( this.options.custom && this.options.custom.refreshContainers ) {
16038				this.options.custom.refreshContainers.call( this );
16039			} else {
16040				for ( i = this.containers.length - 1; i >= 0; i-- ) {
16041					p = this.containers[ i ].element.offset();
16042					this.containers[ i ].containerCache.left = p.left;
16043					this.containers[ i ].containerCache.top = p.top;
16044					this.containers[ i ].containerCache.width =
16045						this.containers[ i ].element.outerWidth();
16046					this.containers[ i ].containerCache.height =
16047						this.containers[ i ].element.outerHeight();
16048				}
16049			}
16050
16051			return this;
16052		},
16053
16054		_createPlaceholder: function( that ) {
16055			that = that || this;
16056			var className,
16057				o = that.options;
16058
16059			if ( !o.placeholder || o.placeholder.constructor === String ) {
16060				className = o.placeholder;
16061				o.placeholder = {
16062					element: function() {
16063
16064						var nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(),
16065							element = $( "<" + nodeName + ">", that.document[ 0 ] );
16066
16067						that._addClass( element, "ui-sortable-placeholder",
16068							className || that.currentItem[ 0 ].className )
16069							._removeClass( element, "ui-sortable-helper" );
16070
16071						if ( nodeName === "tbody" ) {
16072							that._createTrPlaceholder(
16073								that.currentItem.find( "tr" ).eq( 0 ),
16074								$( "<tr>", that.document[ 0 ] ).appendTo( element )
16075							);
16076						} else if ( nodeName === "tr" ) {
16077							that._createTrPlaceholder( that.currentItem, element );
16078						} else if ( nodeName === "img" ) {
16079							element.attr( "src", that.currentItem.attr( "src" ) );
16080						}
16081
16082						if ( !className ) {
16083							element.css( "visibility", "hidden" );
16084						}
16085
16086						return element;
16087					},
16088					update: function( container, p ) {
16089
16090						// 1. If a className is set as 'placeholder option, we don't force sizes -
16091						// the class is responsible for that
16092						// 2. The option 'forcePlaceholderSize can be enabled to force it even if a
16093						// class name is specified
16094						if ( className && !o.forcePlaceholderSize ) {
16095							return;
16096						}
16097
16098						//If the element doesn't have a actual height by itself (without styles coming
16099						// from a stylesheet), it receives the inline height from the dragged item
16100						if ( !p.height() ) {
16101							p.height(
16102								that.currentItem.innerHeight() -
16103								parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) -
16104								parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) );
16105						}
16106						if ( !p.width() ) {
16107							p.width(
16108								that.currentItem.innerWidth() -
16109								parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) -
16110								parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) );
16111						}
16112					}
16113				};
16114			}
16115
16116			//Create the placeholder
16117			that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );
16118
16119			//Append it after the actual current item
16120			that.currentItem.after( that.placeholder );
16121
16122			//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
16123			o.placeholder.update( that, that.placeholder );
16124
16125		},
16126
16127		_createTrPlaceholder: function( sourceTr, targetTr ) {
16128			var that = this;
16129
16130			sourceTr.children().each( function() {
16131				$( "<td>&#160;</td>", that.document[ 0 ] )
16132					.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
16133					.appendTo( targetTr );
16134			} );
16135		},
16136
16137		_contactContainers: function( event ) {
16138			var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
16139				floating, axis,
16140				innermostContainer = null,
16141				innermostIndex = null;
16142
16143			// Get innermost container that intersects with item
16144			for ( i = this.containers.length - 1; i >= 0; i-- ) {
16145
16146				// Never consider a container that's located within the item itself
16147				if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {
16148					continue;
16149				}
16150
16151				if ( this._intersectsWith( this.containers[ i ].containerCache ) ) {
16152
16153					// If we've already found a container and it's more "inner" than this, then continue
16154					if ( innermostContainer &&
16155						$.contains(
16156							this.containers[ i ].element[ 0 ],
16157							innermostContainer.element[ 0 ] ) ) {
16158						continue;
16159					}
16160
16161					innermostContainer = this.containers[ i ];
16162					innermostIndex = i;
16163
16164				} else {
16165
16166					// container doesn't intersect. trigger "out" event if necessary
16167					if ( this.containers[ i ].containerCache.over ) {
16168						this.containers[ i ]._trigger( "out", event, this._uiHash( this ) );
16169						this.containers[ i ].containerCache.over = 0;
16170					}
16171				}
16172
16173			}
16174
16175			// If no intersecting containers found, return
16176			if ( !innermostContainer ) {
16177				return;
16178			}
16179
16180			// Move the item into the container if it's not there already
16181			if ( this.containers.length === 1 ) {
16182				if ( !this.containers[ innermostIndex ].containerCache.over ) {
16183					this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
16184					this.containers[ innermostIndex ].containerCache.over = 1;
16185				}
16186			} else {
16187
16188				// When entering a new container, we will find the item with the least distance and
16189				// append our item near it
16190				dist = 10000;
16191				itemWithLeastDistance = null;
16192				floating = innermostContainer.floating || this._isFloating( this.currentItem );
16193				posProperty = floating ? "left" : "top";
16194				sizeProperty = floating ? "width" : "height";
16195				axis = floating ? "pageX" : "pageY";
16196
16197				for ( j = this.items.length - 1; j >= 0; j-- ) {
16198					if ( !$.contains(
16199							this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )
16200					) {
16201						continue;
16202					}
16203					if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {
16204						continue;
16205					}
16206
16207					cur = this.items[ j ].item.offset()[ posProperty ];
16208					nearBottom = false;
16209					if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
16210						nearBottom = true;
16211					}
16212
16213					if ( Math.abs( event[ axis ] - cur ) < dist ) {
16214						dist = Math.abs( event[ axis ] - cur );
16215						itemWithLeastDistance = this.items[ j ];
16216						this.direction = nearBottom ? "up" : "down";
16217					}
16218				}
16219
16220				//Check if dropOnEmpty is enabled
16221				if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {
16222					return;
16223				}
16224
16225				if ( this.currentContainer === this.containers[ innermostIndex ] ) {
16226					if ( !this.currentContainer.containerCache.over ) {
16227						this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
16228						this.currentContainer.containerCache.over = 1;
16229					}
16230					return;
16231				}
16232
16233				itemWithLeastDistance ?
16234					this._rearrange( event, itemWithLeastDistance, null, true ) :
16235					this._rearrange( event, null, this.containers[ innermostIndex ].element, true );
16236				this._trigger( "change", event, this._uiHash() );
16237				this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) );
16238				this.currentContainer = this.containers[ innermostIndex ];
16239
16240				//Update the placeholder
16241				this.options.placeholder.update( this.currentContainer, this.placeholder );
16242
16243				this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
16244				this.containers[ innermostIndex ].containerCache.over = 1;
16245			}
16246
16247		},
16248
16249		_createHelper: function( event ) {
16250
16251			var o = this.options,
16252				helper = $.isFunction( o.helper ) ?
16253					$( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :
16254					( o.helper === "clone" ? this.currentItem.clone() : this.currentItem );
16255
16256			//Add the helper to the DOM if that didn't happen already
16257			if ( !helper.parents( "body" ).length ) {
16258				$( o.appendTo !== "parent" ?
16259					o.appendTo :
16260					this.currentItem[ 0 ].parentNode )[ 0 ].appendChild( helper[ 0 ] );
16261			}
16262
16263			if ( helper[ 0 ] === this.currentItem[ 0 ] ) {
16264				this._storedCSS = {
16265					width: this.currentItem[ 0 ].style.width,
16266					height: this.currentItem[ 0 ].style.height,
16267					position: this.currentItem.css( "position" ),
16268					top: this.currentItem.css( "top" ),
16269					left: this.currentItem.css( "left" )
16270				};
16271			}
16272
16273			if ( !helper[ 0 ].style.width || o.forceHelperSize ) {
16274				helper.width( this.currentItem.width() );
16275			}
16276			if ( !helper[ 0 ].style.height || o.forceHelperSize ) {
16277				helper.height( this.currentItem.height() );
16278			}
16279
16280			return helper;
16281
16282		},
16283
16284		_adjustOffsetFromHelper: function( obj ) {
16285			if ( typeof obj === "string" ) {
16286				obj = obj.split( " " );
16287			}
16288			if ( $.isArray( obj ) ) {
16289				obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
16290			}
16291			if ( "left" in obj ) {
16292				this.offset.click.left = obj.left + this.margins.left;
16293			}
16294			if ( "right" in obj ) {
16295				this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
16296			}
16297			if ( "top" in obj ) {
16298				this.offset.click.top = obj.top + this.margins.top;
16299			}
16300			if ( "bottom" in obj ) {
16301				this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
16302			}
16303		},
16304
16305		_getParentOffset: function() {
16306
16307			//Get the offsetParent and cache its position
16308			this.offsetParent = this.helper.offsetParent();
16309			var po = this.offsetParent.offset();
16310
16311			// This is a special case where we need to modify a offset calculated on start, since the
16312			// following happened:
16313			// 1. The position of the helper is absolute, so it's position is calculated based on the
16314			// next positioned parent
16315			// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
16316			// the document, which means that the scroll is included in the initial calculation of the
16317			// offset of the parent, and never recalculated upon drag
16318			if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16319				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
16320				po.left += this.scrollParent.scrollLeft();
16321				po.top += this.scrollParent.scrollTop();
16322			}
16323
16324			// This needs to be actually done for all browsers, since pageX/pageY includes this
16325			// information with an ugly IE fix
16326			if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ||
16327				( this.offsetParent[ 0 ].tagName &&
16328				this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) {
16329				po = { top: 0, left: 0 };
16330			}
16331
16332			return {
16333				top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
16334				left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
16335			};
16336
16337		},
16338
16339		_getRelativeOffset: function() {
16340
16341			if ( this.cssPosition === "relative" ) {
16342				var p = this.currentItem.position();
16343				return {
16344					top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
16345					this.scrollParent.scrollTop(),
16346					left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
16347					this.scrollParent.scrollLeft()
16348				};
16349			} else {
16350				return { top: 0, left: 0 };
16351			}
16352
16353		},
16354
16355		_cacheMargins: function() {
16356			this.margins = {
16357				left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ),
16358				top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 )
16359			};
16360		},
16361
16362		_cacheHelperProportions: function() {
16363			this.helperProportions = {
16364				width: this.helper.outerWidth(),
16365				height: this.helper.outerHeight()
16366			};
16367		},
16368
16369		_setContainment: function() {
16370
16371			var ce, co, over,
16372				o = this.options;
16373			if ( o.containment === "parent" ) {
16374				o.containment = this.helper[ 0 ].parentNode;
16375			}
16376			if ( o.containment === "document" || o.containment === "window" ) {
16377				this.containment = [
16378					0 - this.offset.relative.left - this.offset.parent.left,
16379					0 - this.offset.relative.top - this.offset.parent.top,
16380					o.containment === "document" ?
16381						this.document.width() :
16382					this.window.width() - this.helperProportions.width - this.margins.left,
16383					( o.containment === "document" ?
16384							( this.document.height() || document.body.parentNode.scrollHeight ) :
16385						this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight
16386					) - this.helperProportions.height - this.margins.top
16387				];
16388			}
16389
16390			if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {
16391				ce = $( o.containment )[ 0 ];
16392				co = $( o.containment ).offset();
16393				over = ( $( ce ).css( "overflow" ) !== "hidden" );
16394
16395				this.containment = [
16396					co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) +
16397					( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left,
16398					co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) +
16399					( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top,
16400					co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
16401					( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) -
16402					( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) -
16403					this.helperProportions.width - this.margins.left,
16404					co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
16405					( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) -
16406					( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) -
16407					this.helperProportions.height - this.margins.top
16408				];
16409			}
16410
16411		},
16412
16413		_convertPositionTo: function( d, pos ) {
16414
16415			if ( !pos ) {
16416				pos = this.position;
16417			}
16418			var mod = d === "absolute" ? 1 : -1,
16419				scroll = this.cssPosition === "absolute" &&
16420				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16421				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
16422					this.offsetParent :
16423					this.scrollParent,
16424				scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
16425
16426			return {
16427				top: (
16428
16429					// The absolute mouse position
16430					pos.top	+
16431
16432						// Only for relative positioned nodes: Relative offset from element to offset parent
16433					this.offset.relative.top * mod +
16434
16435						// The offsetParent's offset without borders (offset + border)
16436					this.offset.parent.top * mod -
16437					( ( this.cssPosition === "fixed" ?
16438						-this.scrollParent.scrollTop() :
16439						( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )
16440				),
16441				left: (
16442
16443					// The absolute mouse position
16444					pos.left +
16445
16446						// Only for relative positioned nodes: Relative offset from element to offset parent
16447					this.offset.relative.left * mod +
16448
16449						// The offsetParent's offset without borders (offset + border)
16450					this.offset.parent.left * mod	-
16451					( ( this.cssPosition === "fixed" ?
16452						-this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
16453						scroll.scrollLeft() ) * mod )
16454				)
16455			};
16456
16457		},
16458
16459		_generatePosition: function( event ) {
16460
16461			var top, left,
16462				o = this.options,
16463				pageX = event.pageX,
16464				pageY = event.pageY,
16465				scroll = this.cssPosition === "absolute" &&
16466				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16467				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
16468					this.offsetParent :
16469					this.scrollParent,
16470				scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
16471
16472			// This is another very weird special case that only happens for relative elements:
16473			// 1. If the css position is relative
16474			// 2. and the scroll parent is the document or similar to the offset parent
16475			// we have to refresh the relative offset during the scroll so there are no jumps
16476			if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16477				this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {
16478				this.offset.relative = this._getRelativeOffset();
16479			}
16480
16481			/*
16482			 * - Position constraining -
16483			 * Constrain the position to a mix of grid, containment.
16484			 */
16485
16486			if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options
16487
16488				if ( this.containment ) {
16489					if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {
16490						pageX = this.containment[ 0 ] + this.offset.click.left;
16491					}
16492					if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {
16493						pageY = this.containment[ 1 ] + this.offset.click.top;
16494					}
16495					if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {
16496						pageX = this.containment[ 2 ] + this.offset.click.left;
16497					}
16498					if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {
16499						pageY = this.containment[ 3 ] + this.offset.click.top;
16500					}
16501				}
16502
16503				if ( o.grid ) {
16504					top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /
16505							o.grid[ 1 ] ) * o.grid[ 1 ];
16506					pageY = this.containment ?
16507						( ( top - this.offset.click.top >= this.containment[ 1 ] &&
16508						top - this.offset.click.top <= this.containment[ 3 ] ) ?
16509							top :
16510							( ( top - this.offset.click.top >= this.containment[ 1 ] ) ?
16511							top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) :
16512						top;
16513
16514					left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /
16515							o.grid[ 0 ] ) * o.grid[ 0 ];
16516					pageX = this.containment ?
16517						( ( left - this.offset.click.left >= this.containment[ 0 ] &&
16518						left - this.offset.click.left <= this.containment[ 2 ] ) ?
16519							left :
16520							( ( left - this.offset.click.left >= this.containment[ 0 ] ) ?
16521							left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) :
16522						left;
16523				}
16524
16525			}
16526
16527			return {
16528				top: (
16529
16530					// The absolute mouse position
16531					pageY -
16532
16533						// Click offset (relative to the element)
16534					this.offset.click.top -
16535
16536						// Only for relative positioned nodes: Relative offset from element to offset parent
16537					this.offset.relative.top -
16538
16539						// The offsetParent's offset without borders (offset + border)
16540					this.offset.parent.top +
16541					( ( this.cssPosition === "fixed" ?
16542						-this.scrollParent.scrollTop() :
16543						( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )
16544				),
16545				left: (
16546
16547					// The absolute mouse position
16548					pageX -
16549
16550						// Click offset (relative to the element)
16551					this.offset.click.left -
16552
16553						// Only for relative positioned nodes: Relative offset from element to offset parent
16554					this.offset.relative.left -
16555
16556						// The offsetParent's offset without borders (offset + border)
16557					this.offset.parent.left +
16558					( ( this.cssPosition === "fixed" ?
16559						-this.scrollParent.scrollLeft() :
16560						scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
16561				)
16562			};
16563
16564		},
16565
16566		_rearrange: function( event, i, a, hardRefresh ) {
16567
16568			a ? a[ 0 ].appendChild( this.placeholder[ 0 ] ) :
16569				i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ],
16570					( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) );
16571
16572			//Various things done here to improve the performance:
16573			// 1. we create a setTimeout, that calls refreshPositions
16574			// 2. on the instance, we have a counter variable, that get's higher after every append
16575			// 3. on the local scope, we copy the counter variable, and check in the timeout,
16576			// if it's still the same
16577			// 4. this lets only the last addition to the timeout stack through
16578			this.counter = this.counter ? ++this.counter : 1;
16579			var counter = this.counter;
16580
16581			this._delay( function() {
16582				if ( counter === this.counter ) {
16583
16584					//Precompute after each DOM insertion, NOT on mousemove
16585					this.refreshPositions( !hardRefresh );
16586				}
16587			} );
16588
16589		},
16590
16591		_clear: function( event, noPropagation ) {
16592
16593			this.reverting = false;
16594
16595			// We delay all events that have to be triggered to after the point where the placeholder
16596			// has been removed and everything else normalized again
16597			var i,
16598				delayedTriggers = [];
16599
16600			// We first have to update the dom position of the actual currentItem
16601			// Note: don't do it if the current item is already removed (by a user), or it gets
16602			// reappended (see #4088)
16603			if ( !this._noFinalSort && this.currentItem.parent().length ) {
16604				this.placeholder.before( this.currentItem );
16605			}
16606			this._noFinalSort = null;
16607
16608			if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {
16609				for ( i in this._storedCSS ) {
16610					if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) {
16611						this._storedCSS[ i ] = "";
16612					}
16613				}
16614				this.currentItem.css( this._storedCSS );
16615				this._removeClass( this.currentItem, "ui-sortable-helper" );
16616			} else {
16617				this.currentItem.show();
16618			}
16619
16620			if ( this.fromOutside && !noPropagation ) {
16621				delayedTriggers.push( function( event ) {
16622					this._trigger( "receive", event, this._uiHash( this.fromOutside ) );
16623				} );
16624			}
16625			if ( ( this.fromOutside ||
16626				this.domPosition.prev !==
16627				this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] ||
16628				this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {
16629
16630				// Trigger update callback if the DOM position has changed
16631				delayedTriggers.push( function( event ) {
16632					this._trigger( "update", event, this._uiHash() );
16633				} );
16634			}
16635
16636			// Check if the items Container has Changed and trigger appropriate
16637			// events.
16638			if ( this !== this.currentContainer ) {
16639				if ( !noPropagation ) {
16640					delayedTriggers.push( function( event ) {
16641						this._trigger( "remove", event, this._uiHash() );
16642					} );
16643					delayedTriggers.push( ( function( c ) {
16644						return function( event ) {
16645							c._trigger( "receive", event, this._uiHash( this ) );
16646						};
16647					} ).call( this, this.currentContainer ) );
16648					delayedTriggers.push( ( function( c ) {
16649						return function( event ) {
16650							c._trigger( "update", event, this._uiHash( this ) );
16651						};
16652					} ).call( this, this.currentContainer ) );
16653				}
16654			}
16655
16656			//Post events to containers
16657			function delayEvent( type, instance, container ) {
16658				return function( event ) {
16659					container._trigger( type, event, instance._uiHash( instance ) );
16660				};
16661			}
16662			for ( i = this.containers.length - 1; i >= 0; i-- ) {
16663				if ( !noPropagation ) {
16664					delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
16665				}
16666				if ( this.containers[ i ].containerCache.over ) {
16667					delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
16668					this.containers[ i ].containerCache.over = 0;
16669				}
16670			}
16671
16672			//Do what was originally in plugins
16673			if ( this.storedCursor ) {
16674				this.document.find( "body" ).css( "cursor", this.storedCursor );
16675				this.storedStylesheet.remove();
16676			}
16677			if ( this._storedOpacity ) {
16678				this.helper.css( "opacity", this._storedOpacity );
16679			}
16680			if ( this._storedZIndex ) {
16681				this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex );
16682			}
16683
16684			this.dragging = false;
16685
16686			if ( !noPropagation ) {
16687				this._trigger( "beforeStop", event, this._uiHash() );
16688			}
16689
16690			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
16691			// it unbinds ALL events from the original node!
16692			this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
16693
16694			if ( !this.cancelHelperRemoval ) {
16695				if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
16696					this.helper.remove();
16697				}
16698				this.helper = null;
16699			}
16700
16701			if ( !noPropagation ) {
16702				for ( i = 0; i < delayedTriggers.length; i++ ) {
16703
16704					// Trigger all delayed events
16705					delayedTriggers[ i ].call( this, event );
16706				}
16707				this._trigger( "stop", event, this._uiHash() );
16708			}
16709
16710			this.fromOutside = false;
16711			return !this.cancelHelperRemoval;
16712
16713		},
16714
16715		_trigger: function() {
16716			if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {
16717				this.cancel();
16718			}
16719		},
16720
16721		_uiHash: function( _inst ) {
16722			var inst = _inst || this;
16723			return {
16724				helper: inst.helper,
16725				placeholder: inst.placeholder || $( [] ),
16726				position: inst.position,
16727				originalPosition: inst.originalPosition,
16728				offset: inst.positionAbs,
16729				item: inst.currentItem,
16730				sender: _inst ? _inst.element : null
16731			};
16732		}
16733
16734	} );
16735
16736
16737	/*!
vendor: 4,657 bytes, lines 16738-16904
16738	 * jQuery UI Spinner 1.12.1
16739	 * http://jqueryui.com
16740	 *
16741	 * Copyright jQuery Foundation and other contributors
16742	 * Released under the MIT license.
16743	 * http://jquery.org/license
16744	 */
16745
16746//>>label: Spinner
16747//>>group: Widgets
16748//>>description: Displays buttons to easily input numbers via the keyboard or mouse.
16749//>>docs: http://api.jqueryui.com/spinner/
16750//>>demos: http://jqueryui.com/spinner/
16751//>>css.structure: ../../themes/base/core.css
16752//>>css.structure: ../../themes/base/spinner.css
16753//>>css.theme: ../../themes/base/theme.css
16754
16755
16756
16757	function spinnerModifer( fn ) {
16758		return function() {
16759			var previous = this.element.val();
16760			fn.apply( this, arguments );
16761			this._refresh();
16762			if ( previous !== this.element.val() ) {
16763				this._trigger( "change" );
16764			}
16765		};
16766	}
16767
16768	$.widget( "ui.spinner", {
16769		version: "1.12.1",
16770		defaultElement: "<input>",
16771		widgetEventPrefix: "spin",
16772		options: {
16773			classes: {
16774				"ui-spinner": "ui-corner-all",
16775				"ui-spinner-down": "ui-corner-br",
16776				"ui-spinner-up": "ui-corner-tr"
16777			},
16778			culture: null,
16779			icons: {
16780				down: "ui-icon-triangle-1-s",
16781				up: "ui-icon-triangle-1-n"
16782			},
16783			incremental: true,
16784			max: null,
16785			min: null,
16786			numberFormat: null,
16787			page: 10,
16788			step: 1,
16789
16790			change: null,
16791			spin: null,
16792			start: null,
16793			stop: null
16794		},
16795
16796		_create: function() {
16797
16798			// handle string values that need to be parsed
16799			this._setOption( "max", this.options.max );
16800			this._setOption( "min", this.options.min );
16801			this._setOption( "step", this.options.step );
16802
16803			// Only format if there is a value, prevents the field from being marked
16804			// as invalid in Firefox, see #9573.
16805			if ( this.value() !== "" ) {
16806
16807				// Format the value, but don't constrain.
16808				this._value( this.element.val(), true );
16809			}
16810
16811			this._draw();
16812			this._on( this._events );
16813			this._refresh();
16814
16815			// Turning off autocomplete prevents the browser from remembering the
16816			// value when navigating through history, so we re-enable autocomplete
16817			// if the page is unloaded before the widget is destroyed. #7790
16818			this._on( this.window, {
16819				beforeunload: function() {
16820					this.element.removeAttr( "autocomplete" );
16821				}
16822			} );
16823		},
16824
16825		_getCreateOptions: function() {
16826			var options = this._super();
16827			var element = this.element;
16828
16829			$.each( [ "min", "max", "step" ], function( i, option ) {
16830				var value = element.attr( option );
16831				if ( value != null && value.length ) {
16832					options[ option ] = value;
16833				}
16834			} );
16835
16836			return options;
16837		},
16838
16839		_events: {
16840			keydown: function( event ) {
16841				if ( this._start( event ) && this._keydown( event ) ) {
16842					event.preventDefault();
16843				}
16844			},
16845			keyup: "_stop",
16846			focus: function() {
16847				this.previous = this.element.val();
16848			},
16849			blur: function( event ) {
16850				if ( this.cancelBlur ) {
16851					delete this.cancelBlur;
16852					return;
16853				}
16854
16855				this._stop();
16856				this._refresh();
16857				if ( this.previous !== this.element.val() ) {
16858					this._trigger( "change", event );
16859				}
16860			},
16861			mousewheel: function( event, delta ) {
16862				if ( !delta ) {
16863					return;
16864				}
16865				if ( !this.spinning && !this._start( event ) ) {
16866					return false;
16867				}
16868
16869				this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event );
16870				clearTimeout( this.mousewheelTimer );
16871				this.mousewheelTimer = this._delay( function() {
16872					if ( this.spinning ) {
16873						this._stop( event );
16874					}
16875				}, 100 );
16876				event.preventDefault();
16877			},
16878			"mousedown .ui-spinner-button": function( event ) {
16879				var previous;
16880
16881				// We never want the buttons to have focus; whenever the user is
16882				// interacting with the spinner, the focus should be on the input.
16883				// If the input is focused then this.previous is properly set from
16884				// when the input first received focus. If the input is not focused
16885				// then we need to set this.previous based on the value before spinning.
16886				previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ?
16887					this.previous : this.element.val();
16888				function checkFocus() {
16889					var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] );
16890					if ( !isActive ) {
16891						this.element.trigger( "focus" );
16892						this.previous = previous;
16893
16894						// support: IE
16895						// IE sets focus asynchronously, so we need to check if focus
16896						// moved off of the input because the user clicked on the button.
16897						this._delay( function() {
16898							this.previous = previous;
16899						} );
16900					}
16901				}
16902
16903				// Ensure focus is on (or stays on) the text field
16904				event.preventDefault();
vendor: 6,177 bytes, lines 16905-17134
16905				checkFocus.call( this );
16906
16907				// Support: IE
16908				// IE doesn't prevent moving focus even with event.preventDefault()
16909				// so we set a flag to know when we should ignore the blur event
16910				// and check (again) if focus moved off of the input.
16911				this.cancelBlur = true;
16912				this._delay( function() {
16913					delete this.cancelBlur;
16914					checkFocus.call( this );
16915				} );
16916
16917				if ( this._start( event ) === false ) {
16918					return;
16919				}
16920
16921				this._repeat( null, $( event.currentTarget )
16922					.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
16923			},
16924			"mouseup .ui-spinner-button": "_stop",
16925			"mouseenter .ui-spinner-button": function( event ) {
16926
16927				// button will add ui-state-active if mouse was down while mouseleave and kept down
16928				if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
16929					return;
16930				}
16931
16932				if ( this._start( event ) === false ) {
16933					return false;
16934				}
16935				this._repeat( null, $( event.currentTarget )
16936					.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
16937			},
16938
16939			// TODO: do we really want to consider this a stop?
16940			// shouldn't we just stop the repeater and wait until mouseup before
16941			// we trigger the stop event?
16942			"mouseleave .ui-spinner-button": "_stop"
16943		},
16944
16945		// Support mobile enhanced option and make backcompat more sane
16946		_enhance: function() {
16947			this.uiSpinner = this.element
16948				.attr( "autocomplete", "off" )
16949				.wrap( "<span>" )
16950				.parent()
16951
16952				// Add buttons
16953				.append(
16954				"<a></a><a></a>"
16955			);
16956		},
16957
16958		_draw: function() {
16959			this._enhance();
16960
16961			this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" );
16962			this._addClass( "ui-spinner-input" );
16963
16964			this.element.attr( "role", "spinbutton" );
16965
16966			// Button bindings
16967			this.buttons = this.uiSpinner.children( "a" )
16968				.attr( "tabIndex", -1 )
16969				.attr( "aria-hidden", true )
16970				.button( {
16971					classes: {
16972						"ui-button": ""
16973					}
16974				} );
16975
16976			// TODO: Right now button does not support classes this is already updated in button PR
16977			this._removeClass( this.buttons, "ui-corner-all" );
16978
16979			this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" );
16980			this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" );
16981			this.buttons.first().button( {
16982				"icon": this.options.icons.up,
16983				"showLabel": false
16984			} );
16985			this.buttons.last().button( {
16986				"icon": this.options.icons.down,
16987				"showLabel": false
16988			} );
16989
16990			// IE 6 doesn't understand height: 50% for the buttons
16991			// unless the wrapper has an explicit height
16992			if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) &&
16993				this.uiSpinner.height() > 0 ) {
16994				this.uiSpinner.height( this.uiSpinner.height() );
16995			}
16996		},
16997
16998		_keydown: function( event ) {
16999			var options = this.options,
17000				keyCode = $.ui.keyCode;
17001
17002			switch ( event.keyCode ) {
17003				case keyCode.UP:
17004					this._repeat( null, 1, event );
17005					return true;
17006				case keyCode.DOWN:
17007					this._repeat( null, -1, event );
17008					return true;
17009				case keyCode.PAGE_UP:
17010					this._repeat( null, options.page, event );
17011					return true;
17012				case keyCode.PAGE_DOWN:
17013					this._repeat( null, -options.page, event );
17014					return true;
17015			}
17016
17017			return false;
17018		},
17019
17020		_start: function( event ) {
17021			if ( !this.spinning && this._trigger( "start", event ) === false ) {
17022				return false;
17023			}
17024
17025			if ( !this.counter ) {
17026				this.counter = 1;
17027			}
17028			this.spinning = true;
17029			return true;
17030		},
17031
17032		_repeat: function( i, steps, event ) {
17033			i = i || 500;
17034
17035			clearTimeout( this.timer );
17036			this.timer = this._delay( function() {
17037				this._repeat( 40, steps, event );
17038			}, i );
17039
17040			this._spin( steps * this.options.step, event );
17041		},
17042
17043		_spin: function( step, event ) {
17044			var value = this.value() || 0;
17045
17046			if ( !this.counter ) {
17047				this.counter = 1;
17048			}
17049
17050			value = this._adjustValue( value + step * this._increment( this.counter ) );
17051
17052			if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) {
17053				this._value( value );
17054				this.counter++;
17055			}
17056		},
17057
17058		_increment: function( i ) {
17059			var incremental = this.options.incremental;
17060
17061			if ( incremental ) {
17062				return $.isFunction( incremental ) ?
17063					incremental( i ) :
17064					Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
17065			}
17066
17067			return 1;
17068		},
17069
17070		_precision: function() {
17071			var precision = this._precisionOf( this.options.step );
17072			if ( this.options.min !== null ) {
17073				precision = Math.max( precision, this._precisionOf( this.options.min ) );
17074			}
17075			return precision;
17076		},
17077
17078		_precisionOf: function( num ) {
17079			var str = num.toString(),
17080				decimal = str.indexOf( "." );
17081			return decimal === -1 ? 0 : str.length - decimal - 1;
17082		},
17083
17084		_adjustValue: function( value ) {
17085			var base, aboveMin,
17086				options = this.options;
17087
17088			// Make sure we're at a valid step
17089			// - find out where we are relative to the base (min or 0)
17090			base = options.min !== null ? options.min : 0;
17091			aboveMin = value - base;
17092
17093			// - round to the nearest step
17094			aboveMin = Math.round( aboveMin / options.step ) * options.step;
17095
17096			// - rounding is based on 0, so adjust back to our base
17097			value = base + aboveMin;
17098
17099			// Fix precision from bad JS floating point math
17100			value = parseFloat( value.toFixed( this._precision() ) );
17101
17102			// Clamp the value
17103			if ( options.max !== null && value > options.max ) {
17104				return options.max;
17105			}
17106			if ( options.min !== null && value < options.min ) {
17107				return options.min;
17108			}
17109
17110			return value;
17111		},
17112
17113		_stop: function( event ) {
17114			if ( !this.spinning ) {
17115				return;
17116			}
17117
17118			clearTimeout( this.timer );
17119			clearTimeout( this.mousewheelTimer );
17120			this.counter = 0;
17121			this.spinning = false;
17122			this._trigger( "stop", event );
17123		},
17124
17125		_setOption: function( key, value ) {
17126			var prevValue, first, last;
17127
17128			if ( key === "culture" || key === "numberFormat" ) {
17129				prevValue = this._parse( this.element.val() );
17130				this.options[ key ] = value;
17131				this.element.val( this._format( prevValue ) );
17132				return;
17133			}
17134
vendor: 4,162 bytes, lines 17135-17297
17135			if ( key === "max" || key === "min" || key === "step" ) {
17136				if ( typeof value === "string" ) {
17137					value = this._parse( value );
17138				}
17139			}
17140			if ( key === "icons" ) {
17141				first = this.buttons.first().find( ".ui-icon" );
17142				this._removeClass( first, null, this.options.icons.up );
17143				this._addClass( first, null, value.up );
17144				last = this.buttons.last().find( ".ui-icon" );
17145				this._removeClass( last, null, this.options.icons.down );
17146				this._addClass( last, null, value.down );
17147			}
17148
17149			this._super( key, value );
17150		},
17151
17152		_setOptionDisabled: function( value ) {
17153			this._super( value );
17154
17155			this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value );
17156			this.element.prop( "disabled", !!value );
17157			this.buttons.button( value ? "disable" : "enable" );
17158		},
17159
17160		_setOptions: spinnerModifer( function( options ) {
17161			this._super( options );
17162		} ),
17163
17164		_parse: function( val ) {
17165			if ( typeof val === "string" && val !== "" ) {
17166				val = window.Globalize && this.options.numberFormat ?
17167					Globalize.parseFloat( val, 10, this.options.culture ) : +val;
17168			}
17169			return val === "" || isNaN( val ) ? null : val;
17170		},
17171
17172		_format: function( value ) {
17173			if ( value === "" ) {
17174				return "";
17175			}
17176			return window.Globalize && this.options.numberFormat ?
17177				Globalize.format( value, this.options.numberFormat, this.options.culture ) :
17178				value;
17179		},
17180
17181		_refresh: function() {
17182			this.element.attr( {
17183				"aria-valuemin": this.options.min,
17184				"aria-valuemax": this.options.max,
17185
17186				// TODO: what should we do with values that can't be parsed?
17187				"aria-valuenow": this._parse( this.element.val() )
17188			} );
17189		},
17190
17191		isValid: function() {
17192			var value = this.value();
17193
17194			// Null is invalid
17195			if ( value === null ) {
17196				return false;
17197			}
17198
17199			// If value gets adjusted, it's invalid
17200			return value === this._adjustValue( value );
17201		},
17202
17203		// Update the value without triggering change
17204		_value: function( value, allowAny ) {
17205			var parsed;
17206			if ( value !== "" ) {
17207				parsed = this._parse( value );
17208				if ( parsed !== null ) {
17209					if ( !allowAny ) {
17210						parsed = this._adjustValue( parsed );
17211					}
17212					value = this._format( parsed );
17213				}
17214			}
17215			this.element.val( value );
17216			this._refresh();
17217		},
17218
17219		_destroy: function() {
17220			this.element
17221				.prop( "disabled", false )
17222				.removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" );
17223
17224			this.uiSpinner.replaceWith( this.element );
17225		},
17226
17227		stepUp: spinnerModifer( function( steps ) {
17228			this._stepUp( steps );
17229		} ),
17230		_stepUp: function( steps ) {
17231			if ( this._start() ) {
17232				this._spin( ( steps || 1 ) * this.options.step );
17233				this._stop();
17234			}
17235		},
17236
17237		stepDown: spinnerModifer( function( steps ) {
17238			this._stepDown( steps );
17239		} ),
17240		_stepDown: function( steps ) {
17241			if ( this._start() ) {
17242				this._spin( ( steps || 1 ) * -this.options.step );
17243				this._stop();
17244			}
17245		},
17246
17247		pageUp: spinnerModifer( function( pages ) {
17248			this._stepUp( ( pages || 1 ) * this.options.page );
17249		} ),
17250
17251		pageDown: spinnerModifer( function( pages ) {
17252			this._stepDown( ( pages || 1 ) * this.options.page );
17253		} ),
17254
17255		value: function( newVal ) {
17256			if ( !arguments.length ) {
17257				return this._parse( this.element.val() );
17258			}
17259			spinnerModifer( this._value ).call( this, newVal );
17260		},
17261
17262		widget: function() {
17263			return this.uiSpinner;
17264		}
17265	} );
17266
17267// DEPRECATED
17268// TODO: switch return back to widget declaration at top of file when this is removed
17269	if ( $.uiBackCompat !== false ) {
17270
17271		// Backcompat for spinner html extension points
17272		$.widget( "ui.spinner", $.ui.spinner, {
17273			_enhance: function() {
17274				this.uiSpinner = this.element
17275					.attr( "autocomplete", "off" )
17276					.wrap( this._uiSpinnerHtml() )
17277					.parent()
17278
17279					// Add buttons
17280					.append( this._buttonHtml() );
17281			},
17282			_uiSpinnerHtml: function() {
17283				return "<span>";
17284			},
17285
17286			_buttonHtml: function() {
17287				return "<a></a><a></a>";
17288			}
17289		} );
17290	}
17291
17292	var widgetsSpinner = $.ui.spinner;
17293
17294
17295	/*!
17296	 * jQuery UI Tabs 1.12.1
17297	 * http://jqueryui.com
17298	 *
17299	 * Copyright jQuery Foundation and other contributors
17300	 * Released under the MIT license.
17301	 * http://jquery.org/license
17302	 */
17303
17304//>>label: Tabs
17305//>>group: Widgets
17306//>>description: Transforms a set of container elements into a tab structure.
17307//>>docs: http://api.jqueryui.com/tabs/
17308//>>demos: http://jqueryui.com/tabs/
17309//>>css.structure: ../../themes/base/core.css
17310//>>css.structure: ../../themes/base/tabs.css
17311//>>css.theme: ../../themes/base/theme.css
17312
17313
17314
17315	$.widget( "ui.tabs", {
17316		version: "1.12.1",
17317		delay: 300,
17318		options: {
17319			active: null,
17320			classes: {
17321				"ui-tabs": "ui-corner-all",
17322				"ui-tabs-nav": "ui-corner-all",
17323				"ui-tabs-panel": "ui-corner-bottom",
17324				"ui-tabs-tab": "ui-corner-top"
17325			},
17326			collapsible: false,
17327			event: "click",
17328			heightStyle: "content",
17329			hide: null,
17330			show: null,
17331
17332			// Callbacks
17333			activate: null,
17334			beforeActivate: null,
17335			beforeLoad: null,
17336			load: null
17337		},
17338
17339		_isLocal: ( function() {
17340			var rhash = /#.*$/;
17341
17342			return function( anchor ) {
17343				var anchorUrl, locationUrl;
17344
17345				anchorUrl = anchor.href.replace( rhash, "" );
17346				locationUrl = location.href.replace( rhash, "" );
17347
17348				// Decoding may throw an error if the URL isn't UTF-8 (#9518)
vendor: 7,936 bytes, lines 17349-17631
17349				try {
17350					anchorUrl = decodeURIComponent( anchorUrl );
17351				} catch ( error ) {}
17352				try {
17353					locationUrl = decodeURIComponent( locationUrl );
17354				} catch ( error ) {}
17355
17356				return anchor.hash.length > 1 && anchorUrl === locationUrl;
17357			};
17358		} )(),
17359
17360		_create: function() {
17361			var that = this,
17362				options = this.options;
17363
17364			this.running = false;
17365
17366			this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
17367			this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
17368
17369			this._processTabs();
17370			options.active = this._initialActive();
17371
17372			// Take disabling tabs via class attribute from HTML
17373			// into account and update option properly.
17374			if ( $.isArray( options.disabled ) ) {
17375				options.disabled = $.unique( options.disabled.concat(
17376					$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
17377						return that.tabs.index( li );
17378					} )
17379				) ).sort();
17380			}
17381
17382			// Check for length avoids error when initializing empty list
17383			if ( this.options.active !== false && this.anchors.length ) {
17384				this.active = this._findActive( options.active );
17385			} else {
17386				this.active = $();
17387			}
17388
17389			this._refresh();
17390
17391			if ( this.active.length ) {
17392				this.load( options.active );
17393			}
17394		},
17395
17396		_initialActive: function() {
17397			var active = this.options.active,
17398				collapsible = this.options.collapsible,
17399				locationHash = location.hash.substring( 1 );
17400
17401			if ( active === null ) {
17402
17403				// check the fragment identifier in the URL
17404				if ( locationHash ) {
17405					this.tabs.each( function( i, tab ) {
17406						if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
17407							active = i;
17408							return false;
17409						}
17410					} );
17411				}
17412
17413				// Check for a tab marked active via a class
17414				if ( active === null ) {
17415					active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
17416				}
17417
17418				// No active tab, set to false
17419				if ( active === null || active === -1 ) {
17420					active = this.tabs.length ? 0 : false;
17421				}
17422			}
17423
17424			// Handle numbers: negative, out of range
17425			if ( active !== false ) {
17426				active = this.tabs.index( this.tabs.eq( active ) );
17427				if ( active === -1 ) {
17428					active = collapsible ? false : 0;
17429				}
17430			}
17431
17432			// Don't allow collapsible: false and active: false
17433			if ( !collapsible && active === false && this.anchors.length ) {
17434				active = 0;
17435			}
17436
17437			return active;
17438		},
17439
17440		_getCreateEventData: function() {
17441			return {
17442				tab: this.active,
17443				panel: !this.active.length ? $() : this._getPanelForTab( this.active )
17444			};
17445		},
17446
17447		_tabKeydown: function( event ) {
17448			var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ),
17449				selectedIndex = this.tabs.index( focusedTab ),
17450				goingForward = true;
17451
17452			if ( this._handlePageNav( event ) ) {
17453				return;
17454			}
17455
17456			switch ( event.keyCode ) {
17457				case $.ui.keyCode.RIGHT:
17458				case $.ui.keyCode.DOWN:
17459					selectedIndex++;
17460					break;
17461				case $.ui.keyCode.UP:
17462				case $.ui.keyCode.LEFT:
17463					goingForward = false;
17464					selectedIndex--;
17465					break;
17466				case $.ui.keyCode.END:
17467					selectedIndex = this.anchors.length - 1;
17468					break;
17469				case $.ui.keyCode.HOME:
17470					selectedIndex = 0;
17471					break;
17472				case $.ui.keyCode.SPACE:
17473
17474					// Activate only, no collapsing
17475					event.preventDefault();
17476					clearTimeout( this.activating );
17477					this._activate( selectedIndex );
17478					return;
17479				case $.ui.keyCode.ENTER:
17480
17481					// Toggle (cancel delayed activation, allow collapsing)
17482					event.preventDefault();
17483					clearTimeout( this.activating );
17484
17485					// Determine if we should collapse or activate
17486					this._activate( selectedIndex === this.options.active ? false : selectedIndex );
17487					return;
17488				default:
17489					return;
17490			}
17491
17492			// Focus the appropriate tab, based on which key was pressed
17493			event.preventDefault();
17494			clearTimeout( this.activating );
17495			selectedIndex = this._focusNextTab( selectedIndex, goingForward );
17496
17497			// Navigating with control/command key will prevent automatic activation
17498			if ( !event.ctrlKey && !event.metaKey ) {
17499
17500				// Update aria-selected immediately so that AT think the tab is already selected.
17501				// Otherwise AT may confuse the user by stating that they need to activate the tab,
17502				// but the tab will already be activated by the time the announcement finishes.
17503				focusedTab.attr( "aria-selected", "false" );
17504				this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
17505
17506				this.activating = this._delay( function() {
17507					this.option( "active", selectedIndex );
17508				}, this.delay );
17509			}
17510		},
17511
17512		_panelKeydown: function( event ) {
17513			if ( this._handlePageNav( event ) ) {
17514				return;
17515			}
17516
17517			// Ctrl+up moves focus to the current tab
17518			if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
17519				event.preventDefault();
17520				this.active.trigger( "focus" );
17521			}
17522		},
17523
17524		// Alt+page up/down moves focus to the previous/next tab (and activates)
17525		_handlePageNav: function( event ) {
17526			if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
17527				this._activate( this._focusNextTab( this.options.active - 1, false ) );
17528				return true;
17529			}
17530			if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
17531				this._activate( this._focusNextTab( this.options.active + 1, true ) );
17532				return true;
17533			}
17534		},
17535
17536		_findNextTab: function( index, goingForward ) {
17537			var lastTabIndex = this.tabs.length - 1;
17538
17539			function constrain() {
17540				if ( index > lastTabIndex ) {
17541					index = 0;
17542				}
17543				if ( index < 0 ) {
17544					index = lastTabIndex;
17545				}
17546				return index;
17547			}
17548
17549			while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
17550				index = goingForward ? index + 1 : index - 1;
17551			}
17552
17553			return index;
17554		},
17555
17556		_focusNextTab: function( index, goingForward ) {
17557			index = this._findNextTab( index, goingForward );
17558			this.tabs.eq( index ).trigger( "focus" );
17559			return index;
17560		},
17561
17562		_setOption: function( key, value ) {
17563			if ( key === "active" ) {
17564
17565				// _activate() will handle invalid values and update this.options
17566				this._activate( value );
17567				return;
17568			}
17569
17570			this._super( key, value );
17571
17572			if ( key === "collapsible" ) {
17573				this._toggleClass( "ui-tabs-collapsible", null, value );
17574
17575				// Setting collapsible: false while collapsed; open first panel
17576				if ( !value && this.options.active === false ) {
17577					this._activate( 0 );
17578				}
17579			}
17580
17581			if ( key === "event" ) {
17582				this._setupEvents( value );
17583			}
17584
17585			if ( key === "heightStyle" ) {
17586				this._setupHeightStyle( value );
17587			}
17588		},
17589
17590		_sanitizeSelector: function( hash ) {
17591			return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
17592		},
17593
17594		refresh: function() {
17595			var options = this.options,
17596				lis = this.tablist.children( ":has(a[href])" );
17597
17598			// Get disabled tabs from class attribute from HTML
17599			// this will get converted to a boolean if needed in _refresh()
17600			options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
17601				return lis.index( tab );
17602			} );
17603
17604			this._processTabs();
17605
17606			// Was collapsed or no tabs
17607			if ( options.active === false || !this.anchors.length ) {
17608				options.active = false;
17609				this.active = $();
17610
17611				// was active, but active tab is gone
17612			} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
17613
17614				// all remaining tabs are disabled
17615				if ( this.tabs.length === options.disabled.length ) {
17616					options.active = false;
17617					this.active = $();
17618
17619					// activate previous tab
17620				} else {
17621					this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
17622				}
17623
17624				// was active, active tab still exists
17625			} else {
17626
17627				// make sure active index is correct
17628				options.active = this.tabs.index( this.active );
17629			}
17630
17631			this._refresh();
vendor: 19,484 bytes, lines 17632-18337
17632		},
17633
17634		_refresh: function() {
17635			this._setOptionDisabled( this.options.disabled );
17636			this._setupEvents( this.options.event );
17637			this._setupHeightStyle( this.options.heightStyle );
17638
17639			this.tabs.not( this.active ).attr( {
17640				"aria-selected": "false",
17641				"aria-expanded": "false",
17642				tabIndex: -1
17643			} );
17644			this.panels.not( this._getPanelForTab( this.active ) )
17645				.hide()
17646				.attr( {
17647					"aria-hidden": "true"
17648				} );
17649
17650			// Make sure one tab is in the tab order
17651			if ( !this.active.length ) {
17652				this.tabs.eq( 0 ).attr( "tabIndex", 0 );
17653			} else {
17654				this.active
17655					.attr( {
17656						"aria-selected": "true",
17657						"aria-expanded": "true",
17658						tabIndex: 0
17659					} );
17660				this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
17661				this._getPanelForTab( this.active )
17662					.show()
17663					.attr( {
17664						"aria-hidden": "false"
17665					} );
17666			}
17667		},
17668
17669		_processTabs: function() {
17670			var that = this,
17671				prevTabs = this.tabs,
17672				prevAnchors = this.anchors,
17673				prevPanels = this.panels;
17674
17675			this.tablist = this._getList().attr( "role", "tablist" );
17676			this._addClass( this.tablist, "ui-tabs-nav",
17677				"ui-helper-reset ui-helper-clearfix ui-widget-header" );
17678
17679			// Prevent users from focusing disabled tabs via click
17680			this.tablist
17681				.on( "mousedown" + this.eventNamespace, "> li", function( event ) {
17682					if ( $( this ).is( ".ui-state-disabled" ) ) {
17683						event.preventDefault();
17684					}
17685				} )
17686
17687				// Support: IE <9
17688				// Preventing the default action in mousedown doesn't prevent IE
17689				// from focusing the element, so if the anchor gets focused, blur.
17690				// We don't have to worry about focusing the previously focused
17691				// element since clicking on a non-focusable element should focus
17692				// the body anyway.
17693				.on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() {
17694					if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
17695						this.blur();
17696					}
17697				} );
17698
17699			this.tabs = this.tablist.find( "> li:has(a[href])" )
17700				.attr( {
17701					role: "tab",
17702					tabIndex: -1
17703				} );
17704			this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" );
17705
17706			this.anchors = this.tabs.map( function() {
17707				return $( "a", this )[ 0 ];
17708			} )
17709				.attr( {
17710					role: "presentation",
17711					tabIndex: -1
17712				} );
17713			this._addClass( this.anchors, "ui-tabs-anchor" );
17714
17715			this.panels = $();
17716
17717			this.anchors.each( function( i, anchor ) {
17718				var selector, panel, panelId,
17719					anchorId = $( anchor ).uniqueId().attr( "id" ),
17720					tab = $( anchor ).closest( "li" ),
17721					originalAriaControls = tab.attr( "aria-controls" );
17722
17723				// Inline tab
17724				if ( that._isLocal( anchor ) ) {
17725					selector = anchor.hash;
17726					panelId = selector.substring( 1 );
17727					panel = that.element.find( that._sanitizeSelector( selector ) );
17728
17729					// remote tab
17730				} else {
17731
17732					// If the tab doesn't already have aria-controls,
17733					// generate an id by using a throw-away element
17734					panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
17735					selector = "#" + panelId;
17736					panel = that.element.find( selector );
17737					if ( !panel.length ) {
17738						panel = that._createPanel( panelId );
17739						panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
17740					}
17741					panel.attr( "aria-live", "polite" );
17742				}
17743
17744				if ( panel.length ) {
17745					that.panels = that.panels.add( panel );
17746				}
17747				if ( originalAriaControls ) {
17748					tab.data( "ui-tabs-aria-controls", originalAriaControls );
17749				}
17750				tab.attr( {
17751					"aria-controls": panelId,
17752					"aria-labelledby": anchorId
17753				} );
17754				panel.attr( "aria-labelledby", anchorId );
17755			} );
17756
17757			this.panels.attr( "role", "tabpanel" );
17758			this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
17759
17760			// Avoid memory leaks (#10056)
17761			if ( prevTabs ) {
17762				this._off( prevTabs.not( this.tabs ) );
17763				this._off( prevAnchors.not( this.anchors ) );
17764				this._off( prevPanels.not( this.panels ) );
17765			}
17766		},
17767
17768		// Allow overriding how to find the list for rare usage scenarios (#7715)
17769		_getList: function() {
17770			return this.tablist || this.element.find( "ol, ul" ).eq( 0 );
17771		},
17772
17773		_createPanel: function( id ) {
17774			return $( "<div>" )
17775				.attr( "id", id )
17776				.data( "ui-tabs-destroy", true );
17777		},
17778
17779		_setOptionDisabled: function( disabled ) {
17780			var currentItem, li, i;
17781
17782			if ( $.isArray( disabled ) ) {
17783				if ( !disabled.length ) {
17784					disabled = false;
17785				} else if ( disabled.length === this.anchors.length ) {
17786					disabled = true;
17787				}
17788			}
17789
17790			// Disable tabs
17791			for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
17792				currentItem = $( li );
17793				if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
17794					currentItem.attr( "aria-disabled", "true" );
17795					this._addClass( currentItem, null, "ui-state-disabled" );
17796				} else {
17797					currentItem.removeAttr( "aria-disabled" );
17798					this._removeClass( currentItem, null, "ui-state-disabled" );
17799				}
17800			}
17801
17802			this.options.disabled = disabled;
17803
17804			this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null,
17805				disabled === true );
17806		},
17807
17808		_setupEvents: function( event ) {
17809			var events = {};
17810			if ( event ) {
17811				$.each( event.split( " " ), function( index, eventName ) {
17812					events[ eventName ] = "_eventHandler";
17813				} );
17814			}
17815
17816			this._off( this.anchors.add( this.tabs ).add( this.panels ) );
17817
17818			// Always prevent the default action, even when disabled
17819			this._on( true, this.anchors, {
17820				click: function( event ) {
17821					event.preventDefault();
17822				}
17823			} );
17824			this._on( this.anchors, events );
17825			this._on( this.tabs, { keydown: "_tabKeydown" } );
17826			this._on( this.panels, { keydown: "_panelKeydown" } );
17827
17828			this._focusable( this.tabs );
17829			this._hoverable( this.tabs );
17830		},
17831
17832		_setupHeightStyle: function( heightStyle ) {
17833			var maxHeight,
17834				parent = this.element.parent();
17835
17836			if ( heightStyle === "fill" ) {
17837				maxHeight = parent.height();
17838				maxHeight -= this.element.outerHeight() - this.element.height();
17839
17840				this.element.siblings( ":visible" ).each( function() {
17841					var elem = $( this ),
17842						position = elem.css( "position" );
17843
17844					if ( position === "absolute" || position === "fixed" ) {
17845						return;
17846					}
17847					maxHeight -= elem.outerHeight( true );
17848				} );
17849
17850				this.element.children().not( this.panels ).each( function() {
17851					maxHeight -= $( this ).outerHeight( true );
17852				} );
17853
17854				this.panels.each( function() {
17855					$( this ).height( Math.max( 0, maxHeight -
17856						$( this ).innerHeight() + $( this ).height() ) );
17857				} )
17858					.css( "overflow", "auto" );
17859			} else if ( heightStyle === "auto" ) {
17860				maxHeight = 0;
17861				this.panels.each( function() {
17862					maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
17863				} ).height( maxHeight );
17864			}
17865		},
17866
17867		_eventHandler: function( event ) {
17868			var options = this.options,
17869				active = this.active,
17870				anchor = $( event.currentTarget ),
17871				tab = anchor.closest( "li" ),
17872				clickedIsActive = tab[ 0 ] === active[ 0 ],
17873				collapsing = clickedIsActive && options.collapsible,
17874				toShow = collapsing ? $() : this._getPanelForTab( tab ),
17875				toHide = !active.length ? $() : this._getPanelForTab( active ),
17876				eventData = {
17877					oldTab: active,
17878					oldPanel: toHide,
17879					newTab: collapsing ? $() : tab,
17880					newPanel: toShow
17881				};
17882
17883			event.preventDefault();
17884
17885			if ( tab.hasClass( "ui-state-disabled" ) ||
17886
17887					// tab is already loading
17888				tab.hasClass( "ui-tabs-loading" ) ||
17889
17890					// can't switch durning an animation
17891				this.running ||
17892
17893					// click on active header, but not collapsible
17894				( clickedIsActive && !options.collapsible ) ||
17895
17896					// allow canceling activation
17897				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
17898				return;
17899			}
17900
17901			options.active = collapsing ? false : this.tabs.index( tab );
17902
17903			this.active = clickedIsActive ? $() : tab;
17904			if ( this.xhr ) {
17905				this.xhr.abort();
17906			}
17907
17908			if ( !toHide.length && !toShow.length ) {
17909				$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
17910			}
17911
17912			if ( toShow.length ) {
17913				this.load( this.tabs.index( tab ), event );
17914			}
17915			this._toggle( event, eventData );
17916		},
17917
17918		// Handles show/hide for selecting tabs
17919		_toggle: function( event, eventData ) {
17920			var that = this,
17921				toShow = eventData.newPanel,
17922				toHide = eventData.oldPanel;
17923
17924			this.running = true;
17925
17926			function complete() {
17927				that.running = false;
17928				that._trigger( "activate", event, eventData );
17929			}
17930
17931			function show() {
17932				that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
17933
17934				if ( toShow.length && that.options.show ) {
17935					that._show( toShow, that.options.show, complete );
17936				} else {
17937					toShow.show();
17938					complete();
17939				}
17940			}
17941
17942			// Start out by hiding, then showing, then completing
17943			if ( toHide.length && this.options.hide ) {
17944				this._hide( toHide, this.options.hide, function() {
17945					that._removeClass( eventData.oldTab.closest( "li" ),
17946						"ui-tabs-active", "ui-state-active" );
17947					show();
17948				} );
17949			} else {
17950				this._removeClass( eventData.oldTab.closest( "li" ),
17951					"ui-tabs-active", "ui-state-active" );
17952				toHide.hide();
17953				show();
17954			}
17955
17956			toHide.attr( "aria-hidden", "true" );
17957			eventData.oldTab.attr( {
17958				"aria-selected": "false",
17959				"aria-expanded": "false"
17960			} );
17961
17962			// If we're switching tabs, remove the old tab from the tab order.
17963			// If we're opening from collapsed state, remove the previous tab from the tab order.
17964			// If we're collapsing, then keep the collapsing tab in the tab order.
17965			if ( toShow.length && toHide.length ) {
17966				eventData.oldTab.attr( "tabIndex", -1 );
17967			} else if ( toShow.length ) {
17968				this.tabs.filter( function() {
17969					return $( this ).attr( "tabIndex" ) === 0;
17970				} )
17971					.attr( "tabIndex", -1 );
17972			}
17973
17974			toShow.attr( "aria-hidden", "false" );
17975			eventData.newTab.attr( {
17976				"aria-selected": "true",
17977				"aria-expanded": "true",
17978				tabIndex: 0
17979			} );
17980		},
17981
17982		_activate: function( index ) {
17983			var anchor,
17984				active = this._findActive( index );
17985
17986			// Trying to activate the already active panel
17987			if ( active[ 0 ] === this.active[ 0 ] ) {
17988				return;
17989			}
17990
17991			// Trying to collapse, simulate a click on the current active header
17992			if ( !active.length ) {
17993				active = this.active;
17994			}
17995
17996			anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
17997			this._eventHandler( {
17998				target: anchor,
17999				currentTarget: anchor,
18000				preventDefault: $.noop
18001			} );
18002		},
18003
18004		_findActive: function( index ) {
18005			return index === false ? $() : this.tabs.eq( index );
18006		},
18007
18008		_getIndex: function( index ) {
18009
18010			// meta-function to give users option to provide a href string instead of a numerical index.
18011			if ( typeof index === "string" ) {
18012				index = this.anchors.index( this.anchors.filter( "[href$='" +
18013					$.ui.escapeSelector( index ) + "']" ) );
18014			}
18015
18016			return index;
18017		},
18018
18019		_destroy: function() {
18020			if ( this.xhr ) {
18021				this.xhr.abort();
18022			}
18023
18024			this.tablist
18025				.removeAttr( "role" )
18026				.off( this.eventNamespace );
18027
18028			this.anchors
18029				.removeAttr( "role tabIndex" )
18030				.removeUniqueId();
18031
18032			this.tabs.add( this.panels ).each( function() {
18033				if ( $.data( this, "ui-tabs-destroy" ) ) {
18034					$( this ).remove();
18035				} else {
18036					$( this ).removeAttr( "role tabIndex " +
18037						"aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" );
18038				}
18039			} );
18040
18041			this.tabs.each( function() {
18042				var li = $( this ),
18043					prev = li.data( "ui-tabs-aria-controls" );
18044				if ( prev ) {
18045					li
18046						.attr( "aria-controls", prev )
18047						.removeData( "ui-tabs-aria-controls" );
18048				} else {
18049					li.removeAttr( "aria-controls" );
18050				}
18051			} );
18052
18053			this.panels.show();
18054
18055			if ( this.options.heightStyle !== "content" ) {
18056				this.panels.css( "height", "" );
18057			}
18058		},
18059
18060		enable: function( index ) {
18061			var disabled = this.options.disabled;
18062			if ( disabled === false ) {
18063				return;
18064			}
18065
18066			if ( index === undefined ) {
18067				disabled = false;
18068			} else {
18069				index = this._getIndex( index );
18070				if ( $.isArray( disabled ) ) {
18071					disabled = $.map( disabled, function( num ) {
18072						return num !== index ? num : null;
18073					} );
18074				} else {
18075					disabled = $.map( this.tabs, function( li, num ) {
18076						return num !== index ? num : null;
18077					} );
18078				}
18079			}
18080			this._setOptionDisabled( disabled );
18081		},
18082
18083		disable: function( index ) {
18084			var disabled = this.options.disabled;
18085			if ( disabled === true ) {
18086				return;
18087			}
18088
18089			if ( index === undefined ) {
18090				disabled = true;
18091			} else {
18092				index = this._getIndex( index );
18093				if ( $.inArray( index, disabled ) !== -1 ) {
18094					return;
18095				}
18096				if ( $.isArray( disabled ) ) {
18097					disabled = $.merge( [ index ], disabled ).sort();
18098				} else {
18099					disabled = [ index ];
18100				}
18101			}
18102			this._setOptionDisabled( disabled );
18103		},
18104
18105		load: function( index, event ) {
18106			index = this._getIndex( index );
18107			var that = this,
18108				tab = this.tabs.eq( index ),
18109				anchor = tab.find( ".ui-tabs-anchor" ),
18110				panel = this._getPanelForTab( tab ),
18111				eventData = {
18112					tab: tab,
18113					panel: panel
18114				},
18115				complete = function( jqXHR, status ) {
18116					if ( status === "abort" ) {
18117						that.panels.stop( false, true );
18118					}
18119
18120					that._removeClass( tab, "ui-tabs-loading" );
18121					panel.removeAttr( "aria-busy" );
18122
18123					if ( jqXHR === that.xhr ) {
18124						delete that.xhr;
18125					}
18126				};
18127
18128			// Not remote
18129			if ( this._isLocal( anchor[ 0 ] ) ) {
18130				return;
18131			}
18132
18133			this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
18134
18135			// Support: jQuery <1.8
18136			// jQuery <1.8 returns false if the request is canceled in beforeSend,
18137			// but as of 1.8, $.ajax() always returns a jqXHR object.
18138			if ( this.xhr && this.xhr.statusText !== "canceled" ) {
18139				this._addClass( tab, "ui-tabs-loading" );
18140				panel.attr( "aria-busy", "true" );
18141
18142				this.xhr
18143					.done( function( response, status, jqXHR ) {
18144
18145						// support: jQuery <1.8
18146						// http://bugs.jquery.com/ticket/11778
18147						setTimeout( function() {
18148							panel.html( response );
18149							that._trigger( "load", event, eventData );
18150
18151							complete( jqXHR, status );
18152						}, 1 );
18153					} )
18154					.fail( function( jqXHR, status ) {
18155
18156						// support: jQuery <1.8
18157						// http://bugs.jquery.com/ticket/11778
18158						setTimeout( function() {
18159							complete( jqXHR, status );
18160						}, 1 );
18161					} );
18162			}
18163		},
18164
18165		_ajaxSettings: function( anchor, event, eventData ) {
18166			var that = this;
18167			return {
18168
18169				// Support: IE <11 only
18170				// Strip any hash that exists to prevent errors with the Ajax request
18171				url: anchor.attr( "href" ).replace( /#.*$/, "" ),
18172				beforeSend: function( jqXHR, settings ) {
18173					return that._trigger( "beforeLoad", event,
18174						$.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
18175				}
18176			};
18177		},
18178
18179		_getPanelForTab: function( tab ) {
18180			var id = $( tab ).attr( "aria-controls" );
18181			return this.element.find( this._sanitizeSelector( "#" + id ) );
18182		}
18183	} );
18184
18185// DEPRECATED
18186// TODO: Switch return back to widget declaration at top of file when this is removed
18187	if ( $.uiBackCompat !== false ) {
18188
18189		// Backcompat for ui-tab class (now ui-tabs-tab)
18190		$.widget( "ui.tabs", $.ui.tabs, {
18191			_processTabs: function() {
18192				this._superApply( arguments );
18193				this._addClass( this.tabs, "ui-tab" );
18194			}
18195		} );
18196	}
18197
18198	var widgetsTabs = $.ui.tabs;
18199
18200
18201	/*!
18202	 * jQuery UI Tooltip 1.12.1
18203	 * http://jqueryui.com
18204	 *
18205	 * Copyright jQuery Foundation and other contributors
18206	 * Released under the MIT license.
18207	 * http://jquery.org/license
18208	 */
18209
18210//>>label: Tooltip
18211//>>group: Widgets
18212//>>description: Shows additional information for any element on hover or focus.
18213//>>docs: http://api.jqueryui.com/tooltip/
18214//>>demos: http://jqueryui.com/tooltip/
18215//>>css.structure: ../../themes/base/core.css
18216//>>css.structure: ../../themes/base/tooltip.css
18217//>>css.theme: ../../themes/base/theme.css
18218
18219
18220
18221	$.widget( "ui.tooltip", {
18222		version: "1.12.1",
18223		options: {
18224			classes: {
18225				"ui-tooltip": "ui-corner-all ui-widget-shadow"
18226			},
18227			content: function() {
18228
18229				// support: IE<9, Opera in jQuery <1.7
18230				// .text() can't accept undefined, so coerce to a string
18231				var title = $( this ).attr( "title" ) || "";
18232
18233				// Escape title, since we're going from an attribute to raw HTML
18234				return $( "<a>" ).text( title ).html();
18235			},
18236			hide: true,
18237
18238			// Disabled elements have inconsistent behavior across browsers (#8661)
18239			items: "[title]:not([disabled])",
18240			position: {
18241				my: "left top+15",
18242				at: "left bottom",
18243				collision: "flipfit flip"
18244			},
18245			show: true,
18246			track: false,
18247
18248			// Callbacks
18249			close: null,
18250			open: null
18251		},
18252
18253		_addDescribedBy: function( elem, id ) {
18254			var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ );
18255			describedby.push( id );
18256			elem
18257				.data( "ui-tooltip-id", id )
18258				.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
18259		},
18260
18261		_removeDescribedBy: function( elem ) {
18262			var id = elem.data( "ui-tooltip-id" ),
18263				describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ),
18264				index = $.inArray( id, describedby );
18265
18266			if ( index !== -1 ) {
18267				describedby.splice( index, 1 );
18268			}
18269
18270			elem.removeData( "ui-tooltip-id" );
18271			describedby = $.trim( describedby.join( " " ) );
18272			if ( describedby ) {
18273				elem.attr( "aria-describedby", describedby );
18274			} else {
18275				elem.removeAttr( "aria-describedby" );
18276			}
18277		},
18278
18279		_create: function() {
18280			this._on( {
18281				mouseover: "open",
18282				focusin: "open"
18283			} );
18284
18285			// IDs of generated tooltips, needed for destroy
18286			this.tooltips = {};
18287
18288			// IDs of parent tooltips where we removed the title attribute
18289			this.parents = {};
18290
18291			// Append the aria-live region so tooltips announce correctly
18292			this.liveRegion = $( "<div>" )
18293				.attr( {
18294					role: "log",
18295					"aria-live": "assertive",
18296					"aria-relevant": "additions"
18297				} )
18298				.appendTo( this.document[ 0 ].body );
18299			this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
18300
18301			this.disabledTitles = $( [] );
18302		},
18303
18304		_setOption: function( key, value ) {
18305			var that = this;
18306
18307			this._super( key, value );
18308
18309			if ( key === "content" ) {
18310				$.each( this.tooltips, function( id, tooltipData ) {
18311					that._updateContent( tooltipData.element );
18312				} );
18313			}
18314		},
18315
18316		_setOptionDisabled: function( value ) {
18317			this[ value ? "_disable" : "_enable" ]();
18318		},
18319
18320		_disable: function() {
18321			var that = this;
18322
18323			// Close open tooltips
18324			$.each( this.tooltips, function( id, tooltipData ) {
18325				var event = $.Event( "blur" );
18326				event.target = event.currentTarget = tooltipData.element[ 0 ];
18327				that.close( event, true );
18328			} );
18329
18330			// Remove title attributes to prevent native tooltips
18331			this.disabledTitles = this.disabledTitles.add(
18332				this.element.find( this.options.items ).addBack()
18333					.filter( function() {
18334						var element = $( this );
18335						if ( element.is( "[title]" ) ) {
18336							return element
18337								.data( "ui-tooltip-title", element.attr( "title" ) )
vendor: 4,233 bytes, lines 18338-18473
18338								.removeAttr( "title" );
18339						}
18340					} )
18341			);
18342		},
18343
18344		_enable: function() {
18345
18346			// restore title attributes
18347			this.disabledTitles.each( function() {
18348				var element = $( this );
18349				if ( element.data( "ui-tooltip-title" ) ) {
18350					element.attr( "title", element.data( "ui-tooltip-title" ) );
18351				}
18352			} );
18353			this.disabledTitles = $( [] );
18354		},
18355
18356		open: function( event ) {
18357			var that = this,
18358				target = $( event ? event.target : this.element )
18359
18360					// we need closest here due to mouseover bubbling,
18361					// but always pointing at the same event target
18362					.closest( this.options.items );
18363
18364			// No element to show a tooltip for or the tooltip is already open
18365			if ( !target.length || target.data( "ui-tooltip-id" ) ) {
18366				return;
18367			}
18368
18369			if ( target.attr( "title" ) ) {
18370				target.data( "ui-tooltip-title", target.attr( "title" ) );
18371			}
18372
18373			target.data( "ui-tooltip-open", true );
18374
18375			// Kill parent tooltips, custom or native, for hover
18376			if ( event && event.type === "mouseover" ) {
18377				target.parents().each( function() {
18378					var parent = $( this ),
18379						blurEvent;
18380					if ( parent.data( "ui-tooltip-open" ) ) {
18381						blurEvent = $.Event( "blur" );
18382						blurEvent.target = blurEvent.currentTarget = this;
18383						that.close( blurEvent, true );
18384					}
18385					if ( parent.attr( "title" ) ) {
18386						parent.uniqueId();
18387						that.parents[ this.id ] = {
18388							element: this,
18389							title: parent.attr( "title" )
18390						};
18391						parent.attr( "title", "" );
18392					}
18393				} );
18394			}
18395
18396			this._registerCloseHandlers( event, target );
18397			this._updateContent( target, event );
18398		},
18399
18400		_updateContent: function( target, event ) {
18401			var content,
18402				contentOption = this.options.content,
18403				that = this,
18404				eventType = event ? event.type : null;
18405
18406			if ( typeof contentOption === "string" || contentOption.nodeType ||
18407				contentOption.jquery ) {
18408				return this._open( event, target, contentOption );
18409			}
18410
18411			content = contentOption.call( target[ 0 ], function( response ) {
18412
18413				// IE may instantly serve a cached response for ajax requests
18414				// delay this call to _open so the other call to _open runs first
18415				that._delay( function() {
18416
18417					// Ignore async response if tooltip was closed already
18418					if ( !target.data( "ui-tooltip-open" ) ) {
18419						return;
18420					}
18421
18422					// JQuery creates a special event for focusin when it doesn't
18423					// exist natively. To improve performance, the native event
18424					// object is reused and the type is changed. Therefore, we can't
18425					// rely on the type being correct after the event finished
18426					// bubbling, so we set it back to the previous value. (#8740)
18427					if ( event ) {
18428						event.type = eventType;
18429					}
18430					this._open( event, target, response );
18431				} );
18432			} );
18433			if ( content ) {
18434				this._open( event, target, content );
18435			}
18436		},
18437
18438		_open: function( event, target, content ) {
18439			var tooltipData, tooltip, delayedShow, a11yContent,
18440				positionOption = $.extend( {}, this.options.position );
18441
18442			if ( !content ) {
18443				return;
18444			}
18445
18446			// Content can be updated multiple times. If the tooltip already
18447			// exists, then just update the content and bail.
18448			tooltipData = this._find( target );
18449			if ( tooltipData ) {
18450				tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
18451				return;
18452			}
18453
18454			// If we have a title, clear it to prevent the native tooltip
18455			// we have to check first to avoid defining a title if none exists
18456			// (we don't want to cause an element to start matching [title])
18457			//
18458			// We use removeAttr only for key events, to allow IE to export the correct
18459			// accessible attributes. For mouse events, set to empty string to avoid
18460			// native tooltip showing up (happens only when removing inside mouseover).
18461			if ( target.is( "[title]" ) ) {
18462				if ( event && event.type === "mouseover" ) {
18463					target.attr( "title", "" );
18464				} else {
18465					target.removeAttr( "title" );
18466				}
18467			}
18468
18469			tooltipData = this._tooltip( target );
18470			tooltip = tooltipData.tooltip;
18471			this._addDescribedBy( target, tooltip.attr( "id" ) );
18472			tooltip.find( ".ui-tooltip-content" ).html( content );
18473
vendor: 6,988 bytes, lines 18474-18707
18474			// Support: Voiceover on OS X, JAWS on IE <= 9
18475			// JAWS announces deletions even when aria-relevant="additions"
18476			// Voiceover will sometimes re-read the entire log region's contents from the beginning
18477			this.liveRegion.children().hide();
18478			a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() );
18479			a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" );
18480			a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
18481			a11yContent.appendTo( this.liveRegion );
18482
18483			function position( event ) {
18484				positionOption.of = event;
18485				if ( tooltip.is( ":hidden" ) ) {
18486					return;
18487				}
18488				tooltip.position( positionOption );
18489			}
18490			if ( this.options.track && event && /^mouse/.test( event.type ) ) {
18491				this._on( this.document, {
18492					mousemove: position
18493				} );
18494
18495				// trigger once to override element-relative positioning
18496				position( event );
18497			} else {
18498				tooltip.position( $.extend( {
18499					of: target
18500				}, this.options.position ) );
18501			}
18502
18503			tooltip.hide();
18504
18505			this._show( tooltip, this.options.show );
18506
18507			// Handle tracking tooltips that are shown with a delay (#8644). As soon
18508			// as the tooltip is visible, position the tooltip using the most recent
18509			// event.
18510			// Adds the check to add the timers only when both delay and track options are set (#14682)
18511			if ( this.options.track && this.options.show && this.options.show.delay ) {
18512				delayedShow = this.delayedShow = setInterval( function() {
18513					if ( tooltip.is( ":visible" ) ) {
18514						position( positionOption.of );
18515						clearInterval( delayedShow );
18516					}
18517				}, $.fx.interval );
18518			}
18519
18520			this._trigger( "open", event, { tooltip: tooltip } );
18521		},
18522
18523		_registerCloseHandlers: function( event, target ) {
18524			var events = {
18525				keyup: function( event ) {
18526					if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
18527						var fakeEvent = $.Event( event );
18528						fakeEvent.currentTarget = target[ 0 ];
18529						this.close( fakeEvent, true );
18530					}
18531				}
18532			};
18533
18534			// Only bind remove handler for delegated targets. Non-delegated
18535			// tooltips will handle this in destroy.
18536			if ( target[ 0 ] !== this.element[ 0 ] ) {
18537				events.remove = function() {
18538					this._removeTooltip( this._find( target ).tooltip );
18539				};
18540			}
18541
18542			if ( !event || event.type === "mouseover" ) {
18543				events.mouseleave = "close";
18544			}
18545			if ( !event || event.type === "focusin" ) {
18546				events.focusout = "close";
18547			}
18548			this._on( true, target, events );
18549		},
18550
18551		close: function( event ) {
18552			var tooltip,
18553				that = this,
18554				target = $( event ? event.currentTarget : this.element ),
18555				tooltipData = this._find( target );
18556
18557			// The tooltip may already be closed
18558			if ( !tooltipData ) {
18559
18560				// We set ui-tooltip-open immediately upon open (in open()), but only set the
18561				// additional data once there's actually content to show (in _open()). So even if the
18562				// tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
18563				// the period between open() and _open().
18564				target.removeData( "ui-tooltip-open" );
18565				return;
18566			}
18567
18568			tooltip = tooltipData.tooltip;
18569
18570			// Disabling closes the tooltip, so we need to track when we're closing
18571			// to avoid an infinite loop in case the tooltip becomes disabled on close
18572			if ( tooltipData.closing ) {
18573				return;
18574			}
18575
18576			// Clear the interval for delayed tracking tooltips
18577			clearInterval( this.delayedShow );
18578
18579			// Only set title if we had one before (see comment in _open())
18580			// If the title attribute has changed since open(), don't restore
18581			if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
18582				target.attr( "title", target.data( "ui-tooltip-title" ) );
18583			}
18584
18585			this._removeDescribedBy( target );
18586
18587			tooltipData.hiding = true;
18588			tooltip.stop( true );
18589			this._hide( tooltip, this.options.hide, function() {
18590				that._removeTooltip( $( this ) );
18591			} );
18592
18593			target.removeData( "ui-tooltip-open" );
18594			this._off( target, "mouseleave focusout keyup" );
18595
18596			// Remove 'remove' binding only on delegated targets
18597			if ( target[ 0 ] !== this.element[ 0 ] ) {
18598				this._off( target, "remove" );
18599			}
18600			this._off( this.document, "mousemove" );
18601
18602			if ( event && event.type === "mouseleave" ) {
18603				$.each( this.parents, function( id, parent ) {
18604					$( parent.element ).attr( "title", parent.title );
18605					delete that.parents[ id ];
18606				} );
18607			}
18608
18609			tooltipData.closing = true;
18610			this._trigger( "close", event, { tooltip: tooltip } );
18611			if ( !tooltipData.hiding ) {
18612				tooltipData.closing = false;
18613			}
18614		},
18615
18616		_tooltip: function( element ) {
18617			var tooltip = $( "<div>" ).attr( "role", "tooltip" ),
18618				content = $( "<div>" ).appendTo( tooltip ),
18619				id = tooltip.uniqueId().attr( "id" );
18620
18621			this._addClass( content, "ui-tooltip-content" );
18622			this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" );
18623
18624			tooltip.appendTo( this._appendTo( element ) );
18625
18626			return this.tooltips[ id ] = {
18627				element: element,
18628				tooltip: tooltip
18629			};
18630		},
18631
18632		_find: function( target ) {
18633			var id = target.data( "ui-tooltip-id" );
18634			return id ? this.tooltips[ id ] : null;
18635		},
18636
18637		_removeTooltip: function( tooltip ) {
18638			tooltip.remove();
18639			delete this.tooltips[ tooltip.attr( "id" ) ];
18640		},
18641
18642		_appendTo: function( target ) {
18643			var element = target.closest( ".ui-front, dialog" );
18644
18645			if ( !element.length ) {
18646				element = this.document[ 0 ].body;
18647			}
18648
18649			return element;
18650		},
18651
18652		_destroy: function() {
18653			var that = this;
18654
18655			// Close open tooltips
18656			$.each( this.tooltips, function( id, tooltipData ) {
18657
18658				// Delegate to close method to handle common cleanup
18659				var event = $.Event( "blur" ),
18660					element = tooltipData.element;
18661				event.target = event.currentTarget = element[ 0 ];
18662				that.close( event, true );
18663
18664				// Remove immediately; destroying an open tooltip doesn't use the
18665				// hide animation
18666				$( "#" + id ).remove();
18667
18668				// Restore the title
18669				if ( element.data( "ui-tooltip-title" ) ) {
18670
18671					// If the title attribute has changed since open(), don't restore
18672					if ( !element.attr( "title" ) ) {
18673						element.attr( "title", element.data( "ui-tooltip-title" ) );
18674					}
18675					element.removeData( "ui-tooltip-title" );
18676				}
18677			} );
18678			this.liveRegion.remove();
18679		}
18680	} );
18681
18682// DEPRECATED
18683// TODO: Switch return back to widget declaration at top of file when this is removed
18684	if ( $.uiBackCompat !== false ) {
18685
18686		// Backcompat for tooltipClass option
18687		$.widget( "ui.tooltip", $.ui.tooltip, {
18688			options: {
18689				tooltipClass: null
18690			},
18691			_tooltip: function() {
18692				var tooltipData = this._superApply( arguments );
18693				if ( this.options.tooltipClass ) {
18694					tooltipData.tooltip.addClass( this.options.tooltipClass );
18695				}
18696				return tooltipData;
18697			}
18698		} );
18699	}
18700
18701	var widgetsTooltip = $.ui.tooltip;
18702
18703
18704
18705
18706}));
18707

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.