Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
/*! jQuery UI - v1.13.2 - 2022-07-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-patch.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
	"use strict";
8
 
9
	if ( typeof define === "function" && define.amd ) {
10
 
11
		// AMD. Register as an anonymous module.
12
		define( [ "jquery" ], factory );
13
	} else {
14
 
15
		// Browser globals
16
		factory( jQuery );
17
	}
18
} )( function( $ ) {
19
"use strict";
20
 
21
$.ui = $.ui || {};
22
 
23
var version = $.ui.version = "1.13.2";
24
 
25
 
26
/*!
27
 * jQuery UI Widget 1.13.2
28
 * http://jqueryui.com
29
 *
30
 * Copyright jQuery Foundation and other contributors
31
 * Released under the MIT license.
32
 * http://jquery.org/license
33
 */
34
 
35
//>>label: Widget
36
//>>group: Core
37
//>>description: Provides a factory for creating stateful widgets with a common API.
38
//>>docs: http://api.jqueryui.com/jQuery.widget/
39
//>>demos: http://jqueryui.com/widget/
40
 
41
 
42
var widgetUuid = 0;
43
var widgetHasOwnProperty = Array.prototype.hasOwnProperty;
44
var widgetSlice = Array.prototype.slice;
45
 
46
$.cleanData = ( function( orig ) {
47
	return function( elems ) {
48
		var events, elem, i;
49
		for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
50
 
51
			// Only trigger remove when necessary to save time
52
			events = $._data( elem, "events" );
53
			if ( events && events.remove ) {
54
				$( elem ).triggerHandler( "remove" );
55
			}
56
		}
57
		orig( elems );
58
	};
59
} )( $.cleanData );
60
 
61
$.widget = function( name, base, prototype ) {
62
	var existingConstructor, constructor, basePrototype;
63
 
64
	// ProxiedPrototype allows the provided prototype to remain unmodified
65
	// so that it can be used as a mixin for multiple widgets (#8876)
66
	var proxiedPrototype = {};
67
 
68
	var namespace = name.split( "." )[ 0 ];
69
	name = name.split( "." )[ 1 ];
70
	var fullName = namespace + "-" + name;
71
 
72
	if ( !prototype ) {
73
		prototype = base;
74
		base = $.Widget;
75
	}
76
 
77
	if ( Array.isArray( prototype ) ) {
78
		prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
79
	}
80
 
81
	// Create selector for plugin
82
	$.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) {
83
		return !!$.data( elem, fullName );
84
	};
85
 
86
	$[ namespace ] = $[ namespace ] || {};
87
	existingConstructor = $[ namespace ][ name ];
88
	constructor = $[ namespace ][ name ] = function( options, element ) {
89
 
90
		// Allow instantiation without "new" keyword
91
		if ( !this || !this._createWidget ) {
92
			return new constructor( options, element );
93
		}
94
 
95
		// Allow instantiation without initializing for simple inheritance
96
		// must use "new" keyword (the code above always passes args)
97
		if ( arguments.length ) {
98
			this._createWidget( options, element );
99
		}
100
	};
101
 
102
	// Extend with the existing constructor to carry over any static properties
103
	$.extend( constructor, existingConstructor, {
104
		version: prototype.version,
105
 
106
		// Copy the object used to create the prototype in case we need to
107
		// redefine the widget later
108
		_proto: $.extend( {}, prototype ),
109
 
110
		// Track widgets that inherit from this widget in case this widget is
111
		// redefined after a widget inherits from it
112
		_childConstructors: []
113
	} );
114
 
115
	basePrototype = new base();
116
 
117
	// We need to make the options hash a property directly on the new instance
118
	// otherwise we'll modify the options hash on the prototype that we're
119
	// inheriting from
120
	basePrototype.options = $.widget.extend( {}, basePrototype.options );
121
	$.each( prototype, function( prop, value ) {
122
		if ( typeof value !== "function" ) {
123
			proxiedPrototype[ prop ] = value;
124
			return;
125
		}
126
		proxiedPrototype[ prop ] = ( function() {
127
			function _super() {
128
				return base.prototype[ prop ].apply( this, arguments );
129
			}
130
 
131
			function _superApply( args ) {
132
				return base.prototype[ prop ].apply( this, args );
133
			}
134
 
135
			return function() {
136
				var __super = this._super;
137
				var __superApply = this._superApply;
138
				var returnValue;
139
 
140
				this._super = _super;
141
				this._superApply = _superApply;
142
 
143
				returnValue = value.apply( this, arguments );
144
 
145
				this._super = __super;
146
				this._superApply = __superApply;
147
 
148
				return returnValue;
149
			};
150
		} )();
151
	} );
152
	constructor.prototype = $.widget.extend( basePrototype, {
153
 
154
		// TODO: remove support for widgetEventPrefix
155
		// always use the name + a colon as the prefix, e.g., draggable:start
156
		// don't prefix for widgets that aren't DOM-based
157
		widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
158
	}, proxiedPrototype, {
159
		constructor: constructor,
160
		namespace: namespace,
161
		widgetName: name,
162
		widgetFullName: fullName
163
	} );
164
 
165
	// If this widget is being redefined then we need to find all widgets that
166
	// are inheriting from it and redefine all of them so that they inherit from
167
	// the new version of this widget. We're essentially trying to replace one
168
	// level in the prototype chain.
169
	if ( existingConstructor ) {
170
		$.each( existingConstructor._childConstructors, function( i, child ) {
171
			var childPrototype = child.prototype;
172
 
173
			// Redefine the child widget using the same prototype that was
174
			// originally used, but inherit from the new version of the base
175
			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
176
				child._proto );
177
		} );
178
 
179
		// Remove the list of existing child constructors from the old constructor
180
		// so the old child constructors can be garbage collected
181
		delete existingConstructor._childConstructors;
182
	} else {
183
		base._childConstructors.push( constructor );
184
	}
185
 
186
	$.widget.bridge( name, constructor );
187
 
188
	return constructor;
189
};
190
 
191
$.widget.extend = function( target ) {
192
	var input = widgetSlice.call( arguments, 1 );
193
	var inputIndex = 0;
194
	var inputLength = input.length;
195
	var key;
196
	var value;
197
 
198
	for ( ; inputIndex < inputLength; inputIndex++ ) {
199
		for ( key in input[ inputIndex ] ) {
200
			value = input[ inputIndex ][ key ];
201
			if ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) {
202
 
203
				// Clone objects
204
				if ( $.isPlainObject( value ) ) {
205
					target[ key ] = $.isPlainObject( target[ key ] ) ?
206
						$.widget.extend( {}, target[ key ], value ) :
207
 
208
						// Don't extend strings, arrays, etc. with objects
209
						$.widget.extend( {}, value );
210
 
211
				// Copy everything else by reference
212
				} else {
213
					target[ key ] = value;
214
				}
215
			}
216
		}
217
	}
218
	return target;
219
};
220
 
221
$.widget.bridge = function( name, object ) {
222
	var fullName = object.prototype.widgetFullName || name;
223
	$.fn[ name ] = function( options ) {
224
		var isMethodCall = typeof options === "string";
225
		var args = widgetSlice.call( arguments, 1 );
226
		var returnValue = this;
227
 
228
		if ( isMethodCall ) {
229
 
230
			// If this is an empty collection, we need to have the instance method
231
			// return undefined instead of the jQuery instance
232
			if ( !this.length && options === "instance" ) {
233
				returnValue = undefined;
234
			} else {
235
				this.each( function() {
236
					var methodValue;
237
					var instance = $.data( this, fullName );
238
 
239
					if ( options === "instance" ) {
240
						returnValue = instance;
241
						return false;
242
					}
243
 
244
					if ( !instance ) {
245
						return $.error( "cannot call methods on " + name +
246
							" prior to initialization; " +
247
							"attempted to call method '" + options + "'" );
248
					}
249
 
250
					if ( typeof instance[ options ] !== "function" ||
251
						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 bindRemoveEvent() {
513
			var nodesToBind = [];
514
 
515
			options.element.each( function( _, element ) {
516
				var isTracked = $.map( that.classesElementLookup, function( elements ) {
517
					return elements;
518
				} )
519
					.some( function( elements ) {
520
						return elements.is( element );
521
					} );
522
 
523
				if ( !isTracked ) {
524
					nodesToBind.push( element );
525
				}
526
			} );
527
 
528
			that._on( $( nodesToBind ), {
529
				remove: "_untrackClassesElement"
530
			} );
531
		}
532
 
533
		function processClassString( classes, checkOption ) {
534
			var current, i;
535
			for ( i = 0; i < classes.length; i++ ) {
536
				current = that.classesElementLookup[ classes[ i ] ] || $();
537
				if ( options.add ) {
538
					bindRemoveEvent();
539
					current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) );
540
				} else {
541
					current = $( current.not( options.element ).get() );
542
				}
543
				that.classesElementLookup[ classes[ i ] ] = current;
544
				full.push( classes[ i ] );
545
				if ( checkOption && options.classes[ classes[ i ] ] ) {
546
					full.push( options.classes[ classes[ i ] ] );
547
				}
548
			}
549
		}
550
 
551
		if ( options.keys ) {
552
			processClassString( options.keys.match( /\S+/g ) || [], true );
553
		}
554
		if ( options.extra ) {
555
			processClassString( options.extra.match( /\S+/g ) || [] );
556
		}
557
 
558
		return full.join( " " );
559
	},
560
 
561
	_untrackClassesElement: function( event ) {
562
		var that = this;
563
		$.each( that.classesElementLookup, function( key, value ) {
564
			if ( $.inArray( event.target, value ) !== -1 ) {
565
				that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
566
			}
567
		} );
568
 
569
		this._off( $( event.target ) );
570
	},
571
 
572
	_removeClass: function( element, keys, extra ) {
573
		return this._toggleClass( element, keys, extra, false );
574
	},
575
 
576
	_addClass: function( element, keys, extra ) {
577
		return this._toggleClass( element, keys, extra, true );
578
	},
579
 
580
	_toggleClass: function( element, keys, extra, add ) {
581
		add = ( typeof add === "boolean" ) ? add : extra;
582
		var shift = ( typeof element === "string" || element === null ),
583
			options = {
584
				extra: shift ? keys : extra,
585
				keys: shift ? element : keys,
586
				element: shift ? this.element : element,
587
				add: add
588
			};
589
		options.element.toggleClass( this._classes( options ), add );
590
		return this;
591
	},
592
 
593
	_on: function( suppressDisabledCheck, element, handlers ) {
594
		var delegateElement;
595
		var instance = this;
596
 
597
		// No suppressDisabledCheck flag, shuffle arguments
598
		if ( typeof suppressDisabledCheck !== "boolean" ) {
599
			handlers = element;
600
			element = suppressDisabledCheck;
601
			suppressDisabledCheck = false;
602
		}
603
 
604
		// No element argument, shuffle and use this.element
605
		if ( !handlers ) {
606
			handlers = element;
607
			element = this.element;
608
			delegateElement = this.widget();
609
		} else {
610
			element = delegateElement = $( element );
611
			this.bindings = this.bindings.add( element );
612
		}
613
 
614
		$.each( handlers, function( event, handler ) {
615
			function handlerProxy() {
616
 
617
				// Allow widgets to customize the disabled handling
618
				// - disabled as an array instead of boolean
619
				// - disabled class as method for disabling individual parts
620
				if ( !suppressDisabledCheck &&
621
						( instance.options.disabled === true ||
622
						$( this ).hasClass( "ui-state-disabled" ) ) ) {
623
					return;
624
				}
625
				return ( typeof handler === "string" ? instance[ handler ] : handler )
626
					.apply( instance, arguments );
627
			}
628
 
629
			// Copy the guid so direct unbinding works
630
			if ( typeof handler !== "string" ) {
631
				handlerProxy.guid = handler.guid =
632
					handler.guid || handlerProxy.guid || $.guid++;
633
			}
634
 
635
			var match = event.match( /^([\w:-]*)\s*(.*)$/ );
636
			var eventName = match[ 1 ] + instance.eventNamespace;
637
			var selector = match[ 2 ];
638
 
639
			if ( selector ) {
640
				delegateElement.on( eventName, selector, handlerProxy );
641
			} else {
642
				element.on( eventName, handlerProxy );
643
			}
644
		} );
645
	},
646
 
647
	_off: function( element, eventName ) {
648
		eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
649
			this.eventNamespace;
650
		element.off( eventName );
651
 
652
		// Clear the stack to avoid memory leaks (#10056)
653
		this.bindings = $( this.bindings.not( element ).get() );
654
		this.focusable = $( this.focusable.not( element ).get() );
655
		this.hoverable = $( this.hoverable.not( element ).get() );
656
	},
657
 
658
	_delay: function( handler, delay ) {
659
		function handlerProxy() {
660
			return ( typeof handler === "string" ? instance[ handler ] : handler )
661
				.apply( instance, arguments );
662
		}
663
		var instance = this;
664
		return setTimeout( handlerProxy, delay || 0 );
665
	},
666
 
667
	_hoverable: function( element ) {
668
		this.hoverable = this.hoverable.add( element );
669
		this._on( element, {
670
			mouseenter: function( event ) {
671
				this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
672
			},
673
			mouseleave: function( event ) {
674
				this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
675
			}
676
		} );
677
	},
678
 
679
	_focusable: function( element ) {
680
		this.focusable = this.focusable.add( element );
681
		this._on( element, {
682
			focusin: function( event ) {
683
				this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
684
			},
685
			focusout: function( event ) {
686
				this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
687
			}
688
		} );
689
	},
690
 
691
	_trigger: function( type, event, data ) {
692
		var prop, orig;
693
		var callback = this.options[ type ];
694
 
695
		data = data || {};
696
		event = $.Event( event );
697
		event.type = ( type === this.widgetEventPrefix ?
698
			type :
699
			this.widgetEventPrefix + type ).toLowerCase();
700
 
701
		// The original event may come from any element
702
		// so we need to reset the target on the new event
703
		event.target = this.element[ 0 ];
704
 
705
		// Copy original event properties over to the new event
706
		orig = event.originalEvent;
707
		if ( orig ) {
708
			for ( prop in orig ) {
709
				if ( !( prop in event ) ) {
710
					event[ prop ] = orig[ prop ];
711
				}
712
			}
713
		}
714
 
715
		this.element.trigger( event, data );
716
		return !( typeof callback === "function" &&
717
			callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
718
			event.isDefaultPrevented() );
719
	}
720
};
721
 
722
$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
723
	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
724
		if ( typeof options === "string" ) {
725
			options = { effect: options };
726
		}
727
 
728
		var hasOptions;
729
		var effectName = !options ?
730
			method :
731
			options === true || typeof options === "number" ?
732
				defaultEffect :
733
				options.effect || defaultEffect;
734
 
735
		options = options || {};
736
		if ( typeof options === "number" ) {
737
			options = { duration: options };
738
		} else if ( options === true ) {
739
			options = {};
740
		}
741
 
742
		hasOptions = !$.isEmptyObject( options );
743
		options.complete = callback;
744
 
745
		if ( options.delay ) {
746
			element.delay( options.delay );
747
		}
748
 
749
		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
750
			element[ method ]( options );
751
		} else if ( effectName !== method && element[ effectName ] ) {
752
			element[ effectName ]( options.duration, options.easing, callback );
753
		} else {
754
			element.queue( function( next ) {
755
				$( this )[ method ]();
756
				if ( callback ) {
757
					callback.call( element[ 0 ] );
758
				}
759
				next();
760
			} );
761
		}
762
	};
763
} );
764
 
765
var widget = $.widget;
766
 
767
 
768
/*!
769
 * jQuery UI Position 1.13.2
770
 * http://jqueryui.com
771
 *
772
 * Copyright jQuery Foundation and other contributors
773
 * Released under the MIT license.
774
 * http://jquery.org/license
775
 *
776
 * http://api.jqueryui.com/position/
777
 */
778
 
779
//>>label: Position
780
//>>group: Core
781
//>>description: Positions elements relative to other elements.
782
//>>docs: http://api.jqueryui.com/position/
783
//>>demos: http://jqueryui.com/position/
784
 
785
 
786
( function() {
787
var cachedScrollbarWidth,
788
	max = Math.max,
789
	abs = Math.abs,
790
	rhorizontal = /left|center|right/,
791
	rvertical = /top|center|bottom/,
792
	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
793
	rposition = /^\w+/,
794
	rpercent = /%$/,
795
	_position = $.fn.position;
796
 
797
function getOffsets( offsets, width, height ) {
798
	return [
799
		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
800
		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
801
	];
802
}
803
 
804
function parseCss( element, property ) {
805
	return parseInt( $.css( element, property ), 10 ) || 0;
806
}
807
 
808
function isWindow( obj ) {
809
	return obj != null && obj === obj.window;
810
}
811
 
812
function getDimensions( elem ) {
813
	var raw = elem[ 0 ];
814
	if ( raw.nodeType === 9 ) {
815
		return {
816
			width: elem.width(),
817
			height: elem.height(),
818
			offset: { top: 0, left: 0 }
819
		};
820
	}
821
	if ( isWindow( raw ) ) {
822
		return {
823
			width: elem.width(),
824
			height: elem.height(),
825
			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
826
		};
827
	}
828
	if ( raw.preventDefault ) {
829
		return {
830
			width: 0,
831
			height: 0,
832
			offset: { top: raw.pageY, left: raw.pageX }
833
		};
834
	}
835
	return {
836
		width: elem.outerWidth(),
837
		height: elem.outerHeight(),
838
		offset: elem.offset()
839
	};
840
}
841
 
842
$.position = {
843
	scrollbarWidth: function() {
844
		if ( cachedScrollbarWidth !== undefined ) {
845
			return cachedScrollbarWidth;
846
		}
847
		var w1, w2,
848
			div = $( "<div style=" +
849
				"'display:block;position:absolute;width:200px;height:200px;overflow:hidden;'>" +
850
				"<div style='height:300px;width:auto;'></div></div>" ),
851
			innerDiv = div.children()[ 0 ];
852
 
853
		$( "body" ).append( div );
854
		w1 = innerDiv.offsetWidth;
855
		div.css( "overflow", "scroll" );
856
 
857
		w2 = innerDiv.offsetWidth;
858
 
859
		if ( w1 === w2 ) {
860
			w2 = div[ 0 ].clientWidth;
861
		}
862
 
863
		div.remove();
864
 
865
		return ( cachedScrollbarWidth = w1 - w2 );
866
	},
867
	getScrollInfo: function( within ) {
868
		var overflowX = within.isWindow || within.isDocument ? "" :
869
				within.element.css( "overflow-x" ),
870
			overflowY = within.isWindow || within.isDocument ? "" :
871
				within.element.css( "overflow-y" ),
872
			hasOverflowX = overflowX === "scroll" ||
873
				( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ),
874
			hasOverflowY = overflowY === "scroll" ||
875
				( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight );
876
		return {
877
			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
878
			height: hasOverflowX ? $.position.scrollbarWidth() : 0
879
		};
880
	},
881
	getWithinInfo: function( element ) {
882
		var withinElement = $( element || window ),
883
			isElemWindow = isWindow( withinElement[ 0 ] ),
884
			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,
885
			hasOffset = !isElemWindow && !isDocument;
886
		return {
887
			element: withinElement,
888
			isWindow: isElemWindow,
889
			isDocument: isDocument,
890
			offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },
891
			scrollLeft: withinElement.scrollLeft(),
892
			scrollTop: withinElement.scrollTop(),
893
			width: withinElement.outerWidth(),
894
			height: withinElement.outerHeight()
895
		};
896
	}
897
};
898
 
899
$.fn.position = function( options ) {
900
	if ( !options || !options.of ) {
901
		return _position.apply( this, arguments );
902
	}
903
 
904
	// Make a copy, we don't want to modify arguments
905
	options = $.extend( {}, options );
906
 
907
	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
908
 
909
		// Make sure string options are treated as CSS selectors
910
		target = typeof options.of === "string" ?
911
			$( document ).find( options.of ) :
912
			$( options.of ),
913
 
914
		within = $.position.getWithinInfo( options.within ),
915
		scrollInfo = $.position.getScrollInfo( within ),
916
		collision = ( options.collision || "flip" ).split( " " ),
917
		offsets = {};
918
 
919
	dimensions = getDimensions( target );
920
	if ( target[ 0 ].preventDefault ) {
921
 
922
		// Force left top to allow flipping
923
		options.at = "left top";
924
	}
925
	targetWidth = dimensions.width;
926
	targetHeight = dimensions.height;
927
	targetOffset = dimensions.offset;
928
 
929
	// Clone to reuse original targetOffset later
930
	basePosition = $.extend( {}, targetOffset );
931
 
932
	// Force my and at to have valid horizontal and vertical positions
933
	// if a value is missing or invalid, it will be converted to center
934
	$.each( [ "my", "at" ], function() {
935
		var pos = ( options[ this ] || "" ).split( " " ),
936
			horizontalOffset,
937
			verticalOffset;
938
 
939
		if ( pos.length === 1 ) {
940
			pos = rhorizontal.test( pos[ 0 ] ) ?
941
				pos.concat( [ "center" ] ) :
942
				rvertical.test( pos[ 0 ] ) ?
943
					[ "center" ].concat( pos ) :
944
					[ "center", "center" ];
945
		}
946
		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
947
		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
948
 
949
		// Calculate offsets
950
		horizontalOffset = roffset.exec( pos[ 0 ] );
951
		verticalOffset = roffset.exec( pos[ 1 ] );
952
		offsets[ this ] = [
953
			horizontalOffset ? horizontalOffset[ 0 ] : 0,
954
			verticalOffset ? verticalOffset[ 0 ] : 0
955
		];
956
 
957
		// Reduce to just the positions without the offsets
958
		options[ this ] = [
959
			rposition.exec( pos[ 0 ] )[ 0 ],
960
			rposition.exec( pos[ 1 ] )[ 0 ]
961
		];
962
	} );
963
 
964
	// Normalize collision option
965
	if ( collision.length === 1 ) {
966
		collision[ 1 ] = collision[ 0 ];
967
	}
968
 
969
	if ( options.at[ 0 ] === "right" ) {
970
		basePosition.left += targetWidth;
971
	} else if ( options.at[ 0 ] === "center" ) {
972
		basePosition.left += targetWidth / 2;
973
	}
974
 
975
	if ( options.at[ 1 ] === "bottom" ) {
976
		basePosition.top += targetHeight;
977
	} else if ( options.at[ 1 ] === "center" ) {
978
		basePosition.top += targetHeight / 2;
979
	}
980
 
981
	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
982
	basePosition.left += atOffset[ 0 ];
983
	basePosition.top += atOffset[ 1 ];
984
 
985
	return this.each( function() {
986
		var collisionPosition, using,
987
			elem = $( this ),
988
			elemWidth = elem.outerWidth(),
989
			elemHeight = elem.outerHeight(),
990
			marginLeft = parseCss( this, "marginLeft" ),
991
			marginTop = parseCss( this, "marginTop" ),
992
			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) +
993
				scrollInfo.width,
994
			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) +
995
				scrollInfo.height,
996
			position = $.extend( {}, basePosition ),
997
			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
998
 
999
		if ( options.my[ 0 ] === "right" ) {
1000
			position.left -= elemWidth;
1001
		} else if ( options.my[ 0 ] === "center" ) {
1002
			position.left -= elemWidth / 2;
1003
		}
1004
 
1005
		if ( options.my[ 1 ] === "bottom" ) {
1006
			position.top -= elemHeight;
1007
		} else if ( options.my[ 1 ] === "center" ) {
1008
			position.top -= elemHeight / 2;
1009
		}
1010
 
1011
		position.left += myOffset[ 0 ];
1012
		position.top += myOffset[ 1 ];
1013
 
1014
		collisionPosition = {
1015
			marginLeft: marginLeft,
1016
			marginTop: marginTop
1017
		};
1018
 
1019
		$.each( [ "left", "top" ], function( i, dir ) {
1020
			if ( $.ui.position[ collision[ i ] ] ) {
1021
				$.ui.position[ collision[ i ] ][ dir ]( position, {
1022
					targetWidth: targetWidth,
1023
					targetHeight: targetHeight,
1024
					elemWidth: elemWidth,
1025
					elemHeight: elemHeight,
1026
					collisionPosition: collisionPosition,
1027
					collisionWidth: collisionWidth,
1028
					collisionHeight: collisionHeight,
1029
					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1030
					my: options.my,
1031
					at: options.at,
1032
					within: within,
1033
					elem: elem
1034
				} );
1035
			}
1036
		} );
1037
 
1038
		if ( options.using ) {
1039
 
1040
			// Adds feedback as second argument to using callback, if present
1041
			using = function( props ) {
1042
				var left = targetOffset.left - position.left,
1043
					right = left + targetWidth - elemWidth,
1044
					top = targetOffset.top - position.top,
1045
					bottom = top + targetHeight - elemHeight,
1046
					feedback = {
1047
						target: {
1048
							element: target,
1049
							left: targetOffset.left,
1050
							top: targetOffset.top,
1051
							width: targetWidth,
1052
							height: targetHeight
1053
						},
1054
						element: {
1055
							element: elem,
1056
							left: position.left,
1057
							top: position.top,
1058
							width: elemWidth,
1059
							height: elemHeight
1060
						},
1061
						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1062
						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1063
					};
1064
				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1065
					feedback.horizontal = "center";
1066
				}
1067
				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1068
					feedback.vertical = "middle";
1069
				}
1070
				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1071
					feedback.important = "horizontal";
1072
				} else {
1073
					feedback.important = "vertical";
1074
				}
1075
				options.using.call( this, props, feedback );
1076
			};
1077
		}
1078
 
1079
		elem.offset( $.extend( position, { using: using } ) );
1080
	} );
1081
};
1082
 
1083
$.ui.position = {
1084
	fit: {
1085
		left: function( position, data ) {
1086
			var within = data.within,
1087
				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1088
				outerWidth = within.width,
1089
				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1090
				overLeft = withinOffset - collisionPosLeft,
1091
				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1092
				newOverRight;
1093
 
1094
			// Element is wider than within
1095
			if ( data.collisionWidth > outerWidth ) {
1096
 
1097
				// Element is initially over the left side of within
1098
				if ( overLeft > 0 && overRight <= 0 ) {
1099
					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth -
1100
						withinOffset;
1101
					position.left += overLeft - newOverRight;
1102
 
1103
				// Element is initially over right side of within
1104
				} else if ( overRight > 0 && overLeft <= 0 ) {
1105
					position.left = withinOffset;
1106
 
1107
				// Element is initially over both left and right sides of within
1108
				} else {
1109
					if ( overLeft > overRight ) {
1110
						position.left = withinOffset + outerWidth - data.collisionWidth;
1111
					} else {
1112
						position.left = withinOffset;
1113
					}
1114
				}
1115
 
1116
			// Too far left -> align with left edge
1117
			} else if ( overLeft > 0 ) {
1118
				position.left += overLeft;
1119
 
1120
			// Too far right -> align with right edge
1121
			} else if ( overRight > 0 ) {
1122
				position.left -= overRight;
1123
 
1124
			// Adjust based on position and margin
1125
			} else {
1126
				position.left = max( position.left - collisionPosLeft, position.left );
1127
			}
1128
		},
1129
		top: function( position, data ) {
1130
			var within = data.within,
1131
				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1132
				outerHeight = data.within.height,
1133
				collisionPosTop = position.top - data.collisionPosition.marginTop,
1134
				overTop = withinOffset - collisionPosTop,
1135
				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1136
				newOverBottom;
1137
 
1138
			// Element is taller than within
1139
			if ( data.collisionHeight > outerHeight ) {
1140
 
1141
				// Element is initially over the top of within
1142
				if ( overTop > 0 && overBottom <= 0 ) {
1143
					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight -
1144
						withinOffset;
1145
					position.top += overTop - newOverBottom;
1146
 
1147
				// Element is initially over bottom of within
1148
				} else if ( overBottom > 0 && overTop <= 0 ) {
1149
					position.top = withinOffset;
1150
 
1151
				// Element is initially over both top and bottom of within
1152
				} else {
1153
					if ( overTop > overBottom ) {
1154
						position.top = withinOffset + outerHeight - data.collisionHeight;
1155
					} else {
1156
						position.top = withinOffset;
1157
					}
1158
				}
1159
 
1160
			// Too far up -> align with top
1161
			} else if ( overTop > 0 ) {
1162
				position.top += overTop;
1163
 
1164
			// Too far down -> align with bottom edge
1165
			} else if ( overBottom > 0 ) {
1166
				position.top -= overBottom;
1167
 
1168
			// Adjust based on position and margin
1169
			} else {
1170
				position.top = max( position.top - collisionPosTop, position.top );
1171
			}
1172
		}
1173
	},
1174
	flip: {
1175
		left: function( position, data ) {
1176
			var within = data.within,
1177
				withinOffset = within.offset.left + within.scrollLeft,
1178
				outerWidth = within.width,
1179
				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1180
				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1181
				overLeft = collisionPosLeft - offsetLeft,
1182
				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1183
				myOffset = data.my[ 0 ] === "left" ?
1184
					-data.elemWidth :
1185
					data.my[ 0 ] === "right" ?
1186
						data.elemWidth :
1187
						0,
1188
				atOffset = data.at[ 0 ] === "left" ?
1189
					data.targetWidth :
1190
					data.at[ 0 ] === "right" ?
1191
						-data.targetWidth :
1192
						0,
1193
				offset = -2 * data.offset[ 0 ],
1194
				newOverRight,
1195
				newOverLeft;
1196
 
1197
			if ( overLeft < 0 ) {
1198
				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -
1199
					outerWidth - withinOffset;
1200
				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1201
					position.left += myOffset + atOffset + offset;
1202
				}
1203
			} else if ( overRight > 0 ) {
1204
				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +
1205
					atOffset + offset - offsetLeft;
1206
				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1207
					position.left += myOffset + atOffset + offset;
1208
				}
1209
			}
1210
		},
1211
		top: function( position, data ) {
1212
			var within = data.within,
1213
				withinOffset = within.offset.top + within.scrollTop,
1214
				outerHeight = within.height,
1215
				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1216
				collisionPosTop = position.top - data.collisionPosition.marginTop,
1217
				overTop = collisionPosTop - offsetTop,
1218
				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1219
				top = data.my[ 1 ] === "top",
1220
				myOffset = top ?
1221
					-data.elemHeight :
1222
					data.my[ 1 ] === "bottom" ?
1223
						data.elemHeight :
1224
						0,
1225
				atOffset = data.at[ 1 ] === "top" ?
1226
					data.targetHeight :
1227
					data.at[ 1 ] === "bottom" ?
1228
						-data.targetHeight :
1229
						0,
1230
				offset = -2 * data.offset[ 1 ],
1231
				newOverTop,
1232
				newOverBottom;
1233
			if ( overTop < 0 ) {
1234
				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -
1235
					outerHeight - withinOffset;
1236
				if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
1237
					position.top += myOffset + atOffset + offset;
1238
				}
1239
			} else if ( overBottom > 0 ) {
1240
				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +
1241
					offset - offsetTop;
1242
				if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
1243
					position.top += myOffset + atOffset + offset;
1244
				}
1245
			}
1246
		}
1247
	},
1248
	flipfit: {
1249
		left: function() {
1250
			$.ui.position.flip.left.apply( this, arguments );
1251
			$.ui.position.fit.left.apply( this, arguments );
1252
		},
1253
		top: function() {
1254
			$.ui.position.flip.top.apply( this, arguments );
1255
			$.ui.position.fit.top.apply( this, arguments );
1256
		}
1257
	}
1258
};
1259
 
1260
} )();
1261
 
1262
var position = $.ui.position;
1263
 
1264
 
1265
/*!
1266
 * jQuery UI :data 1.13.2
1267
 * http://jqueryui.com
1268
 *
1269
 * Copyright jQuery Foundation and other contributors
1270
 * Released under the MIT license.
1271
 * http://jquery.org/license
1272
 */
1273
 
1274
//>>label: :data Selector
1275
//>>group: Core
1276
//>>description: Selects elements which have data stored under the specified key.
1277
//>>docs: http://api.jqueryui.com/data-selector/
1278
 
1279
 
1280
var data = $.extend( $.expr.pseudos, {
1281
	data: $.expr.createPseudo ?
1282
		$.expr.createPseudo( function( dataName ) {
1283
			return function( elem ) {
1284
				return !!$.data( elem, dataName );
1285
			};
1286
		} ) :
1287
 
1288
		// Support: jQuery <1.8
1289
		function( elem, i, match ) {
1290
			return !!$.data( elem, match[ 3 ] );
1291
		}
1292
} );
1293
 
1294
/*!
1295
 * jQuery UI Disable Selection 1.13.2
1296
 * http://jqueryui.com
1297
 *
1298
 * Copyright jQuery Foundation and other contributors
1299
 * Released under the MIT license.
1300
 * http://jquery.org/license
1301
 */
1302
 
1303
//>>label: disableSelection
1304
//>>group: Core
1305
//>>description: Disable selection of text content within the set of matched elements.
1306
//>>docs: http://api.jqueryui.com/disableSelection/
1307
 
1308
// This file is deprecated
1309
 
1310
var disableSelection = $.fn.extend( {
1311
	disableSelection: ( function() {
1312
		var eventType = "onselectstart" in document.createElement( "div" ) ?
1313
			"selectstart" :
1314
			"mousedown";
1315
 
1316
		return function() {
1317
			return this.on( eventType + ".ui-disableSelection", function( event ) {
1318
				event.preventDefault();
1319
			} );
1320
		};
1321
	} )(),
1322
 
1323
	enableSelection: function() {
1324
		return this.off( ".ui-disableSelection" );
1325
	}
1326
} );
1327
 
1328
 
1329
 
1330
// Create a local jQuery because jQuery Color relies on it and the
1331
// global may not exist with AMD and a custom build (#10199).
1332
// This module is a noop if used as a regular AMD module.
1333
// eslint-disable-next-line no-unused-vars
1334
var jQuery = $;
1335
 
1336
 
1337
/*!
1338
 * jQuery Color Animations v2.2.0
1339
 * https://github.com/jquery/jquery-color
1340
 *
1341
 * Copyright OpenJS Foundation and other contributors
1342
 * Released under the MIT license.
1343
 * http://jquery.org/license
1344
 *
1345
 * Date: Sun May 10 09:02:36 2020 +0200
1346
 */
1347
 
1348
 
1349
 
1350
	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " +
1351
		"borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
1352
 
1353
	class2type = {},
1354
	toString = class2type.toString,
1355
 
1356
	// plusequals test for += 100 -= 100
1357
	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
1358
 
1359
	// a set of RE's that can match strings and generate color tuples.
1360
	stringParsers = [ {
1361
			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1362
			parse: function( execResult ) {
1363
				return [
1364
					execResult[ 1 ],
1365
					execResult[ 2 ],
1366
					execResult[ 3 ],
1367
					execResult[ 4 ]
1368
				];
1369
			}
1370
		}, {
1371
			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1372
			parse: function( execResult ) {
1373
				return [
1374
					execResult[ 1 ] * 2.55,
1375
					execResult[ 2 ] * 2.55,
1376
					execResult[ 3 ] * 2.55,
1377
					execResult[ 4 ]
1378
				];
1379
			}
1380
		}, {
1381
 
1382
			// this regex ignores A-F because it's compared against an already lowercased string
1383
			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?/,
1384
			parse: function( execResult ) {
1385
				return [
1386
					parseInt( execResult[ 1 ], 16 ),
1387
					parseInt( execResult[ 2 ], 16 ),
1388
					parseInt( execResult[ 3 ], 16 ),
1389
					execResult[ 4 ] ?
1390
						( parseInt( execResult[ 4 ], 16 ) / 255 ).toFixed( 2 ) :
1391
						1
1392
				];
1393
			}
1394
		}, {
1395
 
1396
			// this regex ignores A-F because it's compared against an already lowercased string
1397
			re: /#([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])?/,
1398
			parse: function( execResult ) {
1399
				return [
1400
					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
1401
					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
1402
					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ),
1403
					execResult[ 4 ] ?
1404
						( parseInt( execResult[ 4 ] + execResult[ 4 ], 16 ) / 255 )
1405
							.toFixed( 2 ) :
1406
						1
1407
				];
1408
			}
1409
		}, {
1410
			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1411
			space: "hsla",
1412
			parse: function( execResult ) {
1413
				return [
1414
					execResult[ 1 ],
1415
					execResult[ 2 ] / 100,
1416
					execResult[ 3 ] / 100,
1417
					execResult[ 4 ]
1418
				];
1419
			}
1420
		} ],
1421
 
1422
	// jQuery.Color( )
1423
	color = jQuery.Color = function( color, green, blue, alpha ) {
1424
		return new jQuery.Color.fn.parse( color, green, blue, alpha );
1425
	},
1426
	spaces = {
1427
		rgba: {
1428
			props: {
1429
				red: {
1430
					idx: 0,
1431
					type: "byte"
1432
				},
1433
				green: {
1434
					idx: 1,
1435
					type: "byte"
1436
				},
1437
				blue: {
1438
					idx: 2,
1439
					type: "byte"
1440
				}
1441
			}
1442
		},
1443
 
1444
		hsla: {
1445
			props: {
1446
				hue: {
1447
					idx: 0,
1448
					type: "degrees"
1449
				},
1450
				saturation: {
1451
					idx: 1,
1452
					type: "percent"
1453
				},
1454
				lightness: {
1455
					idx: 2,
1456
					type: "percent"
1457
				}
1458
			}
1459
		}
1460
	},
1461
	propTypes = {
1462
		"byte": {
1463
			floor: true,
1464
			max: 255
1465
		},
1466
		"percent": {
1467
			max: 1
1468
		},
1469
		"degrees": {
1470
			mod: 360,
1471
			floor: true
1472
		}
1473
	},
1474
	support = color.support = {},
1475
 
1476
	// element for support tests
1477
	supportElem = jQuery( "<p>" )[ 0 ],
1478
 
1479
	// colors = jQuery.Color.names
1480
	colors,
1481
 
1482
	// local aliases of functions called often
1483
	each = jQuery.each;
1484
 
1485
// determine rgba support immediately
1486
supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
1487
support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
1488
 
1489
// define cache name and alpha properties
1490
// for rgba and hsla spaces
1491
each( spaces, function( spaceName, space ) {
1492
	space.cache = "_" + spaceName;
1493
	space.props.alpha = {
1494
		idx: 3,
1495
		type: "percent",
1496
		def: 1
1497
	};
1498
} );
1499
 
1500
// Populate the class2type map
1501
jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
1502
	function( _i, name ) {
1503
		class2type[ "[object " + name + "]" ] = name.toLowerCase();
1504
	} );
1505
 
1506
function getType( obj ) {
1507
	if ( obj == null ) {
1508
		return obj + "";
1509
	}
1510
 
1511
	return typeof obj === "object" ?
1512
		class2type[ toString.call( obj ) ] || "object" :
1513
		typeof obj;
1514
}
1515
 
1516
function clamp( value, prop, allowEmpty ) {
1517
	var type = propTypes[ prop.type ] || {};
1518
 
1519
	if ( value == null ) {
1520
		return ( allowEmpty || !prop.def ) ? null : prop.def;
1521
	}
1522
 
1523
	// ~~ is an short way of doing floor for positive numbers
1524
	value = type.floor ? ~~value : parseFloat( value );
1525
 
1526
	// IE will pass in empty strings as value for alpha,
1527
	// which will hit this case
1528
	if ( isNaN( value ) ) {
1529
		return prop.def;
1530
	}
1531
 
1532
	if ( type.mod ) {
1533
 
1534
		// we add mod before modding to make sure that negatives values
1535
		// get converted properly: -10 -> 350
1536
		return ( value + type.mod ) % type.mod;
1537
	}
1538
 
1539
	// for now all property types without mod have min and max
1540
	return Math.min( type.max, Math.max( 0, value ) );
1541
}
1542
 
1543
function stringParse( string ) {
1544
	var inst = color(),
1545
		rgba = inst._rgba = [];
1546
 
1547
	string = string.toLowerCase();
1548
 
1549
	each( stringParsers, function( _i, parser ) {
1550
		var parsed,
1551
			match = parser.re.exec( string ),
1552
			values = match && parser.parse( match ),
1553
			spaceName = parser.space || "rgba";
1554
 
1555
		if ( values ) {
1556
			parsed = inst[ spaceName ]( values );
1557
 
1558
			// if this was an rgba parse the assignment might happen twice
1559
			// oh well....
1560
			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
1561
			rgba = inst._rgba = parsed._rgba;
1562
 
1563
			// exit each( stringParsers ) here because we matched
1564
			return false;
1565
		}
1566
	} );
1567
 
1568
	// Found a stringParser that handled it
1569
	if ( rgba.length ) {
1570
 
1571
		// if this came from a parsed string, force "transparent" when alpha is 0
1572
		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
1573
		if ( rgba.join() === "0,0,0,0" ) {
1574
			jQuery.extend( rgba, colors.transparent );
1575
		}
1576
		return inst;
1577
	}
1578
 
1579
	// named colors
1580
	return colors[ string ];
1581
}
1582
 
1583
color.fn = jQuery.extend( color.prototype, {
1584
	parse: function( red, green, blue, alpha ) {
1585
		if ( red === undefined ) {
1586
			this._rgba = [ null, null, null, null ];
1587
			return this;
1588
		}
1589
		if ( red.jquery || red.nodeType ) {
1590
			red = jQuery( red ).css( green );
1591
			green = undefined;
1592
		}
1593
 
1594
		var inst = this,
1595
			type = getType( red ),
1596
			rgba = this._rgba = [];
1597
 
1598
		// more than 1 argument specified - assume ( red, green, blue, alpha )
1599
		if ( green !== undefined ) {
1600
			red = [ red, green, blue, alpha ];
1601
			type = "array";
1602
		}
1603
 
1604
		if ( type === "string" ) {
1605
			return this.parse( stringParse( red ) || colors._default );
1606
		}
1607
 
1608
		if ( type === "array" ) {
1609
			each( spaces.rgba.props, function( _key, prop ) {
1610
				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
1611
			} );
1612
			return this;
1613
		}
1614
 
1615
		if ( type === "object" ) {
1616
			if ( red instanceof color ) {
1617
				each( spaces, function( _spaceName, space ) {
1618
					if ( red[ space.cache ] ) {
1619
						inst[ space.cache ] = red[ space.cache ].slice();
1620
					}
1621
				} );
1622
			} else {
1623
				each( spaces, function( _spaceName, space ) {
1624
					var cache = space.cache;
1625
					each( space.props, function( key, prop ) {
1626
 
1627
						// if the cache doesn't exist, and we know how to convert
1628
						if ( !inst[ cache ] && space.to ) {
1629
 
1630
							// if the value was null, we don't need to copy it
1631
							// if the key was alpha, we don't need to copy it either
1632
							if ( key === "alpha" || red[ key ] == null ) {
1633
								return;
1634
							}
1635
							inst[ cache ] = space.to( inst._rgba );
1636
						}
1637
 
1638
						// this is the only case where we allow nulls for ALL properties.
1639
						// call clamp with alwaysAllowEmpty
1640
						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
1641
					} );
1642
 
1643
					// everything defined but alpha?
1644
					if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
1645
 
1646
						// use the default of 1
1647
						if ( inst[ cache ][ 3 ] == null ) {
1648
							inst[ cache ][ 3 ] = 1;
1649
						}
1650
 
1651
						if ( space.from ) {
1652
							inst._rgba = space.from( inst[ cache ] );
1653
						}
1654
					}
1655
				} );
1656
			}
1657
			return this;
1658
		}
1659
	},
1660
	is: function( compare ) {
1661
		var is = color( compare ),
1662
			same = true,
1663
			inst = this;
1664
 
1665
		each( spaces, function( _, space ) {
1666
			var localCache,
1667
				isCache = is[ space.cache ];
1668
			if ( isCache ) {
1669
				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
1670
				each( space.props, function( _, prop ) {
1671
					if ( isCache[ prop.idx ] != null ) {
1672
						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
1673
						return same;
1674
					}
1675
				} );
1676
			}
1677
			return same;
1678
		} );
1679
		return same;
1680
	},
1681
	_space: function() {
1682
		var used = [],
1683
			inst = this;
1684
		each( spaces, function( spaceName, space ) {
1685
			if ( inst[ space.cache ] ) {
1686
				used.push( spaceName );
1687
			}
1688
		} );
1689
		return used.pop();
1690
	},
1691
	transition: function( other, distance ) {
1692
		var end = color( other ),
1693
			spaceName = end._space(),
1694
			space = spaces[ spaceName ],
1695
			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
1696
			start = startColor[ space.cache ] || space.to( startColor._rgba ),
1697
			result = start.slice();
1698
 
1699
		end = end[ space.cache ];
1700
		each( space.props, function( _key, prop ) {
1701
			var index = prop.idx,
1702
				startValue = start[ index ],
1703
				endValue = end[ index ],
1704
				type = propTypes[ prop.type ] || {};
1705
 
1706
			// if null, don't override start value
1707
			if ( endValue === null ) {
1708
				return;
1709
			}
1710
 
1711
			// if null - use end
1712
			if ( startValue === null ) {
1713
				result[ index ] = endValue;
1714
			} else {
1715
				if ( type.mod ) {
1716
					if ( endValue - startValue > type.mod / 2 ) {
1717
						startValue += type.mod;
1718
					} else if ( startValue - endValue > type.mod / 2 ) {
1719
						startValue -= type.mod;
1720
					}
1721
				}
1722
				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
1723
			}
1724
		} );
1725
		return this[ spaceName ]( result );
1726
	},
1727
	blend: function( opaque ) {
1728
 
1729
		// if we are already opaque - return ourself
1730
		if ( this._rgba[ 3 ] === 1 ) {
1731
			return this;
1732
		}
1733
 
1734
		var rgb = this._rgba.slice(),
1735
			a = rgb.pop(),
1736
			blend = color( opaque )._rgba;
1737
 
1738
		return color( jQuery.map( rgb, function( v, i ) {
1739
			return ( 1 - a ) * blend[ i ] + a * v;
1740
		} ) );
1741
	},
1742
	toRgbaString: function() {
1743
		var prefix = "rgba(",
1744
			rgba = jQuery.map( this._rgba, function( v, i ) {
1745
				if ( v != null ) {
1746
					return v;
1747
				}
1748
				return i > 2 ? 1 : 0;
1749
			} );
1750
 
1751
		if ( rgba[ 3 ] === 1 ) {
1752
			rgba.pop();
1753
			prefix = "rgb(";
1754
		}
1755
 
1756
		return prefix + rgba.join() + ")";
1757
	},
1758
	toHslaString: function() {
1759
		var prefix = "hsla(",
1760
			hsla = jQuery.map( this.hsla(), function( v, i ) {
1761
				if ( v == null ) {
1762
					v = i > 2 ? 1 : 0;
1763
				}
1764
 
1765
				// catch 1 and 2
1766
				if ( i && i < 3 ) {
1767
					v = Math.round( v * 100 ) + "%";
1768
				}
1769
				return v;
1770
			} );
1771
 
1772
		if ( hsla[ 3 ] === 1 ) {
1773
			hsla.pop();
1774
			prefix = "hsl(";
1775
		}
1776
		return prefix + hsla.join() + ")";
1777
	},
1778
	toHexString: function( includeAlpha ) {
1779
		var rgba = this._rgba.slice(),
1780
			alpha = rgba.pop();
1781
 
1782
		if ( includeAlpha ) {
1783
			rgba.push( ~~( alpha * 255 ) );
1784
		}
1785
 
1786
		return "#" + jQuery.map( rgba, function( v ) {
1787
 
1788
			// default to 0 when nulls exist
1789
			v = ( v || 0 ).toString( 16 );
1790
			return v.length === 1 ? "0" + v : v;
1791
		} ).join( "" );
1792
	},
1793
	toString: function() {
1794
		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
1795
	}
1796
} );
1797
color.fn.parse.prototype = color.fn;
1798
 
1799
// hsla conversions adapted from:
1800
// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
1801
 
1802
function hue2rgb( p, q, h ) {
1803
	h = ( h + 1 ) % 1;
1804
	if ( h * 6 < 1 ) {
1805
		return p + ( q - p ) * h * 6;
1806
	}
1807
	if ( h * 2 < 1 ) {
1808
		return q;
1809
	}
1810
	if ( h * 3 < 2 ) {
1811
		return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
1812
	}
1813
	return p;
1814
}
1815
 
1816
spaces.hsla.to = function( rgba ) {
1817
	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
1818
		return [ null, null, null, rgba[ 3 ] ];
1819
	}
1820
	var r = rgba[ 0 ] / 255,
1821
		g = rgba[ 1 ] / 255,
1822
		b = rgba[ 2 ] / 255,
1823
		a = rgba[ 3 ],
1824
		max = Math.max( r, g, b ),
1825
		min = Math.min( r, g, b ),
1826
		diff = max - min,
1827
		add = max + min,
1828
		l = add * 0.5,
1829
		h, s;
1830
 
1831
	if ( min === max ) {
1832
		h = 0;
1833
	} else if ( r === max ) {
1834
		h = ( 60 * ( g - b ) / diff ) + 360;
1835
	} else if ( g === max ) {
1836
		h = ( 60 * ( b - r ) / diff ) + 120;
1837
	} else {
1838
		h = ( 60 * ( r - g ) / diff ) + 240;
1839
	}
1840
 
1841
	// chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
1842
	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
1843
	if ( diff === 0 ) {
1844
		s = 0;
1845
	} else if ( l <= 0.5 ) {
1846
		s = diff / add;
1847
	} else {
1848
		s = diff / ( 2 - add );
1849
	}
1850
	return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ];
1851
};
1852
 
1853
spaces.hsla.from = function( hsla ) {
1854
	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
1855
		return [ null, null, null, hsla[ 3 ] ];
1856
	}
1857
	var h = hsla[ 0 ] / 360,
1858
		s = hsla[ 1 ],
1859
		l = hsla[ 2 ],
1860
		a = hsla[ 3 ],
1861
		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
1862
		p = 2 * l - q;
1863
 
1864
	return [
1865
		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
1866
		Math.round( hue2rgb( p, q, h ) * 255 ),
1867
		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
1868
		a
1869
	];
1870
};
1871
 
1872
 
1873
each( spaces, function( spaceName, space ) {
1874
	var props = space.props,
1875
		cache = space.cache,
1876
		to = space.to,
1877
		from = space.from;
1878
 
1879
	// makes rgba() and hsla()
1880
	color.fn[ spaceName ] = function( value ) {
1881
 
1882
		// generate a cache for this space if it doesn't exist
1883
		if ( to && !this[ cache ] ) {
1884
			this[ cache ] = to( this._rgba );
1885
		}
1886
		if ( value === undefined ) {
1887
			return this[ cache ].slice();
1888
		}
1889
 
1890
		var ret,
1891
			type = getType( value ),
1892
			arr = ( type === "array" || type === "object" ) ? value : arguments,
1893
			local = this[ cache ].slice();
1894
 
1895
		each( props, function( key, prop ) {
1896
			var val = arr[ type === "object" ? key : prop.idx ];
1897
			if ( val == null ) {
1898
				val = local[ prop.idx ];
1899
			}
1900
			local[ prop.idx ] = clamp( val, prop );
1901
		} );
1902
 
1903
		if ( from ) {
1904
			ret = color( from( local ) );
1905
			ret[ cache ] = local;
1906
			return ret;
1907
		} else {
1908
			return color( local );
1909
		}
1910
	};
1911
 
1912
	// makes red() green() blue() alpha() hue() saturation() lightness()
1913
	each( props, function( key, prop ) {
1914
 
1915
		// alpha is included in more than one space
1916
		if ( color.fn[ key ] ) {
1917
			return;
1918
		}
1919
		color.fn[ key ] = function( value ) {
1920
			var local, cur, match, fn,
1921
				vtype = getType( value );
1922
 
1923
			if ( key === "alpha" ) {
1924
				fn = this._hsla ? "hsla" : "rgba";
1925
			} else {
1926
				fn = spaceName;
1927
			}
1928
			local = this[ fn ]();
1929
			cur = local[ prop.idx ];
1930
 
1931
			if ( vtype === "undefined" ) {
1932
				return cur;
1933
			}
1934
 
1935
			if ( vtype === "function" ) {
1936
				value = value.call( this, cur );
1937
				vtype = getType( value );
1938
			}
1939
			if ( value == null && prop.empty ) {
1940
				return this;
1941
			}
1942
			if ( vtype === "string" ) {
1943
				match = rplusequals.exec( value );
1944
				if ( match ) {
1945
					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
1946
				}
1947
			}
1948
			local[ prop.idx ] = value;
1949
			return this[ fn ]( local );
1950
		};
1951
	} );
1952
} );
1953
 
1954
// add cssHook and .fx.step function for each named hook.
1955
// accept a space separated string of properties
1956
color.hook = function( hook ) {
1957
	var hooks = hook.split( " " );
1958
	each( hooks, function( _i, hook ) {
1959
		jQuery.cssHooks[ hook ] = {
1960
			set: function( elem, value ) {
1961
				var parsed, curElem,
1962
					backgroundColor = "";
1963
 
1964
				if ( value !== "transparent" && ( getType( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
1965
					value = color( parsed || value );
1966
					if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
1967
						curElem = hook === "backgroundColor" ? elem.parentNode : elem;
1968
						while (
1969
							( backgroundColor === "" || backgroundColor === "transparent" ) &&
1970
							curElem && curElem.style
1971
						) {
1972
							try {
1973
								backgroundColor = jQuery.css( curElem, "backgroundColor" );
1974
								curElem = curElem.parentNode;
1975
							} catch ( e ) {
1976
							}
1977
						}
1978
 
1979
						value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
1980
							backgroundColor :
1981
							"_default" );
1982
					}
1983
 
1984
					value = value.toRgbaString();
1985
				}
1986
				try {
1987
					elem.style[ hook ] = value;
1988
				} catch ( e ) {
1989
 
1990
					// wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
1991
				}
1992
			}
1993
		};
1994
		jQuery.fx.step[ hook ] = function( fx ) {
1995
			if ( !fx.colorInit ) {
1996
				fx.start = color( fx.elem, hook );
1997
				fx.end = color( fx.end );
1998
				fx.colorInit = true;
1999
			}
2000
			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
2001
		};
2002
	} );
2003
 
2004
};
2005
 
2006
color.hook( stepHooks );
2007
 
2008
jQuery.cssHooks.borderColor = {
2009
	expand: function( value ) {
2010
		var expanded = {};
2011
 
2012
		each( [ "Top", "Right", "Bottom", "Left" ], function( _i, part ) {
2013
			expanded[ "border" + part + "Color" ] = value;
2014
		} );
2015
		return expanded;
2016
	}
2017
};
2018
 
2019
// Basic color names only.
2020
// Usage of any of the other color names requires adding yourself or including
2021
// jquery.color.svg-names.js.
2022
colors = jQuery.Color.names = {
2023
 
2024
	// 4.1. Basic color keywords
2025
	aqua: "#00ffff",
2026
	black: "#000000",
2027
	blue: "#0000ff",
2028
	fuchsia: "#ff00ff",
2029
	gray: "#808080",
2030
	green: "#008000",
2031
	lime: "#00ff00",
2032
	maroon: "#800000",
2033
	navy: "#000080",
2034
	olive: "#808000",
2035
	purple: "#800080",
2036
	red: "#ff0000",
2037
	silver: "#c0c0c0",
2038
	teal: "#008080",
2039
	white: "#ffffff",
2040
	yellow: "#ffff00",
2041
 
2042
	// 4.2.3. "transparent" color keyword
2043
	transparent: [ null, null, null, 0 ],
2044
 
2045
	_default: "#ffffff"
2046
};
2047
 
2048
 
2049
/*!
2050
 * jQuery UI Effects 1.13.2
2051
 * http://jqueryui.com
2052
 *
2053
 * Copyright jQuery Foundation and other contributors
2054
 * Released under the MIT license.
2055
 * http://jquery.org/license
2056
 */
2057
 
2058
//>>label: Effects Core
2059
//>>group: Effects
2060
/* eslint-disable max-len */
2061
//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects.
2062
/* eslint-enable max-len */
2063
//>>docs: http://api.jqueryui.com/category/effects-core/
2064
//>>demos: http://jqueryui.com/effect/
2065
 
2066
 
2067
var dataSpace = "ui-effects-",
2068
	dataSpaceStyle = "ui-effects-style",
2069
	dataSpaceAnimated = "ui-effects-animated";
2070
 
2071
$.effects = {
2072
	effect: {}
2073
};
2074
 
2075
/******************************************************************************/
2076
/****************************** CLASS ANIMATIONS ******************************/
2077
/******************************************************************************/
2078
( function() {
2079
 
2080
var classAnimationActions = [ "add", "remove", "toggle" ],
2081
	shorthandStyles = {
2082
		border: 1,
2083
		borderBottom: 1,
2084
		borderColor: 1,
2085
		borderLeft: 1,
2086
		borderRight: 1,
2087
		borderTop: 1,
2088
		borderWidth: 1,
2089
		margin: 1,
2090
		padding: 1
2091
	};
2092
 
2093
$.each(
2094
	[ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ],
2095
	function( _, prop ) {
2096
		$.fx.step[ prop ] = function( fx ) {
2097
			if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
2098
				jQuery.style( fx.elem, prop, fx.end );
2099
				fx.setAttr = true;
2100
			}
2101
		};
2102
	}
2103
);
2104
 
2105
function camelCase( string ) {
2106
	return string.replace( /-([\da-z])/gi, function( all, letter ) {
2107
		return letter.toUpperCase();
2108
	} );
2109
}
2110
 
2111
function getElementStyles( elem ) {
2112
	var key, len,
2113
		style = elem.ownerDocument.defaultView ?
2114
			elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
2115
			elem.currentStyle,
2116
		styles = {};
2117
 
2118
	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
2119
		len = style.length;
2120
		while ( len-- ) {
2121
			key = style[ len ];
2122
			if ( typeof style[ key ] === "string" ) {
2123
				styles[ camelCase( key ) ] = style[ key ];
2124
			}
2125
		}
2126
 
2127
	// Support: Opera, IE <9
2128
	} else {
2129
		for ( key in style ) {
2130
			if ( typeof style[ key ] === "string" ) {
2131
				styles[ key ] = style[ key ];
2132
			}
2133
		}
2134
	}
2135
 
2136
	return styles;
2137
}
2138
 
2139
function styleDifference( oldStyle, newStyle ) {
2140
	var diff = {},
2141
		name, value;
2142
 
2143
	for ( name in newStyle ) {
2144
		value = newStyle[ name ];
2145
		if ( oldStyle[ name ] !== value ) {
2146
			if ( !shorthandStyles[ name ] ) {
2147
				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
2148
					diff[ name ] = value;
2149
				}
2150
			}
2151
		}
2152
	}
2153
 
2154
	return diff;
2155
}
2156
 
2157
// Support: jQuery <1.8
2158
if ( !$.fn.addBack ) {
2159
	$.fn.addBack = function( selector ) {
2160
		return this.add( selector == null ?
2161
			this.prevObject : this.prevObject.filter( selector )
2162
		);
2163
	};
2164
}
2165
 
2166
$.effects.animateClass = function( value, duration, easing, callback ) {
2167
	var o = $.speed( duration, easing, callback );
2168
 
2169
	return this.queue( function() {
2170
		var animated = $( this ),
2171
			baseClass = animated.attr( "class" ) || "",
2172
			applyClassChange,
2173
			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
2174
 
2175
		// Map the animated objects to store the original styles.
2176
		allAnimations = allAnimations.map( function() {
2177
			var el = $( this );
2178
			return {
2179
				el: el,
2180
				start: getElementStyles( this )
2181
			};
2182
		} );
2183
 
2184
		// Apply class change
2185
		applyClassChange = function() {
2186
			$.each( classAnimationActions, function( i, action ) {
2187
				if ( value[ action ] ) {
2188
					animated[ action + "Class" ]( value[ action ] );
2189
				}
2190
			} );
2191
		};
2192
		applyClassChange();
2193
 
2194
		// Map all animated objects again - calculate new styles and diff
2195
		allAnimations = allAnimations.map( function() {
2196
			this.end = getElementStyles( this.el[ 0 ] );
2197
			this.diff = styleDifference( this.start, this.end );
2198
			return this;
2199
		} );
2200
 
2201
		// Apply original class
2202
		animated.attr( "class", baseClass );
2203
 
2204
		// Map all animated objects again - this time collecting a promise
2205
		allAnimations = allAnimations.map( function() {
2206
			var styleInfo = this,
2207
				dfd = $.Deferred(),
2208
				opts = $.extend( {}, o, {
2209
					queue: false,
2210
					complete: function() {
2211
						dfd.resolve( styleInfo );
2212
					}
2213
				} );
2214
 
2215
			this.el.animate( this.diff, opts );
2216
			return dfd.promise();
2217
		} );
2218
 
2219
		// Once all animations have completed:
2220
		$.when.apply( $, allAnimations.get() ).done( function() {
2221
 
2222
			// Set the final class
2223
			applyClassChange();
2224
 
2225
			// For each animated element,
2226
			// clear all css properties that were animated
2227
			$.each( arguments, function() {
2228
				var el = this.el;
2229
				$.each( this.diff, function( key ) {
2230
					el.css( key, "" );
2231
				} );
2232
			} );
2233
 
2234
			// This is guarnteed to be there if you use jQuery.speed()
2235
			// it also handles dequeuing the next anim...
2236
			o.complete.call( animated[ 0 ] );
2237
		} );
2238
	} );
2239
};
2240
 
2241
$.fn.extend( {
2242
	addClass: ( function( orig ) {
2243
		return function( classNames, speed, easing, callback ) {
2244
			return speed ?
2245
				$.effects.animateClass.call( this,
2246
					{ add: classNames }, speed, easing, callback ) :
2247
				orig.apply( this, arguments );
2248
		};
2249
	} )( $.fn.addClass ),
2250
 
2251
	removeClass: ( function( orig ) {
2252
		return function( classNames, speed, easing, callback ) {
2253
			return arguments.length > 1 ?
2254
				$.effects.animateClass.call( this,
2255
					{ remove: classNames }, speed, easing, callback ) :
2256
				orig.apply( this, arguments );
2257
		};
2258
	} )( $.fn.removeClass ),
2259
 
2260
	toggleClass: ( function( orig ) {
2261
		return function( classNames, force, speed, easing, callback ) {
2262
			if ( typeof force === "boolean" || force === undefined ) {
2263
				if ( !speed ) {
2264
 
2265
					// Without speed parameter
2266
					return orig.apply( this, arguments );
2267
				} else {
2268
					return $.effects.animateClass.call( this,
2269
						( force ? { add: classNames } : { remove: classNames } ),
2270
						speed, easing, callback );
2271
				}
2272
			} else {
2273
 
2274
				// Without force parameter
2275
				return $.effects.animateClass.call( this,
2276
					{ toggle: classNames }, force, speed, easing );
2277
			}
2278
		};
2279
	} )( $.fn.toggleClass ),
2280
 
2281
	switchClass: function( remove, add, speed, easing, callback ) {
2282
		return $.effects.animateClass.call( this, {
2283
			add: add,
2284
			remove: remove
2285
		}, speed, easing, callback );
2286
	}
2287
} );
2288
 
2289
} )();
2290
 
2291
/******************************************************************************/
2292
/*********************************** EFFECTS **********************************/
2293
/******************************************************************************/
2294
 
2295
( function() {
2296
 
2297
if ( $.expr && $.expr.pseudos && $.expr.pseudos.animated ) {
2298
	$.expr.pseudos.animated = ( function( orig ) {
2299
		return function( elem ) {
2300
			return !!$( elem ).data( dataSpaceAnimated ) || orig( elem );
2301
		};
2302
	} )( $.expr.pseudos.animated );
2303
}
2304
 
2305
if ( $.uiBackCompat !== false ) {
2306
	$.extend( $.effects, {
2307
 
2308
		// Saves a set of properties in a data storage
2309
		save: function( element, set ) {
2310
			var i = 0, length = set.length;
2311
			for ( ; i < length; i++ ) {
2312
				if ( set[ i ] !== null ) {
2313
					element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
2314
				}
2315
			}
2316
		},
2317
 
2318
		// Restores a set of previously saved properties from a data storage
2319
		restore: function( element, set ) {
2320
			var val, i = 0, length = set.length;
2321
			for ( ; i < length; i++ ) {
2322
				if ( set[ i ] !== null ) {
2323
					val = element.data( dataSpace + set[ i ] );
2324
					element.css( set[ i ], val );
2325
				}
2326
			}
2327
		},
2328
 
2329
		setMode: function( el, mode ) {
2330
			if ( mode === "toggle" ) {
2331
				mode = el.is( ":hidden" ) ? "show" : "hide";
2332
			}
2333
			return mode;
2334
		},
2335
 
2336
		// Wraps the element around a wrapper that copies position properties
2337
		createWrapper: function( element ) {
2338
 
2339
			// If the element is already wrapped, return it
2340
			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
2341
				return element.parent();
2342
			}
2343
 
2344
			// Wrap the element
2345
			var props = {
2346
					width: element.outerWidth( true ),
2347
					height: element.outerHeight( true ),
2348
					"float": element.css( "float" )
2349
				},
2350
				wrapper = $( "<div></div>" )
2351
					.addClass( "ui-effects-wrapper" )
2352
					.css( {
2353
						fontSize: "100%",
2354
						background: "transparent",
2355
						border: "none",
2356
						margin: 0,
2357
						padding: 0
2358
					} ),
2359
 
2360
				// Store the size in case width/height are defined in % - Fixes #5245
2361
				size = {
2362
					width: element.width(),
2363
					height: element.height()
2364
				},
2365
				active = document.activeElement;
2366
 
2367
			// Support: Firefox
2368
			// Firefox incorrectly exposes anonymous content
2369
			// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
2370
			try {
2371
				// eslint-disable-next-line no-unused-expressions
2372
				active.id;
2373
			} catch ( e ) {
2374
				active = document.body;
2375
			}
2376
 
2377
			element.wrap( wrapper );
2378
 
2379
			// Fixes #7595 - Elements lose focus when wrapped.
2380
			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
2381
				$( active ).trigger( "focus" );
2382
			}
2383
 
2384
			// Hotfix for jQuery 1.4 since some change in wrap() seems to actually
2385
			// lose the reference to the wrapped element
2386
			wrapper = element.parent();
2387
 
2388
			// Transfer positioning properties to the wrapper
2389
			if ( element.css( "position" ) === "static" ) {
2390
				wrapper.css( { position: "relative" } );
2391
				element.css( { position: "relative" } );
2392
			} else {
2393
				$.extend( props, {
2394
					position: element.css( "position" ),
2395
					zIndex: element.css( "z-index" )
2396
				} );
2397
				$.each( [ "top", "left", "bottom", "right" ], function( i, pos ) {
2398
					props[ pos ] = element.css( pos );
2399
					if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
2400
						props[ pos ] = "auto";
2401
					}
2402
				} );
2403
				element.css( {
2404
					position: "relative",
2405
					top: 0,
2406
					left: 0,
2407
					right: "auto",
2408
					bottom: "auto"
2409
				} );
2410
			}
2411
			element.css( size );
2412
 
2413
			return wrapper.css( props ).show();
2414
		},
2415
 
2416
		removeWrapper: function( element ) {
2417
			var active = document.activeElement;
2418
 
2419
			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
2420
				element.parent().replaceWith( element );
2421
 
2422
				// Fixes #7595 - Elements lose focus when wrapped.
2423
				if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
2424
					$( active ).trigger( "focus" );
2425
				}
2426
			}
2427
 
2428
			return element;
2429
		}
2430
	} );
2431
}
2432
 
2433
$.extend( $.effects, {
2434
	version: "1.13.2",
2435
 
2436
	define: function( name, mode, effect ) {
2437
		if ( !effect ) {
2438
			effect = mode;
2439
			mode = "effect";
2440
		}
2441
 
2442
		$.effects.effect[ name ] = effect;
2443
		$.effects.effect[ name ].mode = mode;
2444
 
2445
		return effect;
2446
	},
2447
 
2448
	scaledDimensions: function( element, percent, direction ) {
2449
		if ( percent === 0 ) {
2450
			return {
2451
				height: 0,
2452
				width: 0,
2453
				outerHeight: 0,
2454
				outerWidth: 0
2455
			};
2456
		}
2457
 
2458
		var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1,
2459
			y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1;
2460
 
2461
		return {
2462
			height: element.height() * y,
2463
			width: element.width() * x,
2464
			outerHeight: element.outerHeight() * y,
2465
			outerWidth: element.outerWidth() * x
2466
		};
2467
 
2468
	},
2469
 
2470
	clipToBox: function( animation ) {
2471
		return {
2472
			width: animation.clip.right - animation.clip.left,
2473
			height: animation.clip.bottom - animation.clip.top,
2474
			left: animation.clip.left,
2475
			top: animation.clip.top
2476
		};
2477
	},
2478
 
2479
	// Injects recently queued functions to be first in line (after "inprogress")
2480
	unshift: function( element, queueLength, count ) {
2481
		var queue = element.queue();
2482
 
2483
		if ( queueLength > 1 ) {
2484
			queue.splice.apply( queue,
2485
				[ 1, 0 ].concat( queue.splice( queueLength, count ) ) );
2486
		}
2487
		element.dequeue();
2488
	},
2489
 
2490
	saveStyle: function( element ) {
2491
		element.data( dataSpaceStyle, element[ 0 ].style.cssText );
2492
	},
2493
 
2494
	restoreStyle: function( element ) {
2495
		element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || "";
2496
		element.removeData( dataSpaceStyle );
2497
	},
2498
 
2499
	mode: function( element, mode ) {
2500
		var hidden = element.is( ":hidden" );
2501
 
2502
		if ( mode === "toggle" ) {
2503
			mode = hidden ? "show" : "hide";
2504
		}
2505
		if ( hidden ? mode === "hide" : mode === "show" ) {
2506
			mode = "none";
2507
		}
2508
		return mode;
2509
	},
2510
 
2511
	// Translates a [top,left] array into a baseline value
2512
	getBaseline: function( origin, original ) {
2513
		var y, x;
2514
 
2515
		switch ( origin[ 0 ] ) {
2516
		case "top":
2517
			y = 0;
2518
			break;
2519
		case "middle":
2520
			y = 0.5;
2521
			break;
2522
		case "bottom":
2523
			y = 1;
2524
			break;
2525
		default:
2526
			y = origin[ 0 ] / original.height;
2527
		}
2528
 
2529
		switch ( origin[ 1 ] ) {
2530
		case "left":
2531
			x = 0;
2532
			break;
2533
		case "center":
2534
			x = 0.5;
2535
			break;
2536
		case "right":
2537
			x = 1;
2538
			break;
2539
		default:
2540
			x = origin[ 1 ] / original.width;
2541
		}
2542
 
2543
		return {
2544
			x: x,
2545
			y: y
2546
		};
2547
	},
2548
 
2549
	// Creates a placeholder element so that the original element can be made absolute
2550
	createPlaceholder: function( element ) {
2551
		var placeholder,
2552
			cssPosition = element.css( "position" ),
2553
			position = element.position();
2554
 
2555
		// Lock in margins first to account for form elements, which
2556
		// will change margin if you explicitly set height
2557
		// see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380
2558
		// Support: Safari
2559
		element.css( {
2560
			marginTop: element.css( "marginTop" ),
2561
			marginBottom: element.css( "marginBottom" ),
2562
			marginLeft: element.css( "marginLeft" ),
2563
			marginRight: element.css( "marginRight" )
2564
		} )
2565
		.outerWidth( element.outerWidth() )
2566
		.outerHeight( element.outerHeight() );
2567
 
2568
		if ( /^(static|relative)/.test( cssPosition ) ) {
2569
			cssPosition = "absolute";
2570
 
2571
			placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( {
2572
 
2573
				// Convert inline to inline block to account for inline elements
2574
				// that turn to inline block based on content (like img)
2575
				display: /^(inline|ruby)/.test( element.css( "display" ) ) ?
2576
					"inline-block" :
2577
					"block",
2578
				visibility: "hidden",
2579
 
2580
				// Margins need to be set to account for margin collapse
2581
				marginTop: element.css( "marginTop" ),
2582
				marginBottom: element.css( "marginBottom" ),
2583
				marginLeft: element.css( "marginLeft" ),
2584
				marginRight: element.css( "marginRight" ),
2585
				"float": element.css( "float" )
2586
			} )
2587
			.outerWidth( element.outerWidth() )
2588
			.outerHeight( element.outerHeight() )
2589
			.addClass( "ui-effects-placeholder" );
2590
 
2591
			element.data( dataSpace + "placeholder", placeholder );
2592
		}
2593
 
2594
		element.css( {
2595
			position: cssPosition,
2596
			left: position.left,
2597
			top: position.top
2598
		} );
2599
 
2600
		return placeholder;
2601
	},
2602
 
2603
	removePlaceholder: function( element ) {
2604
		var dataKey = dataSpace + "placeholder",
2605
				placeholder = element.data( dataKey );
2606
 
2607
		if ( placeholder ) {
2608
			placeholder.remove();
2609
			element.removeData( dataKey );
2610
		}
2611
	},
2612
 
2613
	// Removes a placeholder if it exists and restores
2614
	// properties that were modified during placeholder creation
2615
	cleanUp: function( element ) {
2616
		$.effects.restoreStyle( element );
2617
		$.effects.removePlaceholder( element );
2618
	},
2619
 
2620
	setTransition: function( element, list, factor, value ) {
2621
		value = value || {};
2622
		$.each( list, function( i, x ) {
2623
			var unit = element.cssUnit( x );
2624
			if ( unit[ 0 ] > 0 ) {
2625
				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
2626
			}
2627
		} );
2628
		return value;
2629
	}
2630
} );
2631
 
2632
// Return an effect options object for the given parameters:
2633
function _normalizeArguments( effect, options, speed, callback ) {
2634
 
2635
	// Allow passing all options as the first parameter
2636
	if ( $.isPlainObject( effect ) ) {
2637
		options = effect;
2638
		effect = effect.effect;
2639
	}
2640
 
2641
	// Convert to an object
2642
	effect = { effect: effect };
2643
 
2644
	// Catch (effect, null, ...)
2645
	if ( options == null ) {
2646
		options = {};
2647
	}
2648
 
2649
	// Catch (effect, callback)
2650
	if ( typeof options === "function" ) {
2651
		callback = options;
2652
		speed = null;
2653
		options = {};
2654
	}
2655
 
2656
	// Catch (effect, speed, ?)
2657
	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
2658
		callback = speed;
2659
		speed = options;
2660
		options = {};
2661
	}
2662
 
2663
	// Catch (effect, options, callback)
2664
	if ( typeof speed === "function" ) {
2665
		callback = speed;
2666
		speed = null;
2667
	}
2668
 
2669
	// Add options to effect
2670
	if ( options ) {
2671
		$.extend( effect, options );
2672
	}
2673
 
2674
	speed = speed || options.duration;
2675
	effect.duration = $.fx.off ? 0 :
2676
		typeof speed === "number" ? speed :
2677
		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
2678
		$.fx.speeds._default;
2679
 
2680
	effect.complete = callback || options.complete;
2681
 
2682
	return effect;
2683
}
2684
 
2685
function standardAnimationOption( option ) {
2686
 
2687
	// Valid standard speeds (nothing, number, named speed)
2688
	if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
2689
		return true;
2690
	}
2691
 
2692
	// Invalid strings - treat as "normal" speed
2693
	if ( typeof option === "string" && !$.effects.effect[ option ] ) {
2694
		return true;
2695
	}
2696
 
2697
	// Complete callback
2698
	if ( typeof option === "function" ) {
2699
		return true;
2700
	}
2701
 
2702
	// Options hash (but not naming an effect)
2703
	if ( typeof option === "object" && !option.effect ) {
2704
		return true;
2705
	}
2706
 
2707
	// Didn't match any standard API
2708
	return false;
2709
}
2710
 
2711
$.fn.extend( {
2712
	effect: function( /* effect, options, speed, callback */ ) {
2713
		var args = _normalizeArguments.apply( this, arguments ),
2714
			effectMethod = $.effects.effect[ args.effect ],
2715
			defaultMode = effectMethod.mode,
2716
			queue = args.queue,
2717
			queueName = queue || "fx",
2718
			complete = args.complete,
2719
			mode = args.mode,
2720
			modes = [],
2721
			prefilter = function( next ) {
2722
				var el = $( this ),
2723
					normalizedMode = $.effects.mode( el, mode ) || defaultMode;
2724
 
2725
				// Sentinel for duck-punching the :animated pseudo-selector
2726
				el.data( dataSpaceAnimated, true );
2727
 
2728
				// Save effect mode for later use,
2729
				// we can't just call $.effects.mode again later,
2730
				// as the .show() below destroys the initial state
2731
				modes.push( normalizedMode );
2732
 
2733
				// See $.uiBackCompat inside of run() for removal of defaultMode in 1.14
2734
				if ( defaultMode && ( normalizedMode === "show" ||
2735
						( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) {
2736
					el.show();
2737
				}
2738
 
2739
				if ( !defaultMode || normalizedMode !== "none" ) {
2740
					$.effects.saveStyle( el );
2741
				}
2742
 
2743
				if ( typeof next === "function" ) {
2744
					next();
2745
				}
2746
			};
2747
 
2748
		if ( $.fx.off || !effectMethod ) {
2749
 
2750
			// Delegate to the original method (e.g., .show()) if possible
2751
			if ( mode ) {
2752
				return this[ mode ]( args.duration, complete );
2753
			} else {
2754
				return this.each( function() {
2755
					if ( complete ) {
2756
						complete.call( this );
2757
					}
2758
				} );
2759
			}
2760
		}
2761
 
2762
		function run( next ) {
2763
			var elem = $( this );
2764
 
2765
			function cleanup() {
2766
				elem.removeData( dataSpaceAnimated );
2767
 
2768
				$.effects.cleanUp( elem );
2769
 
2770
				if ( args.mode === "hide" ) {
2771
					elem.hide();
2772
				}
2773
 
2774
				done();
2775
			}
2776
 
2777
			function done() {
2778
				if ( typeof complete === "function" ) {
2779
					complete.call( elem[ 0 ] );
2780
				}
2781
 
2782
				if ( typeof next === "function" ) {
2783
					next();
2784
				}
2785
			}
2786
 
2787
			// Override mode option on a per element basis,
2788
			// as toggle can be either show or hide depending on element state
2789
			args.mode = modes.shift();
2790
 
2791
			if ( $.uiBackCompat !== false && !defaultMode ) {
2792
				if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
2793
 
2794
					// Call the core method to track "olddisplay" properly
2795
					elem[ mode ]();
2796
					done();
2797
				} else {
2798
					effectMethod.call( elem[ 0 ], args, done );
2799
				}
2800
			} else {
2801
				if ( args.mode === "none" ) {
2802
 
2803
					// Call the core method to track "olddisplay" properly
2804
					elem[ mode ]();
2805
					done();
2806
				} else {
2807
					effectMethod.call( elem[ 0 ], args, cleanup );
2808
				}
2809
			}
2810
		}
2811
 
2812
		// Run prefilter on all elements first to ensure that
2813
		// any showing or hiding happens before placeholder creation,
2814
		// which ensures that any layout changes are correctly captured.
2815
		return queue === false ?
2816
			this.each( prefilter ).each( run ) :
2817
			this.queue( queueName, prefilter ).queue( queueName, run );
2818
	},
2819
 
2820
	show: ( function( orig ) {
2821
		return function( option ) {
2822
			if ( standardAnimationOption( option ) ) {
2823
				return orig.apply( this, arguments );
2824
			} else {
2825
				var args = _normalizeArguments.apply( this, arguments );
2826
				args.mode = "show";
2827
				return this.effect.call( this, args );
2828
			}
2829
		};
2830
	} )( $.fn.show ),
2831
 
2832
	hide: ( function( orig ) {
2833
		return function( option ) {
2834
			if ( standardAnimationOption( option ) ) {
2835
				return orig.apply( this, arguments );
2836
			} else {
2837
				var args = _normalizeArguments.apply( this, arguments );
2838
				args.mode = "hide";
2839
				return this.effect.call( this, args );
2840
			}
2841
		};
2842
	} )( $.fn.hide ),
2843
 
2844
	toggle: ( function( orig ) {
2845
		return function( option ) {
2846
			if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
2847
				return orig.apply( this, arguments );
2848
			} else {
2849
				var args = _normalizeArguments.apply( this, arguments );
2850
				args.mode = "toggle";
2851
				return this.effect.call( this, args );
2852
			}
2853
		};
2854
	} )( $.fn.toggle ),
2855
 
2856
	cssUnit: function( key ) {
2857
		var style = this.css( key ),
2858
			val = [];
2859
 
2860
		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
2861
			if ( style.indexOf( unit ) > 0 ) {
2862
				val = [ parseFloat( style ), unit ];
2863
			}
2864
		} );
2865
		return val;
2866
	},
2867
 
2868
	cssClip: function( clipObj ) {
2869
		if ( clipObj ) {
2870
			return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " +
2871
				clipObj.bottom + "px " + clipObj.left + "px)" );
2872
		}
2873
		return parseClip( this.css( "clip" ), this );
2874
	},
2875
 
2876
	transfer: function( options, done ) {
2877
		var element = $( this ),
2878
			target = $( options.to ),
2879
			targetFixed = target.css( "position" ) === "fixed",
2880
			body = $( "body" ),
2881
			fixTop = targetFixed ? body.scrollTop() : 0,
2882
			fixLeft = targetFixed ? body.scrollLeft() : 0,
2883
			endPosition = target.offset(),
2884
			animation = {
2885
				top: endPosition.top - fixTop,
2886
				left: endPosition.left - fixLeft,
2887
				height: target.innerHeight(),
2888
				width: target.innerWidth()
2889
			},
2890
			startPosition = element.offset(),
2891
			transfer = $( "<div class='ui-effects-transfer'></div>" );
2892
 
2893
		transfer
2894
			.appendTo( "body" )
2895
			.addClass( options.className )
2896
			.css( {
2897
				top: startPosition.top - fixTop,
2898
				left: startPosition.left - fixLeft,
2899
				height: element.innerHeight(),
2900
				width: element.innerWidth(),
2901
				position: targetFixed ? "fixed" : "absolute"
2902
			} )
2903
			.animate( animation, options.duration, options.easing, function() {
2904
				transfer.remove();
2905
				if ( typeof done === "function" ) {
2906
					done();
2907
				}
2908
			} );
2909
	}
2910
} );
2911
 
2912
function parseClip( str, element ) {
2913
		var outerWidth = element.outerWidth(),
2914
			outerHeight = element.outerHeight(),
2915
			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)\)$/,
2916
			values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ];
2917
 
2918
		return {
2919
			top: parseFloat( values[ 1 ] ) || 0,
2920
			right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ),
2921
			bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ),
2922
			left: parseFloat( values[ 4 ] ) || 0
2923
		};
2924
}
2925
 
2926
$.fx.step.clip = function( fx ) {
2927
	if ( !fx.clipInit ) {
2928
		fx.start = $( fx.elem ).cssClip();
2929
		if ( typeof fx.end === "string" ) {
2930
			fx.end = parseClip( fx.end, fx.elem );
2931
		}
2932
		fx.clipInit = true;
2933
	}
2934
 
2935
	$( fx.elem ).cssClip( {
2936
		top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top,
2937
		right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right,
2938
		bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom,
2939
		left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left
2940
	} );
2941
};
2942
 
2943
} )();
2944
 
2945
/******************************************************************************/
2946
/*********************************** EASING ***********************************/
2947
/******************************************************************************/
2948
 
2949
( function() {
2950
 
2951
// Based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
2952
 
2953
var baseEasings = {};
2954
 
2955
$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
2956
	baseEasings[ name ] = function( p ) {
2957
		return Math.pow( p, i + 2 );
2958
	};
2959
} );
2960
 
2961
$.extend( baseEasings, {
2962
	Sine: function( p ) {
2963
		return 1 - Math.cos( p * Math.PI / 2 );
2964
	},
2965
	Circ: function( p ) {
2966
		return 1 - Math.sqrt( 1 - p * p );
2967
	},
2968
	Elastic: function( p ) {
2969
		return p === 0 || p === 1 ? p :
2970
			-Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );
2971
	},
2972
	Back: function( p ) {
2973
		return p * p * ( 3 * p - 2 );
2974
	},
2975
	Bounce: function( p ) {
2976
		var pow2,
2977
			bounce = 4;
2978
 
2979
		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
2980
		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
2981
	}
2982
} );
2983
 
2984
$.each( baseEasings, function( name, easeIn ) {
2985
	$.easing[ "easeIn" + name ] = easeIn;
2986
	$.easing[ "easeOut" + name ] = function( p ) {
2987
		return 1 - easeIn( 1 - p );
2988
	};
2989
	$.easing[ "easeInOut" + name ] = function( p ) {
2990
		return p < 0.5 ?
2991
			easeIn( p * 2 ) / 2 :
2992
			1 - easeIn( p * -2 + 2 ) / 2;
2993
	};
2994
} );
2995
 
2996
} )();
2997
 
2998
var effect = $.effects;
2999
 
3000
 
3001
/*!
3002
 * jQuery UI Effects Blind 1.13.2
3003
 * http://jqueryui.com
3004
 *
3005
 * Copyright jQuery Foundation and other contributors
3006
 * Released under the MIT license.
3007
 * http://jquery.org/license
3008
 */
3009
 
3010
//>>label: Blind Effect
3011
//>>group: Effects
3012
//>>description: Blinds the element.
3013
//>>docs: http://api.jqueryui.com/blind-effect/
3014
//>>demos: http://jqueryui.com/effect/
3015
 
3016
 
3017
var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) {
3018
	var map = {
3019
			up: [ "bottom", "top" ],
3020
			vertical: [ "bottom", "top" ],
3021
			down: [ "top", "bottom" ],
3022
			left: [ "right", "left" ],
3023
			horizontal: [ "right", "left" ],
3024
			right: [ "left", "right" ]
3025
		},
3026
		element = $( this ),
3027
		direction = options.direction || "up",
3028
		start = element.cssClip(),
3029
		animate = { clip: $.extend( {}, start ) },
3030
		placeholder = $.effects.createPlaceholder( element );
3031
 
3032
	animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ];
3033
 
3034
	if ( options.mode === "show" ) {
3035
		element.cssClip( animate.clip );
3036
		if ( placeholder ) {
3037
			placeholder.css( $.effects.clipToBox( animate ) );
3038
		}
3039
 
3040
		animate.clip = start;
3041
	}
3042
 
3043
	if ( placeholder ) {
3044
		placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing );
3045
	}
3046
 
3047
	element.animate( animate, {
3048
		queue: false,
3049
		duration: options.duration,
3050
		easing: options.easing,
3051
		complete: done
3052
	} );
3053
} );
3054
 
3055
 
3056
/*!
3057
 * jQuery UI Effects Bounce 1.13.2
3058
 * http://jqueryui.com
3059
 *
3060
 * Copyright jQuery Foundation and other contributors
3061
 * Released under the MIT license.
3062
 * http://jquery.org/license
3063
 */
3064
 
3065
//>>label: Bounce Effect
3066
//>>group: Effects
3067
//>>description: Bounces an element horizontally or vertically n times.
3068
//>>docs: http://api.jqueryui.com/bounce-effect/
3069
//>>demos: http://jqueryui.com/effect/
3070
 
3071
 
3072
var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) {
3073
	var upAnim, downAnim, refValue,
3074
		element = $( this ),
3075
 
3076
		// Defaults:
3077
		mode = options.mode,
3078
		hide = mode === "hide",
3079
		show = mode === "show",
3080
		direction = options.direction || "up",
3081
		distance = options.distance,
3082
		times = options.times || 5,
3083
 
3084
		// Number of internal animations
3085
		anims = times * 2 + ( show || hide ? 1 : 0 ),
3086
		speed = options.duration / anims,
3087
		easing = options.easing,
3088
 
3089
		// Utility:
3090
		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3091
		motion = ( direction === "up" || direction === "left" ),
3092
		i = 0,
3093
 
3094
		queuelen = element.queue().length;
3095
 
3096
	$.effects.createPlaceholder( element );
3097
 
3098
	refValue = element.css( ref );
3099
 
3100
	// Default distance for the BIGGEST bounce is the outer Distance / 3
3101
	if ( !distance ) {
3102
		distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
3103
	}
3104
 
3105
	if ( show ) {
3106
		downAnim = { opacity: 1 };
3107
		downAnim[ ref ] = refValue;
3108
 
3109
		// If we are showing, force opacity 0 and set the initial position
3110
		// then do the "first" animation
3111
		element
3112
			.css( "opacity", 0 )
3113
			.css( ref, motion ? -distance * 2 : distance * 2 )
3114
			.animate( downAnim, speed, easing );
3115
	}
3116
 
3117
	// Start at the smallest distance if we are hiding
3118
	if ( hide ) {
3119
		distance = distance / Math.pow( 2, times - 1 );
3120
	}
3121
 
3122
	downAnim = {};
3123
	downAnim[ ref ] = refValue;
3124
 
3125
	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
3126
	for ( ; i < times; i++ ) {
3127
		upAnim = {};
3128
		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
3129
 
3130
		element
3131
			.animate( upAnim, speed, easing )
3132
			.animate( downAnim, speed, easing );
3133
 
3134
		distance = hide ? distance * 2 : distance / 2;
3135
	}
3136
 
3137
	// Last Bounce when Hiding
3138
	if ( hide ) {
3139
		upAnim = { opacity: 0 };
3140
		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
3141
 
3142
		element.animate( upAnim, speed, easing );
3143
	}
3144
 
3145
	element.queue( done );
3146
 
3147
	$.effects.unshift( element, queuelen, anims + 1 );
3148
} );
3149
 
3150
 
3151
/*!
3152
 * jQuery UI Effects Clip 1.13.2
3153
 * http://jqueryui.com
3154
 *
3155
 * Copyright jQuery Foundation and other contributors
3156
 * Released under the MIT license.
3157
 * http://jquery.org/license
3158
 */
3159
 
3160
//>>label: Clip Effect
3161
//>>group: Effects
3162
//>>description: Clips the element on and off like an old TV.
3163
//>>docs: http://api.jqueryui.com/clip-effect/
3164
//>>demos: http://jqueryui.com/effect/
3165
 
3166
 
3167
var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) {
3168
	var start,
3169
		animate = {},
3170
		element = $( this ),
3171
		direction = options.direction || "vertical",
3172
		both = direction === "both",
3173
		horizontal = both || direction === "horizontal",
3174
		vertical = both || direction === "vertical";
3175
 
3176
	start = element.cssClip();
3177
	animate.clip = {
3178
		top: vertical ? ( start.bottom - start.top ) / 2 : start.top,
3179
		right: horizontal ? ( start.right - start.left ) / 2 : start.right,
3180
		bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom,
3181
		left: horizontal ? ( start.right - start.left ) / 2 : start.left
3182
	};
3183
 
3184
	$.effects.createPlaceholder( element );
3185
 
3186
	if ( options.mode === "show" ) {
3187
		element.cssClip( animate.clip );
3188
		animate.clip = start;
3189
	}
3190
 
3191
	element.animate( animate, {
3192
		queue: false,
3193
		duration: options.duration,
3194
		easing: options.easing,
3195
		complete: done
3196
	} );
3197
 
3198
} );
3199
 
3200
 
3201
/*!
3202
 * jQuery UI Effects Drop 1.13.2
3203
 * http://jqueryui.com
3204
 *
3205
 * Copyright jQuery Foundation and other contributors
3206
 * Released under the MIT license.
3207
 * http://jquery.org/license
3208
 */
3209
 
3210
//>>label: Drop Effect
3211
//>>group: Effects
3212
//>>description: Moves an element in one direction and hides it at the same time.
3213
//>>docs: http://api.jqueryui.com/drop-effect/
3214
//>>demos: http://jqueryui.com/effect/
3215
 
3216
 
3217
var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) {
3218
 
3219
	var distance,
3220
		element = $( this ),
3221
		mode = options.mode,
3222
		show = mode === "show",
3223
		direction = options.direction || "left",
3224
		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3225
		motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=",
3226
		oppositeMotion = ( motion === "+=" ) ? "-=" : "+=",
3227
		animation = {
3228
			opacity: 0
3229
		};
3230
 
3231
	$.effects.createPlaceholder( element );
3232
 
3233
	distance = options.distance ||
3234
		element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
3235
 
3236
	animation[ ref ] = motion + distance;
3237
 
3238
	if ( show ) {
3239
		element.css( animation );
3240
 
3241
		animation[ ref ] = oppositeMotion + distance;
3242
		animation.opacity = 1;
3243
	}
3244
 
3245
	// Animate
3246
	element.animate( animation, {
3247
		queue: false,
3248
		duration: options.duration,
3249
		easing: options.easing,
3250
		complete: done
3251
	} );
3252
} );
3253
 
3254
 
3255
/*!
3256
 * jQuery UI Effects Explode 1.13.2
3257
 * http://jqueryui.com
3258
 *
3259
 * Copyright jQuery Foundation and other contributors
3260
 * Released under the MIT license.
3261
 * http://jquery.org/license
3262
 */
3263
 
3264
//>>label: Explode Effect
3265
//>>group: Effects
3266
/* eslint-disable max-len */
3267
//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness.
3268
/* eslint-enable max-len */
3269
//>>docs: http://api.jqueryui.com/explode-effect/
3270
//>>demos: http://jqueryui.com/effect/
3271
 
3272
 
3273
var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) {
3274
 
3275
	var i, j, left, top, mx, my,
3276
		rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3,
3277
		cells = rows,
3278
		element = $( this ),
3279
		mode = options.mode,
3280
		show = mode === "show",
3281
 
3282
		// Show and then visibility:hidden the element before calculating offset
3283
		offset = element.show().css( "visibility", "hidden" ).offset(),
3284
 
3285
		// Width and height of a piece
3286
		width = Math.ceil( element.outerWidth() / cells ),
3287
		height = Math.ceil( element.outerHeight() / rows ),
3288
		pieces = [];
3289
 
3290
	// Children animate complete:
3291
	function childComplete() {
3292
		pieces.push( this );
3293
		if ( pieces.length === rows * cells ) {
3294
			animComplete();
3295
		}
3296
	}
3297
 
3298
	// Clone the element for each row and cell.
3299
	for ( i = 0; i < rows; i++ ) { // ===>
3300
		top = offset.top + i * height;
3301
		my = i - ( rows - 1 ) / 2;
3302
 
3303
		for ( j = 0; j < cells; j++ ) { // |||
3304
			left = offset.left + j * width;
3305
			mx = j - ( cells - 1 ) / 2;
3306
 
3307
			// Create a clone of the now hidden main element that will be absolute positioned
3308
			// within a wrapper div off the -left and -top equal to size of our pieces
3309
			element
3310
				.clone()
3311
				.appendTo( "body" )
3312
				.wrap( "<div></div>" )
3313
				.css( {
3314
					position: "absolute",
3315
					visibility: "visible",
3316
					left: -j * width,
3317
					top: -i * height
3318
				} )
3319
 
3320
				// Select the wrapper - make it overflow: hidden and absolute positioned based on
3321
				// where the original was located +left and +top equal to the size of pieces
3322
				.parent()
3323
					.addClass( "ui-effects-explode" )
3324
					.css( {
3325
						position: "absolute",
3326
						overflow: "hidden",
3327
						width: width,
3328
						height: height,
3329
						left: left + ( show ? mx * width : 0 ),
3330
						top: top + ( show ? my * height : 0 ),
3331
						opacity: show ? 0 : 1
3332
					} )
3333
					.animate( {
3334
						left: left + ( show ? 0 : mx * width ),
3335
						top: top + ( show ? 0 : my * height ),
3336
						opacity: show ? 1 : 0
3337
					}, options.duration || 500, options.easing, childComplete );
3338
		}
3339
	}
3340
 
3341
	function animComplete() {
3342
		element.css( {
3343
			visibility: "visible"
3344
		} );
3345
		$( pieces ).remove();
3346
		done();
3347
	}
3348
} );
3349
 
3350
 
3351
/*!
3352
 * jQuery UI Effects Fade 1.13.2
3353
 * http://jqueryui.com
3354
 *
3355
 * Copyright jQuery Foundation and other contributors
3356
 * Released under the MIT license.
3357
 * http://jquery.org/license
3358
 */
3359
 
3360
//>>label: Fade Effect
3361
//>>group: Effects
3362
//>>description: Fades the element.
3363
//>>docs: http://api.jqueryui.com/fade-effect/
3364
//>>demos: http://jqueryui.com/effect/
3365
 
3366
 
3367
var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) {
3368
	var show = options.mode === "show";
3369
 
3370
	$( this )
3371
		.css( "opacity", show ? 0 : 1 )
3372
		.animate( {
3373
			opacity: show ? 1 : 0
3374
		}, {
3375
			queue: false,
3376
			duration: options.duration,
3377
			easing: options.easing,
3378
			complete: done
3379
		} );
3380
} );
3381
 
3382
 
3383
/*!
3384
 * jQuery UI Effects Fold 1.13.2
3385
 * http://jqueryui.com
3386
 *
3387
 * Copyright jQuery Foundation and other contributors
3388
 * Released under the MIT license.
3389
 * http://jquery.org/license
3390
 */
3391
 
3392
//>>label: Fold Effect
3393
//>>group: Effects
3394
//>>description: Folds an element first horizontally and then vertically.
3395
//>>docs: http://api.jqueryui.com/fold-effect/
3396
//>>demos: http://jqueryui.com/effect/
3397
 
3398
 
3399
var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) {
3400
 
3401
	// Create element
3402
	var element = $( this ),
3403
		mode = options.mode,
3404
		show = mode === "show",
3405
		hide = mode === "hide",
3406
		size = options.size || 15,
3407
		percent = /([0-9]+)%/.exec( size ),
3408
		horizFirst = !!options.horizFirst,
3409
		ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ],
3410
		duration = options.duration / 2,
3411
 
3412
		placeholder = $.effects.createPlaceholder( element ),
3413
 
3414
		start = element.cssClip(),
3415
		animation1 = { clip: $.extend( {}, start ) },
3416
		animation2 = { clip: $.extend( {}, start ) },
3417
 
3418
		distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ],
3419
 
3420
		queuelen = element.queue().length;
3421
 
3422
	if ( percent ) {
3423
		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
3424
	}
3425
	animation1.clip[ ref[ 0 ] ] = size;
3426
	animation2.clip[ ref[ 0 ] ] = size;
3427
	animation2.clip[ ref[ 1 ] ] = 0;
3428
 
3429
	if ( show ) {
3430
		element.cssClip( animation2.clip );
3431
		if ( placeholder ) {
3432
			placeholder.css( $.effects.clipToBox( animation2 ) );
3433
		}
3434
 
3435
		animation2.clip = start;
3436
	}
3437
 
3438
	// Animate
3439
	element
3440
		.queue( function( next ) {
3441
			if ( placeholder ) {
3442
				placeholder
3443
					.animate( $.effects.clipToBox( animation1 ), duration, options.easing )
3444
					.animate( $.effects.clipToBox( animation2 ), duration, options.easing );
3445
			}
3446
 
3447
			next();
3448
		} )
3449
		.animate( animation1, duration, options.easing )
3450
		.animate( animation2, duration, options.easing )
3451
		.queue( done );
3452
 
3453
	$.effects.unshift( element, queuelen, 4 );
3454
} );
3455
 
3456
 
3457
/*!
3458
 * jQuery UI Effects Highlight 1.13.2
3459
 * http://jqueryui.com
3460
 *
3461
 * Copyright jQuery Foundation and other contributors
3462
 * Released under the MIT license.
3463
 * http://jquery.org/license
3464
 */
3465
 
3466
//>>label: Highlight Effect
3467
//>>group: Effects
3468
//>>description: Highlights the background of an element in a defined color for a custom duration.
3469
//>>docs: http://api.jqueryui.com/highlight-effect/
3470
//>>demos: http://jqueryui.com/effect/
3471
 
3472
 
3473
var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) {
3474
	var element = $( this ),
3475
		animation = {
3476
			backgroundColor: element.css( "backgroundColor" )
3477
		};
3478
 
3479
	if ( options.mode === "hide" ) {
3480
		animation.opacity = 0;
3481
	}
3482
 
3483
	$.effects.saveStyle( element );
3484
 
3485
	element
3486
		.css( {
3487
			backgroundImage: "none",
3488
			backgroundColor: options.color || "#ffff99"
3489
		} )
3490
		.animate( animation, {
3491
			queue: false,
3492
			duration: options.duration,
3493
			easing: options.easing,
3494
			complete: done
3495
		} );
3496
} );
3497
 
3498
 
3499
/*!
3500
 * jQuery UI Effects Size 1.13.2
3501
 * http://jqueryui.com
3502
 *
3503
 * Copyright jQuery Foundation and other contributors
3504
 * Released under the MIT license.
3505
 * http://jquery.org/license
3506
 */
3507
 
3508
//>>label: Size Effect
3509
//>>group: Effects
3510
//>>description: Resize an element to a specified width and height.
3511
//>>docs: http://api.jqueryui.com/size-effect/
3512
//>>demos: http://jqueryui.com/effect/
3513
 
3514
 
3515
var effectsEffectSize = $.effects.define( "size", function( options, done ) {
3516
 
3517
	// Create element
3518
	var baseline, factor, temp,
3519
		element = $( this ),
3520
 
3521
		// Copy for children
3522
		cProps = [ "fontSize" ],
3523
		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
3524
		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
3525
 
3526
		// Set options
3527
		mode = options.mode,
3528
		restore = mode !== "effect",
3529
		scale = options.scale || "both",
3530
		origin = options.origin || [ "middle", "center" ],
3531
		position = element.css( "position" ),
3532
		pos = element.position(),
3533
		original = $.effects.scaledDimensions( element ),
3534
		from = options.from || original,
3535
		to = options.to || $.effects.scaledDimensions( element, 0 );
3536
 
3537
	$.effects.createPlaceholder( element );
3538
 
3539
	if ( mode === "show" ) {
3540
		temp = from;
3541
		from = to;
3542
		to = temp;
3543
	}
3544
 
3545
	// Set scaling factor
3546
	factor = {
3547
		from: {
3548
			y: from.height / original.height,
3549
			x: from.width / original.width
3550
		},
3551
		to: {
3552
			y: to.height / original.height,
3553
			x: to.width / original.width
3554
		}
3555
	};
3556
 
3557
	// Scale the css box
3558
	if ( scale === "box" || scale === "both" ) {
3559
 
3560
		// Vertical props scaling
3561
		if ( factor.from.y !== factor.to.y ) {
3562
			from = $.effects.setTransition( element, vProps, factor.from.y, from );
3563
			to = $.effects.setTransition( element, vProps, factor.to.y, to );
3564
		}
3565
 
3566
		// Horizontal props scaling
3567
		if ( factor.from.x !== factor.to.x ) {
3568
			from = $.effects.setTransition( element, hProps, factor.from.x, from );
3569
			to = $.effects.setTransition( element, hProps, factor.to.x, to );
3570
		}
3571
	}
3572
 
3573
	// Scale the content
3574
	if ( scale === "content" || scale === "both" ) {
3575
 
3576
		// Vertical props scaling
3577
		if ( factor.from.y !== factor.to.y ) {
3578
			from = $.effects.setTransition( element, cProps, factor.from.y, from );
3579
			to = $.effects.setTransition( element, cProps, factor.to.y, to );
3580
		}
3581
	}
3582
 
3583
	// Adjust the position properties based on the provided origin points
3584
	if ( origin ) {
3585
		baseline = $.effects.getBaseline( origin, original );
3586
		from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top;
3587
		from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left;
3588
		to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top;
3589
		to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left;
3590
	}
3591
	delete from.outerHeight;
3592
	delete from.outerWidth;
3593
	element.css( from );
3594
 
3595
	// Animate the children if desired
3596
	if ( scale === "content" || scale === "both" ) {
3597
 
3598
		vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps );
3599
		hProps = hProps.concat( [ "marginLeft", "marginRight" ] );
3600
 
3601
		// Only animate children with width attributes specified
3602
		// TODO: is this right? should we include anything with css width specified as well
3603
		element.find( "*[width]" ).each( function() {
3604
			var child = $( this ),
3605
				childOriginal = $.effects.scaledDimensions( child ),
3606
				childFrom = {
3607
					height: childOriginal.height * factor.from.y,
3608
					width: childOriginal.width * factor.from.x,
3609
					outerHeight: childOriginal.outerHeight * factor.from.y,
3610
					outerWidth: childOriginal.outerWidth * factor.from.x
3611
				},
3612
				childTo = {
3613
					height: childOriginal.height * factor.to.y,
3614
					width: childOriginal.width * factor.to.x,
3615
					outerHeight: childOriginal.height * factor.to.y,
3616
					outerWidth: childOriginal.width * factor.to.x
3617
				};
3618
 
3619
			// Vertical props scaling
3620
			if ( factor.from.y !== factor.to.y ) {
3621
				childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom );
3622
				childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo );
3623
			}
3624
 
3625
			// Horizontal props scaling
3626
			if ( factor.from.x !== factor.to.x ) {
3627
				childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom );
3628
				childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo );
3629
			}
3630
 
3631
			if ( restore ) {
3632
				$.effects.saveStyle( child );
3633
			}
3634
 
3635
			// Animate children
3636
			child.css( childFrom );
3637
			child.animate( childTo, options.duration, options.easing, function() {
3638
 
3639
				// Restore children
3640
				if ( restore ) {
3641
					$.effects.restoreStyle( child );
3642
				}
3643
			} );
3644
		} );
3645
	}
3646
 
3647
	// Animate
3648
	element.animate( to, {
3649
		queue: false,
3650
		duration: options.duration,
3651
		easing: options.easing,
3652
		complete: function() {
3653
 
3654
			var offset = element.offset();
3655
 
3656
			if ( to.opacity === 0 ) {
3657
				element.css( "opacity", from.opacity );
3658
			}
3659
 
3660
			if ( !restore ) {
3661
				element
3662
					.css( "position", position === "static" ? "relative" : position )
3663
					.offset( offset );
3664
 
3665
				// Need to save style here so that automatic style restoration
3666
				// doesn't restore to the original styles from before the animation.
3667
				$.effects.saveStyle( element );
3668
			}
3669
 
3670
			done();
3671
		}
3672
	} );
3673
 
3674
} );
3675
 
3676
 
3677
/*!
3678
 * jQuery UI Effects Scale 1.13.2
3679
 * http://jqueryui.com
3680
 *
3681
 * Copyright jQuery Foundation and other contributors
3682
 * Released under the MIT license.
3683
 * http://jquery.org/license
3684
 */
3685
 
3686
//>>label: Scale Effect
3687
//>>group: Effects
3688
//>>description: Grows or shrinks an element and its content.
3689
//>>docs: http://api.jqueryui.com/scale-effect/
3690
//>>demos: http://jqueryui.com/effect/
3691
 
3692
 
3693
var effectsEffectScale = $.effects.define( "scale", function( options, done ) {
3694
 
3695
	// Create element
3696
	var el = $( this ),
3697
		mode = options.mode,
3698
		percent = parseInt( options.percent, 10 ) ||
3699
			( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ),
3700
 
3701
		newOptions = $.extend( true, {
3702
			from: $.effects.scaledDimensions( el ),
3703
			to: $.effects.scaledDimensions( el, percent, options.direction || "both" ),
3704
			origin: options.origin || [ "middle", "center" ]
3705
		}, options );
3706
 
3707
	// Fade option to support puff
3708
	if ( options.fade ) {
3709
		newOptions.from.opacity = 1;
3710
		newOptions.to.opacity = 0;
3711
	}
3712
 
3713
	$.effects.effect.size.call( this, newOptions, done );
3714
} );
3715
 
3716
 
3717
/*!
3718
 * jQuery UI Effects Puff 1.13.2
3719
 * http://jqueryui.com
3720
 *
3721
 * Copyright jQuery Foundation and other contributors
3722
 * Released under the MIT license.
3723
 * http://jquery.org/license
3724
 */
3725
 
3726
//>>label: Puff Effect
3727
//>>group: Effects
3728
//>>description: Creates a puff effect by scaling the element up and hiding it at the same time.
3729
//>>docs: http://api.jqueryui.com/puff-effect/
3730
//>>demos: http://jqueryui.com/effect/
3731
 
3732
 
3733
var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) {
3734
	var newOptions = $.extend( true, {}, options, {
3735
		fade: true,
3736
		percent: parseInt( options.percent, 10 ) || 150
3737
	} );
3738
 
3739
	$.effects.effect.scale.call( this, newOptions, done );
3740
} );
3741
 
3742
 
3743
/*!
3744
 * jQuery UI Effects Pulsate 1.13.2
3745
 * http://jqueryui.com
3746
 *
3747
 * Copyright jQuery Foundation and other contributors
3748
 * Released under the MIT license.
3749
 * http://jquery.org/license
3750
 */
3751
 
3752
//>>label: Pulsate Effect
3753
//>>group: Effects
3754
//>>description: Pulsates an element n times by changing the opacity to zero and back.
3755
//>>docs: http://api.jqueryui.com/pulsate-effect/
3756
//>>demos: http://jqueryui.com/effect/
3757
 
3758
 
3759
var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) {
3760
	var element = $( this ),
3761
		mode = options.mode,
3762
		show = mode === "show",
3763
		hide = mode === "hide",
3764
		showhide = show || hide,
3765
 
3766
		// Showing or hiding leaves off the "last" animation
3767
		anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
3768
		duration = options.duration / anims,
3769
		animateTo = 0,
3770
		i = 1,
3771
		queuelen = element.queue().length;
3772
 
3773
	if ( show || !element.is( ":visible" ) ) {
3774
		element.css( "opacity", 0 ).show();
3775
		animateTo = 1;
3776
	}
3777
 
3778
	// Anims - 1 opacity "toggles"
3779
	for ( ; i < anims; i++ ) {
3780
		element.animate( { opacity: animateTo }, duration, options.easing );
3781
		animateTo = 1 - animateTo;
3782
	}
3783
 
3784
	element.animate( { opacity: animateTo }, duration, options.easing );
3785
 
3786
	element.queue( done );
3787
 
3788
	$.effects.unshift( element, queuelen, anims + 1 );
3789
} );
3790
 
3791
 
3792
/*!
3793
 * jQuery UI Effects Shake 1.13.2
3794
 * http://jqueryui.com
3795
 *
3796
 * Copyright jQuery Foundation and other contributors
3797
 * Released under the MIT license.
3798
 * http://jquery.org/license
3799
 */
3800
 
3801
//>>label: Shake Effect
3802
//>>group: Effects
3803
//>>description: Shakes an element horizontally or vertically n times.
3804
//>>docs: http://api.jqueryui.com/shake-effect/
3805
//>>demos: http://jqueryui.com/effect/
3806
 
3807
 
3808
var effectsEffectShake = $.effects.define( "shake", function( options, done ) {
3809
 
3810
	var i = 1,
3811
		element = $( this ),
3812
		direction = options.direction || "left",
3813
		distance = options.distance || 20,
3814
		times = options.times || 3,
3815
		anims = times * 2 + 1,
3816
		speed = Math.round( options.duration / anims ),
3817
		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3818
		positiveMotion = ( direction === "up" || direction === "left" ),
3819
		animation = {},
3820
		animation1 = {},
3821
		animation2 = {},
3822
 
3823
		queuelen = element.queue().length;
3824
 
3825
	$.effects.createPlaceholder( element );
3826
 
3827
	// Animation
3828
	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
3829
	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
3830
	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
3831
 
3832
	// Animate
3833
	element.animate( animation, speed, options.easing );
3834
 
3835
	// Shakes
3836
	for ( ; i < times; i++ ) {
3837
		element
3838
			.animate( animation1, speed, options.easing )
3839
			.animate( animation2, speed, options.easing );
3840
	}
3841
 
3842
	element
3843
		.animate( animation1, speed, options.easing )
3844
		.animate( animation, speed / 2, options.easing )
3845
		.queue( done );
3846
 
3847
	$.effects.unshift( element, queuelen, anims + 1 );
3848
} );
3849
 
3850
 
3851
/*!
3852
 * jQuery UI Effects Slide 1.13.2
3853
 * http://jqueryui.com
3854
 *
3855
 * Copyright jQuery Foundation and other contributors
3856
 * Released under the MIT license.
3857
 * http://jquery.org/license
3858
 */
3859
 
3860
//>>label: Slide Effect
3861
//>>group: Effects
3862
//>>description: Slides an element in and out of the viewport.
3863
//>>docs: http://api.jqueryui.com/slide-effect/
3864
//>>demos: http://jqueryui.com/effect/
3865
 
3866
 
3867
var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) {
3868
	var startClip, startRef,
3869
		element = $( this ),
3870
		map = {
3871
			up: [ "bottom", "top" ],
3872
			down: [ "top", "bottom" ],
3873
			left: [ "right", "left" ],
3874
			right: [ "left", "right" ]
3875
		},
3876
		mode = options.mode,
3877
		direction = options.direction || "left",
3878
		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3879
		positiveMotion = ( direction === "up" || direction === "left" ),
3880
		distance = options.distance ||
3881
			element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ),
3882
		animation = {};
3883
 
3884
	$.effects.createPlaceholder( element );
3885
 
3886
	startClip = element.cssClip();
3887
	startRef = element.position()[ ref ];
3888
 
3889
	// Define hide animation
3890
	animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef;
3891
	animation.clip = element.cssClip();
3892
	animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ];
3893
 
3894
	// Reverse the animation if we're showing
3895
	if ( mode === "show" ) {
3896
		element.cssClip( animation.clip );
3897
		element.css( ref, animation[ ref ] );
3898
		animation.clip = startClip;
3899
		animation[ ref ] = startRef;
3900
	}
3901
 
3902
	// Actually animate
3903
	element.animate( animation, {
3904
		queue: false,
3905
		duration: options.duration,
3906
		easing: options.easing,
3907
		complete: done
3908
	} );
3909
} );
3910
 
3911
 
3912
/*!
3913
 * jQuery UI Effects Transfer 1.13.2
3914
 * http://jqueryui.com
3915
 *
3916
 * Copyright jQuery Foundation and other contributors
3917
 * Released under the MIT license.
3918
 * http://jquery.org/license
3919
 */
3920
 
3921
//>>label: Transfer Effect
3922
//>>group: Effects
3923
//>>description: Displays a transfer effect from one element to another.
3924
//>>docs: http://api.jqueryui.com/transfer-effect/
3925
//>>demos: http://jqueryui.com/effect/
3926
 
3927
 
3928
var effect;
3929
if ( $.uiBackCompat !== false ) {
3930
	effect = $.effects.define( "transfer", function( options, done ) {
3931
		$( this ).transfer( options, done );
3932
	} );
3933
}
3934
var effectsEffectTransfer = effect;
3935
 
3936
 
3937
/*!
3938
 * jQuery UI Focusable 1.13.2
3939
 * http://jqueryui.com
3940
 *
3941
 * Copyright jQuery Foundation and other contributors
3942
 * Released under the MIT license.
3943
 * http://jquery.org/license
3944
 */
3945
 
3946
//>>label: :focusable Selector
3947
//>>group: Core
3948
//>>description: Selects elements which can be focused.
3949
//>>docs: http://api.jqueryui.com/focusable-selector/
3950
 
3951
 
3952
// Selectors
3953
$.ui.focusable = function( element, hasTabindex ) {
3954
	var map, mapName, img, focusableIfVisible, fieldset,
3955
		nodeName = element.nodeName.toLowerCase();
3956
 
3957
	if ( "area" === nodeName ) {
3958
		map = element.parentNode;
3959
		mapName = map.name;
3960
		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
3961
			return false;
3962
		}
3963
		img = $( "img[usemap='#" + mapName + "']" );
3964
		return img.length > 0 && img.is( ":visible" );
3965
	}
3966
 
3967
	if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) {
3968
		focusableIfVisible = !element.disabled;
3969
 
3970
		if ( focusableIfVisible ) {
3971
 
3972
			// Form controls within a disabled fieldset are disabled.
3973
			// However, controls within the fieldset's legend do not get disabled.
3974
			// Since controls generally aren't placed inside legends, we skip
3975
			// this portion of the check.
3976
			fieldset = $( element ).closest( "fieldset" )[ 0 ];
3977
			if ( fieldset ) {
3978
				focusableIfVisible = !fieldset.disabled;
3979
			}
3980
		}
3981
	} else if ( "a" === nodeName ) {
3982
		focusableIfVisible = element.href || hasTabindex;
3983
	} else {
3984
		focusableIfVisible = hasTabindex;
3985
	}
3986
 
3987
	return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) );
3988
};
3989
 
3990
// Support: IE 8 only
3991
// IE 8 doesn't resolve inherit to visible/hidden for computed values
3992
function visible( element ) {
3993
	var visibility = element.css( "visibility" );
3994
	while ( visibility === "inherit" ) {
3995
		element = element.parent();
3996
		visibility = element.css( "visibility" );
3997
	}
3998
	return visibility === "visible";
3999
}
4000
 
4001
$.extend( $.expr.pseudos, {
4002
	focusable: function( element ) {
4003
		return $.ui.focusable( element, $.attr( element, "tabindex" ) != null );
4004
	}
4005
} );
4006
 
4007
var focusable = $.ui.focusable;
4008
 
4009
 
4010
 
4011
// Support: IE8 Only
4012
// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop
4013
// with a string, so we need to find the proper form.
4014
var form = $.fn._form = function() {
4015
	return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form );
4016
};
4017
 
4018
 
4019
/*!
4020
 * jQuery UI Form Reset Mixin 1.13.2
4021
 * http://jqueryui.com
4022
 *
4023
 * Copyright jQuery Foundation and other contributors
4024
 * Released under the MIT license.
4025
 * http://jquery.org/license
4026
 */
4027
 
4028
//>>label: Form Reset Mixin
4029
//>>group: Core
4030
//>>description: Refresh input widgets when their form is reset
4031
//>>docs: http://api.jqueryui.com/form-reset-mixin/
4032
 
4033
 
4034
var formResetMixin = $.ui.formResetMixin = {
4035
	_formResetHandler: function() {
4036
		var form = $( this );
4037
 
4038
		// Wait for the form reset to actually happen before refreshing
4039
		setTimeout( function() {
4040
			var instances = form.data( "ui-form-reset-instances" );
4041
			$.each( instances, function() {
4042
				this.refresh();
4043
			} );
4044
		} );
4045
	},
4046
 
4047
	_bindFormResetHandler: function() {
4048
		this.form = this.element._form();
4049
		if ( !this.form.length ) {
4050
			return;
4051
		}
4052
 
4053
		var instances = this.form.data( "ui-form-reset-instances" ) || [];
4054
		if ( !instances.length ) {
4055
 
4056
			// We don't use _on() here because we use a single event handler per form
4057
			this.form.on( "reset.ui-form-reset", this._formResetHandler );
4058
		}
4059
		instances.push( this );
4060
		this.form.data( "ui-form-reset-instances", instances );
4061
	},
4062
 
4063
	_unbindFormResetHandler: function() {
4064
		if ( !this.form.length ) {
4065
			return;
4066
		}
4067
 
4068
		var instances = this.form.data( "ui-form-reset-instances" );
4069
		instances.splice( $.inArray( this, instances ), 1 );
4070
		if ( instances.length ) {
4071
			this.form.data( "ui-form-reset-instances", instances );
4072
		} else {
4073
			this.form
4074
				.removeData( "ui-form-reset-instances" )
4075
				.off( "reset.ui-form-reset" );
4076
		}
4077
	}
4078
};
4079
 
4080
 
4081
/*!
4082
 * jQuery UI Support for jQuery core 1.8.x and newer 1.13.2
4083
 * http://jqueryui.com
4084
 *
4085
 * Copyright jQuery Foundation and other contributors
4086
 * Released under the MIT license.
4087
 * http://jquery.org/license
4088
 *
4089
 */
4090
 
4091
//>>label: jQuery 1.8+ Support
4092
//>>group: Core
4093
//>>description: Support version 1.8.x and newer of jQuery core
4094
 
4095
 
4096
// Support: jQuery 1.9.x or older
4097
// $.expr[ ":" ] is deprecated.
4098
if ( !$.expr.pseudos ) {
4099
	$.expr.pseudos = $.expr[ ":" ];
4100
}
4101
 
4102
// Support: jQuery 1.11.x or older
4103
// $.unique has been renamed to $.uniqueSort
4104
if ( !$.uniqueSort ) {
4105
	$.uniqueSort = $.unique;
4106
}
4107
 
4108
// Support: jQuery 2.2.x or older.
4109
// This method has been defined in jQuery 3.0.0.
4110
// Code from https://github.com/jquery/jquery/blob/e539bac79e666bba95bba86d690b4e609dca2286/src/selector/escapeSelector.js
4111
if ( !$.escapeSelector ) {
4112
 
4113
	// CSS string/identifier serialization
4114
	// https://drafts.csswg.org/cssom/#common-serializing-idioms
4115
	var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;
4116
 
4117
	var fcssescape = function( ch, asCodePoint ) {
4118
		if ( asCodePoint ) {
4119
 
4120
			// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
4121
			if ( ch === "\0" ) {
4122
				return "\uFFFD";
4123
			}
4124
 
4125
			// Control characters and (dependent upon position) numbers get escaped as code points
4126
			return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
4127
		}
4128
 
4129
		// Other potentially-special ASCII characters get backslash-escaped
4130
		return "\\" + ch;
4131
	};
4132
 
4133
	$.escapeSelector = function( sel ) {
4134
		return ( sel + "" ).replace( rcssescape, fcssescape );
4135
	};
4136
}
4137
 
4138
// Support: jQuery 3.4.x or older
4139
// These methods have been defined in jQuery 3.5.0.
4140
if ( !$.fn.even || !$.fn.odd ) {
4141
	$.fn.extend( {
4142
		even: function() {
4143
			return this.filter( function( i ) {
4144
				return i % 2 === 0;
4145
			} );
4146
		},
4147
		odd: function() {
4148
			return this.filter( function( i ) {
4149
				return i % 2 === 1;
4150
			} );
4151
		}
4152
	} );
4153
}
4154
 
4155
;
4156
/*!
4157
 * jQuery UI Keycode 1.13.2
4158
 * http://jqueryui.com
4159
 *
4160
 * Copyright jQuery Foundation and other contributors
4161
 * Released under the MIT license.
4162
 * http://jquery.org/license
4163
 */
4164
 
4165
//>>label: Keycode
4166
//>>group: Core
4167
//>>description: Provide keycodes as keynames
4168
//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/
4169
 
4170
 
4171
var keycode = $.ui.keyCode = {
4172
	BACKSPACE: 8,
4173
	COMMA: 188,
4174
	DELETE: 46,
4175
	DOWN: 40,
4176
	END: 35,
4177
	ENTER: 13,
4178
	ESCAPE: 27,
4179
	HOME: 36,
4180
	LEFT: 37,
4181
	PAGE_DOWN: 34,
4182
	PAGE_UP: 33,
4183
	PERIOD: 190,
4184
	RIGHT: 39,
4185
	SPACE: 32,
4186
	TAB: 9,
4187
	UP: 38
4188
};
4189
 
4190
 
4191
/*!
4192
 * jQuery UI Labels 1.13.2
4193
 * http://jqueryui.com
4194
 *
4195
 * Copyright jQuery Foundation and other contributors
4196
 * Released under the MIT license.
4197
 * http://jquery.org/license
4198
 */
4199
 
4200
//>>label: labels
4201
//>>group: Core
4202
//>>description: Find all the labels associated with a given input
4203
//>>docs: http://api.jqueryui.com/labels/
4204
 
4205
 
4206
var labels = $.fn.labels = function() {
4207
	var ancestor, selector, id, labels, ancestors;
4208
 
4209
	if ( !this.length ) {
4210
		return this.pushStack( [] );
4211
	}
4212
 
4213
	// Check control.labels first
4214
	if ( this[ 0 ].labels && this[ 0 ].labels.length ) {
4215
		return this.pushStack( this[ 0 ].labels );
4216
	}
4217
 
4218
	// Support: IE <= 11, FF <= 37, Android <= 2.3 only
4219
	// Above browsers do not support control.labels. Everything below is to support them
4220
	// as well as document fragments. control.labels does not work on document fragments
4221
	labels = this.eq( 0 ).parents( "label" );
4222
 
4223
	// Look for the label based on the id
4224
	id = this.attr( "id" );
4225
	if ( id ) {
4226
 
4227
		// We don't search against the document in case the element
4228
		// is disconnected from the DOM
4229
		ancestor = this.eq( 0 ).parents().last();
4230
 
4231
		// Get a full set of top level ancestors
4232
		ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() );
4233
 
4234
		// Create a selector for the label based on the id
4235
		selector = "label[for='" + $.escapeSelector( id ) + "']";
4236
 
4237
		labels = labels.add( ancestors.find( selector ).addBack( selector ) );
4238
 
4239
	}
4240
 
4241
	// Return whatever we have found for labels
4242
	return this.pushStack( labels );
4243
};
4244
 
4245
 
4246
/*!
4247
 * jQuery UI Scroll Parent 1.13.2
4248
 * http://jqueryui.com
4249
 *
4250
 * Copyright jQuery Foundation and other contributors
4251
 * Released under the MIT license.
4252
 * http://jquery.org/license
4253
 */
4254
 
4255
//>>label: scrollParent
4256
//>>group: Core
4257
//>>description: Get the closest ancestor element that is scrollable.
4258
//>>docs: http://api.jqueryui.com/scrollParent/
4259
 
4260
 
4261
var scrollParent = $.fn.scrollParent = function( includeHidden ) {
4262
	var position = this.css( "position" ),
4263
		excludeStaticParent = position === "absolute",
4264
		overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
4265
		scrollParent = this.parents().filter( function() {
4266
			var parent = $( this );
4267
			if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
4268
				return false;
4269
			}
4270
			return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
4271
				parent.css( "overflow-x" ) );
4272
		} ).eq( 0 );
4273
 
4274
	return position === "fixed" || !scrollParent.length ?
4275
		$( this[ 0 ].ownerDocument || document ) :
4276
		scrollParent;
4277
};
4278
 
4279
 
4280
/*!
4281
 * jQuery UI Tabbable 1.13.2
4282
 * http://jqueryui.com
4283
 *
4284
 * Copyright jQuery Foundation and other contributors
4285
 * Released under the MIT license.
4286
 * http://jquery.org/license
4287
 */
4288
 
4289
//>>label: :tabbable Selector
4290
//>>group: Core
4291
//>>description: Selects elements which can be tabbed to.
4292
//>>docs: http://api.jqueryui.com/tabbable-selector/
4293
 
4294
 
4295
var tabbable = $.extend( $.expr.pseudos, {
4296
	tabbable: function( element ) {
4297
		var tabIndex = $.attr( element, "tabindex" ),
4298
			hasTabindex = tabIndex != null;
4299
		return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex );
4300
	}
4301
} );
4302
 
4303
 
4304
/*!
4305
 * jQuery UI Unique ID 1.13.2
4306
 * http://jqueryui.com
4307
 *
4308
 * Copyright jQuery Foundation and other contributors
4309
 * Released under the MIT license.
4310
 * http://jquery.org/license
4311
 */
4312
 
4313
//>>label: uniqueId
4314
//>>group: Core
4315
//>>description: Functions to generate and remove uniqueId's
4316
//>>docs: http://api.jqueryui.com/uniqueId/
4317
 
4318
 
4319
var uniqueId = $.fn.extend( {
4320
	uniqueId: ( function() {
4321
		var uuid = 0;
4322
 
4323
		return function() {
4324
			return this.each( function() {
4325
				if ( !this.id ) {
4326
					this.id = "ui-id-" + ( ++uuid );
4327
				}
4328
			} );
4329
		};
4330
	} )(),
4331
 
4332
	removeUniqueId: function() {
4333
		return this.each( function() {
4334
			if ( /^ui-id-\d+$/.test( this.id ) ) {
4335
				$( this ).removeAttr( "id" );
4336
			}
4337
		} );
4338
	}
4339
} );
4340
 
4341
 
4342
/*!
4343
 * jQuery UI Accordion 1.13.2
4344
 * http://jqueryui.com
4345
 *
4346
 * Copyright jQuery Foundation and other contributors
4347
 * Released under the MIT license.
4348
 * http://jquery.org/license
4349
 */
4350
 
4351
//>>label: Accordion
4352
//>>group: Widgets
4353
/* eslint-disable max-len */
4354
//>>description: Displays collapsible content panels for presenting information in a limited amount of space.
4355
/* eslint-enable max-len */
4356
//>>docs: http://api.jqueryui.com/accordion/
4357
//>>demos: http://jqueryui.com/accordion/
4358
//>>css.structure: ../../themes/base/core.css
4359
//>>css.structure: ../../themes/base/accordion.css
4360
//>>css.theme: ../../themes/base/theme.css
4361
 
4362
 
4363
var widgetsAccordion = $.widget( "ui.accordion", {
4364
	version: "1.13.2",
4365
	options: {
4366
		active: 0,
4367
		animate: {},
4368
		classes: {
4369
			"ui-accordion-header": "ui-corner-top",
4370
			"ui-accordion-header-collapsed": "ui-corner-all",
4371
			"ui-accordion-content": "ui-corner-bottom"
4372
		},
4373
		collapsible: false,
4374
		event: "click",
4375
		header: function( elem ) {
4376
			return elem.find( "> li > :first-child" ).add( elem.find( "> :not(li)" ).even() );
4377
		},
4378
		heightStyle: "auto",
4379
		icons: {
4380
			activeHeader: "ui-icon-triangle-1-s",
4381
			header: "ui-icon-triangle-1-e"
4382
		},
4383
 
4384
		// Callbacks
4385
		activate: null,
4386
		beforeActivate: null
4387
	},
4388
 
4389
	hideProps: {
4390
		borderTopWidth: "hide",
4391
		borderBottomWidth: "hide",
4392
		paddingTop: "hide",
4393
		paddingBottom: "hide",
4394
		height: "hide"
4395
	},
4396
 
4397
	showProps: {
4398
		borderTopWidth: "show",
4399
		borderBottomWidth: "show",
4400
		paddingTop: "show",
4401
		paddingBottom: "show",
4402
		height: "show"
4403
	},
4404
 
4405
	_create: function() {
4406
		var options = this.options;
4407
 
4408
		this.prevShow = this.prevHide = $();
4409
		this._addClass( "ui-accordion", "ui-widget ui-helper-reset" );
4410
		this.element.attr( "role", "tablist" );
4411
 
4412
		// Don't allow collapsible: false and active: false / null
4413
		if ( !options.collapsible && ( options.active === false || options.active == null ) ) {
4414
			options.active = 0;
4415
		}
4416
 
4417
		this._processPanels();
4418
 
4419
		// handle negative values
4420
		if ( options.active < 0 ) {
4421
			options.active += this.headers.length;
4422
		}
4423
		this._refresh();
4424
	},
4425
 
4426
	_getCreateEventData: function() {
4427
		return {
4428
			header: this.active,
4429
			panel: !this.active.length ? $() : this.active.next()
4430
		};
4431
	},
4432
 
4433
	_createIcons: function() {
4434
		var icon, children,
4435
			icons = this.options.icons;
4436
 
4437
		if ( icons ) {
4438
			icon = $( "<span>" );
4439
			this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header );
4440
			icon.prependTo( this.headers );
4441
			children = this.active.children( ".ui-accordion-header-icon" );
4442
			this._removeClass( children, icons.header )
4443
				._addClass( children, null, icons.activeHeader )
4444
				._addClass( this.headers, "ui-accordion-icons" );
4445
		}
4446
	},
4447
 
4448
	_destroyIcons: function() {
4449
		this._removeClass( this.headers, "ui-accordion-icons" );
4450
		this.headers.children( ".ui-accordion-header-icon" ).remove();
4451
	},
4452
 
4453
	_destroy: function() {
4454
		var contents;
4455
 
4456
		// Clean up main element
4457
		this.element.removeAttr( "role" );
4458
 
4459
		// Clean up headers
4460
		this.headers
4461
			.removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" )
4462
			.removeUniqueId();
4463
 
4464
		this._destroyIcons();
4465
 
4466
		// Clean up content panels
4467
		contents = this.headers.next()
4468
			.css( "display", "" )
4469
			.removeAttr( "role aria-hidden aria-labelledby" )
4470
			.removeUniqueId();
4471
 
4472
		if ( this.options.heightStyle !== "content" ) {
4473
			contents.css( "height", "" );
4474
		}
4475
	},
4476
 
4477
	_setOption: function( key, value ) {
4478
		if ( key === "active" ) {
4479
 
4480
			// _activate() will handle invalid values and update this.options
4481
			this._activate( value );
4482
			return;
4483
		}
4484
 
4485
		if ( key === "event" ) {
4486
			if ( this.options.event ) {
4487
				this._off( this.headers, this.options.event );
4488
			}
4489
			this._setupEvents( value );
4490
		}
4491
 
4492
		this._super( key, value );
4493
 
4494
		// Setting collapsible: false while collapsed; open first panel
4495
		if ( key === "collapsible" && !value && this.options.active === false ) {
4496
			this._activate( 0 );
4497
		}
4498
 
4499
		if ( key === "icons" ) {
4500
			this._destroyIcons();
4501
			if ( value ) {
4502
				this._createIcons();
4503
			}
4504
		}
4505
	},
4506
 
4507
	_setOptionDisabled: function( value ) {
4508
		this._super( value );
4509
 
4510
		this.element.attr( "aria-disabled", value );
4511
 
4512
		// Support: IE8 Only
4513
		// #5332 / #6059 - opacity doesn't cascade to positioned elements in IE
4514
		// so we need to add the disabled class to the headers and panels
4515
		this._toggleClass( null, "ui-state-disabled", !!value );
4516
		this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled",
4517
			!!value );
4518
	},
4519
 
4520
	_keydown: function( event ) {
4521
		if ( event.altKey || event.ctrlKey ) {
4522
			return;
4523
		}
4524
 
4525
		var keyCode = $.ui.keyCode,
4526
			length = this.headers.length,
4527
			currentIndex = this.headers.index( event.target ),
4528
			toFocus = false;
4529
 
4530
		switch ( event.keyCode ) {
4531
		case keyCode.RIGHT:
4532
		case keyCode.DOWN:
4533
			toFocus = this.headers[ ( currentIndex + 1 ) % length ];
4534
			break;
4535
		case keyCode.LEFT:
4536
		case keyCode.UP:
4537
			toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
4538
			break;
4539
		case keyCode.SPACE:
4540
		case keyCode.ENTER:
4541
			this._eventHandler( event );
4542
			break;
4543
		case keyCode.HOME:
4544
			toFocus = this.headers[ 0 ];
4545
			break;
4546
		case keyCode.END:
4547
			toFocus = this.headers[ length - 1 ];
4548
			break;
4549
		}
4550
 
4551
		if ( toFocus ) {
4552
			$( event.target ).attr( "tabIndex", -1 );
4553
			$( toFocus ).attr( "tabIndex", 0 );
4554
			$( toFocus ).trigger( "focus" );
4555
			event.preventDefault();
4556
		}
4557
	},
4558
 
4559
	_panelKeyDown: function( event ) {
4560
		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
4561
			$( event.currentTarget ).prev().trigger( "focus" );
4562
		}
4563
	},
4564
 
4565
	refresh: function() {
4566
		var options = this.options;
4567
		this._processPanels();
4568
 
4569
		// Was collapsed or no panel
4570
		if ( ( options.active === false && options.collapsible === true ) ||
4571
				!this.headers.length ) {
4572
			options.active = false;
4573
			this.active = $();
4574
 
4575
		// active false only when collapsible is true
4576
		} else if ( options.active === false ) {
4577
			this._activate( 0 );
4578
 
4579
		// was active, but active panel is gone
4580
		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
4581
 
4582
			// all remaining panel are disabled
4583
			if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) {
4584
				options.active = false;
4585
				this.active = $();
4586
 
4587
			// activate previous panel
4588
			} else {
4589
				this._activate( Math.max( 0, options.active - 1 ) );
4590
			}
4591
 
4592
		// was active, active panel still exists
4593
		} else {
4594
 
4595
			// make sure active index is correct
4596
			options.active = this.headers.index( this.active );
4597
		}
4598
 
4599
		this._destroyIcons();
4600
 
4601
		this._refresh();
4602
	},
4603
 
4604
	_processPanels: function() {
4605
		var prevHeaders = this.headers,
4606
			prevPanels = this.panels;
4607
 
4608
		if ( typeof this.options.header === "function" ) {
4609
			this.headers = this.options.header( this.element );
4610
		} else {
4611
			this.headers = this.element.find( this.options.header );
4612
		}
4613
		this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed",
4614
			"ui-state-default" );
4615
 
4616
		this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide();
4617
		this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" );
4618
 
4619
		// Avoid memory leaks (#10056)
4620
		if ( prevPanels ) {
4621
			this._off( prevHeaders.not( this.headers ) );
4622
			this._off( prevPanels.not( this.panels ) );
4623
		}
4624
	},
4625
 
4626
	_refresh: function() {
4627
		var maxHeight,
4628
			options = this.options,
4629
			heightStyle = options.heightStyle,
4630
			parent = this.element.parent();
4631
 
4632
		this.active = this._findActive( options.active );
4633
		this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" )
4634
			._removeClass( this.active, "ui-accordion-header-collapsed" );
4635
		this._addClass( this.active.next(), "ui-accordion-content-active" );
4636
		this.active.next().show();
4637
 
4638
		this.headers
4639
			.attr( "role", "tab" )
4640
			.each( function() {
4641
				var header = $( this ),
4642
					headerId = header.uniqueId().attr( "id" ),
4643
					panel = header.next(),
4644
					panelId = panel.uniqueId().attr( "id" );
4645
				header.attr( "aria-controls", panelId );
4646
				panel.attr( "aria-labelledby", headerId );
4647
			} )
4648
			.next()
4649
				.attr( "role", "tabpanel" );
4650
 
4651
		this.headers
4652
			.not( this.active )
4653
				.attr( {
4654
					"aria-selected": "false",
4655
					"aria-expanded": "false",
4656
					tabIndex: -1
4657
				} )
4658
				.next()
4659
					.attr( {
4660
						"aria-hidden": "true"
4661
					} )
4662
					.hide();
4663
 
4664
		// Make sure at least one header is in the tab order
4665
		if ( !this.active.length ) {
4666
			this.headers.eq( 0 ).attr( "tabIndex", 0 );
4667
		} else {
4668
			this.active.attr( {
4669
				"aria-selected": "true",
4670
				"aria-expanded": "true",
4671
				tabIndex: 0
4672
			} )
4673
				.next()
4674
					.attr( {
4675
						"aria-hidden": "false"
4676
					} );
4677
		}
4678
 
4679
		this._createIcons();
4680
 
4681
		this._setupEvents( options.event );
4682
 
4683
		if ( heightStyle === "fill" ) {
4684
			maxHeight = parent.height();
4685
			this.element.siblings( ":visible" ).each( function() {
4686
				var elem = $( this ),
4687
					position = elem.css( "position" );
4688
 
4689
				if ( position === "absolute" || position === "fixed" ) {
4690
					return;
4691
				}
4692
				maxHeight -= elem.outerHeight( true );
4693
			} );
4694
 
4695
			this.headers.each( function() {
4696
				maxHeight -= $( this ).outerHeight( true );
4697
			} );
4698
 
4699
			this.headers.next()
4700
				.each( function() {
4701
					$( this ).height( Math.max( 0, maxHeight -
4702
						$( this ).innerHeight() + $( this ).height() ) );
4703
				} )
4704
				.css( "overflow", "auto" );
4705
		} else if ( heightStyle === "auto" ) {
4706
			maxHeight = 0;
4707
			this.headers.next()
4708
				.each( function() {
4709
					var isVisible = $( this ).is( ":visible" );
4710
					if ( !isVisible ) {
4711
						$( this ).show();
4712
					}
4713
					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
4714
					if ( !isVisible ) {
4715
						$( this ).hide();
4716
					}
4717
				} )
4718
				.height( maxHeight );
4719
		}
4720
	},
4721
 
4722
	_activate: function( index ) {
4723
		var active = this._findActive( index )[ 0 ];
4724
 
4725
		// Trying to activate the already active panel
4726
		if ( active === this.active[ 0 ] ) {
4727
			return;
4728
		}
4729
 
4730
		// Trying to collapse, simulate a click on the currently active header
4731
		active = active || this.active[ 0 ];
4732
 
4733
		this._eventHandler( {
4734
			target: active,
4735
			currentTarget: active,
4736
			preventDefault: $.noop
4737
		} );
4738
	},
4739
 
4740
	_findActive: function( selector ) {
4741
		return typeof selector === "number" ? this.headers.eq( selector ) : $();
4742
	},
4743
 
4744
	_setupEvents: function( event ) {
4745
		var events = {
4746
			keydown: "_keydown"
4747
		};
4748
		if ( event ) {
4749
			$.each( event.split( " " ), function( index, eventName ) {
4750
				events[ eventName ] = "_eventHandler";
4751
			} );
4752
		}
4753
 
4754
		this._off( this.headers.add( this.headers.next() ) );
4755
		this._on( this.headers, events );
4756
		this._on( this.headers.next(), { keydown: "_panelKeyDown" } );
4757
		this._hoverable( this.headers );
4758
		this._focusable( this.headers );
4759
	},
4760
 
4761
	_eventHandler: function( event ) {
4762
		var activeChildren, clickedChildren,
4763
			options = this.options,
4764
			active = this.active,
4765
			clicked = $( event.currentTarget ),
4766
			clickedIsActive = clicked[ 0 ] === active[ 0 ],
4767
			collapsing = clickedIsActive && options.collapsible,
4768
			toShow = collapsing ? $() : clicked.next(),
4769
			toHide = active.next(),
4770
			eventData = {
4771
				oldHeader: active,
4772
				oldPanel: toHide,
4773
				newHeader: collapsing ? $() : clicked,
4774
				newPanel: toShow
4775
			};
4776
 
4777
		event.preventDefault();
4778
 
4779
		if (
4780
 
4781
				// click on active header, but not collapsible
4782
				( clickedIsActive && !options.collapsible ) ||
4783
 
4784
				// allow canceling activation
4785
				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
4786
			return;
4787
		}
4788
 
4789
		options.active = collapsing ? false : this.headers.index( clicked );
4790
 
4791
		// When the call to ._toggle() comes after the class changes
4792
		// it causes a very odd bug in IE 8 (see #6720)
4793
		this.active = clickedIsActive ? $() : clicked;
4794
		this._toggle( eventData );
4795
 
4796
		// Switch classes
4797
		// corner classes on the previously active header stay after the animation
4798
		this._removeClass( active, "ui-accordion-header-active", "ui-state-active" );
4799
		if ( options.icons ) {
4800
			activeChildren = active.children( ".ui-accordion-header-icon" );
4801
			this._removeClass( activeChildren, null, options.icons.activeHeader )
4802
				._addClass( activeChildren, null, options.icons.header );
4803
		}
4804
 
4805
		if ( !clickedIsActive ) {
4806
			this._removeClass( clicked, "ui-accordion-header-collapsed" )
4807
				._addClass( clicked, "ui-accordion-header-active", "ui-state-active" );
4808
			if ( options.icons ) {
4809
				clickedChildren = clicked.children( ".ui-accordion-header-icon" );
4810
				this._removeClass( clickedChildren, null, options.icons.header )
4811
					._addClass( clickedChildren, null, options.icons.activeHeader );
4812
			}
4813
 
4814
			this._addClass( clicked.next(), "ui-accordion-content-active" );
4815
		}
4816
	},
4817
 
4818
	_toggle: function( data ) {
4819
		var toShow = data.newPanel,
4820
			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
4821
 
4822
		// Handle activating a panel during the animation for another activation
4823
		this.prevShow.add( this.prevHide ).stop( true, true );
4824
		this.prevShow = toShow;
4825
		this.prevHide = toHide;
4826
 
4827
		if ( this.options.animate ) {
4828
			this._animate( toShow, toHide, data );
4829
		} else {
4830
			toHide.hide();
4831
			toShow.show();
4832
			this._toggleComplete( data );
4833
		}
4834
 
4835
		toHide.attr( {
4836
			"aria-hidden": "true"
4837
		} );
4838
		toHide.prev().attr( {
4839
			"aria-selected": "false",
4840
			"aria-expanded": "false"
4841
		} );
4842
 
4843
		// if we're switching panels, remove the old header from the tab order
4844
		// if we're opening from collapsed state, remove the previous header from the tab order
4845
		// if we're collapsing, then keep the collapsing header in the tab order
4846
		if ( toShow.length && toHide.length ) {
4847
			toHide.prev().attr( {
4848
				"tabIndex": -1,
4849
				"aria-expanded": "false"
4850
			} );
4851
		} else if ( toShow.length ) {
4852
			this.headers.filter( function() {
4853
				return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
4854
			} )
4855
				.attr( "tabIndex", -1 );
4856
		}
4857
 
4858
		toShow
4859
			.attr( "aria-hidden", "false" )
4860
			.prev()
4861
				.attr( {
4862
					"aria-selected": "true",
4863
					"aria-expanded": "true",
4864
					tabIndex: 0
4865
				} );
4866
	},
4867
 
4868
	_animate: function( toShow, toHide, data ) {
4869
		var total, easing, duration,
4870
			that = this,
4871
			adjust = 0,
4872
			boxSizing = toShow.css( "box-sizing" ),
4873
			down = toShow.length &&
4874
				( !toHide.length || ( toShow.index() < toHide.index() ) ),
4875
			animate = this.options.animate || {},
4876
			options = down && animate.down || animate,
4877
			complete = function() {
4878
				that._toggleComplete( data );
4879
			};
4880
 
4881
		if ( typeof options === "number" ) {
4882
			duration = options;
4883
		}
4884
		if ( typeof options === "string" ) {
4885
			easing = options;
4886
		}
4887
 
4888
		// fall back from options to animation in case of partial down settings
4889
		easing = easing || options.easing || animate.easing;
4890
		duration = duration || options.duration || animate.duration;
4891
 
4892
		if ( !toHide.length ) {
4893
			return toShow.animate( this.showProps, duration, easing, complete );
4894
		}
4895
		if ( !toShow.length ) {
4896
			return toHide.animate( this.hideProps, duration, easing, complete );
4897
		}
4898
 
4899
		total = toShow.show().outerHeight();
4900
		toHide.animate( this.hideProps, {
4901
			duration: duration,
4902
			easing: easing,
4903
			step: function( now, fx ) {
4904
				fx.now = Math.round( now );
4905
			}
4906
		} );
4907
		toShow
4908
			.hide()
4909
			.animate( this.showProps, {
4910
				duration: duration,
4911
				easing: easing,
4912
				complete: complete,
4913
				step: function( now, fx ) {
4914
					fx.now = Math.round( now );
4915
					if ( fx.prop !== "height" ) {
4916
						if ( boxSizing === "content-box" ) {
4917
							adjust += fx.now;
4918
						}
4919
					} else if ( that.options.heightStyle !== "content" ) {
4920
						fx.now = Math.round( total - toHide.outerHeight() - adjust );
4921
						adjust = 0;
4922
					}
4923
				}
4924
			} );
4925
	},
4926
 
4927
	_toggleComplete: function( data ) {
4928
		var toHide = data.oldPanel,
4929
			prev = toHide.prev();
4930
 
4931
		this._removeClass( toHide, "ui-accordion-content-active" );
4932
		this._removeClass( prev, "ui-accordion-header-active" )
4933
			._addClass( prev, "ui-accordion-header-collapsed" );
4934
 
4935
		// Work around for rendering bug in IE (#5421)
4936
		if ( toHide.length ) {
4937
			toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
4938
		}
4939
		this._trigger( "activate", null, data );
4940
	}
4941
} );
4942
 
4943
 
4944
 
4945
var safeActiveElement = $.ui.safeActiveElement = function( document ) {
4946
	var activeElement;
4947
 
4948
	// Support: IE 9 only
4949
	// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
4950
	try {
4951
		activeElement = document.activeElement;
4952
	} catch ( error ) {
4953
		activeElement = document.body;
4954
	}
4955
 
4956
	// Support: IE 9 - 11 only
4957
	// IE may return null instead of an element
4958
	// Interestingly, this only seems to occur when NOT in an iframe
4959
	if ( !activeElement ) {
4960
		activeElement = document.body;
4961
	}
4962
 
4963
	// Support: IE 11 only
4964
	// IE11 returns a seemingly empty object in some cases when accessing
4965
	// document.activeElement from an <iframe>
4966
	if ( !activeElement.nodeName ) {
4967
		activeElement = document.body;
4968
	}
4969
 
4970
	return activeElement;
4971
};
4972
 
4973
 
4974
/*!
4975
 * jQuery UI Menu 1.13.2
4976
 * http://jqueryui.com
4977
 *
4978
 * Copyright jQuery Foundation and other contributors
4979
 * Released under the MIT license.
4980
 * http://jquery.org/license
4981
 */
4982
 
4983
//>>label: Menu
4984
//>>group: Widgets
4985
//>>description: Creates nestable menus.
4986
//>>docs: http://api.jqueryui.com/menu/
4987
//>>demos: http://jqueryui.com/menu/
4988
//>>css.structure: ../../themes/base/core.css
4989
//>>css.structure: ../../themes/base/menu.css
4990
//>>css.theme: ../../themes/base/theme.css
4991
 
4992
 
4993
var widgetsMenu = $.widget( "ui.menu", {
4994
	version: "1.13.2",
4995
	defaultElement: "<ul>",
4996
	delay: 300,
4997
	options: {
4998
		icons: {
4999
			submenu: "ui-icon-caret-1-e"
5000
		},
5001
		items: "> *",
5002
		menus: "ul",
5003
		position: {
5004
			my: "left top",
5005
			at: "right top"
5006
		},
5007
		role: "menu",
5008
 
5009
		// Callbacks
5010
		blur: null,
5011
		focus: null,
5012
		select: null
5013
	},
5014
 
5015
	_create: function() {
5016
		this.activeMenu = this.element;
5017
 
5018
		// Flag used to prevent firing of the click handler
5019
		// as the event bubbles up through nested menus
5020
		this.mouseHandled = false;
5021
		this.lastMousePosition = { x: null, y: null };
5022
		this.element
5023
			.uniqueId()
5024
			.attr( {
5025
				role: this.options.role,
5026
				tabIndex: 0
5027
			} );
5028
 
5029
		this._addClass( "ui-menu", "ui-widget ui-widget-content" );
5030
		this._on( {
5031
 
5032
			// Prevent focus from sticking to links inside menu after clicking
5033
			// them (focus should always stay on UL during navigation).
5034
			"mousedown .ui-menu-item": function( event ) {
5035
				event.preventDefault();
5036
 
5037
				this._activateItem( event );
5038
			},
5039
			"click .ui-menu-item": function( event ) {
5040
				var target = $( event.target );
5041
				var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
5042
				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
5043
					this.select( event );
5044
 
5045
					// Only set the mouseHandled flag if the event will bubble, see #9469.
5046
					if ( !event.isPropagationStopped() ) {
5047
						this.mouseHandled = true;
5048
					}
5049
 
5050
					// Open submenu on click
5051
					if ( target.has( ".ui-menu" ).length ) {
5052
						this.expand( event );
5053
					} else if ( !this.element.is( ":focus" ) &&
5054
							active.closest( ".ui-menu" ).length ) {
5055
 
5056
						// Redirect focus to the menu
5057
						this.element.trigger( "focus", [ true ] );
5058
 
5059
						// If the active item is on the top level, let it stay active.
5060
						// Otherwise, blur the active item since it is no longer visible.
5061
						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
5062
							clearTimeout( this.timer );
5063
						}
5064
					}
5065
				}
5066
			},
5067
			"mouseenter .ui-menu-item": "_activateItem",
5068
			"mousemove .ui-menu-item": "_activateItem",
5069
			mouseleave: "collapseAll",
5070
			"mouseleave .ui-menu": "collapseAll",
5071
			focus: function( event, keepActiveItem ) {
5072
 
5073
				// If there's already an active item, keep it active
5074
				// If not, activate the first item
5075
				var item = this.active || this._menuItems().first();
5076
 
5077
				if ( !keepActiveItem ) {
5078
					this.focus( event, item );
5079
				}
5080
			},
5081
			blur: function( event ) {
5082
				this._delay( function() {
5083
					var notContained = !$.contains(
5084
						this.element[ 0 ],
5085
						$.ui.safeActiveElement( this.document[ 0 ] )
5086
					);
5087
					if ( notContained ) {
5088
						this.collapseAll( event );
5089
					}
5090
				} );
5091
			},
5092
			keydown: "_keydown"
5093
		} );
5094
 
5095
		this.refresh();
5096
 
5097
		// Clicks outside of a menu collapse any open menus
5098
		this._on( this.document, {
5099
			click: function( event ) {
5100
				if ( this._closeOnDocumentClick( event ) ) {
5101
					this.collapseAll( event, true );
5102
				}
5103
 
5104
				// Reset the mouseHandled flag
5105
				this.mouseHandled = false;
5106
			}
5107
		} );
5108
	},
5109
 
5110
	_activateItem: function( event ) {
5111
 
5112
		// Ignore mouse events while typeahead is active, see #10458.
5113
		// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
5114
		// is over an item in the menu
5115
		if ( this.previousFilter ) {
5116
			return;
5117
		}
5118
 
5119
		// If the mouse didn't actually move, but the page was scrolled, ignore the event (#9356)
5120
		if ( event.clientX === this.lastMousePosition.x &&
5121
				event.clientY === this.lastMousePosition.y ) {
5122
			return;
5123
		}
5124
 
5125
		this.lastMousePosition = {
5126
			x: event.clientX,
5127
			y: event.clientY
5128
		};
5129
 
5130
		var actualTarget = $( event.target ).closest( ".ui-menu-item" ),
5131
			target = $( event.currentTarget );
5132
 
5133
		// Ignore bubbled events on parent items, see #11641
5134
		if ( actualTarget[ 0 ] !== target[ 0 ] ) {
5135
			return;
5136
		}
5137
 
5138
		// If the item is already active, there's nothing to do
5139
		if ( target.is( ".ui-state-active" ) ) {
5140
			return;
5141
		}
5142
 
5143
		// Remove ui-state-active class from siblings of the newly focused menu item
5144
		// to avoid a jump caused by adjacent elements both having a class with a border
5145
		this._removeClass( target.siblings().children( ".ui-state-active" ),
5146
			null, "ui-state-active" );
5147
		this.focus( event, target );
5148
	},
5149
 
5150
	_destroy: function() {
5151
		var items = this.element.find( ".ui-menu-item" )
5152
				.removeAttr( "role aria-disabled" ),
5153
			submenus = items.children( ".ui-menu-item-wrapper" )
5154
				.removeUniqueId()
5155
				.removeAttr( "tabIndex role aria-haspopup" );
5156
 
5157
		// Destroy (sub)menus
5158
		this.element
5159
			.removeAttr( "aria-activedescendant" )
5160
			.find( ".ui-menu" ).addBack()
5161
				.removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " +
5162
					"tabIndex" )
5163
				.removeUniqueId()
5164
				.show();
5165
 
5166
		submenus.children().each( function() {
5167
			var elem = $( this );
5168
			if ( elem.data( "ui-menu-submenu-caret" ) ) {
5169
				elem.remove();
5170
			}
5171
		} );
5172
	},
5173
 
5174
	_keydown: function( event ) {
5175
		var match, prev, character, skip,
5176
			preventDefault = true;
5177
 
5178
		switch ( event.keyCode ) {
5179
		case $.ui.keyCode.PAGE_UP:
5180
			this.previousPage( event );
5181
			break;
5182
		case $.ui.keyCode.PAGE_DOWN:
5183
			this.nextPage( event );
5184
			break;
5185
		case $.ui.keyCode.HOME:
5186
			this._move( "first", "first", event );
5187
			break;
5188
		case $.ui.keyCode.END:
5189
			this._move( "last", "last", event );
5190
			break;
5191
		case $.ui.keyCode.UP:
5192
			this.previous( event );
5193
			break;
5194
		case $.ui.keyCode.DOWN:
5195
			this.next( event );
5196
			break;
5197
		case $.ui.keyCode.LEFT:
5198
			this.collapse( event );
5199
			break;
5200
		case $.ui.keyCode.RIGHT:
5201
			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
5202
				this.expand( event );
5203
			}
5204
			break;
5205
		case $.ui.keyCode.ENTER:
5206
		case $.ui.keyCode.SPACE:
5207
			this._activate( event );
5208
			break;
5209
		case $.ui.keyCode.ESCAPE:
5210
			this.collapse( event );
5211
			break;
5212
		default:
5213
			preventDefault = false;
5214
			prev = this.previousFilter || "";
5215
			skip = false;
5216
 
5217
			// Support number pad values
5218
			character = event.keyCode >= 96 && event.keyCode <= 105 ?
5219
				( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode );
5220
 
5221
			clearTimeout( this.filterTimer );
5222
 
5223
			if ( character === prev ) {
5224
				skip = true;
5225
			} else {
5226
				character = prev + character;
5227
			}
5228
 
5229
			match = this._filterMenuItems( character );
5230
			match = skip && match.index( this.active.next() ) !== -1 ?
5231
				this.active.nextAll( ".ui-menu-item" ) :
5232
				match;
5233
 
5234
			// If no matches on the current filter, reset to the last character pressed
5235
			// to move down the menu to the first item that starts with that character
5236
			if ( !match.length ) {
5237
				character = String.fromCharCode( event.keyCode );
5238
				match = this._filterMenuItems( character );
5239
			}
5240
 
5241
			if ( match.length ) {
5242
				this.focus( event, match );
5243
				this.previousFilter = character;
5244
				this.filterTimer = this._delay( function() {
5245
					delete this.previousFilter;
5246
				}, 1000 );
5247
			} else {
5248
				delete this.previousFilter;
5249
			}
5250
		}
5251
 
5252
		if ( preventDefault ) {
5253
			event.preventDefault();
5254
		}
5255
	},
5256
 
5257
	_activate: function( event ) {
5258
		if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
5259
			if ( this.active.children( "[aria-haspopup='true']" ).length ) {
5260
				this.expand( event );
5261
			} else {
5262
				this.select( event );
5263
			}
5264
		}
5265
	},
5266
 
5267
	refresh: function() {
5268
		var menus, items, newSubmenus, newItems, newWrappers,
5269
			that = this,
5270
			icon = this.options.icons.submenu,
5271
			submenus = this.element.find( this.options.menus );
5272
 
5273
		this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length );
5274
 
5275
		// Initialize nested menus
5276
		newSubmenus = submenus.filter( ":not(.ui-menu)" )
5277
			.hide()
5278
			.attr( {
5279
				role: this.options.role,
5280
				"aria-hidden": "true",
5281
				"aria-expanded": "false"
5282
			} )
5283
			.each( function() {
5284
				var menu = $( this ),
5285
					item = menu.prev(),
5286
					submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true );
5287
 
5288
				that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon );
5289
				item
5290
					.attr( "aria-haspopup", "true" )
5291
					.prepend( submenuCaret );
5292
				menu.attr( "aria-labelledby", item.attr( "id" ) );
5293
			} );
5294
 
5295
		this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" );
5296
 
5297
		menus = submenus.add( this.element );
5298
		items = menus.find( this.options.items );
5299
 
5300
		// Initialize menu-items containing spaces and/or dashes only as dividers
5301
		items.not( ".ui-menu-item" ).each( function() {
5302
			var item = $( this );
5303
			if ( that._isDivider( item ) ) {
5304
				that._addClass( item, "ui-menu-divider", "ui-widget-content" );
5305
			}
5306
		} );
5307
 
5308
		// Don't refresh list items that are already adapted
5309
		newItems = items.not( ".ui-menu-item, .ui-menu-divider" );
5310
		newWrappers = newItems.children()
5311
			.not( ".ui-menu" )
5312
				.uniqueId()
5313
				.attr( {
5314
					tabIndex: -1,
5315
					role: this._itemRole()
5316
				} );
5317
		this._addClass( newItems, "ui-menu-item" )
5318
			._addClass( newWrappers, "ui-menu-item-wrapper" );
5319
 
5320
		// Add aria-disabled attribute to any disabled menu item
5321
		items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
5322
 
5323
		// If the active item has been removed, blur the menu
5324
		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
5325
			this.blur();
5326
		}
5327
	},
5328
 
5329
	_itemRole: function() {
5330
		return {
5331
			menu: "menuitem",
5332
			listbox: "option"
5333
		}[ this.options.role ];
5334
	},
5335
 
5336
	_setOption: function( key, value ) {
5337
		if ( key === "icons" ) {
5338
			var icons = this.element.find( ".ui-menu-icon" );
5339
			this._removeClass( icons, null, this.options.icons.submenu )
5340
				._addClass( icons, null, value.submenu );
5341
		}
5342
		this._super( key, value );
5343
	},
5344
 
5345
	_setOptionDisabled: function( value ) {
5346
		this._super( value );
5347
 
5348
		this.element.attr( "aria-disabled", String( value ) );
5349
		this._toggleClass( null, "ui-state-disabled", !!value );
5350
	},
5351
 
5352
	focus: function( event, item ) {
5353
		var nested, focused, activeParent;
5354
		this.blur( event, event && event.type === "focus" );
5355
 
5356
		this._scrollIntoView( item );
5357
 
5358
		this.active = item.first();
5359
 
5360
		focused = this.active.children( ".ui-menu-item-wrapper" );
5361
		this._addClass( focused, null, "ui-state-active" );
5362
 
5363
		// Only update aria-activedescendant if there's a role
5364
		// otherwise we assume focus is managed elsewhere
5365
		if ( this.options.role ) {
5366
			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
5367
		}
5368
 
5369
		// Highlight active parent menu item, if any
5370
		activeParent = this.active
5371
			.parent()
5372
				.closest( ".ui-menu-item" )
5373
					.children( ".ui-menu-item-wrapper" );
5374
		this._addClass( activeParent, null, "ui-state-active" );
5375
 
5376
		if ( event && event.type === "keydown" ) {
5377
			this._close();
5378
		} else {
5379
			this.timer = this._delay( function() {
5380
				this._close();
5381
			}, this.delay );
5382
		}
5383
 
5384
		nested = item.children( ".ui-menu" );
5385
		if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
5386
			this._startOpening( nested );
5387
		}
5388
		this.activeMenu = item.parent();
5389
 
5390
		this._trigger( "focus", event, { item: item } );
5391
	},
5392
 
5393
	_scrollIntoView: function( item ) {
5394
		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
5395
		if ( this._hasScroll() ) {
5396
			borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0;
5397
			paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0;
5398
			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
5399
			scroll = this.activeMenu.scrollTop();
5400
			elementHeight = this.activeMenu.height();
5401
			itemHeight = item.outerHeight();
5402
 
5403
			if ( offset < 0 ) {
5404
				this.activeMenu.scrollTop( scroll + offset );
5405
			} else if ( offset + itemHeight > elementHeight ) {
5406
				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
5407
			}
5408
		}
5409
	},
5410
 
5411
	blur: function( event, fromFocus ) {
5412
		if ( !fromFocus ) {
5413
			clearTimeout( this.timer );
5414
		}
5415
 
5416
		if ( !this.active ) {
5417
			return;
5418
		}
5419
 
5420
		this._removeClass( this.active.children( ".ui-menu-item-wrapper" ),
5421
			null, "ui-state-active" );
5422
 
5423
		this._trigger( "blur", event, { item: this.active } );
5424
		this.active = null;
5425
	},
5426
 
5427
	_startOpening: function( submenu ) {
5428
		clearTimeout( this.timer );
5429
 
5430
		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
5431
		// shift in the submenu position when mousing over the caret icon
5432
		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
5433
			return;
5434
		}
5435
 
5436
		this.timer = this._delay( function() {
5437
			this._close();
5438
			this._open( submenu );
5439
		}, this.delay );
5440
	},
5441
 
5442
	_open: function( submenu ) {
5443
		var position = $.extend( {
5444
			of: this.active
5445
		}, this.options.position );
5446
 
5447
		clearTimeout( this.timer );
5448
		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
5449
			.hide()
5450
			.attr( "aria-hidden", "true" );
5451
 
5452
		submenu
5453
			.show()
5454
			.removeAttr( "aria-hidden" )
5455
			.attr( "aria-expanded", "true" )
5456
			.position( position );
5457
	},
5458
 
5459
	collapseAll: function( event, all ) {
5460
		clearTimeout( this.timer );
5461
		this.timer = this._delay( function() {
5462
 
5463
			// If we were passed an event, look for the submenu that contains the event
5464
			var currentMenu = all ? this.element :
5465
				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
5466
 
5467
			// If we found no valid submenu ancestor, use the main menu to close all
5468
			// sub menus anyway
5469
			if ( !currentMenu.length ) {
5470
				currentMenu = this.element;
5471
			}
5472
 
5473
			this._close( currentMenu );
5474
 
5475
			this.blur( event );
5476
 
5477
			// Work around active item staying active after menu is blurred
5478
			this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" );
5479
 
5480
			this.activeMenu = currentMenu;
5481
		}, all ? 0 : this.delay );
5482
	},
5483
 
5484
	// With no arguments, closes the currently active menu - if nothing is active
5485
	// it closes all menus.  If passed an argument, it will search for menus BELOW
5486
	_close: function( startMenu ) {
5487
		if ( !startMenu ) {
5488
			startMenu = this.active ? this.active.parent() : this.element;
5489
		}
5490
 
5491
		startMenu.find( ".ui-menu" )
5492
			.hide()
5493
			.attr( "aria-hidden", "true" )
5494
			.attr( "aria-expanded", "false" );
5495
	},
5496
 
5497
	_closeOnDocumentClick: function( event ) {
5498
		return !$( event.target ).closest( ".ui-menu" ).length;
5499
	},
5500
 
5501
	_isDivider: function( item ) {
5502
 
5503
		// Match hyphen, em dash, en dash
5504
		return !/[^\-\u2014\u2013\s]/.test( item.text() );
5505
	},
5506
 
5507
	collapse: function( event ) {
5508
		var newItem = this.active &&
5509
			this.active.parent().closest( ".ui-menu-item", this.element );
5510
		if ( newItem && newItem.length ) {
5511
			this._close();
5512
			this.focus( event, newItem );
5513
		}
5514
	},
5515
 
5516
	expand: function( event ) {
5517
		var newItem = this.active && this._menuItems( this.active.children( ".ui-menu" ) ).first();
5518
 
5519
		if ( newItem && newItem.length ) {
5520
			this._open( newItem.parent() );
5521
 
5522
			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
5523
			this._delay( function() {
5524
				this.focus( event, newItem );
5525
			} );
5526
		}
5527
	},
5528
 
5529
	next: function( event ) {
5530
		this._move( "next", "first", event );
5531
	},
5532
 
5533
	previous: function( event ) {
5534
		this._move( "prev", "last", event );
5535
	},
5536
 
5537
	isFirstItem: function() {
5538
		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
5539
	},
5540
 
5541
	isLastItem: function() {
5542
		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
5543
	},
5544
 
5545
	_menuItems: function( menu ) {
5546
		return ( menu || this.element )
5547
			.find( this.options.items )
5548
			.filter( ".ui-menu-item" );
5549
	},
5550
 
5551
	_move: function( direction, filter, event ) {
5552
		var next;
5553
		if ( this.active ) {
5554
			if ( direction === "first" || direction === "last" ) {
5555
				next = this.active
5556
					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
5557
					.last();
5558
			} else {
5559
				next = this.active
5560
					[ direction + "All" ]( ".ui-menu-item" )
5561
					.first();
5562
			}
5563
		}
5564
		if ( !next || !next.length || !this.active ) {
5565
			next = this._menuItems( this.activeMenu )[ filter ]();
5566
		}
5567
 
5568
		this.focus( event, next );
5569
	},
5570
 
5571
	nextPage: function( event ) {
5572
		var item, base, height;
5573
 
5574
		if ( !this.active ) {
5575
			this.next( event );
5576
			return;
5577
		}
5578
		if ( this.isLastItem() ) {
5579
			return;
5580
		}
5581
		if ( this._hasScroll() ) {
5582
			base = this.active.offset().top;
5583
			height = this.element.innerHeight();
5584
 
5585
			// jQuery 3.2 doesn't include scrollbars in innerHeight, add it back.
5586
			if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) {
5587
				height += this.element[ 0 ].offsetHeight - this.element.outerHeight();
5588
			}
5589
 
5590
			this.active.nextAll( ".ui-menu-item" ).each( function() {
5591
				item = $( this );
5592
				return item.offset().top - base - height < 0;
5593
			} );
5594
 
5595
			this.focus( event, item );
5596
		} else {
5597
			this.focus( event, this._menuItems( this.activeMenu )
5598
				[ !this.active ? "first" : "last" ]() );
5599
		}
5600
	},
5601
 
5602
	previousPage: function( event ) {
5603
		var item, base, height;
5604
		if ( !this.active ) {
5605
			this.next( event );
5606
			return;
5607
		}
5608
		if ( this.isFirstItem() ) {
5609
			return;
5610
		}
5611
		if ( this._hasScroll() ) {
5612
			base = this.active.offset().top;
5613
			height = this.element.innerHeight();
5614
 
5615
			// jQuery 3.2 doesn't include scrollbars in innerHeight, add it back.
5616
			if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) {
5617
				height += this.element[ 0 ].offsetHeight - this.element.outerHeight();
5618
			}
5619
 
5620
			this.active.prevAll( ".ui-menu-item" ).each( function() {
5621
				item = $( this );
5622
				return item.offset().top - base + height > 0;
5623
			} );
5624
 
5625
			this.focus( event, item );
5626
		} else {
5627
			this.focus( event, this._menuItems( this.activeMenu ).first() );
5628
		}
5629
	},
5630
 
5631
	_hasScroll: function() {
5632
		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
5633
	},
5634
 
5635
	select: function( event ) {
5636
 
5637
		// TODO: It should never be possible to not have an active item at this
5638
		// point, but the tests don't trigger mouseenter before click.
5639
		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
5640
		var ui = { item: this.active };
5641
		if ( !this.active.has( ".ui-menu" ).length ) {
5642
			this.collapseAll( event, true );
5643
		}
5644
		this._trigger( "select", event, ui );
5645
	},
5646
 
5647
	_filterMenuItems: function( character ) {
5648
		var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
5649
			regex = new RegExp( "^" + escapedCharacter, "i" );
5650
 
5651
		return this.activeMenu
5652
			.find( this.options.items )
5653
 
5654
				// Only match on items, not dividers or other content (#10571)
5655
				.filter( ".ui-menu-item" )
5656
					.filter( function() {
5657
						return regex.test(
5658
							String.prototype.trim.call(
5659
								$( this ).children( ".ui-menu-item-wrapper" ).text() ) );
5660
					} );
5661
	}
5662
} );
5663
 
5664
 
5665
/*!
5666
 * jQuery UI Autocomplete 1.13.2
5667
 * http://jqueryui.com
5668
 *
5669
 * Copyright jQuery Foundation and other contributors
5670
 * Released under the MIT license.
5671
 * http://jquery.org/license
5672
 */
5673
 
5674
//>>label: Autocomplete
5675
//>>group: Widgets
5676
//>>description: Lists suggested words as the user is typing.
5677
//>>docs: http://api.jqueryui.com/autocomplete/
5678
//>>demos: http://jqueryui.com/autocomplete/
5679
//>>css.structure: ../../themes/base/core.css
5680
//>>css.structure: ../../themes/base/autocomplete.css
5681
//>>css.theme: ../../themes/base/theme.css
5682
 
5683
 
5684
$.widget( "ui.autocomplete", {
5685
	version: "1.13.2",
5686
	defaultElement: "<input>",
5687
	options: {
5688
		appendTo: null,
5689
		autoFocus: false,
5690
		delay: 300,
5691
		minLength: 1,
5692
		position: {
5693
			my: "left top",
5694
			at: "left bottom",
5695
			collision: "none"
5696
		},
5697
		source: null,
5698
 
5699
		// Callbacks
5700
		change: null,
5701
		close: null,
5702
		focus: null,
5703
		open: null,
5704
		response: null,
5705
		search: null,
5706
		select: null
5707
	},
5708
 
5709
	requestIndex: 0,
5710
	pending: 0,
5711
	liveRegionTimer: null,
5712
 
5713
	_create: function() {
5714
 
5715
		// Some browsers only repeat keydown events, not keypress events,
5716
		// so we use the suppressKeyPress flag to determine if we've already
5717
		// handled the keydown event. #7269
5718
		// Unfortunately the code for & in keypress is the same as the up arrow,
5719
		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
5720
		// events when we know the keydown event was used to modify the
5721
		// search term. #7799
5722
		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
5723
			nodeName = this.element[ 0 ].nodeName.toLowerCase(),
5724
			isTextarea = nodeName === "textarea",
5725
			isInput = nodeName === "input";
5726
 
5727
		// Textareas are always multi-line
5728
		// Inputs are always single-line, even if inside a contentEditable element
5729
		// IE also treats inputs as contentEditable
5730
		// All other element types are determined by whether or not they're contentEditable
5731
		this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element );
5732
 
5733
		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
5734
		this.isNewMenu = true;
5735
 
5736
		this._addClass( "ui-autocomplete-input" );
5737
		this.element.attr( "autocomplete", "off" );
5738
 
5739
		this._on( this.element, {
5740
			keydown: function( event ) {
5741
				if ( this.element.prop( "readOnly" ) ) {
5742
					suppressKeyPress = true;
5743
					suppressInput = true;
5744
					suppressKeyPressRepeat = true;
5745
					return;
5746
				}
5747
 
5748
				suppressKeyPress = false;
5749
				suppressInput = false;
5750
				suppressKeyPressRepeat = false;
5751
				var keyCode = $.ui.keyCode;
5752
				switch ( event.keyCode ) {
5753
				case keyCode.PAGE_UP:
5754
					suppressKeyPress = true;
5755
					this._move( "previousPage", event );
5756
					break;
5757
				case keyCode.PAGE_DOWN:
5758
					suppressKeyPress = true;
5759
					this._move( "nextPage", event );
5760
					break;
5761
				case keyCode.UP:
5762
					suppressKeyPress = true;
5763
					this._keyEvent( "previous", event );
5764
					break;
5765
				case keyCode.DOWN:
5766
					suppressKeyPress = true;
5767
					this._keyEvent( "next", event );
5768
					break;
5769
				case keyCode.ENTER:
5770
 
5771
					// when menu is open and has focus
5772
					if ( this.menu.active ) {
5773
 
5774
						// #6055 - Opera still allows the keypress to occur
5775
						// which causes forms to submit
5776
						suppressKeyPress = true;
5777
						event.preventDefault();
5778
						this.menu.select( event );
5779
					}
5780
					break;
5781
				case keyCode.TAB:
5782
					if ( this.menu.active ) {
5783
						this.menu.select( event );
5784
					}
5785
					break;
5786
				case keyCode.ESCAPE:
5787
					if ( this.menu.element.is( ":visible" ) ) {
5788
						if ( !this.isMultiLine ) {
5789
							this._value( this.term );
5790
						}
5791
						this.close( event );
5792
 
5793
						// Different browsers have different default behavior for escape
5794
						// Single press can mean undo or clear
5795
						// Double press in IE means clear the whole form
5796
						event.preventDefault();
5797
					}
5798
					break;
5799
				default:
5800
					suppressKeyPressRepeat = true;
5801
 
5802
					// search timeout should be triggered before the input value is changed
5803
					this._searchTimeout( event );
5804
					break;
5805
				}
5806
			},
5807
			keypress: function( event ) {
5808
				if ( suppressKeyPress ) {
5809
					suppressKeyPress = false;
5810
					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
5811
						event.preventDefault();
5812
					}
5813
					return;
5814
				}
5815
				if ( suppressKeyPressRepeat ) {
5816
					return;
5817
				}
5818
 
5819
				// Replicate some key handlers to allow them to repeat in Firefox and Opera
5820
				var keyCode = $.ui.keyCode;
5821
				switch ( event.keyCode ) {
5822
				case keyCode.PAGE_UP:
5823
					this._move( "previousPage", event );
5824
					break;
5825
				case keyCode.PAGE_DOWN:
5826
					this._move( "nextPage", event );
5827
					break;
5828
				case keyCode.UP:
5829
					this._keyEvent( "previous", event );
5830
					break;
5831
				case keyCode.DOWN:
5832
					this._keyEvent( "next", event );
5833
					break;
5834
				}
5835
			},
5836
			input: function( event ) {
5837
				if ( suppressInput ) {
5838
					suppressInput = false;
5839
					event.preventDefault();
5840
					return;
5841
				}
5842
				this._searchTimeout( event );
5843
			},
5844
			focus: function() {
5845
				this.selectedItem = null;
5846
				this.previous = this._value();
5847
			},
5848
			blur: function( event ) {
5849
				clearTimeout( this.searching );
5850
				this.close( event );
5851
				this._change( event );
5852
			}
5853
		} );
5854
 
5855
		this._initSource();
5856
		this.menu = $( "<ul>" )
5857
			.appendTo( this._appendTo() )
5858
			.menu( {
5859
 
5860
				// disable ARIA support, the live region takes care of that
5861
				role: null
5862
			} )
5863
			.hide()
5864
 
5865
			// Support: IE 11 only, Edge <= 14
5866
			// For other browsers, we preventDefault() on the mousedown event
5867
			// to keep the dropdown from taking focus from the input. This doesn't
5868
			// work for IE/Edge, causing problems with selection and scrolling (#9638)
5869
			// Happily, IE and Edge support an "unselectable" attribute that
5870
			// prevents an element from receiving focus, exactly what we want here.
5871
			.attr( {
5872
				"unselectable": "on"
5873
			} )
5874
			.menu( "instance" );
5875
 
5876
		this._addClass( this.menu.element, "ui-autocomplete", "ui-front" );
5877
		this._on( this.menu.element, {
5878
			mousedown: function( event ) {
5879
 
5880
				// Prevent moving focus out of the text field
5881
				event.preventDefault();
5882
			},
5883
			menufocus: function( event, ui ) {
5884
				var label, item;
5885
 
5886
				// support: Firefox
5887
				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
5888
				if ( this.isNewMenu ) {
5889
					this.isNewMenu = false;
5890
					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
5891
						this.menu.blur();
5892
 
5893
						this.document.one( "mousemove", function() {
5894
							$( event.target ).trigger( event.originalEvent );
5895
						} );
5896
 
5897
						return;
5898
					}
5899
				}
5900
 
5901
				item = ui.item.data( "ui-autocomplete-item" );
5902
				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
5903
 
5904
					// use value to match what will end up in the input, if it was a key event
5905
					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
5906
						this._value( item.value );
5907
					}
5908
				}
5909
 
5910
				// Announce the value in the liveRegion
5911
				label = ui.item.attr( "aria-label" ) || item.value;
5912
				if ( label && String.prototype.trim.call( label ).length ) {
5913
					clearTimeout( this.liveRegionTimer );
5914
					this.liveRegionTimer = this._delay( function() {
5915
						this.liveRegion.html( $( "<div>" ).text( label ) );
5916
					}, 100 );
5917
				}
5918
			},
5919
			menuselect: function( event, ui ) {
5920
				var item = ui.item.data( "ui-autocomplete-item" ),
5921
					previous = this.previous;
5922
 
5923
				// Only trigger when focus was lost (click on menu)
5924
				if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
5925
					this.element.trigger( "focus" );
5926
					this.previous = previous;
5927
 
5928
					// #6109 - IE triggers two focus events and the second
5929
					// is asynchronous, so we need to reset the previous
5930
					// term synchronously and asynchronously :-(
5931
					this._delay( function() {
5932
						this.previous = previous;
5933
						this.selectedItem = item;
5934
					} );
5935
				}
5936
 
5937
				if ( false !== this._trigger( "select", event, { item: item } ) ) {
5938
					this._value( item.value );
5939
				}
5940
 
5941
				// reset the term after the select event
5942
				// this allows custom select handling to work properly
5943
				this.term = this._value();
5944
 
5945
				this.close( event );
5946
				this.selectedItem = item;
5947
			}
5948
		} );
5949
 
5950
		this.liveRegion = $( "<div>", {
5951
			role: "status",
5952
			"aria-live": "assertive",
5953
			"aria-relevant": "additions"
5954
		} )
5955
			.appendTo( this.document[ 0 ].body );
5956
 
5957
		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
5958
 
5959
		// Turning off autocomplete prevents the browser from remembering the
5960
		// value when navigating through history, so we re-enable autocomplete
5961
		// if the page is unloaded before the widget is destroyed. #7790
5962
		this._on( this.window, {
5963
			beforeunload: function() {
5964
				this.element.removeAttr( "autocomplete" );
5965
			}
5966
		} );
5967
	},
5968
 
5969
	_destroy: function() {
5970
		clearTimeout( this.searching );
5971
		this.element.removeAttr( "autocomplete" );
5972
		this.menu.element.remove();
5973
		this.liveRegion.remove();
5974
	},
5975
 
5976
	_setOption: function( key, value ) {
5977
		this._super( key, value );
5978
		if ( key === "source" ) {
5979
			this._initSource();
5980
		}
5981
		if ( key === "appendTo" ) {
5982
			this.menu.element.appendTo( this._appendTo() );
5983
		}
5984
		if ( key === "disabled" && value && this.xhr ) {
5985
			this.xhr.abort();
5986
		}
5987
	},
5988
 
5989
	_isEventTargetInWidget: function( event ) {
5990
		var menuElement = this.menu.element[ 0 ];
5991
 
5992
		return event.target === this.element[ 0 ] ||
5993
			event.target === menuElement ||
5994
			$.contains( menuElement, event.target );
5995
	},
5996
 
5997
	_closeOnClickOutside: function( event ) {
5998
		if ( !this._isEventTargetInWidget( event ) ) {
5999
			this.close();
6000
		}
6001
	},
6002
 
6003
	_appendTo: function() {
6004
		var element = this.options.appendTo;
6005
 
6006
		if ( element ) {
6007
			element = element.jquery || element.nodeType ?
6008
				$( element ) :
6009
				this.document.find( element ).eq( 0 );
6010
		}
6011
 
6012
		if ( !element || !element[ 0 ] ) {
6013
			element = this.element.closest( ".ui-front, dialog" );
6014
		}
6015
 
6016
		if ( !element.length ) {
6017
			element = this.document[ 0 ].body;
6018
		}
6019
 
6020
		return element;
6021
	},
6022
 
6023
	_initSource: function() {
6024
		var array, url,
6025
			that = this;
6026
		if ( Array.isArray( this.options.source ) ) {
6027
			array = this.options.source;
6028
			this.source = function( request, response ) {
6029
				response( $.ui.autocomplete.filter( array, request.term ) );
6030
			};
6031
		} else if ( typeof this.options.source === "string" ) {
6032
			url = this.options.source;
6033
			this.source = function( request, response ) {
6034
				if ( that.xhr ) {
6035
					that.xhr.abort();
6036
				}
6037
				that.xhr = $.ajax( {
6038
					url: url,
6039
					data: request,
6040
					dataType: "json",
6041
					success: function( data ) {
6042
						response( data );
6043
					},
6044
					error: function() {
6045
						response( [] );
6046
					}
6047
				} );
6048
			};
6049
		} else {
6050
			this.source = this.options.source;
6051
		}
6052
	},
6053
 
6054
	_searchTimeout: function( event ) {
6055
		clearTimeout( this.searching );
6056
		this.searching = this._delay( function() {
6057
 
6058
			// Search if the value has changed, or if the user retypes the same value (see #7434)
6059
			var equalValues = this.term === this._value(),
6060
				menuVisible = this.menu.element.is( ":visible" ),
6061
				modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
6062
 
6063
			if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
6064
				this.selectedItem = null;
6065
				this.search( null, event );
6066
			}
6067
		}, this.options.delay );
6068
	},
6069
 
6070
	search: function( value, event ) {
6071
		value = value != null ? value : this._value();
6072
 
6073
		// Always save the actual value, not the one passed as an argument
6074
		this.term = this._value();
6075
 
6076
		if ( value.length < this.options.minLength ) {
6077
			return this.close( event );
6078
		}
6079
 
6080
		if ( this._trigger( "search", event ) === false ) {
6081
			return;
6082
		}
6083
 
6084
		return this._search( value );
6085
	},
6086
 
6087
	_search: function( value ) {
6088
		this.pending++;
6089
		this._addClass( "ui-autocomplete-loading" );
6090
		this.cancelSearch = false;
6091
 
6092
		this.source( { term: value }, this._response() );
6093
	},
6094
 
6095
	_response: function() {
6096
		var index = ++this.requestIndex;
6097
 
6098
		return function( content ) {
6099
			if ( index === this.requestIndex ) {
6100
				this.__response( content );
6101
			}
6102
 
6103
			this.pending--;
6104
			if ( !this.pending ) {
6105
				this._removeClass( "ui-autocomplete-loading" );
6106
			}
6107
		}.bind( this );
6108
	},
6109
 
6110
	__response: function( content ) {
6111
		if ( content ) {
6112
			content = this._normalize( content );
6113
		}
6114
		this._trigger( "response", null, { content: content } );
6115
		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
6116
			this._suggest( content );
6117
			this._trigger( "open" );
6118
		} else {
6119
 
6120
			// use ._close() instead of .close() so we don't cancel future searches
6121
			this._close();
6122
		}
6123
	},
6124
 
6125
	close: function( event ) {
6126
		this.cancelSearch = true;
6127
		this._close( event );
6128
	},
6129
 
6130
	_close: function( event ) {
6131
 
6132
		// Remove the handler that closes the menu on outside clicks
6133
		this._off( this.document, "mousedown" );
6134
 
6135
		if ( this.menu.element.is( ":visible" ) ) {
6136
			this.menu.element.hide();
6137
			this.menu.blur();
6138
			this.isNewMenu = true;
6139
			this._trigger( "close", event );
6140
		}
6141
	},
6142
 
6143
	_change: function( event ) {
6144
		if ( this.previous !== this._value() ) {
6145
			this._trigger( "change", event, { item: this.selectedItem } );
6146
		}
6147
	},
6148
 
6149
	_normalize: function( items ) {
6150
 
6151
		// assume all items have the right format when the first item is complete
6152
		if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
6153
			return items;
6154
		}
6155
		return $.map( items, function( item ) {
6156
			if ( typeof item === "string" ) {
6157
				return {
6158
					label: item,
6159
					value: item
6160
				};
6161
			}
6162
			return $.extend( {}, item, {
6163
				label: item.label || item.value,
6164
				value: item.value || item.label
6165
			} );
6166
		} );
6167
	},
6168
 
6169
	_suggest: function( items ) {
6170
		var ul = this.menu.element.empty();
6171
		this._renderMenu( ul, items );
6172
		this.isNewMenu = true;
6173
		this.menu.refresh();
6174
 
6175
		// Size and position menu
6176
		ul.show();
6177
		this._resizeMenu();
6178
		ul.position( $.extend( {
6179
			of: this.element
6180
		}, this.options.position ) );
6181
 
6182
		if ( this.options.autoFocus ) {
6183
			this.menu.next();
6184
		}
6185
 
6186
		// Listen for interactions outside of the widget (#6642)
6187
		this._on( this.document, {
6188
			mousedown: "_closeOnClickOutside"
6189
		} );
6190
	},
6191
 
6192
	_resizeMenu: function() {
6193
		var ul = this.menu.element;
6194
		ul.outerWidth( Math.max(
6195
 
6196
			// Firefox wraps long text (possibly a rounding bug)
6197
			// so we add 1px to avoid the wrapping (#7513)
6198
			ul.width( "" ).outerWidth() + 1,
6199
			this.element.outerWidth()
6200
		) );
6201
	},
6202
 
6203
	_renderMenu: function( ul, items ) {
6204
		var that = this;
6205
		$.each( items, function( index, item ) {
6206
			that._renderItemData( ul, item );
6207
		} );
6208
	},
6209
 
6210
	_renderItemData: function( ul, item ) {
6211
		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
6212
	},
6213
 
6214
	_renderItem: function( ul, item ) {
6215
		return $( "<li>" )
6216
			.append( $( "<div>" ).text( item.label ) )
6217
			.appendTo( ul );
6218
	},
6219
 
6220
	_move: function( direction, event ) {
6221
		if ( !this.menu.element.is( ":visible" ) ) {
6222
			this.search( null, event );
6223
			return;
6224
		}
6225
		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
6226
				this.menu.isLastItem() && /^next/.test( direction ) ) {
6227
 
6228
			if ( !this.isMultiLine ) {
6229
				this._value( this.term );
6230
			}
6231
 
6232
			this.menu.blur();
6233
			return;
6234
		}
6235
		this.menu[ direction ]( event );
6236
	},
6237
 
6238
	widget: function() {
6239
		return this.menu.element;
6240
	},
6241
 
6242
	_value: function() {
6243
		return this.valueMethod.apply( this.element, arguments );
6244
	},
6245
 
6246
	_keyEvent: function( keyEvent, event ) {
6247
		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
6248
			this._move( keyEvent, event );
6249
 
6250
			// Prevents moving cursor to beginning/end of the text field in some browsers
6251
			event.preventDefault();
6252
		}
6253
	},
6254
 
6255
	// Support: Chrome <=50
6256
	// We should be able to just use this.element.prop( "isContentEditable" )
6257
	// but hidden elements always report false in Chrome.
6258
	// https://code.google.com/p/chromium/issues/detail?id=313082
6259
	_isContentEditable: function( element ) {
6260
		if ( !element.length ) {
6261
			return false;
6262
		}
6263
 
6264
		var editable = element.prop( "contentEditable" );
6265
 
6266
		if ( editable === "inherit" ) {
6267
			return this._isContentEditable( element.parent() );
6268
		}
6269
 
6270
		return editable === "true";
6271
	}
6272
} );
6273
 
6274
$.extend( $.ui.autocomplete, {
6275
	escapeRegex: function( value ) {
6276
		return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
6277
	},
6278
	filter: function( array, term ) {
6279
		var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
6280
		return $.grep( array, function( value ) {
6281
			return matcher.test( value.label || value.value || value );
6282
		} );
6283
	}
6284
} );
6285
 
6286
// Live region extension, adding a `messages` option
6287
// NOTE: This is an experimental API. We are still investigating
6288
// a full solution for string manipulation and internationalization.
6289
$.widget( "ui.autocomplete", $.ui.autocomplete, {
6290
	options: {
6291
		messages: {
6292
			noResults: "No search results.",
6293
			results: function( amount ) {
6294
				return amount + ( amount > 1 ? " results are" : " result is" ) +
6295
					" available, use up and down arrow keys to navigate.";
6296
			}
6297
		}
6298
	},
6299
 
6300
	__response: function( content ) {
6301
		var message;
6302
		this._superApply( arguments );
6303
		if ( this.options.disabled || this.cancelSearch ) {
6304
			return;
6305
		}
6306
		if ( content && content.length ) {
6307
			message = this.options.messages.results( content.length );
6308
		} else {
6309
			message = this.options.messages.noResults;
6310
		}
6311
		clearTimeout( this.liveRegionTimer );
6312
		this.liveRegionTimer = this._delay( function() {
6313
			this.liveRegion.html( $( "<div>" ).text( message ) );
6314
		}, 100 );
6315
	}
6316
} );
6317
 
6318
var widgetsAutocomplete = $.ui.autocomplete;
6319
 
6320
 
6321
/*!
6322
 * jQuery UI Controlgroup 1.13.2
6323
 * http://jqueryui.com
6324
 *
6325
 * Copyright jQuery Foundation and other contributors
6326
 * Released under the MIT license.
6327
 * http://jquery.org/license
6328
 */
6329
 
6330
//>>label: Controlgroup
6331
//>>group: Widgets
6332
//>>description: Visually groups form control widgets
6333
//>>docs: http://api.jqueryui.com/controlgroup/
6334
//>>demos: http://jqueryui.com/controlgroup/
6335
//>>css.structure: ../../themes/base/core.css
6336
//>>css.structure: ../../themes/base/controlgroup.css
6337
//>>css.theme: ../../themes/base/theme.css
6338
 
6339
 
6340
var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g;
6341
 
6342
var widgetsControlgroup = $.widget( "ui.controlgroup", {
6343
	version: "1.13.2",
6344
	defaultElement: "<div>",
6345
	options: {
6346
		direction: "horizontal",
6347
		disabled: null,
6348
		onlyVisible: true,
6349
		items: {
6350
			"button": "input[type=button], input[type=submit], input[type=reset], button, a",
6351
			"controlgroupLabel": ".ui-controlgroup-label",
6352
			"checkboxradio": "input[type='checkbox'], input[type='radio']",
6353
			"selectmenu": "select",
6354
			"spinner": ".ui-spinner-input"
6355
		}
6356
	},
6357
 
6358
	_create: function() {
6359
		this._enhance();
6360
	},
6361
 
6362
	// To support the enhanced option in jQuery Mobile, we isolate DOM manipulation
6363
	_enhance: function() {
6364
		this.element.attr( "role", "toolbar" );
6365
		this.refresh();
6366
	},
6367
 
6368
	_destroy: function() {
6369
		this._callChildMethod( "destroy" );
6370
		this.childWidgets.removeData( "ui-controlgroup-data" );
6371
		this.element.removeAttr( "role" );
6372
		if ( this.options.items.controlgroupLabel ) {
6373
			this.element
6374
				.find( this.options.items.controlgroupLabel )
6375
				.find( ".ui-controlgroup-label-contents" )
6376
				.contents().unwrap();
6377
		}
6378
	},
6379
 
6380
	_initWidgets: function() {
6381
		var that = this,
6382
			childWidgets = [];
6383
 
6384
		// First we iterate over each of the items options
6385
		$.each( this.options.items, function( widget, selector ) {
6386
			var labels;
6387
			var options = {};
6388
 
6389
			// Make sure the widget has a selector set
6390
			if ( !selector ) {
6391
				return;
6392
			}
6393
 
6394
			if ( widget === "controlgroupLabel" ) {
6395
				labels = that.element.find( selector );
6396
				labels.each( function() {
6397
					var element = $( this );
6398
 
6399
					if ( element.children( ".ui-controlgroup-label-contents" ).length ) {
6400
						return;
6401
					}
6402
					element.contents()
6403
						.wrapAll( "<span class='ui-controlgroup-label-contents'></span>" );
6404
				} );
6405
				that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" );
6406
				childWidgets = childWidgets.concat( labels.get() );
6407
				return;
6408
			}
6409
 
6410
			// Make sure the widget actually exists
6411
			if ( !$.fn[ widget ] ) {
6412
				return;
6413
			}
6414
 
6415
			// We assume everything is in the middle to start because we can't determine
6416
			// first / last elements until all enhancments are done.
6417
			if ( that[ "_" + widget + "Options" ] ) {
6418
				options = that[ "_" + widget + "Options" ]( "middle" );
6419
			} else {
6420
				options = { classes: {} };
6421
			}
6422
 
6423
			// Find instances of this widget inside controlgroup and init them
6424
			that.element
6425
				.find( selector )
6426
				.each( function() {
6427
					var element = $( this );
6428
					var instance = element[ widget ]( "instance" );
6429
 
6430
					// We need to clone the default options for this type of widget to avoid
6431
					// polluting the variable options which has a wider scope than a single widget.
6432
					var instanceOptions = $.widget.extend( {}, options );
6433
 
6434
					// If the button is the child of a spinner ignore it
6435
					// TODO: Find a more generic solution
6436
					if ( widget === "button" && element.parent( ".ui-spinner" ).length ) {
6437
						return;
6438
					}
6439
 
6440
					// Create the widget if it doesn't exist
6441
					if ( !instance ) {
6442
						instance = element[ widget ]()[ widget ]( "instance" );
6443
					}
6444
					if ( instance ) {
6445
						instanceOptions.classes =
6446
							that._resolveClassesValues( instanceOptions.classes, instance );
6447
					}
6448
					element[ widget ]( instanceOptions );
6449
 
6450
					// Store an instance of the controlgroup to be able to reference
6451
					// from the outermost element for changing options and refresh
6452
					var widgetElement = element[ widget ]( "widget" );
6453
					$.data( widgetElement[ 0 ], "ui-controlgroup-data",
6454
						instance ? instance : element[ widget ]( "instance" ) );
6455
 
6456
					childWidgets.push( widgetElement[ 0 ] );
6457
				} );
6458
		} );
6459
 
6460
		this.childWidgets = $( $.uniqueSort( childWidgets ) );
6461
		this._addClass( this.childWidgets, "ui-controlgroup-item" );
6462
	},
6463
 
6464
	_callChildMethod: function( method ) {
6465
		this.childWidgets.each( function() {
6466
			var element = $( this ),
6467
				data = element.data( "ui-controlgroup-data" );
6468
			if ( data && data[ method ] ) {
6469
				data[ method ]();
6470
			}
6471
		} );
6472
	},
6473
 
6474
	_updateCornerClass: function( element, position ) {
6475
		var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all";
6476
		var add = this._buildSimpleOptions( position, "label" ).classes.label;
6477
 
6478
		this._removeClass( element, null, remove );
6479
		this._addClass( element, null, add );
6480
	},
6481
 
6482
	_buildSimpleOptions: function( position, key ) {
6483
		var direction = this.options.direction === "vertical";
6484
		var result = {
6485
			classes: {}
6486
		};
6487
		result.classes[ key ] = {
6488
			"middle": "",
6489
			"first": "ui-corner-" + ( direction ? "top" : "left" ),
6490
			"last": "ui-corner-" + ( direction ? "bottom" : "right" ),
6491
			"only": "ui-corner-all"
6492
		}[ position ];
6493
 
6494
		return result;
6495
	},
6496
 
6497
	_spinnerOptions: function( position ) {
6498
		var options = this._buildSimpleOptions( position, "ui-spinner" );
6499
 
6500
		options.classes[ "ui-spinner-up" ] = "";
6501
		options.classes[ "ui-spinner-down" ] = "";
6502
 
6503
		return options;
6504
	},
6505
 
6506
	_buttonOptions: function( position ) {
6507
		return this._buildSimpleOptions( position, "ui-button" );
6508
	},
6509
 
6510
	_checkboxradioOptions: function( position ) {
6511
		return this._buildSimpleOptions( position, "ui-checkboxradio-label" );
6512
	},
6513
 
6514
	_selectmenuOptions: function( position ) {
6515
		var direction = this.options.direction === "vertical";
6516
		return {
6517
			width: direction ? "auto" : false,
6518
			classes: {
6519
				middle: {
6520
					"ui-selectmenu-button-open": "",
6521
					"ui-selectmenu-button-closed": ""
6522
				},
6523
				first: {
6524
					"ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ),
6525
					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" )
6526
				},
6527
				last: {
6528
					"ui-selectmenu-button-open": direction ? "" : "ui-corner-tr",
6529
					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" )
6530
				},
6531
				only: {
6532
					"ui-selectmenu-button-open": "ui-corner-top",
6533
					"ui-selectmenu-button-closed": "ui-corner-all"
6534
				}
6535
 
6536
			}[ position ]
6537
		};
6538
	},
6539
 
6540
	_resolveClassesValues: function( classes, instance ) {
6541
		var result = {};
6542
		$.each( classes, function( key ) {
6543
			var current = instance.options.classes[ key ] || "";
6544
			current = String.prototype.trim.call( current.replace( controlgroupCornerRegex, "" ) );
6545
			result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " );
6546
		} );
6547
		return result;
6548
	},
6549
 
6550
	_setOption: function( key, value ) {
6551
		if ( key === "direction" ) {
6552
			this._removeClass( "ui-controlgroup-" + this.options.direction );
6553
		}
6554
 
6555
		this._super( key, value );
6556
		if ( key === "disabled" ) {
6557
			this._callChildMethod( value ? "disable" : "enable" );
6558
			return;
6559
		}
6560
 
6561
		this.refresh();
6562
	},
6563
 
6564
	refresh: function() {
6565
		var children,
6566
			that = this;
6567
 
6568
		this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction );
6569
 
6570
		if ( this.options.direction === "horizontal" ) {
6571
			this._addClass( null, "ui-helper-clearfix" );
6572
		}
6573
		this._initWidgets();
6574
 
6575
		children = this.childWidgets;
6576
 
6577
		// We filter here because we need to track all childWidgets not just the visible ones
6578
		if ( this.options.onlyVisible ) {
6579
			children = children.filter( ":visible" );
6580
		}
6581
 
6582
		if ( children.length ) {
6583
 
6584
			// We do this last because we need to make sure all enhancment is done
6585
			// before determining first and last
6586
			$.each( [ "first", "last" ], function( index, value ) {
6587
				var instance = children[ value ]().data( "ui-controlgroup-data" );
6588
 
6589
				if ( instance && that[ "_" + instance.widgetName + "Options" ] ) {
6590
					var options = that[ "_" + instance.widgetName + "Options" ](
6591
						children.length === 1 ? "only" : value
6592
					);
6593
					options.classes = that._resolveClassesValues( options.classes, instance );
6594
					instance.element[ instance.widgetName ]( options );
6595
				} else {
6596
					that._updateCornerClass( children[ value ](), value );
6597
				}
6598
			} );
6599
 
6600
			// Finally call the refresh method on each of the child widgets.
6601
			this._callChildMethod( "refresh" );
6602
		}
6603
	}
6604
} );
6605
 
6606
/*!
6607
 * jQuery UI Checkboxradio 1.13.2
6608
 * http://jqueryui.com
6609
 *
6610
 * Copyright jQuery Foundation and other contributors
6611
 * Released under the MIT license.
6612
 * http://jquery.org/license
6613
 */
6614
 
6615
//>>label: Checkboxradio
6616
//>>group: Widgets
6617
//>>description: Enhances a form with multiple themeable checkboxes or radio buttons.
6618
//>>docs: http://api.jqueryui.com/checkboxradio/
6619
//>>demos: http://jqueryui.com/checkboxradio/
6620
//>>css.structure: ../../themes/base/core.css
6621
//>>css.structure: ../../themes/base/button.css
6622
//>>css.structure: ../../themes/base/checkboxradio.css
6623
//>>css.theme: ../../themes/base/theme.css
6624
 
6625
 
6626
$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
6627
	version: "1.13.2",
6628
	options: {
6629
		disabled: null,
6630
		label: null,
6631
		icon: true,
6632
		classes: {
6633
			"ui-checkboxradio-label": "ui-corner-all",
6634
			"ui-checkboxradio-icon": "ui-corner-all"
6635
		}
6636
	},
6637
 
6638
	_getCreateOptions: function() {
6639
		var disabled, labels, labelContents;
6640
		var options = this._super() || {};
6641
 
6642
		// We read the type here, because it makes more sense to throw a element type error first,
6643
		// rather then the error for lack of a label. Often if its the wrong type, it
6644
		// won't have a label (e.g. calling on a div, btn, etc)
6645
		this._readType();
6646
 
6647
		labels = this.element.labels();
6648
 
6649
		// If there are multiple labels, use the last one
6650
		this.label = $( labels[ labels.length - 1 ] );
6651
		if ( !this.label.length ) {
6652
			$.error( "No label found for checkboxradio widget" );
6653
		}
6654
 
6655
		this.originalLabel = "";
6656
 
6657
		// We need to get the label text but this may also need to make sure it does not contain the
6658
		// input itself.
6659
		// The label contents could be text, html, or a mix. We wrap all elements
6660
		// and read the wrapper's `innerHTML` to get a string representation of
6661
		// the label, without the input as part of it.
6662
		labelContents = this.label.contents().not( this.element[ 0 ] );
6663
 
6664
		if ( labelContents.length ) {
6665
			this.originalLabel += labelContents
6666
				.clone()
6667
				.wrapAll( "<div></div>" )
6668
				.parent()
6669
				.html();
6670
		}
6671
 
6672
		// Set the label option if we found label text
6673
		if ( this.originalLabel ) {
6674
			options.label = this.originalLabel;
6675
		}
6676
 
6677
		disabled = this.element[ 0 ].disabled;
6678
		if ( disabled != null ) {
6679
			options.disabled = disabled;
6680
		}
6681
		return options;
6682
	},
6683
 
6684
	_create: function() {
6685
		var checked = this.element[ 0 ].checked;
6686
 
6687
		this._bindFormResetHandler();
6688
 
6689
		if ( this.options.disabled == null ) {
6690
			this.options.disabled = this.element[ 0 ].disabled;
6691
		}
6692
 
6693
		this._setOption( "disabled", this.options.disabled );
6694
		this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" );
6695
		this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" );
6696
 
6697
		if ( this.type === "radio" ) {
6698
			this._addClass( this.label, "ui-checkboxradio-radio-label" );
6699
		}
6700
 
6701
		if ( this.options.label && this.options.label !== this.originalLabel ) {
6702
			this._updateLabel();
6703
		} else if ( this.originalLabel ) {
6704
			this.options.label = this.originalLabel;
6705
		}
6706
 
6707
		this._enhance();
6708
 
6709
		if ( checked ) {
6710
			this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" );
6711
		}
6712
 
6713
		this._on( {
6714
			change: "_toggleClasses",
6715
			focus: function() {
6716
				this._addClass( this.label, null, "ui-state-focus ui-visual-focus" );
6717
			},
6718
			blur: function() {
6719
				this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" );
6720
			}
6721
		} );
6722
	},
6723
 
6724
	_readType: function() {
6725
		var nodeName = this.element[ 0 ].nodeName.toLowerCase();
6726
		this.type = this.element[ 0 ].type;
6727
		if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) {
6728
			$.error( "Can't create checkboxradio on element.nodeName=" + nodeName +
6729
				" and element.type=" + this.type );
6730
		}
6731
	},
6732
 
6733
	// Support jQuery Mobile enhanced option
6734
	_enhance: function() {
6735
		this._updateIcon( this.element[ 0 ].checked );
6736
	},
6737
 
6738
	widget: function() {
6739
		return this.label;
6740
	},
6741
 
6742
	_getRadioGroup: function() {
6743
		var group;
6744
		var name = this.element[ 0 ].name;
6745
		var nameSelector = "input[name='" + $.escapeSelector( name ) + "']";
6746
 
6747
		if ( !name ) {
6748
			return $( [] );
6749
		}
6750
 
6751
		if ( this.form.length ) {
6752
			group = $( this.form[ 0 ].elements ).filter( nameSelector );
6753
		} else {
6754
 
6755
			// Not inside a form, check all inputs that also are not inside a form
6756
			group = $( nameSelector ).filter( function() {
6757
				return $( this )._form().length === 0;
6758
			} );
6759
		}
6760
 
6761
		return group.not( this.element );
6762
	},
6763
 
6764
	_toggleClasses: function() {
6765
		var checked = this.element[ 0 ].checked;
6766
		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
6767
 
6768
		if ( this.options.icon && this.type === "checkbox" ) {
6769
			this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked )
6770
				._toggleClass( this.icon, null, "ui-icon-blank", !checked );
6771
		}
6772
 
6773
		if ( this.type === "radio" ) {
6774
			this._getRadioGroup()
6775
				.each( function() {
6776
					var instance = $( this ).checkboxradio( "instance" );
6777
 
6778
					if ( instance ) {
6779
						instance._removeClass( instance.label,
6780
							"ui-checkboxradio-checked", "ui-state-active" );
6781
					}
6782
				} );
6783
		}
6784
	},
6785
 
6786
	_destroy: function() {
6787
		this._unbindFormResetHandler();
6788
 
6789
		if ( this.icon ) {
6790
			this.icon.remove();
6791
			this.iconSpace.remove();
6792
		}
6793
	},
6794
 
6795
	_setOption: function( key, value ) {
6796
 
6797
		// We don't allow the value to be set to nothing
6798
		if ( key === "label" && !value ) {
6799
			return;
6800
		}
6801
 
6802
		this._super( key, value );
6803
 
6804
		if ( key === "disabled" ) {
6805
			this._toggleClass( this.label, null, "ui-state-disabled", value );
6806
			this.element[ 0 ].disabled = value;
6807
 
6808
			// Don't refresh when setting disabled
6809
			return;
6810
		}
6811
		this.refresh();
6812
	},
6813
 
6814
	_updateIcon: function( checked ) {
6815
		var toAdd = "ui-icon ui-icon-background ";
6816
 
6817
		if ( this.options.icon ) {
6818
			if ( !this.icon ) {
6819
				this.icon = $( "<span>" );
6820
				this.iconSpace = $( "<span> </span>" );
6821
				this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" );
6822
			}
6823
 
6824
			if ( this.type === "checkbox" ) {
6825
				toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank";
6826
				this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" );
6827
			} else {
6828
				toAdd += "ui-icon-blank";
6829
			}
6830
			this._addClass( this.icon, "ui-checkboxradio-icon", toAdd );
6831
			if ( !checked ) {
6832
				this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" );
6833
			}
6834
			this.icon.prependTo( this.label ).after( this.iconSpace );
6835
		} else if ( this.icon !== undefined ) {
6836
			this.icon.remove();
6837
			this.iconSpace.remove();
6838
			delete this.icon;
6839
		}
6840
	},
6841
 
6842
	_updateLabel: function() {
6843
 
6844
		// Remove the contents of the label ( minus the icon, icon space, and input )
6845
		var contents = this.label.contents().not( this.element[ 0 ] );
6846
		if ( this.icon ) {
6847
			contents = contents.not( this.icon[ 0 ] );
6848
		}
6849
		if ( this.iconSpace ) {
6850
			contents = contents.not( this.iconSpace[ 0 ] );
6851
		}
6852
		contents.remove();
6853
 
6854
		this.label.append( this.options.label );
6855
	},
6856
 
6857
	refresh: function() {
6858
		var checked = this.element[ 0 ].checked,
6859
			isDisabled = this.element[ 0 ].disabled;
6860
 
6861
		this._updateIcon( checked );
6862
		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
6863
		if ( this.options.label !== null ) {
6864
			this._updateLabel();
6865
		}
6866
 
6867
		if ( isDisabled !== this.options.disabled ) {
6868
			this._setOptions( { "disabled": isDisabled } );
6869
		}
6870
	}
6871
 
6872
} ] );
6873
 
6874
var widgetsCheckboxradio = $.ui.checkboxradio;
6875
 
6876
 
6877
/*!
6878
 * jQuery UI Button 1.13.2
6879
 * http://jqueryui.com
6880
 *
6881
 * Copyright jQuery Foundation and other contributors
6882
 * Released under the MIT license.
6883
 * http://jquery.org/license
6884
 */
6885
 
6886
//>>label: Button
6887
//>>group: Widgets
6888
//>>description: Enhances a form with themeable buttons.
6889
//>>docs: http://api.jqueryui.com/button/
6890
//>>demos: http://jqueryui.com/button/
6891
//>>css.structure: ../../themes/base/core.css
6892
//>>css.structure: ../../themes/base/button.css
6893
//>>css.theme: ../../themes/base/theme.css
6894
 
6895
 
6896
$.widget( "ui.button", {
6897
	version: "1.13.2",
6898
	defaultElement: "<button>",
6899
	options: {
6900
		classes: {
6901
			"ui-button": "ui-corner-all"
6902
		},
6903
		disabled: null,
6904
		icon: null,
6905
		iconPosition: "beginning",
6906
		label: null,
6907
		showLabel: true
6908
	},
6909
 
6910
	_getCreateOptions: function() {
6911
		var disabled,
6912
 
6913
			// This is to support cases like in jQuery Mobile where the base widget does have
6914
			// an implementation of _getCreateOptions
6915
			options = this._super() || {};
6916
 
6917
		this.isInput = this.element.is( "input" );
6918
 
6919
		disabled = this.element[ 0 ].disabled;
6920
		if ( disabled != null ) {
6921
			options.disabled = disabled;
6922
		}
6923
 
6924
		this.originalLabel = this.isInput ? this.element.val() : this.element.html();
6925
		if ( this.originalLabel ) {
6926
			options.label = this.originalLabel;
6927
		}
6928
 
6929
		return options;
6930
	},
6931
 
6932
	_create: function() {
6933
		if ( !this.option.showLabel & !this.options.icon ) {
6934
			this.options.showLabel = true;
6935
		}
6936
 
6937
		// We have to check the option again here even though we did in _getCreateOptions,
6938
		// because null may have been passed on init which would override what was set in
6939
		// _getCreateOptions
6940
		if ( this.options.disabled == null ) {
6941
			this.options.disabled = this.element[ 0 ].disabled || false;
6942
		}
6943
 
6944
		this.hasTitle = !!this.element.attr( "title" );
6945
 
6946
		// Check to see if the label needs to be set or if its already correct
6947
		if ( this.options.label && this.options.label !== this.originalLabel ) {
6948
			if ( this.isInput ) {
6949
				this.element.val( this.options.label );
6950
			} else {
6951
				this.element.html( this.options.label );
6952
			}
6953
		}
6954
		this._addClass( "ui-button", "ui-widget" );
6955
		this._setOption( "disabled", this.options.disabled );
6956
		this._enhance();
6957
 
6958
		if ( this.element.is( "a" ) ) {
6959
			this._on( {
6960
				"keyup": function( event ) {
6961
					if ( event.keyCode === $.ui.keyCode.SPACE ) {
6962
						event.preventDefault();
6963
 
6964
						// Support: PhantomJS <= 1.9, IE 8 Only
6965
						// If a native click is available use it so we actually cause navigation
6966
						// otherwise just trigger a click event
6967
						if ( this.element[ 0 ].click ) {
6968
							this.element[ 0 ].click();
6969
						} else {
6970
							this.element.trigger( "click" );
6971
						}
6972
					}
6973
				}
6974
			} );
6975
		}
6976
	},
6977
 
6978
	_enhance: function() {
6979
		if ( !this.element.is( "button" ) ) {
6980
			this.element.attr( "role", "button" );
6981
		}
6982
 
6983
		if ( this.options.icon ) {
6984
			this._updateIcon( "icon", this.options.icon );
6985
			this._updateTooltip();
6986
		}
6987
	},
6988
 
6989
	_updateTooltip: function() {
6990
		this.title = this.element.attr( "title" );
6991
 
6992
		if ( !this.options.showLabel && !this.title ) {
6993
			this.element.attr( "title", this.options.label );
6994
		}
6995
	},
6996
 
6997
	_updateIcon: function( option, value ) {
6998
		var icon = option !== "iconPosition",
6999
			position = icon ? this.options.iconPosition : value,
7000
			displayBlock = position === "top" || position === "bottom";
7001
 
7002
		// Create icon
7003
		if ( !this.icon ) {
7004
			this.icon = $( "<span>" );
7005
 
7006
			this._addClass( this.icon, "ui-button-icon", "ui-icon" );
7007
 
7008
			if ( !this.options.showLabel ) {
7009
				this._addClass( "ui-button-icon-only" );
7010
			}
7011
		} else if ( icon ) {
7012
 
7013
			// If we are updating the icon remove the old icon class
7014
			this._removeClass( this.icon, null, this.options.icon );
7015
		}
7016
 
7017
		// If we are updating the icon add the new icon class
7018
		if ( icon ) {
7019
			this._addClass( this.icon, null, value );
7020
		}
7021
 
7022
		this._attachIcon( position );
7023
 
7024
		// If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove
7025
		// the iconSpace if there is one.
7026
		if ( displayBlock ) {
7027
			this._addClass( this.icon, null, "ui-widget-icon-block" );
7028
			if ( this.iconSpace ) {
7029
				this.iconSpace.remove();
7030
			}
7031
		} else {
7032
 
7033
			// Position is beginning or end so remove the ui-widget-icon-block class and add the
7034
			// space if it does not exist
7035
			if ( !this.iconSpace ) {
7036
				this.iconSpace = $( "<span> </span>" );
7037
				this._addClass( this.iconSpace, "ui-button-icon-space" );
7038
			}
7039
			this._removeClass( this.icon, null, "ui-wiget-icon-block" );
7040
			this._attachIconSpace( position );
7041
		}
7042
	},
7043
 
7044
	_destroy: function() {
7045
		this.element.removeAttr( "role" );
7046
 
7047
		if ( this.icon ) {
7048
			this.icon.remove();
7049
		}
7050
		if ( this.iconSpace ) {
7051
			this.iconSpace.remove();
7052
		}
7053
		if ( !this.hasTitle ) {
7054
			this.element.removeAttr( "title" );
7055
		}
7056
	},
7057
 
7058
	_attachIconSpace: function( iconPosition ) {
7059
		this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace );
7060
	},
7061
 
7062
	_attachIcon: function( iconPosition ) {
7063
		this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon );
7064
	},
7065
 
7066
	_setOptions: function( options ) {
7067
		var newShowLabel = options.showLabel === undefined ?
7068
				this.options.showLabel :
7069
				options.showLabel,
7070
			newIcon = options.icon === undefined ? this.options.icon : options.icon;
7071
 
7072
		if ( !newShowLabel && !newIcon ) {
7073
			options.showLabel = true;
7074
		}
7075
		this._super( options );
7076
	},
7077
 
7078
	_setOption: function( key, value ) {
7079
		if ( key === "icon" ) {
7080
			if ( value ) {
7081
				this._updateIcon( key, value );
7082
			} else if ( this.icon ) {
7083
				this.icon.remove();
7084
				if ( this.iconSpace ) {
7085
					this.iconSpace.remove();
7086
				}
7087
			}
7088
		}
7089
 
7090
		if ( key === "iconPosition" ) {
7091
			this._updateIcon( key, value );
7092
		}
7093
 
7094
		// Make sure we can't end up with a button that has neither text nor icon
7095
		if ( key === "showLabel" ) {
7096
				this._toggleClass( "ui-button-icon-only", null, !value );
7097
				this._updateTooltip();
7098
		}
7099
 
7100
		if ( key === "label" ) {
7101
			if ( this.isInput ) {
7102
				this.element.val( value );
7103
			} else {
7104
 
7105
				// If there is an icon, append it, else nothing then append the value
7106
				// this avoids removal of the icon when setting label text
7107
				this.element.html( value );
7108
				if ( this.icon ) {
7109
					this._attachIcon( this.options.iconPosition );
7110
					this._attachIconSpace( this.options.iconPosition );
7111
				}
7112
			}
7113
		}
7114
 
7115
		this._super( key, value );
7116
 
7117
		if ( key === "disabled" ) {
7118
			this._toggleClass( null, "ui-state-disabled", value );
7119
			this.element[ 0 ].disabled = value;
7120
			if ( value ) {
7121
				this.element.trigger( "blur" );
7122
			}
7123
		}
7124
	},
7125
 
7126
	refresh: function() {
7127
 
7128
		// Make sure to only check disabled if its an element that supports this otherwise
7129
		// check for the disabled class to determine state
7130
		var isDisabled = this.element.is( "input, button" ) ?
7131
			this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" );
7132
 
7133
		if ( isDisabled !== this.options.disabled ) {
7134
			this._setOptions( { disabled: isDisabled } );
7135
		}
7136
 
7137
		this._updateTooltip();
7138
	}
7139
} );
7140
 
7141
// DEPRECATED
7142
if ( $.uiBackCompat !== false ) {
7143
 
7144
	// Text and Icons options
7145
	$.widget( "ui.button", $.ui.button, {
7146
		options: {
7147
			text: true,
7148
			icons: {
7149
				primary: null,
7150
				secondary: null
7151
			}
7152
		},
7153
 
7154
		_create: function() {
7155
			if ( this.options.showLabel && !this.options.text ) {
7156
				this.options.showLabel = this.options.text;
7157
			}
7158
			if ( !this.options.showLabel && this.options.text ) {
7159
				this.options.text = this.options.showLabel;
7160
			}
7161
			if ( !this.options.icon && ( this.options.icons.primary ||
7162
					this.options.icons.secondary ) ) {
7163
				if ( this.options.icons.primary ) {
7164
					this.options.icon = this.options.icons.primary;
7165
				} else {
7166
					this.options.icon = this.options.icons.secondary;
7167
					this.options.iconPosition = "end";
7168
				}
7169
			} else if ( this.options.icon ) {
7170
				this.options.icons.primary = this.options.icon;
7171
			}
7172
			this._super();
7173
		},
7174
 
7175
		_setOption: function( key, value ) {
7176
			if ( key === "text" ) {
7177
				this._super( "showLabel", value );
7178
				return;
7179
			}
7180
			if ( key === "showLabel" ) {
7181
				this.options.text = value;
7182
			}
7183
			if ( key === "icon" ) {
7184
				this.options.icons.primary = value;
7185
			}
7186
			if ( key === "icons" ) {
7187
				if ( value.primary ) {
7188
					this._super( "icon", value.primary );
7189
					this._super( "iconPosition", "beginning" );
7190
				} else if ( value.secondary ) {
7191
					this._super( "icon", value.secondary );
7192
					this._super( "iconPosition", "end" );
7193
				}
7194
			}
7195
			this._superApply( arguments );
7196
		}
7197
	} );
7198
 
7199
	$.fn.button = ( function( orig ) {
7200
		return function( options ) {
7201
			var isMethodCall = typeof options === "string";
7202
			var args = Array.prototype.slice.call( arguments, 1 );
7203
			var returnValue = this;
7204
 
7205
			if ( isMethodCall ) {
7206
 
7207
				// If this is an empty collection, we need to have the instance method
7208
				// return undefined instead of the jQuery instance
7209
				if ( !this.length && options === "instance" ) {
7210
					returnValue = undefined;
7211
				} else {
7212
					this.each( function() {
7213
						var methodValue;
7214
						var type = $( this ).attr( "type" );
7215
						var name = type !== "checkbox" && type !== "radio" ?
7216
							"button" :
7217
							"checkboxradio";
7218
						var instance = $.data( this, "ui-" + name );
7219
 
7220
						if ( options === "instance" ) {
7221
							returnValue = instance;
7222
							return false;
7223
						}
7224
 
7225
						if ( !instance ) {
7226
							return $.error( "cannot call methods on button" +
7227
								" prior to initialization; " +
7228
								"attempted to call method '" + options + "'" );
7229
						}
7230
 
7231
						if ( typeof instance[ options ] !== "function" ||
7232
							options.charAt( 0 ) === "_" ) {
7233
							return $.error( "no such method '" + options + "' for button" +
7234
								" widget instance" );
7235
						}
7236
 
7237
						methodValue = instance[ options ].apply( instance, args );
7238
 
7239
						if ( methodValue !== instance && methodValue !== undefined ) {
7240
							returnValue = methodValue && methodValue.jquery ?
7241
								returnValue.pushStack( methodValue.get() ) :
7242
								methodValue;
7243
							return false;
7244
						}
7245
					} );
7246
				}
7247
			} else {
7248
 
7249
				// Allow multiple hashes to be passed on init
7250
				if ( args.length ) {
7251
					options = $.widget.extend.apply( null, [ options ].concat( args ) );
7252
				}
7253
 
7254
				this.each( function() {
7255
					var type = $( this ).attr( "type" );
7256
					var name = type !== "checkbox" && type !== "radio" ? "button" : "checkboxradio";
7257
					var instance = $.data( this, "ui-" + name );
7258
 
7259
					if ( instance ) {
7260
						instance.option( options || {} );
7261
						if ( instance._init ) {
7262
							instance._init();
7263
						}
7264
					} else {
7265
						if ( name === "button" ) {
7266
							orig.call( $( this ), options );
7267
							return;
7268
						}
7269
 
7270
						$( this ).checkboxradio( $.extend( { icon: false }, options ) );
7271
					}
7272
				} );
7273
			}
7274
 
7275
			return returnValue;
7276
		};
7277
	} )( $.fn.button );
7278
 
7279
	$.fn.buttonset = function() {
7280
		if ( !$.ui.controlgroup ) {
7281
			$.error( "Controlgroup widget missing" );
7282
		}
7283
		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) {
7284
			return this.controlgroup.apply( this,
7285
				[ arguments[ 0 ], "items.button", arguments[ 2 ] ] );
7286
		}
7287
		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) {
7288
			return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] );
7289
		}
7290
		if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) {
7291
			arguments[ 0 ].items = {
7292
				button: arguments[ 0 ].items
7293
			};
7294
		}
7295
		return this.controlgroup.apply( this, arguments );
7296
	};
7297
}
7298
 
7299
var widgetsButton = $.ui.button;
7300
 
7301
 
7302
/* eslint-disable max-len, camelcase */
7303
/*!
7304
 * jQuery UI Datepicker 1.13.2
7305
 * http://jqueryui.com
7306
 *
7307
 * Copyright jQuery Foundation and other contributors
7308
 * Released under the MIT license.
7309
 * http://jquery.org/license
7310
 */
7311
 
7312
//>>label: Datepicker
7313
//>>group: Widgets
7314
//>>description: Displays a calendar from an input or inline for selecting dates.
7315
//>>docs: http://api.jqueryui.com/datepicker/
7316
//>>demos: http://jqueryui.com/datepicker/
7317
//>>css.structure: ../../themes/base/core.css
7318
//>>css.structure: ../../themes/base/datepicker.css
7319
//>>css.theme: ../../themes/base/theme.css
7320
 
7321
 
7322
$.extend( $.ui, { datepicker: { version: "1.13.2" } } );
7323
 
7324
var datepicker_instActive;
7325
 
7326
function datepicker_getZindex( elem ) {
7327
	var position, value;
7328
	while ( elem.length && elem[ 0 ] !== document ) {
7329
 
7330
		// Ignore z-index if position is set to a value where z-index is ignored by the browser
7331
		// This makes behavior of this function consistent across browsers
7332
		// WebKit always returns auto if the element is positioned
7333
		position = elem.css( "position" );
7334
		if ( position === "absolute" || position === "relative" || position === "fixed" ) {
7335
 
7336
			// IE returns 0 when zIndex is not specified
7337
			// other browsers return a string
7338
			// we ignore the case of nested elements with an explicit value of 0
7339
			// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
7340
			value = parseInt( elem.css( "zIndex" ), 10 );
7341
			if ( !isNaN( value ) && value !== 0 ) {
7342
				return value;
7343
			}
7344
		}
7345
		elem = elem.parent();
7346
	}
7347
 
7348
	return 0;
7349
}
7350
 
7351
/* Date picker manager.
7352
   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
7353
   Settings for (groups of) date pickers are maintained in an instance object,
7354
   allowing multiple different settings on the same page. */
7355
 
7356
function Datepicker() {
7357
	this._curInst = null; // The current instance in use
7358
	this._keyEvent = false; // If the last event was a key event
7359
	this._disabledInputs = []; // List of date picker inputs that have been disabled
7360
	this._datepickerShowing = false; // True if the popup picker is showing , false if not
7361
	this._inDialog = false; // True if showing within a "dialog", false if not
7362
	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
7363
	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
7364
	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
7365
	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
7366
	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
7367
	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
7368
	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
7369
	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
7370
	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
7371
	this.regional = []; // Available regional settings, indexed by language code
7372
	this.regional[ "" ] = { // Default regional settings
7373
		closeText: "Done", // Display text for close link
7374
		prevText: "Prev", // Display text for previous month link
7375
		nextText: "Next", // Display text for next month link
7376
		currentText: "Today", // Display text for current month link
7377
		monthNames: [ "January", "February", "March", "April", "May", "June",
7378
			"July", "August", "September", "October", "November", "December" ], // Names of months for drop-down and formatting
7379
		monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting
7380
		dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting
7381
		dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting
7382
		dayNamesMin: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ], // Column headings for days starting at Sunday
7383
		weekHeader: "Wk", // Column header for week of the year
7384
		dateFormat: "mm/dd/yy", // See format options on parseDate
7385
		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
7386
		isRTL: false, // True if right-to-left language, false if left-to-right
7387
		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
7388
		yearSuffix: "", // Additional text to append to the year in the month headers,
7389
		selectMonthLabel: "Select month", // Invisible label for month selector
7390
		selectYearLabel: "Select year" // Invisible label for year selector
7391
	};
7392
	this._defaults = { // Global defaults for all the date picker instances
7393
		showOn: "focus", // "focus" for popup on focus,
7394
			// "button" for trigger button, or "both" for either
7395
		showAnim: "fadeIn", // Name of jQuery animation for popup
7396
		showOptions: {}, // Options for enhanced animations
7397
		defaultDate: null, // Used when field is blank: actual date,
7398
			// +/-number for offset from today, null for today
7399
		appendText: "", // Display text following the input box, e.g. showing the format
7400
		buttonText: "...", // Text for trigger button
7401
		buttonImage: "", // URL for trigger button image
7402
		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
7403
		hideIfNoPrevNext: false, // True to hide next/previous month links
7404
			// if not applicable, false to just disable them
7405
		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
7406
		gotoCurrent: false, // True if today link goes back to current selection instead
7407
		changeMonth: false, // True if month can be selected directly, false if only prev/next
7408
		changeYear: false, // True if year can be selected directly, false if only prev/next
7409
		yearRange: "c-10:c+10", // Range of years to display in drop-down,
7410
			// either relative to today's year (-nn:+nn), relative to currently displayed year
7411
			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
7412
		showOtherMonths: false, // True to show dates in other months, false to leave blank
7413
		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
7414
		showWeek: false, // True to show week of the year, false to not show it
7415
		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
7416
			// takes a Date and returns the number of the week for it
7417
		shortYearCutoff: "+10", // Short year values < this are in the current century,
7418
			// > this are in the previous century,
7419
			// string value starting with "+" for current year + value
7420
		minDate: null, // The earliest selectable date, or null for no limit
7421
		maxDate: null, // The latest selectable date, or null for no limit
7422
		duration: "fast", // Duration of display/closure
7423
		beforeShowDay: null, // Function that takes a date and returns an array with
7424
			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
7425
			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
7426
		beforeShow: null, // Function that takes an input field and
7427
			// returns a set of custom settings for the date picker
7428
		onSelect: null, // Define a callback function when a date is selected
7429
		onChangeMonthYear: null, // Define a callback function when the month or year is changed
7430
		onClose: null, // Define a callback function when the datepicker is closed
7431
		onUpdateDatepicker: null, // Define a callback function when the datepicker is updated
7432
		numberOfMonths: 1, // Number of months to show at a time
7433
		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
7434
		stepMonths: 1, // Number of months to step back/forward
7435
		stepBigMonths: 12, // Number of months to step back/forward for the big links
7436
		altField: "", // Selector for an alternate field to store selected dates into
7437
		altFormat: "", // The date format to use for the alternate field
7438
		constrainInput: true, // The input is constrained by the current date format
7439
		showButtonPanel: false, // True to show button panel, false to not show it
7440
		autoSize: false, // True to size the input for the date format, false to leave as is
7441
		disabled: false // The initial disabled state
7442
	};
7443
	$.extend( this._defaults, this.regional[ "" ] );
7444
	this.regional.en = $.extend( true, {}, this.regional[ "" ] );
7445
	this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
7446
	this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) );
7447
}
7448
 
7449
$.extend( Datepicker.prototype, {
7450
 
7451
	/* Class name added to elements to indicate already configured with a date picker. */
7452
	markerClassName: "hasDatepicker",
7453
 
7454
	//Keep track of the maximum number of rows displayed (see #7043)
7455
	maxRows: 4,
7456
 
7457
	// TODO rename to "widget" when switching to widget factory
7458
	_widgetDatepicker: function() {
7459
		return this.dpDiv;
7460
	},
7461
 
7462
	/* Override the default settings for all instances of the date picker.
7463
	 * @param  settings  object - the new settings to use as defaults (anonymous object)
7464
	 * @return the manager object
7465
	 */
7466
	setDefaults: function( settings ) {
7467
		datepicker_extendRemove( this._defaults, settings || {} );
7468
		return this;
7469
	},
7470
 
7471
	/* Attach the date picker to a jQuery selection.
7472
	 * @param  target	element - the target input field or division or span
7473
	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
7474
	 */
7475
	_attachDatepicker: function( target, settings ) {
7476
		var nodeName, inline, inst;
7477
		nodeName = target.nodeName.toLowerCase();
7478
		inline = ( nodeName === "div" || nodeName === "span" );
7479
		if ( !target.id ) {
7480
			this.uuid += 1;
7481
			target.id = "dp" + this.uuid;
7482
		}
7483
		inst = this._newInst( $( target ), inline );
7484
		inst.settings = $.extend( {}, settings || {} );
7485
		if ( nodeName === "input" ) {
7486
			this._connectDatepicker( target, inst );
7487
		} else if ( inline ) {
7488
			this._inlineDatepicker( target, inst );
7489
		}
7490
	},
7491
 
7492
	/* Create a new instance object. */
7493
	_newInst: function( target, inline ) {
7494
		var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars
7495
		return { id: id, input: target, // associated target
7496
			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
7497
			drawMonth: 0, drawYear: 0, // month being drawn
7498
			inline: inline, // is datepicker inline or not
7499
			dpDiv: ( !inline ? this.dpDiv : // presentation div
7500
			datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) };
7501
	},
7502
 
7503
	/* Attach the date picker to an input field. */
7504
	_connectDatepicker: function( target, inst ) {
7505
		var input = $( target );
7506
		inst.append = $( [] );
7507
		inst.trigger = $( [] );
7508
		if ( input.hasClass( this.markerClassName ) ) {
7509
			return;
7510
		}
7511
		this._attachments( input, inst );
7512
		input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ).
7513
			on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp );
7514
		this._autoSize( inst );
7515
		$.data( target, "datepicker", inst );
7516
 
7517
		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
7518
		if ( inst.settings.disabled ) {
7519
			this._disableDatepicker( target );
7520
		}
7521
	},
7522
 
7523
	/* Make attachments based on settings. */
7524
	_attachments: function( input, inst ) {
7525
		var showOn, buttonText, buttonImage,
7526
			appendText = this._get( inst, "appendText" ),
7527
			isRTL = this._get( inst, "isRTL" );
7528
 
7529
		if ( inst.append ) {
7530
			inst.append.remove();
7531
		}
7532
		if ( appendText ) {
7533
			inst.append = $( "<span>" )
7534
				.addClass( this._appendClass )
7535
				.text( appendText );
7536
			input[ isRTL ? "before" : "after" ]( inst.append );
7537
		}
7538
 
7539
		input.off( "focus", this._showDatepicker );
7540
 
7541
		if ( inst.trigger ) {
7542
			inst.trigger.remove();
7543
		}
7544
 
7545
		showOn = this._get( inst, "showOn" );
7546
		if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field
7547
			input.on( "focus", this._showDatepicker );
7548
		}
7549
		if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked
7550
			buttonText = this._get( inst, "buttonText" );
7551
			buttonImage = this._get( inst, "buttonImage" );
7552
 
7553
			if ( this._get( inst, "buttonImageOnly" ) ) {
7554
				inst.trigger = $( "<img>" )
7555
					.addClass( this._triggerClass )
7556
					.attr( {
7557
						src: buttonImage,
7558
						alt: buttonText,
7559
						title: buttonText
7560
					} );
7561
			} else {
7562
				inst.trigger = $( "<button type='button'>" )
7563
					.addClass( this._triggerClass );
7564
				if ( buttonImage ) {
7565
					inst.trigger.html(
7566
						$( "<img>" )
7567
							.attr( {
7568
								src: buttonImage,
7569
								alt: buttonText,
7570
								title: buttonText
7571
							} )
7572
					);
7573
				} else {
7574
					inst.trigger.text( buttonText );
7575
				}
7576
			}
7577
 
7578
			input[ isRTL ? "before" : "after" ]( inst.trigger );
7579
			inst.trigger.on( "click", function() {
7580
				if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) {
7581
					$.datepicker._hideDatepicker();
7582
				} else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) {
7583
					$.datepicker._hideDatepicker();
7584
					$.datepicker._showDatepicker( input[ 0 ] );
7585
				} else {
7586
					$.datepicker._showDatepicker( input[ 0 ] );
7587
				}
7588
				return false;
7589
			} );
7590
		}
7591
	},
7592
 
7593
	/* Apply the maximum length for the date format. */
7594
	_autoSize: function( inst ) {
7595
		if ( this._get( inst, "autoSize" ) && !inst.inline ) {
7596
			var findMax, max, maxI, i,
7597
				date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits
7598
				dateFormat = this._get( inst, "dateFormat" );
7599
 
7600
			if ( dateFormat.match( /[DM]/ ) ) {
7601
				findMax = function( names ) {
7602
					max = 0;
7603
					maxI = 0;
7604
					for ( i = 0; i < names.length; i++ ) {
7605
						if ( names[ i ].length > max ) {
7606
							max = names[ i ].length;
7607
							maxI = i;
7608
						}
7609
					}
7610
					return maxI;
7611
				};
7612
				date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ?
7613
					"monthNames" : "monthNamesShort" ) ) ) );
7614
				date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ?
7615
					"dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() );
7616
			}
7617
			inst.input.attr( "size", this._formatDate( inst, date ).length );
7618
		}
7619
	},
7620
 
7621
	/* Attach an inline date picker to a div. */
7622
	_inlineDatepicker: function( target, inst ) {
7623
		var divSpan = $( target );
7624
		if ( divSpan.hasClass( this.markerClassName ) ) {
7625
			return;
7626
		}
7627
		divSpan.addClass( this.markerClassName ).append( inst.dpDiv );
7628
		$.data( target, "datepicker", inst );
7629
		this._setDate( inst, this._getDefaultDate( inst ), true );
7630
		this._updateDatepicker( inst );
7631
		this._updateAlternate( inst );
7632
 
7633
		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7634
		if ( inst.settings.disabled ) {
7635
			this._disableDatepicker( target );
7636
		}
7637
 
7638
		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7639
		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7640
		inst.dpDiv.css( "display", "block" );
7641
	},
7642
 
7643
	/* Pop-up the date picker in a "dialog" box.
7644
	 * @param  input element - ignored
7645
	 * @param  date	string or Date - the initial date to display
7646
	 * @param  onSelect  function - the function to call when a date is selected
7647
	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
7648
	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
7649
	 *					event - with x/y coordinates or
7650
	 *					leave empty for default (screen centre)
7651
	 * @return the manager object
7652
	 */
7653
	_dialogDatepicker: function( input, date, onSelect, settings, pos ) {
7654
		var id, browserWidth, browserHeight, scrollX, scrollY,
7655
			inst = this._dialogInst; // internal instance
7656
 
7657
		if ( !inst ) {
7658
			this.uuid += 1;
7659
			id = "dp" + this.uuid;
7660
			this._dialogInput = $( "<input type='text' id='" + id +
7661
				"' style='position: absolute; top: -100px; width: 0px;'/>" );
7662
			this._dialogInput.on( "keydown", this._doKeyDown );
7663
			$( "body" ).append( this._dialogInput );
7664
			inst = this._dialogInst = this._newInst( this._dialogInput, false );
7665
			inst.settings = {};
7666
			$.data( this._dialogInput[ 0 ], "datepicker", inst );
7667
		}
7668
		datepicker_extendRemove( inst.settings, settings || {} );
7669
		date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date );
7670
		this._dialogInput.val( date );
7671
 
7672
		this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null );
7673
		if ( !this._pos ) {
7674
			browserWidth = document.documentElement.clientWidth;
7675
			browserHeight = document.documentElement.clientHeight;
7676
			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7677
			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7678
			this._pos = // should use actual width/height below
7679
				[ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ];
7680
		}
7681
 
7682
		// Move input on screen for focus, but hidden behind dialog
7683
		this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" );
7684
		inst.settings.onSelect = onSelect;
7685
		this._inDialog = true;
7686
		this.dpDiv.addClass( this._dialogClass );
7687
		this._showDatepicker( this._dialogInput[ 0 ] );
7688
		if ( $.blockUI ) {
7689
			$.blockUI( this.dpDiv );
7690
		}
7691
		$.data( this._dialogInput[ 0 ], "datepicker", inst );
7692
		return this;
7693
	},
7694
 
7695
	/* Detach a datepicker from its control.
7696
	 * @param  target	element - the target input field or division or span
7697
	 */
7698
	_destroyDatepicker: function( target ) {
7699
		var nodeName,
7700
			$target = $( target ),
7701
			inst = $.data( target, "datepicker" );
7702
 
7703
		if ( !$target.hasClass( this.markerClassName ) ) {
7704
			return;
7705
		}
7706
 
7707
		nodeName = target.nodeName.toLowerCase();
7708
		$.removeData( target, "datepicker" );
7709
		if ( nodeName === "input" ) {
7710
			inst.append.remove();
7711
			inst.trigger.remove();
7712
			$target.removeClass( this.markerClassName ).
7713
				off( "focus", this._showDatepicker ).
7714
				off( "keydown", this._doKeyDown ).
7715
				off( "keypress", this._doKeyPress ).
7716
				off( "keyup", this._doKeyUp );
7717
		} else if ( nodeName === "div" || nodeName === "span" ) {
7718
			$target.removeClass( this.markerClassName ).empty();
7719
		}
7720
 
7721
		if ( datepicker_instActive === inst ) {
7722
			datepicker_instActive = null;
7723
			this._curInst = null;
7724
		}
7725
	},
7726
 
7727
	/* Enable the date picker to a jQuery selection.
7728
	 * @param  target	element - the target input field or division or span
7729
	 */
7730
	_enableDatepicker: function( target ) {
7731
		var nodeName, inline,
7732
			$target = $( target ),
7733
			inst = $.data( target, "datepicker" );
7734
 
7735
		if ( !$target.hasClass( this.markerClassName ) ) {
7736
			return;
7737
		}
7738
 
7739
		nodeName = target.nodeName.toLowerCase();
7740
		if ( nodeName === "input" ) {
7741
			target.disabled = false;
7742
			inst.trigger.filter( "button" ).
7743
				each( function() {
7744
					this.disabled = false;
7745
				} ).end().
7746
				filter( "img" ).css( { opacity: "1.0", cursor: "" } );
7747
		} else if ( nodeName === "div" || nodeName === "span" ) {
7748
			inline = $target.children( "." + this._inlineClass );
7749
			inline.children().removeClass( "ui-state-disabled" );
7750
			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
7751
				prop( "disabled", false );
7752
		}
7753
		this._disabledInputs = $.map( this._disabledInputs,
7754
 
7755
			// Delete entry
7756
			function( value ) {
7757
				return ( value === target ? null : value );
7758
			} );
7759
	},
7760
 
7761
	/* Disable the date picker to a jQuery selection.
7762
	 * @param  target	element - the target input field or division or span
7763
	 */
7764
	_disableDatepicker: function( target ) {
7765
		var nodeName, inline,
7766
			$target = $( target ),
7767
			inst = $.data( target, "datepicker" );
7768
 
7769
		if ( !$target.hasClass( this.markerClassName ) ) {
7770
			return;
7771
		}
7772
 
7773
		nodeName = target.nodeName.toLowerCase();
7774
		if ( nodeName === "input" ) {
7775
			target.disabled = true;
7776
			inst.trigger.filter( "button" ).
7777
				each( function() {
7778
					this.disabled = true;
7779
				} ).end().
7780
				filter( "img" ).css( { opacity: "0.5", cursor: "default" } );
7781
		} else if ( nodeName === "div" || nodeName === "span" ) {
7782
			inline = $target.children( "." + this._inlineClass );
7783
			inline.children().addClass( "ui-state-disabled" );
7784
			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
7785
				prop( "disabled", true );
7786
		}
7787
		this._disabledInputs = $.map( this._disabledInputs,
7788
 
7789
			// Delete entry
7790
			function( value ) {
7791
				return ( value === target ? null : value );
7792
			} );
7793
		this._disabledInputs[ this._disabledInputs.length ] = target;
7794
	},
7795
 
7796
	/* Is the first field in a jQuery collection disabled as a datepicker?
7797
	 * @param  target	element - the target input field or division or span
7798
	 * @return boolean - true if disabled, false if enabled
7799
	 */
7800
	_isDisabledDatepicker: function( target ) {
7801
		if ( !target ) {
7802
			return false;
7803
		}
7804
		for ( var i = 0; i < this._disabledInputs.length; i++ ) {
7805
			if ( this._disabledInputs[ i ] === target ) {
7806
				return true;
7807
			}
7808
		}
7809
		return false;
7810
	},
7811
 
7812
	/* Retrieve the instance data for the target control.
7813
	 * @param  target  element - the target input field or division or span
7814
	 * @return  object - the associated instance data
7815
	 * @throws  error if a jQuery problem getting data
7816
	 */
7817
	_getInst: function( target ) {
7818
		try {
7819
			return $.data( target, "datepicker" );
7820
		} catch ( err ) {
7821
			throw "Missing instance data for this datepicker";
7822
		}
7823
	},
7824
 
7825
	/* Update or retrieve the settings for a date picker attached to an input field or division.
7826
	 * @param  target  element - the target input field or division or span
7827
	 * @param  name	object - the new settings to update or
7828
	 *				string - the name of the setting to change or retrieve,
7829
	 *				when retrieving also "all" for all instance settings or
7830
	 *				"defaults" for all global defaults
7831
	 * @param  value   any - the new value for the setting
7832
	 *				(omit if above is an object or to retrieve a value)
7833
	 */
7834
	_optionDatepicker: function( target, name, value ) {
7835
		var settings, date, minDate, maxDate,
7836
			inst = this._getInst( target );
7837
 
7838
		if ( arguments.length === 2 && typeof name === "string" ) {
7839
			return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) :
7840
				( inst ? ( name === "all" ? $.extend( {}, inst.settings ) :
7841
				this._get( inst, name ) ) : null ) );
7842
		}
7843
 
7844
		settings = name || {};
7845
		if ( typeof name === "string" ) {
7846
			settings = {};
7847
			settings[ name ] = value;
7848
		}
7849
 
7850
		if ( inst ) {
7851
			if ( this._curInst === inst ) {
7852
				this._hideDatepicker();
7853
			}
7854
 
7855
			date = this._getDateDatepicker( target, true );
7856
			minDate = this._getMinMaxDate( inst, "min" );
7857
			maxDate = this._getMinMaxDate( inst, "max" );
7858
			datepicker_extendRemove( inst.settings, settings );
7859
 
7860
			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
7861
			if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) {
7862
				inst.settings.minDate = this._formatDate( inst, minDate );
7863
			}
7864
			if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) {
7865
				inst.settings.maxDate = this._formatDate( inst, maxDate );
7866
			}
7867
			if ( "disabled" in settings ) {
7868
				if ( settings.disabled ) {
7869
					this._disableDatepicker( target );
7870
				} else {
7871
					this._enableDatepicker( target );
7872
				}
7873
			}
7874
			this._attachments( $( target ), inst );
7875
			this._autoSize( inst );
7876
			this._setDate( inst, date );
7877
			this._updateAlternate( inst );
7878
			this._updateDatepicker( inst );
7879
		}
7880
	},
7881
 
7882
	// Change method deprecated
7883
	_changeDatepicker: function( target, name, value ) {
7884
		this._optionDatepicker( target, name, value );
7885
	},
7886
 
7887
	/* Redraw the date picker attached to an input field or division.
7888
	 * @param  target  element - the target input field or division or span
7889
	 */
7890
	_refreshDatepicker: function( target ) {
7891
		var inst = this._getInst( target );
7892
		if ( inst ) {
7893
			this._updateDatepicker( inst );
7894
		}
7895
	},
7896
 
7897
	/* Set the dates for a jQuery selection.
7898
	 * @param  target element - the target input field or division or span
7899
	 * @param  date	Date - the new date
7900
	 */
7901
	_setDateDatepicker: function( target, date ) {
7902
		var inst = this._getInst( target );
7903
		if ( inst ) {
7904
			this._setDate( inst, date );
7905
			this._updateDatepicker( inst );
7906
			this._updateAlternate( inst );
7907
		}
7908
	},
7909
 
7910
	/* Get the date(s) for the first entry in a jQuery selection.
7911
	 * @param  target element - the target input field or division or span
7912
	 * @param  noDefault boolean - true if no default date is to be used
7913
	 * @return Date - the current date
7914
	 */
7915
	_getDateDatepicker: function( target, noDefault ) {
7916
		var inst = this._getInst( target );
7917
		if ( inst && !inst.inline ) {
7918
			this._setDateFromField( inst, noDefault );
7919
		}
7920
		return ( inst ? this._getDate( inst ) : null );
7921
	},
7922
 
7923
	/* Handle keystrokes. */
7924
	_doKeyDown: function( event ) {
7925
		var onSelect, dateStr, sel,
7926
			inst = $.datepicker._getInst( event.target ),
7927
			handled = true,
7928
			isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" );
7929
 
7930
		inst._keyEvent = true;
7931
		if ( $.datepicker._datepickerShowing ) {
7932
			switch ( event.keyCode ) {
7933
				case 9: $.datepicker._hideDatepicker();
7934
						handled = false;
7935
						break; // hide on tab out
7936
				case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." +
7937
									$.datepicker._currentClass + ")", inst.dpDiv );
7938
						if ( sel[ 0 ] ) {
7939
							$.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] );
7940
						}
7941
 
7942
						onSelect = $.datepicker._get( inst, "onSelect" );
7943
						if ( onSelect ) {
7944
							dateStr = $.datepicker._formatDate( inst );
7945
 
7946
							// Trigger custom callback
7947
							onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );
7948
						} else {
7949
							$.datepicker._hideDatepicker();
7950
						}
7951
 
7952
						return false; // don't submit the form
7953
				case 27: $.datepicker._hideDatepicker();
7954
						break; // hide on escape
7955
				case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7956
							-$.datepicker._get( inst, "stepBigMonths" ) :
7957
							-$.datepicker._get( inst, "stepMonths" ) ), "M" );
7958
						break; // previous month/year on page up/+ ctrl
7959
				case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7960
							+$.datepicker._get( inst, "stepBigMonths" ) :
7961
							+$.datepicker._get( inst, "stepMonths" ) ), "M" );
7962
						break; // next month/year on page down/+ ctrl
7963
				case 35: if ( event.ctrlKey || event.metaKey ) {
7964
							$.datepicker._clearDate( event.target );
7965
						}
7966
						handled = event.ctrlKey || event.metaKey;
7967
						break; // clear on ctrl or command +end
7968
				case 36: if ( event.ctrlKey || event.metaKey ) {
7969
							$.datepicker._gotoToday( event.target );
7970
						}
7971
						handled = event.ctrlKey || event.metaKey;
7972
						break; // current on ctrl or command +home
7973
				case 37: if ( event.ctrlKey || event.metaKey ) {
7974
							$.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" );
7975
						}
7976
						handled = event.ctrlKey || event.metaKey;
7977
 
7978
						// -1 day on ctrl or command +left
7979
						if ( event.originalEvent.altKey ) {
7980
							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7981
								-$.datepicker._get( inst, "stepBigMonths" ) :
7982
								-$.datepicker._get( inst, "stepMonths" ) ), "M" );
7983
						}
7984
 
7985
						// next month/year on alt +left on Mac
7986
						break;
7987
				case 38: if ( event.ctrlKey || event.metaKey ) {
7988
							$.datepicker._adjustDate( event.target, -7, "D" );
7989
						}
7990
						handled = event.ctrlKey || event.metaKey;
7991
						break; // -1 week on ctrl or command +up
7992
				case 39: if ( event.ctrlKey || event.metaKey ) {
7993
							$.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" );
7994
						}
7995
						handled = event.ctrlKey || event.metaKey;
7996
 
7997
						// +1 day on ctrl or command +right
7998
						if ( event.originalEvent.altKey ) {
7999
							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
8000
								+$.datepicker._get( inst, "stepBigMonths" ) :
8001
								+$.datepicker._get( inst, "stepMonths" ) ), "M" );
8002
						}
8003
 
8004
						// next month/year on alt +right
8005
						break;
8006
				case 40: if ( event.ctrlKey || event.metaKey ) {
8007
							$.datepicker._adjustDate( event.target, +7, "D" );
8008
						}
8009
						handled = event.ctrlKey || event.metaKey;
8010
						break; // +1 week on ctrl or command +down
8011
				default: handled = false;
8012
			}
8013
		} else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home
8014
			$.datepicker._showDatepicker( this );
8015
		} else {
8016
			handled = false;
8017
		}
8018
 
8019
		if ( handled ) {
8020
			event.preventDefault();
8021
			event.stopPropagation();
8022
		}
8023
	},
8024
 
8025
	/* Filter entered characters - based on date format. */
8026
	_doKeyPress: function( event ) {
8027
		var chars, chr,
8028
			inst = $.datepicker._getInst( event.target );
8029
 
8030
		if ( $.datepicker._get( inst, "constrainInput" ) ) {
8031
			chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) );
8032
			chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode );
8033
			return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 );
8034
		}
8035
	},
8036
 
8037
	/* Synchronise manual entry and field/alternate field. */
8038
	_doKeyUp: function( event ) {
8039
		var date,
8040
			inst = $.datepicker._getInst( event.target );
8041
 
8042
		if ( inst.input.val() !== inst.lastVal ) {
8043
			try {
8044
				date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
8045
					( inst.input ? inst.input.val() : null ),
8046
					$.datepicker._getFormatConfig( inst ) );
8047
 
8048
				if ( date ) { // only if valid
8049
					$.datepicker._setDateFromField( inst );
8050
					$.datepicker._updateAlternate( inst );
8051
					$.datepicker._updateDatepicker( inst );
8052
				}
8053
			} catch ( err ) {
8054
			}
8055
		}
8056
		return true;
8057
	},
8058
 
8059
	/* Pop-up the date picker for a given input field.
8060
	 * If false returned from beforeShow event handler do not show.
8061
	 * @param  input  element - the input field attached to the date picker or
8062
	 *					event - if triggered by focus
8063
	 */
8064
	_showDatepicker: function( input ) {
8065
		input = input.target || input;
8066
		if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger
8067
			input = $( "input", input.parentNode )[ 0 ];
8068
		}
8069
 
8070
		if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here
8071
			return;
8072
		}
8073
 
8074
		var inst, beforeShow, beforeShowSettings, isFixed,
8075
			offset, showAnim, duration;
8076
 
8077
		inst = $.datepicker._getInst( input );
8078
		if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) {
8079
			$.datepicker._curInst.dpDiv.stop( true, true );
8080
			if ( inst && $.datepicker._datepickerShowing ) {
8081
				$.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] );
8082
			}
8083
		}
8084
 
8085
		beforeShow = $.datepicker._get( inst, "beforeShow" );
8086
		beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {};
8087
		if ( beforeShowSettings === false ) {
8088
			return;
8089
		}
8090
		datepicker_extendRemove( inst.settings, beforeShowSettings );
8091
 
8092
		inst.lastVal = null;
8093
		$.datepicker._lastInput = input;
8094
		$.datepicker._setDateFromField( inst );
8095
 
8096
		if ( $.datepicker._inDialog ) { // hide cursor
8097
			input.value = "";
8098
		}
8099
		if ( !$.datepicker._pos ) { // position below input
8100
			$.datepicker._pos = $.datepicker._findPos( input );
8101
			$.datepicker._pos[ 1 ] += input.offsetHeight; // add the height
8102
		}
8103
 
8104
		isFixed = false;
8105
		$( input ).parents().each( function() {
8106
			isFixed |= $( this ).css( "position" ) === "fixed";
8107
			return !isFixed;
8108
		} );
8109
 
8110
		offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] };
8111
		$.datepicker._pos = null;
8112
 
8113
		//to avoid flashes on Firefox
8114
		inst.dpDiv.empty();
8115
 
8116
		// determine sizing offscreen
8117
		inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } );
8118
		$.datepicker._updateDatepicker( inst );
8119
 
8120
		// fix width for dynamic number of date pickers
8121
		// and adjust position before showing
8122
		offset = $.datepicker._checkOffset( inst, offset, isFixed );
8123
		inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ?
8124
			"static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none",
8125
			left: offset.left + "px", top: offset.top + "px" } );
8126
 
8127
		if ( !inst.inline ) {
8128
			showAnim = $.datepicker._get( inst, "showAnim" );
8129
			duration = $.datepicker._get( inst, "duration" );
8130
			inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
8131
			$.datepicker._datepickerShowing = true;
8132
 
8133
			if ( $.effects && $.effects.effect[ showAnim ] ) {
8134
				inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration );
8135
			} else {
8136
				inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null );
8137
			}
8138
 
8139
			if ( $.datepicker._shouldFocusInput( inst ) ) {
8140
				inst.input.trigger( "focus" );
8141
			}
8142
 
8143
			$.datepicker._curInst = inst;
8144
		}
8145
	},
8146
 
8147
	/* Generate the date picker content. */
8148
	_updateDatepicker: function( inst ) {
8149
		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
8150
		datepicker_instActive = inst; // for delegate hover events
8151
		inst.dpDiv.empty().append( this._generateHTML( inst ) );
8152
		this._attachHandlers( inst );
8153
 
8154
		var origyearshtml,
8155
			numMonths = this._getNumberOfMonths( inst ),
8156
			cols = numMonths[ 1 ],
8157
			width = 17,
8158
			activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ),
8159
			onUpdateDatepicker = $.datepicker._get( inst, "onUpdateDatepicker" );
8160
 
8161
		if ( activeCell.length > 0 ) {
8162
			datepicker_handleMouseover.apply( activeCell.get( 0 ) );
8163
		}
8164
 
8165
		inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" );
8166
		if ( cols > 1 ) {
8167
			inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" );
8168
		}
8169
		inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) +
8170
			"Class" ]( "ui-datepicker-multi" );
8171
		inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) +
8172
			"Class" ]( "ui-datepicker-rtl" );
8173
 
8174
		if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
8175
			inst.input.trigger( "focus" );
8176
		}
8177
 
8178
		// Deffered render of the years select (to avoid flashes on Firefox)
8179
		if ( inst.yearshtml ) {
8180
			origyearshtml = inst.yearshtml;
8181
			setTimeout( function() {
8182
 
8183
				//assure that inst.yearshtml didn't change.
8184
				if ( origyearshtml === inst.yearshtml && inst.yearshtml ) {
8185
					inst.dpDiv.find( "select.ui-datepicker-year" ).first().replaceWith( inst.yearshtml );
8186
				}
8187
				origyearshtml = inst.yearshtml = null;
8188
			}, 0 );
8189
		}
8190
 
8191
		if ( onUpdateDatepicker ) {
8192
			onUpdateDatepicker.apply( ( inst.input ? inst.input[ 0 ] : null ), [ inst ] );
8193
		}
8194
	},
8195
 
8196
	// #6694 - don't focus the input if it's already focused
8197
	// this breaks the change event in IE
8198
	// Support: IE and jQuery <1.9
8199
	_shouldFocusInput: function( inst ) {
8200
		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
8201
	},
8202
 
8203
	/* Check positioning to remain on screen. */
8204
	_checkOffset: function( inst, offset, isFixed ) {
8205
		var dpWidth = inst.dpDiv.outerWidth(),
8206
			dpHeight = inst.dpDiv.outerHeight(),
8207
			inputWidth = inst.input ? inst.input.outerWidth() : 0,
8208
			inputHeight = inst.input ? inst.input.outerHeight() : 0,
8209
			viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ),
8210
			viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() );
8211
 
8212
		offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 );
8213
		offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0;
8214
		offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0;
8215
 
8216
		// Now check if datepicker is showing outside window viewport - move to a better place if so.
8217
		offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ?
8218
			Math.abs( offset.left + dpWidth - viewWidth ) : 0 );
8219
		offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ?
8220
			Math.abs( dpHeight + inputHeight ) : 0 );
8221
 
8222
		return offset;
8223
	},
8224
 
8225
	/* Find an object's position on the screen. */
8226
	_findPos: function( obj ) {
8227
		var position,
8228
			inst = this._getInst( obj ),
8229
			isRTL = this._get( inst, "isRTL" );
8230
 
8231
		while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.pseudos.hidden( obj ) ) ) {
8232
			obj = obj[ isRTL ? "previousSibling" : "nextSibling" ];
8233
		}
8234
 
8235
		position = $( obj ).offset();
8236
		return [ position.left, position.top ];
8237
	},
8238
 
8239
	/* Hide the date picker from view.
8240
	 * @param  input  element - the input field attached to the date picker
8241
	 */
8242
	_hideDatepicker: function( input ) {
8243
		var showAnim, duration, postProcess, onClose,
8244
			inst = this._curInst;
8245
 
8246
		if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) {
8247
			return;
8248
		}
8249
 
8250
		if ( this._datepickerShowing ) {
8251
			showAnim = this._get( inst, "showAnim" );
8252
			duration = this._get( inst, "duration" );
8253
			postProcess = function() {
8254
				$.datepicker._tidyDialog( inst );
8255
			};
8256
 
8257
			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
8258
			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
8259
				inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess );
8260
			} else {
8261
				inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" :
8262
					( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess );
8263
			}
8264
 
8265
			if ( !showAnim ) {
8266
				postProcess();
8267
			}
8268
			this._datepickerShowing = false;
8269
 
8270
			onClose = this._get( inst, "onClose" );
8271
			if ( onClose ) {
8272
				onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] );
8273
			}
8274
 
8275
			this._lastInput = null;
8276
			if ( this._inDialog ) {
8277
				this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } );
8278
				if ( $.blockUI ) {
8279
					$.unblockUI();
8280
					$( "body" ).append( this.dpDiv );
8281
				}
8282
			}
8283
			this._inDialog = false;
8284
		}
8285
	},
8286
 
8287
	/* Tidy up after a dialog display. */
8288
	_tidyDialog: function( inst ) {
8289
		inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" );
8290
	},
8291
 
8292
	/* Close date picker if clicked elsewhere. */
8293
	_checkExternalClick: function( event ) {
8294
		if ( !$.datepicker._curInst ) {
8295
			return;
8296
		}
8297
 
8298
		var $target = $( event.target ),
8299
			inst = $.datepicker._getInst( $target[ 0 ] );
8300
 
8301
		if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId &&
8302
				$target.parents( "#" + $.datepicker._mainDivId ).length === 0 &&
8303
				!$target.hasClass( $.datepicker.markerClassName ) &&
8304
				!$target.closest( "." + $.datepicker._triggerClass ).length &&
8305
				$.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) ||
8306
			( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) {
8307
				$.datepicker._hideDatepicker();
8308
		}
8309
	},
8310
 
8311
	/* Adjust one of the date sub-fields. */
8312
	_adjustDate: function( id, offset, period ) {
8313
		var target = $( id ),
8314
			inst = this._getInst( target[ 0 ] );
8315
 
8316
		if ( this._isDisabledDatepicker( target[ 0 ] ) ) {
8317
			return;
8318
		}
8319
		this._adjustInstDate( inst, offset, period );
8320
		this._updateDatepicker( inst );
8321
	},
8322
 
8323
	/* Action for current link. */
8324
	_gotoToday: function( id ) {
8325
		var date,
8326
			target = $( id ),
8327
			inst = this._getInst( target[ 0 ] );
8328
 
8329
		if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) {
8330
			inst.selectedDay = inst.currentDay;
8331
			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8332
			inst.drawYear = inst.selectedYear = inst.currentYear;
8333
		} else {
8334
			date = new Date();
8335
			inst.selectedDay = date.getDate();
8336
			inst.drawMonth = inst.selectedMonth = date.getMonth();
8337
			inst.drawYear = inst.selectedYear = date.getFullYear();
8338
		}
8339
		this._notifyChange( inst );
8340
		this._adjustDate( target );
8341
	},
8342
 
8343
	/* Action for selecting a new month/year. */
8344
	_selectMonthYear: function( id, select, period ) {
8345
		var target = $( id ),
8346
			inst = this._getInst( target[ 0 ] );
8347
 
8348
		inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] =
8349
		inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] =
8350
			parseInt( select.options[ select.selectedIndex ].value, 10 );
8351
 
8352
		this._notifyChange( inst );
8353
		this._adjustDate( target );
8354
	},
8355
 
8356
	/* Action for selecting a day. */
8357
	_selectDay: function( id, month, year, td ) {
8358
		var inst,
8359
			target = $( id );
8360
 
8361
		if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) {
8362
			return;
8363
		}
8364
 
8365
		inst = this._getInst( target[ 0 ] );
8366
		inst.selectedDay = inst.currentDay = parseInt( $( "a", td ).attr( "data-date" ) );
8367
		inst.selectedMonth = inst.currentMonth = month;
8368
		inst.selectedYear = inst.currentYear = year;
8369
		this._selectDate( id, this._formatDate( inst,
8370
			inst.currentDay, inst.currentMonth, inst.currentYear ) );
8371
	},
8372
 
8373
	/* Erase the input field and hide the date picker. */
8374
	_clearDate: function( id ) {
8375
		var target = $( id );
8376
		this._selectDate( target, "" );
8377
	},
8378
 
8379
	/* Update the input field with the selected date. */
8380
	_selectDate: function( id, dateStr ) {
8381
		var onSelect,
8382
			target = $( id ),
8383
			inst = this._getInst( target[ 0 ] );
8384
 
8385
		dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) );
8386
		if ( inst.input ) {
8387
			inst.input.val( dateStr );
8388
		}
8389
		this._updateAlternate( inst );
8390
 
8391
		onSelect = this._get( inst, "onSelect" );
8392
		if ( onSelect ) {
8393
			onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );  // trigger custom callback
8394
		} else if ( inst.input ) {
8395
			inst.input.trigger( "change" ); // fire the change event
8396
		}
8397
 
8398
		if ( inst.inline ) {
8399
			this._updateDatepicker( inst );
8400
		} else {
8401
			this._hideDatepicker();
8402
			this._lastInput = inst.input[ 0 ];
8403
			if ( typeof( inst.input[ 0 ] ) !== "object" ) {
8404
				inst.input.trigger( "focus" ); // restore focus
8405
			}
8406
			this._lastInput = null;
8407
		}
8408
	},
8409
 
8410
	/* Update any alternate field to synchronise with the main field. */
8411
	_updateAlternate: function( inst ) {
8412
		var altFormat, date, dateStr,
8413
			altField = this._get( inst, "altField" );
8414
 
8415
		if ( altField ) { // update alternate field too
8416
			altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" );
8417
			date = this._getDate( inst );
8418
			dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) );
8419
			$( document ).find( altField ).val( dateStr );
8420
		}
8421
	},
8422
 
8423
	/* Set as beforeShowDay function to prevent selection of weekends.
8424
	 * @param  date  Date - the date to customise
8425
	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
8426
	 */
8427
	noWeekends: function( date ) {
8428
		var day = date.getDay();
8429
		return [ ( day > 0 && day < 6 ), "" ];
8430
	},
8431
 
8432
	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
8433
	 * @param  date  Date - the date to get the week for
8434
	 * @return  number - the number of the week within the year that contains this date
8435
	 */
8436
	iso8601Week: function( date ) {
8437
		var time,
8438
			checkDate = new Date( date.getTime() );
8439
 
8440
		// Find Thursday of this week starting on Monday
8441
		checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) );
8442
 
8443
		time = checkDate.getTime();
8444
		checkDate.setMonth( 0 ); // Compare with Jan 1
8445
		checkDate.setDate( 1 );
8446
		return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1;
8447
	},
8448
 
8449
	/* Parse a string value into a date object.
8450
	 * See formatDate below for the possible formats.
8451
	 *
8452
	 * @param  format string - the expected format of the date
8453
	 * @param  value string - the date in the above format
8454
	 * @param  settings Object - attributes include:
8455
	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
8456
	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
8457
	 *					dayNames		string[7] - names of the days from Sunday (optional)
8458
	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
8459
	 *					monthNames		string[12] - names of the months (optional)
8460
	 * @return  Date - the extracted date value or null if value is blank
8461
	 */
8462
	parseDate: function( format, value, settings ) {
8463
		if ( format == null || value == null ) {
8464
			throw "Invalid arguments";
8465
		}
8466
 
8467
		value = ( typeof value === "object" ? value.toString() : value + "" );
8468
		if ( value === "" ) {
8469
			return null;
8470
		}
8471
 
8472
		var iFormat, dim, extra,
8473
			iValue = 0,
8474
			shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff,
8475
			shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
8476
				new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ),
8477
			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
8478
			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
8479
			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
8480
			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
8481
			year = -1,
8482
			month = -1,
8483
			day = -1,
8484
			doy = -1,
8485
			literal = false,
8486
			date,
8487
 
8488
			// Check whether a format character is doubled
8489
			lookAhead = function( match ) {
8490
				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8491
				if ( matches ) {
8492
					iFormat++;
8493
				}
8494
				return matches;
8495
			},
8496
 
8497
			// Extract a number from the string value
8498
			getNumber = function( match ) {
8499
				var isDoubled = lookAhead( match ),
8500
					size = ( match === "@" ? 14 : ( match === "!" ? 20 :
8501
					( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ),
8502
					minSize = ( match === "y" ? size : 1 ),
8503
					digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ),
8504
					num = value.substring( iValue ).match( digits );
8505
				if ( !num ) {
8506
					throw "Missing number at position " + iValue;
8507
				}
8508
				iValue += num[ 0 ].length;
8509
				return parseInt( num[ 0 ], 10 );
8510
			},
8511
 
8512
			// Extract a name from the string value and convert to an index
8513
			getName = function( match, shortNames, longNames ) {
8514
				var index = -1,
8515
					names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) {
8516
						return [ [ k, v ] ];
8517
					} ).sort( function( a, b ) {
8518
						return -( a[ 1 ].length - b[ 1 ].length );
8519
					} );
8520
 
8521
				$.each( names, function( i, pair ) {
8522
					var name = pair[ 1 ];
8523
					if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) {
8524
						index = pair[ 0 ];
8525
						iValue += name.length;
8526
						return false;
8527
					}
8528
				} );
8529
				if ( index !== -1 ) {
8530
					return index + 1;
8531
				} else {
8532
					throw "Unknown name at position " + iValue;
8533
				}
8534
			},
8535
 
8536
			// Confirm that a literal character matches the string value
8537
			checkLiteral = function() {
8538
				if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) {
8539
					throw "Unexpected literal at position " + iValue;
8540
				}
8541
				iValue++;
8542
			};
8543
 
8544
		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8545
			if ( literal ) {
8546
				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8547
					literal = false;
8548
				} else {
8549
					checkLiteral();
8550
				}
8551
			} else {
8552
				switch ( format.charAt( iFormat ) ) {
8553
					case "d":
8554
						day = getNumber( "d" );
8555
						break;
8556
					case "D":
8557
						getName( "D", dayNamesShort, dayNames );
8558
						break;
8559
					case "o":
8560
						doy = getNumber( "o" );
8561
						break;
8562
					case "m":
8563
						month = getNumber( "m" );
8564
						break;
8565
					case "M":
8566
						month = getName( "M", monthNamesShort, monthNames );
8567
						break;
8568
					case "y":
8569
						year = getNumber( "y" );
8570
						break;
8571
					case "@":
8572
						date = new Date( getNumber( "@" ) );
8573
						year = date.getFullYear();
8574
						month = date.getMonth() + 1;
8575
						day = date.getDate();
8576
						break;
8577
					case "!":
8578
						date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 );
8579
						year = date.getFullYear();
8580
						month = date.getMonth() + 1;
8581
						day = date.getDate();
8582
						break;
8583
					case "'":
8584
						if ( lookAhead( "'" ) ) {
8585
							checkLiteral();
8586
						} else {
8587
							literal = true;
8588
						}
8589
						break;
8590
					default:
8591
						checkLiteral();
8592
				}
8593
			}
8594
		}
8595
 
8596
		if ( iValue < value.length ) {
8597
			extra = value.substr( iValue );
8598
			if ( !/^\s+/.test( extra ) ) {
8599
				throw "Extra/unparsed characters found in date: " + extra;
8600
			}
8601
		}
8602
 
8603
		if ( year === -1 ) {
8604
			year = new Date().getFullYear();
8605
		} else if ( year < 100 ) {
8606
			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8607
				( year <= shortYearCutoff ? 0 : -100 );
8608
		}
8609
 
8610
		if ( doy > -1 ) {
8611
			month = 1;
8612
			day = doy;
8613
			do {
8614
				dim = this._getDaysInMonth( year, month - 1 );
8615
				if ( day <= dim ) {
8616
					break;
8617
				}
8618
				month++;
8619
				day -= dim;
8620
			} while ( true );
8621
		}
8622
 
8623
		date = this._daylightSavingAdjust( new Date( year, month - 1, day ) );
8624
		if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) {
8625
			throw "Invalid date"; // E.g. 31/02/00
8626
		}
8627
		return date;
8628
	},
8629
 
8630
	/* Standard date formats. */
8631
	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
8632
	COOKIE: "D, dd M yy",
8633
	ISO_8601: "yy-mm-dd",
8634
	RFC_822: "D, d M y",
8635
	RFC_850: "DD, dd-M-y",
8636
	RFC_1036: "D, d M y",
8637
	RFC_1123: "D, d M yy",
8638
	RFC_2822: "D, d M yy",
8639
	RSS: "D, d M y", // RFC 822
8640
	TICKS: "!",
8641
	TIMESTAMP: "@",
8642
	W3C: "yy-mm-dd", // ISO 8601
8643
 
8644
	_ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) +
8645
		Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ),
8646
 
8647
	/* Format a date object into a string value.
8648
	 * The format can be combinations of the following:
8649
	 * d  - day of month (no leading zero)
8650
	 * dd - day of month (two digit)
8651
	 * o  - day of year (no leading zeros)
8652
	 * oo - day of year (three digit)
8653
	 * D  - day name short
8654
	 * DD - day name long
8655
	 * m  - month of year (no leading zero)
8656
	 * mm - month of year (two digit)
8657
	 * M  - month name short
8658
	 * MM - month name long
8659
	 * y  - year (two digit)
8660
	 * yy - year (four digit)
8661
	 * @ - Unix timestamp (ms since 01/01/1970)
8662
	 * ! - Windows ticks (100ns since 01/01/0001)
8663
	 * "..." - literal text
8664
	 * '' - single quote
8665
	 *
8666
	 * @param  format string - the desired format of the date
8667
	 * @param  date Date - the date value to format
8668
	 * @param  settings Object - attributes include:
8669
	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
8670
	 *					dayNames		string[7] - names of the days from Sunday (optional)
8671
	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
8672
	 *					monthNames		string[12] - names of the months (optional)
8673
	 * @return  string - the date in the above format
8674
	 */
8675
	formatDate: function( format, date, settings ) {
8676
		if ( !date ) {
8677
			return "";
8678
		}
8679
 
8680
		var iFormat,
8681
			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
8682
			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
8683
			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
8684
			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
8685
 
8686
			// Check whether a format character is doubled
8687
			lookAhead = function( match ) {
8688
				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8689
				if ( matches ) {
8690
					iFormat++;
8691
				}
8692
				return matches;
8693
			},
8694
 
8695
			// Format a number, with leading zero if necessary
8696
			formatNumber = function( match, value, len ) {
8697
				var num = "" + value;
8698
				if ( lookAhead( match ) ) {
8699
					while ( num.length < len ) {
8700
						num = "0" + num;
8701
					}
8702
				}
8703
				return num;
8704
			},
8705
 
8706
			// Format a name, short or long as requested
8707
			formatName = function( match, value, shortNames, longNames ) {
8708
				return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] );
8709
			},
8710
			output = "",
8711
			literal = false;
8712
 
8713
		if ( date ) {
8714
			for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8715
				if ( literal ) {
8716
					if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8717
						literal = false;
8718
					} else {
8719
						output += format.charAt( iFormat );
8720
					}
8721
				} else {
8722
					switch ( format.charAt( iFormat ) ) {
8723
						case "d":
8724
							output += formatNumber( "d", date.getDate(), 2 );
8725
							break;
8726
						case "D":
8727
							output += formatName( "D", date.getDay(), dayNamesShort, dayNames );
8728
							break;
8729
						case "o":
8730
							output += formatNumber( "o",
8731
								Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 );
8732
							break;
8733
						case "m":
8734
							output += formatNumber( "m", date.getMonth() + 1, 2 );
8735
							break;
8736
						case "M":
8737
							output += formatName( "M", date.getMonth(), monthNamesShort, monthNames );
8738
							break;
8739
						case "y":
8740
							output += ( lookAhead( "y" ) ? date.getFullYear() :
8741
								( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 );
8742
							break;
8743
						case "@":
8744
							output += date.getTime();
8745
							break;
8746
						case "!":
8747
							output += date.getTime() * 10000 + this._ticksTo1970;
8748
							break;
8749
						case "'":
8750
							if ( lookAhead( "'" ) ) {
8751
								output += "'";
8752
							} else {
8753
								literal = true;
8754
							}
8755
							break;
8756
						default:
8757
							output += format.charAt( iFormat );
8758
					}
8759
				}
8760
			}
8761
		}
8762
		return output;
8763
	},
8764
 
8765
	/* Extract all possible characters from the date format. */
8766
	_possibleChars: function( format ) {
8767
		var iFormat,
8768
			chars = "",
8769
			literal = false,
8770
 
8771
			// Check whether a format character is doubled
8772
			lookAhead = function( match ) {
8773
				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8774
				if ( matches ) {
8775
					iFormat++;
8776
				}
8777
				return matches;
8778
			};
8779
 
8780
		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8781
			if ( literal ) {
8782
				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8783
					literal = false;
8784
				} else {
8785
					chars += format.charAt( iFormat );
8786
				}
8787
			} else {
8788
				switch ( format.charAt( iFormat ) ) {
8789
					case "d": case "m": case "y": case "@":
8790
						chars += "0123456789";
8791
						break;
8792
					case "D": case "M":
8793
						return null; // Accept anything
8794
					case "'":
8795
						if ( lookAhead( "'" ) ) {
8796
							chars += "'";
8797
						} else {
8798
							literal = true;
8799
						}
8800
						break;
8801
					default:
8802
						chars += format.charAt( iFormat );
8803
				}
8804
			}
8805
		}
8806
		return chars;
8807
	},
8808
 
8809
	/* Get a setting value, defaulting if necessary. */
8810
	_get: function( inst, name ) {
8811
		return inst.settings[ name ] !== undefined ?
8812
			inst.settings[ name ] : this._defaults[ name ];
8813
	},
8814
 
8815
	/* Parse existing date and initialise date picker. */
8816
	_setDateFromField: function( inst, noDefault ) {
8817
		if ( inst.input.val() === inst.lastVal ) {
8818
			return;
8819
		}
8820
 
8821
		var dateFormat = this._get( inst, "dateFormat" ),
8822
			dates = inst.lastVal = inst.input ? inst.input.val() : null,
8823
			defaultDate = this._getDefaultDate( inst ),
8824
			date = defaultDate,
8825
			settings = this._getFormatConfig( inst );
8826
 
8827
		try {
8828
			date = this.parseDate( dateFormat, dates, settings ) || defaultDate;
8829
		} catch ( event ) {
8830
			dates = ( noDefault ? "" : dates );
8831
		}
8832
		inst.selectedDay = date.getDate();
8833
		inst.drawMonth = inst.selectedMonth = date.getMonth();
8834
		inst.drawYear = inst.selectedYear = date.getFullYear();
8835
		inst.currentDay = ( dates ? date.getDate() : 0 );
8836
		inst.currentMonth = ( dates ? date.getMonth() : 0 );
8837
		inst.currentYear = ( dates ? date.getFullYear() : 0 );
8838
		this._adjustInstDate( inst );
8839
	},
8840
 
8841
	/* Retrieve the default date shown on opening. */
8842
	_getDefaultDate: function( inst ) {
8843
		return this._restrictMinMax( inst,
8844
			this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) );
8845
	},
8846
 
8847
	/* A date may be specified as an exact value or a relative one. */
8848
	_determineDate: function( inst, date, defaultDate ) {
8849
		var offsetNumeric = function( offset ) {
8850
				var date = new Date();
8851
				date.setDate( date.getDate() + offset );
8852
				return date;
8853
			},
8854
			offsetString = function( offset ) {
8855
				try {
8856
					return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
8857
						offset, $.datepicker._getFormatConfig( inst ) );
8858
				} catch ( e ) {
8859
 
8860
					// Ignore
8861
				}
8862
 
8863
				var date = ( offset.toLowerCase().match( /^c/ ) ?
8864
					$.datepicker._getDate( inst ) : null ) || new Date(),
8865
					year = date.getFullYear(),
8866
					month = date.getMonth(),
8867
					day = date.getDate(),
8868
					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
8869
					matches = pattern.exec( offset );
8870
 
8871
				while ( matches ) {
8872
					switch ( matches[ 2 ] || "d" ) {
8873
						case "d" : case "D" :
8874
							day += parseInt( matches[ 1 ], 10 ); break;
8875
						case "w" : case "W" :
8876
							day += parseInt( matches[ 1 ], 10 ) * 7; break;
8877
						case "m" : case "M" :
8878
							month += parseInt( matches[ 1 ], 10 );
8879
							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
8880
							break;
8881
						case "y": case "Y" :
8882
							year += parseInt( matches[ 1 ], 10 );
8883
							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
8884
							break;
8885
					}
8886
					matches = pattern.exec( offset );
8887
				}
8888
				return new Date( year, month, day );
8889
			},
8890
			newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) :
8891
				( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) );
8892
 
8893
		newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate );
8894
		if ( newDate ) {
8895
			newDate.setHours( 0 );
8896
			newDate.setMinutes( 0 );
8897
			newDate.setSeconds( 0 );
8898
			newDate.setMilliseconds( 0 );
8899
		}
8900
		return this._daylightSavingAdjust( newDate );
8901
	},
8902
 
8903
	/* Handle switch to/from daylight saving.
8904
	 * Hours may be non-zero on daylight saving cut-over:
8905
	 * > 12 when midnight changeover, but then cannot generate
8906
	 * midnight datetime, so jump to 1AM, otherwise reset.
8907
	 * @param  date  (Date) the date to check
8908
	 * @return  (Date) the corrected date
8909
	 */
8910
	_daylightSavingAdjust: function( date ) {
8911
		if ( !date ) {
8912
			return null;
8913
		}
8914
		date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 );
8915
		return date;
8916
	},
8917
 
8918
	/* Set the date(s) directly. */
8919
	_setDate: function( inst, date, noChange ) {
8920
		var clear = !date,
8921
			origMonth = inst.selectedMonth,
8922
			origYear = inst.selectedYear,
8923
			newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) );
8924
 
8925
		inst.selectedDay = inst.currentDay = newDate.getDate();
8926
		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
8927
		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
8928
		if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) {
8929
			this._notifyChange( inst );
8930
		}
8931
		this._adjustInstDate( inst );
8932
		if ( inst.input ) {
8933
			inst.input.val( clear ? "" : this._formatDate( inst ) );
8934
		}
8935
	},
8936
 
8937
	/* Retrieve the date(s) directly. */
8938
	_getDate: function( inst ) {
8939
		var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null :
8940
			this._daylightSavingAdjust( new Date(
8941
			inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
8942
			return startDate;
8943
	},
8944
 
8945
	/* Attach the onxxx handlers.  These are declared statically so
8946
	 * they work with static code transformers like Caja.
8947
	 */
8948
	_attachHandlers: function( inst ) {
8949
		var stepMonths = this._get( inst, "stepMonths" ),
8950
			id = "#" + inst.id.replace( /\\\\/g, "\\" );
8951
		inst.dpDiv.find( "[data-handler]" ).map( function() {
8952
			var handler = {
8953
				prev: function() {
8954
					$.datepicker._adjustDate( id, -stepMonths, "M" );
8955
				},
8956
				next: function() {
8957
					$.datepicker._adjustDate( id, +stepMonths, "M" );
8958
				},
8959
				hide: function() {
8960
					$.datepicker._hideDatepicker();
8961
				},
8962
				today: function() {
8963
					$.datepicker._gotoToday( id );
8964
				},
8965
				selectDay: function() {
8966
					$.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this );
8967
					return false;
8968
				},
8969
				selectMonth: function() {
8970
					$.datepicker._selectMonthYear( id, this, "M" );
8971
					return false;
8972
				},
8973
				selectYear: function() {
8974
					$.datepicker._selectMonthYear( id, this, "Y" );
8975
					return false;
8976
				}
8977
			};
8978
			$( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] );
8979
		} );
8980
	},
8981
 
8982
	/* Generate the HTML for the current state of the date picker. */
8983
	_generateHTML: function( inst ) {
8984
		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
8985
			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
8986
			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
8987
			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
8988
			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
8989
			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
8990
			tempDate = new Date(),
8991
			today = this._daylightSavingAdjust(
8992
				new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time
8993
			isRTL = this._get( inst, "isRTL" ),
8994
			showButtonPanel = this._get( inst, "showButtonPanel" ),
8995
			hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ),
8996
			navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ),
8997
			numMonths = this._getNumberOfMonths( inst ),
8998
			showCurrentAtPos = this._get( inst, "showCurrentAtPos" ),
8999
			stepMonths = this._get( inst, "stepMonths" ),
9000
			isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ),
9001
			currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) :
9002
				new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ),
9003
			minDate = this._getMinMaxDate( inst, "min" ),
9004
			maxDate = this._getMinMaxDate( inst, "max" ),
9005
			drawMonth = inst.drawMonth - showCurrentAtPos,
9006
			drawYear = inst.drawYear;
9007
 
9008
		if ( drawMonth < 0 ) {
9009
			drawMonth += 12;
9010
			drawYear--;
9011
		}
9012
		if ( maxDate ) {
9013
			maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(),
9014
				maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) );
9015
			maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw );
9016
			while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) {
9017
				drawMonth--;
9018
				if ( drawMonth < 0 ) {
9019
					drawMonth = 11;
9020
					drawYear--;
9021
				}
9022
			}
9023
		}
9024
		inst.drawMonth = drawMonth;
9025
		inst.drawYear = drawYear;
9026
 
9027
		prevText = this._get( inst, "prevText" );
9028
		prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText,
9029
			this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ),
9030
			this._getFormatConfig( inst ) ) );
9031
 
9032
		if ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ) {
9033
			prev = $( "<a>" )
9034
				.attr( {
9035
					"class": "ui-datepicker-prev ui-corner-all",
9036
					"data-handler": "prev",
9037
					"data-event": "click",
9038
					title: prevText
9039
				} )
9040
				.append(
9041
					$( "<span>" )
9042
						.addClass( "ui-icon ui-icon-circle-triangle-" +
9043
							( isRTL ? "e" : "w" ) )
9044
						.text( prevText )
9045
				)[ 0 ].outerHTML;
9046
		} else if ( hideIfNoPrevNext ) {
9047
			prev = "";
9048
		} else {
9049
			prev = $( "<a>" )
9050
				.attr( {
9051
					"class": "ui-datepicker-prev ui-corner-all ui-state-disabled",
9052
					title: prevText
9053
				} )
9054
				.append(
9055
					$( "<span>" )
9056
						.addClass( "ui-icon ui-icon-circle-triangle-" +
9057
							( isRTL ? "e" : "w" ) )
9058
						.text( prevText )
9059
				)[ 0 ].outerHTML;
9060
		}
9061
 
9062
		nextText = this._get( inst, "nextText" );
9063
		nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText,
9064
			this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ),
9065
			this._getFormatConfig( inst ) ) );
9066
 
9067
		if ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ) {
9068
			next = $( "<a>" )
9069
				.attr( {
9070
					"class": "ui-datepicker-next ui-corner-all",
9071
					"data-handler": "next",
9072
					"data-event": "click",
9073
					title: nextText
9074
				} )
9075
				.append(
9076
					$( "<span>" )
9077
						.addClass( "ui-icon ui-icon-circle-triangle-" +
9078
							( isRTL ? "w" : "e" ) )
9079
						.text( nextText )
9080
				)[ 0 ].outerHTML;
9081
		} else if ( hideIfNoPrevNext ) {
9082
			next = "";
9083
		} else {
9084
			next = $( "<a>" )
9085
				.attr( {
9086
					"class": "ui-datepicker-next ui-corner-all ui-state-disabled",
9087
					title: nextText
9088
				} )
9089
				.append(
9090
					$( "<span>" )
9091
						.attr( "class", "ui-icon ui-icon-circle-triangle-" +
9092
							( isRTL ? "w" : "e" ) )
9093
						.text( nextText )
9094
				)[ 0 ].outerHTML;
9095
		}
9096
 
9097
		currentText = this._get( inst, "currentText" );
9098
		gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today );
9099
		currentText = ( !navigationAsDateFormat ? currentText :
9100
			this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) );
9101
 
9102
		controls = "";
9103
		if ( !inst.inline ) {
9104
			controls = $( "<button>" )
9105
				.attr( {
9106
					type: "button",
9107
					"class": "ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all",
9108
					"data-handler": "hide",
9109
					"data-event": "click"
9110
				} )
9111
				.text( this._get( inst, "closeText" ) )[ 0 ].outerHTML;
9112
		}
9113
 
9114
		buttonPanel = "";
9115
		if ( showButtonPanel ) {
9116
			buttonPanel = $( "<div class='ui-datepicker-buttonpane ui-widget-content'>" )
9117
				.append( isRTL ? controls : "" )
9118
				.append( this._isInRange( inst, gotoDate ) ?
9119
					$( "<button>" )
9120
						.attr( {
9121
							type: "button",
9122
							"class": "ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all",
9123
							"data-handler": "today",
9124
							"data-event": "click"
9125
						} )
9126
						.text( currentText ) :
9127
					"" )
9128
				.append( isRTL ? "" : controls )[ 0 ].outerHTML;
9129
		}
9130
 
9131
		firstDay = parseInt( this._get( inst, "firstDay" ), 10 );
9132
		firstDay = ( isNaN( firstDay ) ? 0 : firstDay );
9133
 
9134
		showWeek = this._get( inst, "showWeek" );
9135
		dayNames = this._get( inst, "dayNames" );
9136
		dayNamesMin = this._get( inst, "dayNamesMin" );
9137
		monthNames = this._get( inst, "monthNames" );
9138
		monthNamesShort = this._get( inst, "monthNamesShort" );
9139
		beforeShowDay = this._get( inst, "beforeShowDay" );
9140
		showOtherMonths = this._get( inst, "showOtherMonths" );
9141
		selectOtherMonths = this._get( inst, "selectOtherMonths" );
9142
		defaultDate = this._getDefaultDate( inst );
9143
		html = "";
9144
 
9145
		for ( row = 0; row < numMonths[ 0 ]; row++ ) {
9146
			group = "";
9147
			this.maxRows = 4;
9148
			for ( col = 0; col < numMonths[ 1 ]; col++ ) {
9149
				selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) );
9150
				cornerClass = " ui-corner-all";
9151
				calender = "";
9152
				if ( isMultiMonth ) {
9153
					calender += "<div class='ui-datepicker-group";
9154
					if ( numMonths[ 1 ] > 1 ) {
9155
						switch ( col ) {
9156
							case 0: calender += " ui-datepicker-group-first";
9157
								cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break;
9158
							case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last";
9159
								cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break;
9160
							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
9161
						}
9162
					}
9163
					calender += "'>";
9164
				}
9165
				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
9166
					( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) +
9167
					( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) +
9168
					this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate,
9169
					row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers
9170
					"</div><table class='ui-datepicker-calendar'><thead>" +
9171
					"<tr>";
9172
				thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" );
9173
				for ( dow = 0; dow < 7; dow++ ) { // days of the week
9174
					day = ( dow + firstDay ) % 7;
9175
					thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" +
9176
						"<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>";
9177
				}
9178
				calender += thead + "</tr></thead><tbody>";
9179
				daysInMonth = this._getDaysInMonth( drawYear, drawMonth );
9180
				if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) {
9181
					inst.selectedDay = Math.min( inst.selectedDay, daysInMonth );
9182
				}
9183
				leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7;
9184
				curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate
9185
				numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043)
9186
				this.maxRows = numRows;
9187
				printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) );
9188
				for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows
9189
					calender += "<tr>";
9190
					tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
9191
						this._get( inst, "calculateWeek" )( printDate ) + "</td>" );
9192
					for ( dow = 0; dow < 7; dow++ ) { // create date picker days
9193
						daySettings = ( beforeShowDay ?
9194
							beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] );
9195
						otherMonth = ( printDate.getMonth() !== drawMonth );
9196
						unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] ||
9197
							( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate );
9198
						tbody += "<td class='" +
9199
							( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends
9200
							( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months
9201
							( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key
9202
							( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ?
9203
 
9204
							// or defaultDate is current printedDate and defaultDate is selectedDate
9205
							" " + this._dayOverClass : "" ) + // highlight selected day
9206
							( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) +  // highlight unselectable days
9207
							( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates
9208
							( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day
9209
							( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different)
9210
							( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "&#39;" ) + "'" : "" ) + // cell title
9211
							( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions
9212
							( otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
9213
							( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
9214
							( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) +
9215
							( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day
9216
							( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months
9217
							"' href='#' aria-current='" + ( printDate.getTime() === currentDate.getTime() ? "true" : "false" ) + // mark date as selected for screen reader
9218
							"' data-date='" + printDate.getDate() + // store date as data
9219
							"'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date
9220
						printDate.setDate( printDate.getDate() + 1 );
9221
						printDate = this._daylightSavingAdjust( printDate );
9222
					}
9223
					calender += tbody + "</tr>";
9224
				}
9225
				drawMonth++;
9226
				if ( drawMonth > 11 ) {
9227
					drawMonth = 0;
9228
					drawYear++;
9229
				}
9230
				calender += "</tbody></table>" + ( isMultiMonth ? "</div>" +
9231
							( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" );
9232
				group += calender;
9233
			}
9234
			html += group;
9235
		}
9236
		html += buttonPanel;
9237
		inst._keyEvent = false;
9238
		return html;
9239
	},
9240
 
9241
	/* Generate the month and year header. */
9242
	_generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate,
9243
			secondary, monthNames, monthNamesShort ) {
9244
 
9245
		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
9246
			changeMonth = this._get( inst, "changeMonth" ),
9247
			changeYear = this._get( inst, "changeYear" ),
9248
			showMonthAfterYear = this._get( inst, "showMonthAfterYear" ),
9249
			selectMonthLabel = this._get( inst, "selectMonthLabel" ),
9250
			selectYearLabel = this._get( inst, "selectYearLabel" ),
9251
			html = "<div class='ui-datepicker-title'>",
9252
			monthHtml = "";
9253
 
9254
		// Month selection
9255
		if ( secondary || !changeMonth ) {
9256
			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>";
9257
		} else {
9258
			inMinYear = ( minDate && minDate.getFullYear() === drawYear );
9259
			inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear );
9260
			monthHtml += "<select class='ui-datepicker-month' aria-label='" + selectMonthLabel + "' data-handler='selectMonth' data-event='change'>";
9261
			for ( month = 0; month < 12; month++ ) {
9262
				if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) {
9263
					monthHtml += "<option value='" + month + "'" +
9264
						( month === drawMonth ? " selected='selected'" : "" ) +
9265
						">" + monthNamesShort[ month ] + "</option>";
9266
				}
9267
			}
9268
			monthHtml += "</select>";
9269
		}
9270
 
9271
		if ( !showMonthAfterYear ) {
9272
			html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" );
9273
		}
9274
 
9275
		// Year selection
9276
		if ( !inst.yearshtml ) {
9277
			inst.yearshtml = "";
9278
			if ( secondary || !changeYear ) {
9279
				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
9280
			} else {
9281
 
9282
				// determine range of years to display
9283
				years = this._get( inst, "yearRange" ).split( ":" );
9284
				thisYear = new Date().getFullYear();
9285
				determineYear = function( value ) {
9286
					var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) :
9287
						( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) :
9288
						parseInt( value, 10 ) ) );
9289
					return ( isNaN( year ) ? thisYear : year );
9290
				};
9291
				year = determineYear( years[ 0 ] );
9292
				endYear = Math.max( year, determineYear( years[ 1 ] || "" ) );
9293
				year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year );
9294
				endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear );
9295
				inst.yearshtml += "<select class='ui-datepicker-year' aria-label='" + selectYearLabel + "' data-handler='selectYear' data-event='change'>";
9296
				for ( ; year <= endYear; year++ ) {
9297
					inst.yearshtml += "<option value='" + year + "'" +
9298
						( year === drawYear ? " selected='selected'" : "" ) +
9299
						">" + year + "</option>";
9300
				}
9301
				inst.yearshtml += "</select>";
9302
 
9303
				html += inst.yearshtml;
9304
				inst.yearshtml = null;
9305
			}
9306
		}
9307
 
9308
		html += this._get( inst, "yearSuffix" );
9309
		if ( showMonthAfterYear ) {
9310
			html += ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" ) + monthHtml;
9311
		}
9312
		html += "</div>"; // Close datepicker_header
9313
		return html;
9314
	},
9315
 
9316
	/* Adjust one of the date sub-fields. */
9317
	_adjustInstDate: function( inst, offset, period ) {
9318
		var year = inst.selectedYear + ( period === "Y" ? offset : 0 ),
9319
			month = inst.selectedMonth + ( period === "M" ? offset : 0 ),
9320
			day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ),
9321
			date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) );
9322
 
9323
		inst.selectedDay = date.getDate();
9324
		inst.drawMonth = inst.selectedMonth = date.getMonth();
9325
		inst.drawYear = inst.selectedYear = date.getFullYear();
9326
		if ( period === "M" || period === "Y" ) {
9327
			this._notifyChange( inst );
9328
		}
9329
	},
9330
 
9331
	/* Ensure a date is within any min/max bounds. */
9332
	_restrictMinMax: function( inst, date ) {
9333
		var minDate = this._getMinMaxDate( inst, "min" ),
9334
			maxDate = this._getMinMaxDate( inst, "max" ),
9335
			newDate = ( minDate && date < minDate ? minDate : date );
9336
		return ( maxDate && newDate > maxDate ? maxDate : newDate );
9337
	},
9338
 
9339
	/* Notify change of month/year. */
9340
	_notifyChange: function( inst ) {
9341
		var onChange = this._get( inst, "onChangeMonthYear" );
9342
		if ( onChange ) {
9343
			onChange.apply( ( inst.input ? inst.input[ 0 ] : null ),
9344
				[ inst.selectedYear, inst.selectedMonth + 1, inst ] );
9345
		}
9346
	},
9347
 
9348
	/* Determine the number of months to show. */
9349
	_getNumberOfMonths: function( inst ) {
9350
		var numMonths = this._get( inst, "numberOfMonths" );
9351
		return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) );
9352
	},
9353
 
9354
	/* Determine the current maximum date - ensure no time components are set. */
9355
	_getMinMaxDate: function( inst, minMax ) {
9356
		return this._determineDate( inst, this._get( inst, minMax + "Date" ), null );
9357
	},
9358
 
9359
	/* Find the number of days in a given month. */
9360
	_getDaysInMonth: function( year, month ) {
9361
		return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate();
9362
	},
9363
 
9364
	/* Find the day of the week of the first of a month. */
9365
	_getFirstDayOfMonth: function( year, month ) {
9366
		return new Date( year, month, 1 ).getDay();
9367
	},
9368
 
9369
	/* Determines if we should allow a "next/prev" month display change. */
9370
	_canAdjustMonth: function( inst, offset, curYear, curMonth ) {
9371
		var numMonths = this._getNumberOfMonths( inst ),
9372
			date = this._daylightSavingAdjust( new Date( curYear,
9373
			curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) );
9374
 
9375
		if ( offset < 0 ) {
9376
			date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) );
9377
		}
9378
		return this._isInRange( inst, date );
9379
	},
9380
 
9381
	/* Is the given date in the accepted range? */
9382
	_isInRange: function( inst, date ) {
9383
		var yearSplit, currentYear,
9384
			minDate = this._getMinMaxDate( inst, "min" ),
9385
			maxDate = this._getMinMaxDate( inst, "max" ),
9386
			minYear = null,
9387
			maxYear = null,
9388
			years = this._get( inst, "yearRange" );
9389
			if ( years ) {
9390
				yearSplit = years.split( ":" );
9391
				currentYear = new Date().getFullYear();
9392
				minYear = parseInt( yearSplit[ 0 ], 10 );
9393
				maxYear = parseInt( yearSplit[ 1 ], 10 );
9394
				if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) {
9395
					minYear += currentYear;
9396
				}
9397
				if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) {
9398
					maxYear += currentYear;
9399
				}
9400
			}
9401
 
9402
		return ( ( !minDate || date.getTime() >= minDate.getTime() ) &&
9403
			( !maxDate || date.getTime() <= maxDate.getTime() ) &&
9404
			( !minYear || date.getFullYear() >= minYear ) &&
9405
			( !maxYear || date.getFullYear() <= maxYear ) );
9406
	},
9407
 
9408
	/* Provide the configuration settings for formatting/parsing. */
9409
	_getFormatConfig: function( inst ) {
9410
		var shortYearCutoff = this._get( inst, "shortYearCutoff" );
9411
		shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff :
9412
			new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) );
9413
		return { shortYearCutoff: shortYearCutoff,
9414
			dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ),
9415
			monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) };
9416
	},
9417
 
9418
	/* Format the given date for display. */
9419
	_formatDate: function( inst, day, month, year ) {
9420
		if ( !day ) {
9421
			inst.currentDay = inst.selectedDay;
9422
			inst.currentMonth = inst.selectedMonth;
9423
			inst.currentYear = inst.selectedYear;
9424
		}
9425
		var date = ( day ? ( typeof day === "object" ? day :
9426
			this._daylightSavingAdjust( new Date( year, month, day ) ) ) :
9427
			this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
9428
		return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) );
9429
	}
9430
} );
9431
 
9432
/*
9433
 * Bind hover events for datepicker elements.
9434
 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9435
 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9436
 */
9437
function datepicker_bindHover( dpDiv ) {
9438
	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
9439
	return dpDiv.on( "mouseout", selector, function() {
9440
			$( this ).removeClass( "ui-state-hover" );
9441
			if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
9442
				$( this ).removeClass( "ui-datepicker-prev-hover" );
9443
			}
9444
			if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
9445
				$( this ).removeClass( "ui-datepicker-next-hover" );
9446
			}
9447
		} )
9448
		.on( "mouseover", selector, datepicker_handleMouseover );
9449
}
9450
 
9451
function datepicker_handleMouseover() {
9452
	if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) {
9453
		$( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" );
9454
		$( this ).addClass( "ui-state-hover" );
9455
		if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
9456
			$( this ).addClass( "ui-datepicker-prev-hover" );
9457
		}
9458
		if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
9459
			$( this ).addClass( "ui-datepicker-next-hover" );
9460
		}
9461
	}
9462
}
9463
 
9464
/* jQuery extend now ignores nulls! */
9465
function datepicker_extendRemove( target, props ) {
9466
	$.extend( target, props );
9467
	for ( var name in props ) {
9468
		if ( props[ name ] == null ) {
9469
			target[ name ] = props[ name ];
9470
		}
9471
	}
9472
	return target;
9473
}
9474
 
9475
/* Invoke the datepicker functionality.
9476
   @param  options  string - a command, optionally followed by additional parameters or
9477
					Object - settings for attaching new datepicker functionality
9478
   @return  jQuery object */
9479
$.fn.datepicker = function( options ) {
9480
 
9481
	/* Verify an empty collection wasn't passed - Fixes #6976 */
9482
	if ( !this.length ) {
9483
		return this;
9484
	}
9485
 
9486
	/* Initialise the date picker. */
9487
	if ( !$.datepicker.initialized ) {
9488
		$( document ).on( "mousedown", $.datepicker._checkExternalClick );
9489
		$.datepicker.initialized = true;
9490
	}
9491
 
9492
	/* Append datepicker main container to body if not exist. */
9493
	if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) {
9494
		$( "body" ).append( $.datepicker.dpDiv );
9495
	}
9496
 
9497
	var otherArgs = Array.prototype.slice.call( arguments, 1 );
9498
	if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) {
9499
		return $.datepicker[ "_" + options + "Datepicker" ].
9500
			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
9501
	}
9502
	if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) {
9503
		return $.datepicker[ "_" + options + "Datepicker" ].
9504
			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
9505
	}
9506
	return this.each( function() {
9507
		if ( typeof options === "string" ) {
9508
			$.datepicker[ "_" + options + "Datepicker" ]
9509
				.apply( $.datepicker, [ this ].concat( otherArgs ) );
9510
		} else {
9511
			$.datepicker._attachDatepicker( this, options );
9512
		}
9513
	} );
9514
};
9515
 
9516
$.datepicker = new Datepicker(); // singleton instance
9517
$.datepicker.initialized = false;
9518
$.datepicker.uuid = new Date().getTime();
9519
$.datepicker.version = "1.13.2";
9520
 
9521
var widgetsDatepicker = $.datepicker;
9522
 
9523
 
9524
 
9525
// This file is deprecated
9526
var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
9527
 
9528
/*!
9529
 * jQuery UI Mouse 1.13.2
9530
 * http://jqueryui.com
9531
 *
9532
 * Copyright jQuery Foundation and other contributors
9533
 * Released under the MIT license.
9534
 * http://jquery.org/license
9535
 */
9536
 
9537
//>>label: Mouse
9538
//>>group: Widgets
9539
//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
9540
//>>docs: http://api.jqueryui.com/mouse/
9541
 
9542
 
9543
var mouseHandled = false;
9544
$( document ).on( "mouseup", function() {
9545
	mouseHandled = false;
9546
} );
9547
 
9548
var widgetsMouse = $.widget( "ui.mouse", {
9549
	version: "1.13.2",
9550
	options: {
9551
		cancel: "input, textarea, button, select, option",
9552
		distance: 1,
9553
		delay: 0
9554
	},
9555
	_mouseInit: function() {
9556
		var that = this;
9557
 
9558
		this.element
9559
			.on( "mousedown." + this.widgetName, function( event ) {
9560
				return that._mouseDown( event );
9561
			} )
9562
			.on( "click." + this.widgetName, function( event ) {
9563
				if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
9564
					$.removeData( event.target, that.widgetName + ".preventClickEvent" );
9565
					event.stopImmediatePropagation();
9566
					return false;
9567
				}
9568
			} );
9569
 
9570
		this.started = false;
9571
	},
9572
 
9573
	// TODO: make sure destroying one instance of mouse doesn't mess with
9574
	// other instances of mouse
9575
	_mouseDestroy: function() {
9576
		this.element.off( "." + this.widgetName );
9577
		if ( this._mouseMoveDelegate ) {
9578
			this.document
9579
				.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9580
				.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
9581
		}
9582
	},
9583
 
9584
	_mouseDown: function( event ) {
9585
 
9586
		// don't let more than one widget handle mouseStart
9587
		if ( mouseHandled ) {
9588
			return;
9589
		}
9590
 
9591
		this._mouseMoved = false;
9592
 
9593
		// We may have missed mouseup (out of window)
9594
		if ( this._mouseStarted ) {
9595
			this._mouseUp( event );
9596
		}
9597
 
9598
		this._mouseDownEvent = event;
9599
 
9600
		var that = this,
9601
			btnIsLeft = ( event.which === 1 ),
9602
 
9603
			// event.target.nodeName works around a bug in IE 8 with
9604
			// disabled inputs (#7620)
9605
			elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
9606
				$( event.target ).closest( this.options.cancel ).length : false );
9607
		if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
9608
			return true;
9609
		}
9610
 
9611
		this.mouseDelayMet = !this.options.delay;
9612
		if ( !this.mouseDelayMet ) {
9613
			this._mouseDelayTimer = setTimeout( function() {
9614
				that.mouseDelayMet = true;
9615
			}, this.options.delay );
9616
		}
9617
 
9618
		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
9619
			this._mouseStarted = ( this._mouseStart( event ) !== false );
9620
			if ( !this._mouseStarted ) {
9621
				event.preventDefault();
9622
				return true;
9623
			}
9624
		}
9625
 
9626
		// Click event may never have fired (Gecko & Opera)
9627
		if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
9628
			$.removeData( event.target, this.widgetName + ".preventClickEvent" );
9629
		}
9630
 
9631
		// These delegates are required to keep context
9632
		this._mouseMoveDelegate = function( event ) {
9633
			return that._mouseMove( event );
9634
		};
9635
		this._mouseUpDelegate = function( event ) {
9636
			return that._mouseUp( event );
9637
		};
9638
 
9639
		this.document
9640
			.on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9641
			.on( "mouseup." + this.widgetName, this._mouseUpDelegate );
9642
 
9643
		event.preventDefault();
9644
 
9645
		mouseHandled = true;
9646
		return true;
9647
	},
9648
 
9649
	_mouseMove: function( event ) {
9650
 
9651
		// Only check for mouseups outside the document if you've moved inside the document
9652
		// at least once. This prevents the firing of mouseup in the case of IE<9, which will
9653
		// fire a mousemove event if content is placed under the cursor. See #7778
9654
		// Support: IE <9
9655
		if ( this._mouseMoved ) {
9656
 
9657
			// IE mouseup check - mouseup happened when mouse was out of window
9658
			if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
9659
					!event.button ) {
9660
				return this._mouseUp( event );
9661
 
9662
			// Iframe mouseup check - mouseup occurred in another document
9663
			} else if ( !event.which ) {
9664
 
9665
				// Support: Safari <=8 - 9
9666
				// Safari sets which to 0 if you press any of the following keys
9667
				// during a drag (#14461)
9668
				if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
9669
						event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
9670
					this.ignoreMissingWhich = true;
9671
				} else if ( !this.ignoreMissingWhich ) {
9672
					return this._mouseUp( event );
9673
				}
9674
			}
9675
		}
9676
 
9677
		if ( event.which || event.button ) {
9678
			this._mouseMoved = true;
9679
		}
9680
 
9681
		if ( this._mouseStarted ) {
9682
			this._mouseDrag( event );
9683
			return event.preventDefault();
9684
		}
9685
 
9686
		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
9687
			this._mouseStarted =
9688
				( this._mouseStart( this._mouseDownEvent, event ) !== false );
9689
			if ( this._mouseStarted ) {
9690
				this._mouseDrag( event );
9691
			} else {
9692
				this._mouseUp( event );
9693
			}
9694
		}
9695
 
9696
		return !this._mouseStarted;
9697
	},
9698
 
9699
	_mouseUp: function( event ) {
9700
		this.document
9701
			.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9702
			.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
9703
 
9704
		if ( this._mouseStarted ) {
9705
			this._mouseStarted = false;
9706
 
9707
			if ( event.target === this._mouseDownEvent.target ) {
9708
				$.data( event.target, this.widgetName + ".preventClickEvent", true );
9709
			}
9710
 
9711
			this._mouseStop( event );
9712
		}
9713
 
9714
		if ( this._mouseDelayTimer ) {
9715
			clearTimeout( this._mouseDelayTimer );
9716
			delete this._mouseDelayTimer;
9717
		}
9718
 
9719
		this.ignoreMissingWhich = false;
9720
		mouseHandled = false;
9721
		event.preventDefault();
9722
	},
9723
 
9724
	_mouseDistanceMet: function( event ) {
9725
		return ( Math.max(
9726
				Math.abs( this._mouseDownEvent.pageX - event.pageX ),
9727
				Math.abs( this._mouseDownEvent.pageY - event.pageY )
9728
			) >= this.options.distance
9729
		);
9730
	},
9731
 
9732
	_mouseDelayMet: function( /* event */ ) {
9733
		return this.mouseDelayMet;
9734
	},
9735
 
9736
	// These are placeholder methods, to be overriden by extending plugin
9737
	_mouseStart: function( /* event */ ) {},
9738
	_mouseDrag: function( /* event */ ) {},
9739
	_mouseStop: function( /* event */ ) {},
9740
	_mouseCapture: function( /* event */ ) {
9741
		return true;
9742
	}
9743
} );
9744
 
9745
 
9746
 
9747
// $.ui.plugin is deprecated. Use $.widget() extensions instead.
9748
var plugin = $.ui.plugin = {
9749
	add: function( module, option, set ) {
9750
		var i,
9751
			proto = $.ui[ module ].prototype;
9752
		for ( i in set ) {
9753
			proto.plugins[ i ] = proto.plugins[ i ] || [];
9754
			proto.plugins[ i ].push( [ option, set[ i ] ] );
9755
		}
9756
	},
9757
	call: function( instance, name, args, allowDisconnected ) {
9758
		var i,
9759
			set = instance.plugins[ name ];
9760
 
9761
		if ( !set ) {
9762
			return;
9763
		}
9764
 
9765
		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
9766
				instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
9767
			return;
9768
		}
9769
 
9770
		for ( i = 0; i < set.length; i++ ) {
9771
			if ( instance.options[ set[ i ][ 0 ] ] ) {
9772
				set[ i ][ 1 ].apply( instance.element, args );
9773
			}
9774
		}
9775
	}
9776
};
9777
 
9778
 
9779
 
9780
var safeBlur = $.ui.safeBlur = function( element ) {
9781
 
9782
	// Support: IE9 - 10 only
9783
	// If the <body> is blurred, IE will switch windows, see #9420
9784
	if ( element && element.nodeName.toLowerCase() !== "body" ) {
9785
		$( element ).trigger( "blur" );
9786
	}
9787
};
9788
 
9789
 
9790
/*!
9791
 * jQuery UI Draggable 1.13.2
9792
 * http://jqueryui.com
9793
 *
9794
 * Copyright jQuery Foundation and other contributors
9795
 * Released under the MIT license.
9796
 * http://jquery.org/license
9797
 */
9798
 
9799
//>>label: Draggable
9800
//>>group: Interactions
9801
//>>description: Enables dragging functionality for any element.
9802
//>>docs: http://api.jqueryui.com/draggable/
9803
//>>demos: http://jqueryui.com/draggable/
9804
//>>css.structure: ../../themes/base/draggable.css
9805
 
9806
 
9807
$.widget( "ui.draggable", $.ui.mouse, {
9808
	version: "1.13.2",
9809
	widgetEventPrefix: "drag",
9810
	options: {
9811
		addClasses: true,
9812
		appendTo: "parent",
9813
		axis: false,
9814
		connectToSortable: false,
9815
		containment: false,
9816
		cursor: "auto",
9817
		cursorAt: false,
9818
		grid: false,
9819
		handle: false,
9820
		helper: "original",
9821
		iframeFix: false,
9822
		opacity: false,
9823
		refreshPositions: false,
9824
		revert: false,
9825
		revertDuration: 500,
9826
		scope: "default",
9827
		scroll: true,
9828
		scrollSensitivity: 20,
9829
		scrollSpeed: 20,
9830
		snap: false,
9831
		snapMode: "both",
9832
		snapTolerance: 20,
9833
		stack: false,
9834
		zIndex: false,
9835
 
9836
		// Callbacks
9837
		drag: null,
9838
		start: null,
9839
		stop: null
9840
	},
9841
	_create: function() {
9842
 
9843
		if ( this.options.helper === "original" ) {
9844
			this._setPositionRelative();
9845
		}
9846
		if ( this.options.addClasses ) {
9847
			this._addClass( "ui-draggable" );
9848
		}
9849
		this._setHandleClassName();
9850
 
9851
		this._mouseInit();
9852
	},
9853
 
9854
	_setOption: function( key, value ) {
9855
		this._super( key, value );
9856
		if ( key === "handle" ) {
9857
			this._removeHandleClassName();
9858
			this._setHandleClassName();
9859
		}
9860
	},
9861
 
9862
	_destroy: function() {
9863
		if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
9864
			this.destroyOnClear = true;
9865
			return;
9866
		}
9867
		this._removeHandleClassName();
9868
		this._mouseDestroy();
9869
	},
9870
 
9871
	_mouseCapture: function( event ) {
9872
		var o = this.options;
9873
 
9874
		// Among others, prevent a drag on a resizable-handle
9875
		if ( this.helper || o.disabled ||
9876
				$( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
9877
			return false;
9878
		}
9879
 
9880
		//Quit if we're not on a valid handle
9881
		this.handle = this._getHandle( event );
9882
		if ( !this.handle ) {
9883
			return false;
9884
		}
9885
 
9886
		this._blurActiveElement( event );
9887
 
9888
		this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
9889
 
9890
		return true;
9891
 
9892
	},
9893
 
9894
	_blockFrames: function( selector ) {
9895
		this.iframeBlocks = this.document.find( selector ).map( function() {
9896
			var iframe = $( this );
9897
 
9898
			return $( "<div>" )
9899
				.css( "position", "absolute" )
9900
				.appendTo( iframe.parent() )
9901
				.outerWidth( iframe.outerWidth() )
9902
				.outerHeight( iframe.outerHeight() )
9903
				.offset( iframe.offset() )[ 0 ];
9904
		} );
9905
	},
9906
 
9907
	_unblockFrames: function() {
9908
		if ( this.iframeBlocks ) {
9909
			this.iframeBlocks.remove();
9910
			delete this.iframeBlocks;
9911
		}
9912
	},
9913
 
9914
	_blurActiveElement: function( event ) {
9915
		var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
9916
			target = $( event.target );
9917
 
9918
		// Don't blur if the event occurred on an element that is within
9919
		// the currently focused element
9920
		// See #10527, #12472
9921
		if ( target.closest( activeElement ).length ) {
9922
			return;
9923
		}
9924
 
9925
		// Blur any element that currently has focus, see #4261
9926
		$.ui.safeBlur( activeElement );
9927
	},
9928
 
9929
	_mouseStart: function( event ) {
9930
 
9931
		var o = this.options;
9932
 
9933
		//Create and append the visible helper
9934
		this.helper = this._createHelper( event );
9935
 
9936
		this._addClass( this.helper, "ui-draggable-dragging" );
9937
 
9938
		//Cache the helper size
9939
		this._cacheHelperProportions();
9940
 
9941
		//If ddmanager is used for droppables, set the global draggable
9942
		if ( $.ui.ddmanager ) {
9943
			$.ui.ddmanager.current = this;
9944
		}
9945
 
9946
		/*
9947
		 * - Position generation -
9948
		 * This block generates everything position related - it's the core of draggables.
9949
		 */
9950
 
9951
		//Cache the margins of the original element
9952
		this._cacheMargins();
9953
 
9954
		//Store the helper's css position
9955
		this.cssPosition = this.helper.css( "position" );
9956
		this.scrollParent = this.helper.scrollParent( true );
9957
		this.offsetParent = this.helper.offsetParent();
9958
		this.hasFixedAncestor = this.helper.parents().filter( function() {
9959
				return $( this ).css( "position" ) === "fixed";
9960
			} ).length > 0;
9961
 
9962
		//The element's absolute position on the page minus margins
9963
		this.positionAbs = this.element.offset();
9964
		this._refreshOffsets( event );
9965
 
9966
		//Generate the original position
9967
		this.originalPosition = this.position = this._generatePosition( event, false );
9968
		this.originalPageX = event.pageX;
9969
		this.originalPageY = event.pageY;
9970
 
9971
		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
9972
		if ( o.cursorAt ) {
9973
			this._adjustOffsetFromHelper( o.cursorAt );
9974
		}
9975
 
9976
		//Set a containment if given in the options
9977
		this._setContainment();
9978
 
9979
		//Trigger event + callbacks
9980
		if ( this._trigger( "start", event ) === false ) {
9981
			this._clear();
9982
			return false;
9983
		}
9984
 
9985
		//Recache the helper size
9986
		this._cacheHelperProportions();
9987
 
9988
		//Prepare the droppable offsets
9989
		if ( $.ui.ddmanager && !o.dropBehaviour ) {
9990
			$.ui.ddmanager.prepareOffsets( this, event );
9991
		}
9992
 
9993
		// Execute the drag once - this causes the helper not to be visible before getting its
9994
		// correct position
9995
		this._mouseDrag( event, true );
9996
 
9997
		// If the ddmanager is used for droppables, inform the manager that dragging has started
9998
		// (see #5003)
9999
		if ( $.ui.ddmanager ) {
10000
			$.ui.ddmanager.dragStart( this, event );
10001
		}
10002
 
10003
		return true;
10004
	},
10005
 
10006
	_refreshOffsets: function( event ) {
10007
		this.offset = {
10008
			top: this.positionAbs.top - this.margins.top,
10009
			left: this.positionAbs.left - this.margins.left,
10010
			scroll: false,
10011
			parent: this._getParentOffset(),
10012
			relative: this._getRelativeOffset()
10013
		};
10014
 
10015
		this.offset.click = {
10016
			left: event.pageX - this.offset.left,
10017
			top: event.pageY - this.offset.top
10018
		};
10019
	},
10020
 
10021
	_mouseDrag: function( event, noPropagation ) {
10022
 
10023
		// reset any necessary cached properties (see #5009)
10024
		if ( this.hasFixedAncestor ) {
10025
			this.offset.parent = this._getParentOffset();
10026
		}
10027
 
10028
		//Compute the helpers position
10029
		this.position = this._generatePosition( event, true );
10030
		this.positionAbs = this._convertPositionTo( "absolute" );
10031
 
10032
		//Call plugins and callbacks and use the resulting position if something is returned
10033
		if ( !noPropagation ) {
10034
			var ui = this._uiHash();
10035
			if ( this._trigger( "drag", event, ui ) === false ) {
10036
				this._mouseUp( new $.Event( "mouseup", event ) );
10037
				return false;
10038
			}
10039
			this.position = ui.position;
10040
		}
10041
 
10042
		this.helper[ 0 ].style.left = this.position.left + "px";
10043
		this.helper[ 0 ].style.top = this.position.top + "px";
10044
 
10045
		if ( $.ui.ddmanager ) {
10046
			$.ui.ddmanager.drag( this, event );
10047
		}
10048
 
10049
		return false;
10050
	},
10051
 
10052
	_mouseStop: function( event ) {
10053
 
10054
		//If we are using droppables, inform the manager about the drop
10055
		var that = this,
10056
			dropped = false;
10057
		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
10058
			dropped = $.ui.ddmanager.drop( this, event );
10059
		}
10060
 
10061
		//if a drop comes from outside (a sortable)
10062
		if ( this.dropped ) {
10063
			dropped = this.dropped;
10064
			this.dropped = false;
10065
		}
10066
 
10067
		if ( ( this.options.revert === "invalid" && !dropped ) ||
10068
				( this.options.revert === "valid" && dropped ) ||
10069
				this.options.revert === true || ( typeof this.options.revert === "function" &&
10070
				this.options.revert.call( this.element, dropped ) )
10071
		) {
10072
			$( this.helper ).animate(
10073
				this.originalPosition,
10074
				parseInt( this.options.revertDuration, 10 ),
10075
				function() {
10076
					if ( that._trigger( "stop", event ) !== false ) {
10077
						that._clear();
10078
					}
10079
				}
10080
			);
10081
		} else {
10082
			if ( this._trigger( "stop", event ) !== false ) {
10083
				this._clear();
10084
			}
10085
		}
10086
 
10087
		return false;
10088
	},
10089
 
10090
	_mouseUp: function( event ) {
10091
		this._unblockFrames();
10092
 
10093
		// If the ddmanager is used for droppables, inform the manager that dragging has stopped
10094
		// (see #5003)
10095
		if ( $.ui.ddmanager ) {
10096
			$.ui.ddmanager.dragStop( this, event );
10097
		}
10098
 
10099
		// Only need to focus if the event occurred on the draggable itself, see #10527
10100
		if ( this.handleElement.is( event.target ) ) {
10101
 
10102
			// The interaction is over; whether or not the click resulted in a drag,
10103
			// focus the element
10104
			this.element.trigger( "focus" );
10105
		}
10106
 
10107
		return $.ui.mouse.prototype._mouseUp.call( this, event );
10108
	},
10109
 
10110
	cancel: function() {
10111
 
10112
		if ( this.helper.is( ".ui-draggable-dragging" ) ) {
10113
			this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
10114
		} else {
10115
			this._clear();
10116
		}
10117
 
10118
		return this;
10119
 
10120
	},
10121
 
10122
	_getHandle: function( event ) {
10123
		return this.options.handle ?
10124
			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
10125
			true;
10126
	},
10127
 
10128
	_setHandleClassName: function() {
10129
		this.handleElement = this.options.handle ?
10130
			this.element.find( this.options.handle ) : this.element;
10131
		this._addClass( this.handleElement, "ui-draggable-handle" );
10132
	},
10133
 
10134
	_removeHandleClassName: function() {
10135
		this._removeClass( this.handleElement, "ui-draggable-handle" );
10136
	},
10137
 
10138
	_createHelper: function( event ) {
10139
 
10140
		var o = this.options,
10141
			helperIsFunction = typeof o.helper === "function",
10142
			helper = helperIsFunction ?
10143
				$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
10144
				( o.helper === "clone" ?
10145
					this.element.clone().removeAttr( "id" ) :
10146
					this.element );
10147
 
10148
		if ( !helper.parents( "body" ).length ) {
10149
			helper.appendTo( ( o.appendTo === "parent" ?
10150
				this.element[ 0 ].parentNode :
10151
				o.appendTo ) );
10152
		}
10153
 
10154
		// Http://bugs.jqueryui.com/ticket/9446
10155
		// a helper function can return the original element
10156
		// which wouldn't have been set to relative in _create
10157
		if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
10158
			this._setPositionRelative();
10159
		}
10160
 
10161
		if ( helper[ 0 ] !== this.element[ 0 ] &&
10162
				!( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
10163
			helper.css( "position", "absolute" );
10164
		}
10165
 
10166
		return helper;
10167
 
10168
	},
10169
 
10170
	_setPositionRelative: function() {
10171
		if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
10172
			this.element[ 0 ].style.position = "relative";
10173
		}
10174
	},
10175
 
10176
	_adjustOffsetFromHelper: function( obj ) {
10177
		if ( typeof obj === "string" ) {
10178
			obj = obj.split( " " );
10179
		}
10180
		if ( Array.isArray( obj ) ) {
10181
			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
10182
		}
10183
		if ( "left" in obj ) {
10184
			this.offset.click.left = obj.left + this.margins.left;
10185
		}
10186
		if ( "right" in obj ) {
10187
			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
10188
		}
10189
		if ( "top" in obj ) {
10190
			this.offset.click.top = obj.top + this.margins.top;
10191
		}
10192
		if ( "bottom" in obj ) {
10193
			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
10194
		}
10195
	},
10196
 
10197
	_isRootNode: function( element ) {
10198
		return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
10199
	},
10200
 
10201
	_getParentOffset: function() {
10202
 
10203
		//Get the offsetParent and cache its position
10204
		var po = this.offsetParent.offset(),
10205
			document = this.document[ 0 ];
10206
 
10207
		// This is a special case where we need to modify a offset calculated on start, since the
10208
		// following happened:
10209
		// 1. The position of the helper is absolute, so it's position is calculated based on the
10210
		// next positioned parent
10211
		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
10212
		// the document, which means that the scroll is included in the initial calculation of the
10213
		// offset of the parent, and never recalculated upon drag
10214
		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
10215
				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
10216
			po.left += this.scrollParent.scrollLeft();
10217
			po.top += this.scrollParent.scrollTop();
10218
		}
10219
 
10220
		if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
10221
			po = { top: 0, left: 0 };
10222
		}
10223
 
10224
		return {
10225
			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
10226
			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
10227
		};
10228
 
10229
	},
10230
 
10231
	_getRelativeOffset: function() {
10232
		if ( this.cssPosition !== "relative" ) {
10233
			return { top: 0, left: 0 };
10234
		}
10235
 
10236
		var p = this.element.position(),
10237
			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
10238
 
10239
		return {
10240
			top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
10241
				( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
10242
			left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
10243
				( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
10244
		};
10245
 
10246
	},
10247
 
10248
	_cacheMargins: function() {
10249
		this.margins = {
10250
			left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
10251
			top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
10252
			right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
10253
			bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
10254
		};
10255
	},
10256
 
10257
	_cacheHelperProportions: function() {
10258
		this.helperProportions = {
10259
			width: this.helper.outerWidth(),
10260
			height: this.helper.outerHeight()
10261
		};
10262
	},
10263
 
10264
	_setContainment: function() {
10265
 
10266
		var isUserScrollable, c, ce,
10267
			o = this.options,
10268
			document = this.document[ 0 ];
10269
 
10270
		this.relativeContainer = null;
10271
 
10272
		if ( !o.containment ) {
10273
			this.containment = null;
10274
			return;
10275
		}
10276
 
10277
		if ( o.containment === "window" ) {
10278
			this.containment = [
10279
				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
10280
				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
10281
				$( window ).scrollLeft() + $( window ).width() -
10282
					this.helperProportions.width - this.margins.left,
10283
				$( window ).scrollTop() +
10284
					( $( window ).height() || document.body.parentNode.scrollHeight ) -
10285
					this.helperProportions.height - this.margins.top
10286
			];
10287
			return;
10288
		}
10289
 
10290
		if ( o.containment === "document" ) {
10291
			this.containment = [
10292
				0,
10293
				0,
10294
				$( document ).width() - this.helperProportions.width - this.margins.left,
10295
				( $( document ).height() || document.body.parentNode.scrollHeight ) -
10296
					this.helperProportions.height - this.margins.top
10297
			];
10298
			return;
10299
		}
10300
 
10301
		if ( o.containment.constructor === Array ) {
10302
			this.containment = o.containment;
10303
			return;
10304
		}
10305
 
10306
		if ( o.containment === "parent" ) {
10307
			o.containment = this.helper[ 0 ].parentNode;
10308
		}
10309
 
10310
		c = $( o.containment );
10311
		ce = c[ 0 ];
10312
 
10313
		if ( !ce ) {
10314
			return;
10315
		}
10316
 
10317
		isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
10318
 
10319
		this.containment = [
10320
			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
10321
				( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
10322
			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
10323
				( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
10324
			( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
10325
				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
10326
				( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
10327
				this.helperProportions.width -
10328
				this.margins.left -
10329
				this.margins.right,
10330
			( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
10331
				( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
10332
				( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
10333
				this.helperProportions.height -
10334
				this.margins.top -
10335
				this.margins.bottom
10336
		];
10337
		this.relativeContainer = c;
10338
	},
10339
 
10340
	_convertPositionTo: function( d, pos ) {
10341
 
10342
		if ( !pos ) {
10343
			pos = this.position;
10344
		}
10345
 
10346
		var mod = d === "absolute" ? 1 : -1,
10347
			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
10348
 
10349
		return {
10350
			top: (
10351
 
10352
				// The absolute mouse position
10353
				pos.top	+
10354
 
10355
				// Only for relative positioned nodes: Relative offset from element to offset parent
10356
				this.offset.relative.top * mod +
10357
 
10358
				// The offsetParent's offset without borders (offset + border)
10359
				this.offset.parent.top * mod -
10360
				( ( this.cssPosition === "fixed" ?
10361
					-this.offset.scroll.top :
10362
					( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
10363
			),
10364
			left: (
10365
 
10366
				// The absolute mouse position
10367
				pos.left +
10368
 
10369
				// Only for relative positioned nodes: Relative offset from element to offset parent
10370
				this.offset.relative.left * mod +
10371
 
10372
				// The offsetParent's offset without borders (offset + border)
10373
				this.offset.parent.left * mod	-
10374
				( ( this.cssPosition === "fixed" ?
10375
					-this.offset.scroll.left :
10376
					( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
10377
			)
10378
		};
10379
 
10380
	},
10381
 
10382
	_generatePosition: function( event, constrainPosition ) {
10383
 
10384
		var containment, co, top, left,
10385
			o = this.options,
10386
			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
10387
			pageX = event.pageX,
10388
			pageY = event.pageY;
10389
 
10390
		// Cache the scroll
10391
		if ( !scrollIsRootNode || !this.offset.scroll ) {
10392
			this.offset.scroll = {
10393
				top: this.scrollParent.scrollTop(),
10394
				left: this.scrollParent.scrollLeft()
10395
			};
10396
		}
10397
 
10398
		/*
10399
		 * - Position constraining -
10400
		 * Constrain the position to a mix of grid, containment.
10401
		 */
10402
 
10403
		// If we are not dragging yet, we won't check for options
10404
		if ( constrainPosition ) {
10405
			if ( this.containment ) {
10406
				if ( this.relativeContainer ) {
10407
					co = this.relativeContainer.offset();
10408
					containment = [
10409
						this.containment[ 0 ] + co.left,
10410
						this.containment[ 1 ] + co.top,
10411
						this.containment[ 2 ] + co.left,
10412
						this.containment[ 3 ] + co.top
10413
					];
10414
				} else {
10415
					containment = this.containment;
10416
				}
10417
 
10418
				if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
10419
					pageX = containment[ 0 ] + this.offset.click.left;
10420
				}
10421
				if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
10422
					pageY = containment[ 1 ] + this.offset.click.top;
10423
				}
10424
				if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
10425
					pageX = containment[ 2 ] + this.offset.click.left;
10426
				}
10427
				if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
10428
					pageY = containment[ 3 ] + this.offset.click.top;
10429
				}
10430
			}
10431
 
10432
			if ( o.grid ) {
10433
 
10434
				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid
10435
				// argument errors in IE (see ticket #6950)
10436
				top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
10437
					this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
10438
				pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
10439
					top - this.offset.click.top > containment[ 3 ] ) ?
10440
						top :
10441
						( ( top - this.offset.click.top >= containment[ 1 ] ) ?
10442
							top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
10443
 
10444
				left = o.grid[ 0 ] ? this.originalPageX +
10445
					Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
10446
					this.originalPageX;
10447
				pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
10448
					left - this.offset.click.left > containment[ 2 ] ) ?
10449
						left :
10450
						( ( left - this.offset.click.left >= containment[ 0 ] ) ?
10451
							left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
10452
			}
10453
 
10454
			if ( o.axis === "y" ) {
10455
				pageX = this.originalPageX;
10456
			}
10457
 
10458
			if ( o.axis === "x" ) {
10459
				pageY = this.originalPageY;
10460
			}
10461
		}
10462
 
10463
		return {
10464
			top: (
10465
 
10466
				// The absolute mouse position
10467
				pageY -
10468
 
10469
				// Click offset (relative to the element)
10470
				this.offset.click.top -
10471
 
10472
				// Only for relative positioned nodes: Relative offset from element to offset parent
10473
				this.offset.relative.top -
10474
 
10475
				// The offsetParent's offset without borders (offset + border)
10476
				this.offset.parent.top +
10477
				( this.cssPosition === "fixed" ?
10478
					-this.offset.scroll.top :
10479
					( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
10480
			),
10481
			left: (
10482
 
10483
				// The absolute mouse position
10484
				pageX -
10485
 
10486
				// Click offset (relative to the element)
10487
				this.offset.click.left -
10488
 
10489
				// Only for relative positioned nodes: Relative offset from element to offset parent
10490
				this.offset.relative.left -
10491
 
10492
				// The offsetParent's offset without borders (offset + border)
10493
				this.offset.parent.left +
10494
				( this.cssPosition === "fixed" ?
10495
					-this.offset.scroll.left :
10496
					( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
10497
			)
10498
		};
10499
 
10500
	},
10501
 
10502
	_clear: function() {
10503
		this._removeClass( this.helper, "ui-draggable-dragging" );
10504
		if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
10505
			this.helper.remove();
10506
		}
10507
		this.helper = null;
10508
		this.cancelHelperRemoval = false;
10509
		if ( this.destroyOnClear ) {
10510
			this.destroy();
10511
		}
10512
	},
10513
 
10514
	// From now on bulk stuff - mainly helpers
10515
 
10516
	_trigger: function( type, event, ui ) {
10517
		ui = ui || this._uiHash();
10518
		$.ui.plugin.call( this, type, [ event, ui, this ], true );
10519
 
10520
		// Absolute position and offset (see #6884 ) have to be recalculated after plugins
10521
		if ( /^(drag|start|stop)/.test( type ) ) {
10522
			this.positionAbs = this._convertPositionTo( "absolute" );
10523
			ui.offset = this.positionAbs;
10524
		}
10525
		return $.Widget.prototype._trigger.call( this, type, event, ui );
10526
	},
10527
 
10528
	plugins: {},
10529
 
10530
	_uiHash: function() {
10531
		return {
10532
			helper: this.helper,
10533
			position: this.position,
10534
			originalPosition: this.originalPosition,
10535
			offset: this.positionAbs
10536
		};
10537
	}
10538
 
10539
} );
10540
 
10541
$.ui.plugin.add( "draggable", "connectToSortable", {
10542
	start: function( event, ui, draggable ) {
10543
		var uiSortable = $.extend( {}, ui, {
10544
			item: draggable.element
10545
		} );
10546
 
10547
		draggable.sortables = [];
10548
		$( draggable.options.connectToSortable ).each( function() {
10549
			var sortable = $( this ).sortable( "instance" );
10550
 
10551
			if ( sortable && !sortable.options.disabled ) {
10552
				draggable.sortables.push( sortable );
10553
 
10554
				// RefreshPositions is called at drag start to refresh the containerCache
10555
				// which is used in drag. This ensures it's initialized and synchronized
10556
				// with any changes that might have happened on the page since initialization.
10557
				sortable.refreshPositions();
10558
				sortable._trigger( "activate", event, uiSortable );
10559
			}
10560
		} );
10561
	},
10562
	stop: function( event, ui, draggable ) {
10563
		var uiSortable = $.extend( {}, ui, {
10564
			item: draggable.element
10565
		} );
10566
 
10567
		draggable.cancelHelperRemoval = false;
10568
 
10569
		$.each( draggable.sortables, function() {
10570
			var sortable = this;
10571
 
10572
			if ( sortable.isOver ) {
10573
				sortable.isOver = 0;
10574
 
10575
				// Allow this sortable to handle removing the helper
10576
				draggable.cancelHelperRemoval = true;
10577
				sortable.cancelHelperRemoval = false;
10578
 
10579
				// Use _storedCSS To restore properties in the sortable,
10580
				// as this also handles revert (#9675) since the draggable
10581
				// may have modified them in unexpected ways (#8809)
10582
				sortable._storedCSS = {
10583
					position: sortable.placeholder.css( "position" ),
10584
					top: sortable.placeholder.css( "top" ),
10585
					left: sortable.placeholder.css( "left" )
10586
				};
10587
 
10588
				sortable._mouseStop( event );
10589
 
10590
				// Once drag has ended, the sortable should return to using
10591
				// its original helper, not the shared helper from draggable
10592
				sortable.options.helper = sortable.options._helper;
10593
			} else {
10594
 
10595
				// Prevent this Sortable from removing the helper.
10596
				// However, don't set the draggable to remove the helper
10597
				// either as another connected Sortable may yet handle the removal.
10598
				sortable.cancelHelperRemoval = true;
10599
 
10600
				sortable._trigger( "deactivate", event, uiSortable );
10601
			}
10602
		} );
10603
	},
10604
	drag: function( event, ui, draggable ) {
10605
		$.each( draggable.sortables, function() {
10606
			var innermostIntersecting = false,
10607
				sortable = this;
10608
 
10609
			// Copy over variables that sortable's _intersectsWith uses
10610
			sortable.positionAbs = draggable.positionAbs;
10611
			sortable.helperProportions = draggable.helperProportions;
10612
			sortable.offset.click = draggable.offset.click;
10613
 
10614
			if ( sortable._intersectsWith( sortable.containerCache ) ) {
10615
				innermostIntersecting = true;
10616
 
10617
				$.each( draggable.sortables, function() {
10618
 
10619
					// Copy over variables that sortable's _intersectsWith uses
10620
					this.positionAbs = draggable.positionAbs;
10621
					this.helperProportions = draggable.helperProportions;
10622
					this.offset.click = draggable.offset.click;
10623
 
10624
					if ( this !== sortable &&
10625
							this._intersectsWith( this.containerCache ) &&
10626
							$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
10627
						innermostIntersecting = false;
10628
					}
10629
 
10630
					return innermostIntersecting;
10631
				} );
10632
			}
10633
 
10634
			if ( innermostIntersecting ) {
10635
 
10636
				// If it intersects, we use a little isOver variable and set it once,
10637
				// so that the move-in stuff gets fired only once.
10638
				if ( !sortable.isOver ) {
10639
					sortable.isOver = 1;
10640
 
10641
					// Store draggable's parent in case we need to reappend to it later.
10642
					draggable._parent = ui.helper.parent();
10643
 
10644
					sortable.currentItem = ui.helper
10645
						.appendTo( sortable.element )
10646
						.data( "ui-sortable-item", true );
10647
 
10648
					// Store helper option to later restore it
10649
					sortable.options._helper = sortable.options.helper;
10650
 
10651
					sortable.options.helper = function() {
10652
						return ui.helper[ 0 ];
10653
					};
10654
 
10655
					// Fire the start events of the sortable with our passed browser event,
10656
					// and our own helper (so it doesn't create a new one)
10657
					event.target = sortable.currentItem[ 0 ];
10658
					sortable._mouseCapture( event, true );
10659
					sortable._mouseStart( event, true, true );
10660
 
10661
					// Because the browser event is way off the new appended portlet,
10662
					// modify necessary variables to reflect the changes
10663
					sortable.offset.click.top = draggable.offset.click.top;
10664
					sortable.offset.click.left = draggable.offset.click.left;
10665
					sortable.offset.parent.left -= draggable.offset.parent.left -
10666
						sortable.offset.parent.left;
10667
					sortable.offset.parent.top -= draggable.offset.parent.top -
10668
						sortable.offset.parent.top;
10669
 
10670
					draggable._trigger( "toSortable", event );
10671
 
10672
					// Inform draggable that the helper is in a valid drop zone,
10673
					// used solely in the revert option to handle "valid/invalid".
10674
					draggable.dropped = sortable.element;
10675
 
10676
					// Need to refreshPositions of all sortables in the case that
10677
					// adding to one sortable changes the location of the other sortables (#9675)
10678
					$.each( draggable.sortables, function() {
10679
						this.refreshPositions();
10680
					} );
10681
 
10682
					// Hack so receive/update callbacks work (mostly)
10683
					draggable.currentItem = draggable.element;
10684
					sortable.fromOutside = draggable;
10685
				}
10686
 
10687
				if ( sortable.currentItem ) {
10688
					sortable._mouseDrag( event );
10689
 
10690
					// Copy the sortable's position because the draggable's can potentially reflect
10691
					// a relative position, while sortable is always absolute, which the dragged
10692
					// element has now become. (#8809)
10693
					ui.position = sortable.position;
10694
				}
10695
			} else {
10696
 
10697
				// If it doesn't intersect with the sortable, and it intersected before,
10698
				// we fake the drag stop of the sortable, but make sure it doesn't remove
10699
				// the helper by using cancelHelperRemoval.
10700
				if ( sortable.isOver ) {
10701
 
10702
					sortable.isOver = 0;
10703
					sortable.cancelHelperRemoval = true;
10704
 
10705
					// Calling sortable's mouseStop would trigger a revert,
10706
					// so revert must be temporarily false until after mouseStop is called.
10707
					sortable.options._revert = sortable.options.revert;
10708
					sortable.options.revert = false;
10709
 
10710
					sortable._trigger( "out", event, sortable._uiHash( sortable ) );
10711
					sortable._mouseStop( event, true );
10712
 
10713
					// Restore sortable behaviors that were modfied
10714
					// when the draggable entered the sortable area (#9481)
10715
					sortable.options.revert = sortable.options._revert;
10716
					sortable.options.helper = sortable.options._helper;
10717
 
10718
					if ( sortable.placeholder ) {
10719
						sortable.placeholder.remove();
10720
					}
10721
 
10722
					// Restore and recalculate the draggable's offset considering the sortable
10723
					// may have modified them in unexpected ways. (#8809, #10669)
10724
					ui.helper.appendTo( draggable._parent );
10725
					draggable._refreshOffsets( event );
10726
					ui.position = draggable._generatePosition( event, true );
10727
 
10728
					draggable._trigger( "fromSortable", event );
10729
 
10730
					// Inform draggable that the helper is no longer in a valid drop zone
10731
					draggable.dropped = false;
10732
 
10733
					// Need to refreshPositions of all sortables just in case removing
10734
					// from one sortable changes the location of other sortables (#9675)
10735
					$.each( draggable.sortables, function() {
10736
						this.refreshPositions();
10737
					} );
10738
				}
10739
			}
10740
		} );
10741
	}
10742
} );
10743
 
10744
$.ui.plugin.add( "draggable", "cursor", {
10745
	start: function( event, ui, instance ) {
10746
		var t = $( "body" ),
10747
			o = instance.options;
10748
 
10749
		if ( t.css( "cursor" ) ) {
10750
			o._cursor = t.css( "cursor" );
10751
		}
10752
		t.css( "cursor", o.cursor );
10753
	},
10754
	stop: function( event, ui, instance ) {
10755
		var o = instance.options;
10756
		if ( o._cursor ) {
10757
			$( "body" ).css( "cursor", o._cursor );
10758
		}
10759
	}
10760
} );
10761
 
10762
$.ui.plugin.add( "draggable", "opacity", {
10763
	start: function( event, ui, instance ) {
10764
		var t = $( ui.helper ),
10765
			o = instance.options;
10766
		if ( t.css( "opacity" ) ) {
10767
			o._opacity = t.css( "opacity" );
10768
		}
10769
		t.css( "opacity", o.opacity );
10770
	},
10771
	stop: function( event, ui, instance ) {
10772
		var o = instance.options;
10773
		if ( o._opacity ) {
10774
			$( ui.helper ).css( "opacity", o._opacity );
10775
		}
10776
	}
10777
} );
10778
 
10779
$.ui.plugin.add( "draggable", "scroll", {
10780
	start: function( event, ui, i ) {
10781
		if ( !i.scrollParentNotHidden ) {
10782
			i.scrollParentNotHidden = i.helper.scrollParent( false );
10783
		}
10784
 
10785
		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
10786
				i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
10787
			i.overflowOffset = i.scrollParentNotHidden.offset();
10788
		}
10789
	},
10790
	drag: function( event, ui, i  ) {
10791
 
10792
		var o = i.options,
10793
			scrolled = false,
10794
			scrollParent = i.scrollParentNotHidden[ 0 ],
10795
			document = i.document[ 0 ];
10796
 
10797
		if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
10798
			if ( !o.axis || o.axis !== "x" ) {
10799
				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
10800
						o.scrollSensitivity ) {
10801
					scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
10802
				} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
10803
					scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
10804
				}
10805
			}
10806
 
10807
			if ( !o.axis || o.axis !== "y" ) {
10808
				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
10809
						o.scrollSensitivity ) {
10810
					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
10811
				} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
10812
					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
10813
				}
10814
			}
10815
 
10816
		} else {
10817
 
10818
			if ( !o.axis || o.axis !== "x" ) {
10819
				if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
10820
					scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
10821
				} else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
10822
						o.scrollSensitivity ) {
10823
					scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
10824
				}
10825
			}
10826
 
10827
			if ( !o.axis || o.axis !== "y" ) {
10828
				if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
10829
					scrolled = $( document ).scrollLeft(
10830
						$( document ).scrollLeft() - o.scrollSpeed
10831
					);
10832
				} else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
10833
						o.scrollSensitivity ) {
10834
					scrolled = $( document ).scrollLeft(
10835
						$( document ).scrollLeft() + o.scrollSpeed
10836
					);
10837
				}
10838
			}
10839
 
10840
		}
10841
 
10842
		if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
10843
			$.ui.ddmanager.prepareOffsets( i, event );
10844
		}
10845
 
10846
	}
10847
} );
10848
 
10849
$.ui.plugin.add( "draggable", "snap", {
10850
	start: function( event, ui, i ) {
10851
 
10852
		var o = i.options;
10853
 
10854
		i.snapElements = [];
10855
 
10856
		$( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
10857
			.each( function() {
10858
				var $t = $( this ),
10859
					$o = $t.offset();
10860
				if ( this !== i.element[ 0 ] ) {
10861
					i.snapElements.push( {
10862
						item: this,
10863
						width: $t.outerWidth(), height: $t.outerHeight(),
10864
						top: $o.top, left: $o.left
10865
					} );
10866
				}
10867
			} );
10868
 
10869
	},
10870
	drag: function( event, ui, inst ) {
10871
 
10872
		var ts, bs, ls, rs, l, r, t, b, i, first,
10873
			o = inst.options,
10874
			d = o.snapTolerance,
10875
			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
10876
			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
10877
 
10878
		for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
10879
 
10880
			l = inst.snapElements[ i ].left - inst.margins.left;
10881
			r = l + inst.snapElements[ i ].width;
10882
			t = inst.snapElements[ i ].top - inst.margins.top;
10883
			b = t + inst.snapElements[ i ].height;
10884
 
10885
			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
10886
					!$.contains( inst.snapElements[ i ].item.ownerDocument,
10887
					inst.snapElements[ i ].item ) ) {
10888
				if ( inst.snapElements[ i ].snapping ) {
10889
					if ( inst.options.snap.release ) {
10890
						inst.options.snap.release.call(
10891
							inst.element,
10892
							event,
10893
							$.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
10894
						);
10895
					}
10896
				}
10897
				inst.snapElements[ i ].snapping = false;
10898
				continue;
10899
			}
10900
 
10901
			if ( o.snapMode !== "inner" ) {
10902
				ts = Math.abs( t - y2 ) <= d;
10903
				bs = Math.abs( b - y1 ) <= d;
10904
				ls = Math.abs( l - x2 ) <= d;
10905
				rs = Math.abs( r - x1 ) <= d;
10906
				if ( ts ) {
10907
					ui.position.top = inst._convertPositionTo( "relative", {
10908
						top: t - inst.helperProportions.height,
10909
						left: 0
10910
					} ).top;
10911
				}
10912
				if ( bs ) {
10913
					ui.position.top = inst._convertPositionTo( "relative", {
10914
						top: b,
10915
						left: 0
10916
					} ).top;
10917
				}
10918
				if ( ls ) {
10919
					ui.position.left = inst._convertPositionTo( "relative", {
10920
						top: 0,
10921
						left: l - inst.helperProportions.width
10922
					} ).left;
10923
				}
10924
				if ( rs ) {
10925
					ui.position.left = inst._convertPositionTo( "relative", {
10926
						top: 0,
10927
						left: r
10928
					} ).left;
10929
				}
10930
			}
10931
 
10932
			first = ( ts || bs || ls || rs );
10933
 
10934
			if ( o.snapMode !== "outer" ) {
10935
				ts = Math.abs( t - y1 ) <= d;
10936
				bs = Math.abs( b - y2 ) <= d;
10937
				ls = Math.abs( l - x1 ) <= d;
10938
				rs = Math.abs( r - x2 ) <= d;
10939
				if ( ts ) {
10940
					ui.position.top = inst._convertPositionTo( "relative", {
10941
						top: t,
10942
						left: 0
10943
					} ).top;
10944
				}
10945
				if ( bs ) {
10946
					ui.position.top = inst._convertPositionTo( "relative", {
10947
						top: b - inst.helperProportions.height,
10948
						left: 0
10949
					} ).top;
10950
				}
10951
				if ( ls ) {
10952
					ui.position.left = inst._convertPositionTo( "relative", {
10953
						top: 0,
10954
						left: l
10955
					} ).left;
10956
				}
10957
				if ( rs ) {
10958
					ui.position.left = inst._convertPositionTo( "relative", {
10959
						top: 0,
10960
						left: r - inst.helperProportions.width
10961
					} ).left;
10962
				}
10963
			}
10964
 
10965
			if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
10966
				if ( inst.options.snap.snap ) {
10967
					inst.options.snap.snap.call(
10968
						inst.element,
10969
						event,
10970
						$.extend( inst._uiHash(), {
10971
							snapItem: inst.snapElements[ i ].item
10972
						} ) );
10973
				}
10974
			}
10975
			inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
10976
 
10977
		}
10978
 
10979
	}
10980
} );
10981
 
10982
$.ui.plugin.add( "draggable", "stack", {
10983
	start: function( event, ui, instance ) {
10984
		var min,
10985
			o = instance.options,
10986
			group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
10987
				return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
10988
					( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
10989
			} );
10990
 
10991
		if ( !group.length ) {
10992
			return;
10993
		}
10994
 
10995
		min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
10996
		$( group ).each( function( i ) {
10997
			$( this ).css( "zIndex", min + i );
10998
		} );
10999
		this.css( "zIndex", ( min + group.length ) );
11000
	}
11001
} );
11002
 
11003
$.ui.plugin.add( "draggable", "zIndex", {
11004
	start: function( event, ui, instance ) {
11005
		var t = $( ui.helper ),
11006
			o = instance.options;
11007
 
11008
		if ( t.css( "zIndex" ) ) {
11009
			o._zIndex = t.css( "zIndex" );
11010
		}
11011
		t.css( "zIndex", o.zIndex );
11012
	},
11013
	stop: function( event, ui, instance ) {
11014
		var o = instance.options;
11015
 
11016
		if ( o._zIndex ) {
11017
			$( ui.helper ).css( "zIndex", o._zIndex );
11018
		}
11019
	}
11020
} );
11021
 
11022
var widgetsDraggable = $.ui.draggable;
11023
 
11024
 
11025
/*!
11026
 * jQuery UI Resizable 1.13.2
11027
 * http://jqueryui.com
11028
 *
11029
 * Copyright jQuery Foundation and other contributors
11030
 * Released under the MIT license.
11031
 * http://jquery.org/license
11032
 */
11033
 
11034
//>>label: Resizable
11035
//>>group: Interactions
11036
//>>description: Enables resize functionality for any element.
11037
//>>docs: http://api.jqueryui.com/resizable/
11038
//>>demos: http://jqueryui.com/resizable/
11039
//>>css.structure: ../../themes/base/core.css
11040
//>>css.structure: ../../themes/base/resizable.css
11041
//>>css.theme: ../../themes/base/theme.css
11042
 
11043
 
11044
$.widget( "ui.resizable", $.ui.mouse, {
11045
	version: "1.13.2",
11046
	widgetEventPrefix: "resize",
11047
	options: {
11048
		alsoResize: false,
11049
		animate: false,
11050
		animateDuration: "slow",
11051
		animateEasing: "swing",
11052
		aspectRatio: false,
11053
		autoHide: false,
11054
		classes: {
11055
			"ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se"
11056
		},
11057
		containment: false,
11058
		ghost: false,
11059
		grid: false,
11060
		handles: "e,s,se",
11061
		helper: false,
11062
		maxHeight: null,
11063
		maxWidth: null,
11064
		minHeight: 10,
11065
		minWidth: 10,
11066
 
11067
		// See #7960
11068
		zIndex: 90,
11069
 
11070
		// Callbacks
11071
		resize: null,
11072
		start: null,
11073
		stop: null
11074
	},
11075
 
11076
	_num: function( value ) {
11077
		return parseFloat( value ) || 0;
11078
	},
11079
 
11080
	_isNumber: function( value ) {
11081
		return !isNaN( parseFloat( value ) );
11082
	},
11083
 
11084
	_hasScroll: function( el, a ) {
11085
 
11086
		if ( $( el ).css( "overflow" ) === "hidden" ) {
11087
			return false;
11088
		}
11089
 
11090
		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
11091
			has = false;
11092
 
11093
		if ( el[ scroll ] > 0 ) {
11094
			return true;
11095
		}
11096
 
11097
		// TODO: determine which cases actually cause this to happen
11098
		// if the element doesn't have the scroll set, see if it's possible to
11099
		// set the scroll
11100
		try {
11101
			el[ scroll ] = 1;
11102
			has = ( el[ scroll ] > 0 );
11103
			el[ scroll ] = 0;
11104
		} catch ( e ) {
11105
 
11106
			// `el` might be a string, then setting `scroll` will throw
11107
			// an error in strict mode; ignore it.
11108
		}
11109
		return has;
11110
	},
11111
 
11112
	_create: function() {
11113
 
11114
		var margins,
11115
			o = this.options,
11116
			that = this;
11117
		this._addClass( "ui-resizable" );
11118
 
11119
		$.extend( this, {
11120
			_aspectRatio: !!( o.aspectRatio ),
11121
			aspectRatio: o.aspectRatio,
11122
			originalElement: this.element,
11123
			_proportionallyResizeElements: [],
11124
			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
11125
		} );
11126
 
11127
		// Wrap the element if it cannot hold child nodes
11128
		if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) {
11129
 
11130
			this.element.wrap(
11131
				$( "<div class='ui-wrapper'></div>" ).css( {
11132
					overflow: "hidden",
11133
					position: this.element.css( "position" ),
11134
					width: this.element.outerWidth(),
11135
					height: this.element.outerHeight(),
11136
					top: this.element.css( "top" ),
11137
					left: this.element.css( "left" )
11138
				} )
11139
			);
11140
 
11141
			this.element = this.element.parent().data(
11142
				"ui-resizable", this.element.resizable( "instance" )
11143
			);
11144
 
11145
			this.elementIsWrapper = true;
11146
 
11147
			margins = {
11148
				marginTop: this.originalElement.css( "marginTop" ),
11149
				marginRight: this.originalElement.css( "marginRight" ),
11150
				marginBottom: this.originalElement.css( "marginBottom" ),
11151
				marginLeft: this.originalElement.css( "marginLeft" )
11152
			};
11153
 
11154
			this.element.css( margins );
11155
			this.originalElement.css( "margin", 0 );
11156
 
11157
			// support: Safari
11158
			// Prevent Safari textarea resize
11159
			this.originalResizeStyle = this.originalElement.css( "resize" );
11160
			this.originalElement.css( "resize", "none" );
11161
 
11162
			this._proportionallyResizeElements.push( this.originalElement.css( {
11163
				position: "static",
11164
				zoom: 1,
11165
				display: "block"
11166
			} ) );
11167
 
11168
			// Support: IE9
11169
			// avoid IE jump (hard set the margin)
11170
			this.originalElement.css( margins );
11171
 
11172
			this._proportionallyResize();
11173
		}
11174
 
11175
		this._setupHandles();
11176
 
11177
		if ( o.autoHide ) {
11178
			$( this.element )
11179
				.on( "mouseenter", function() {
11180
					if ( o.disabled ) {
11181
						return;
11182
					}
11183
					that._removeClass( "ui-resizable-autohide" );
11184
					that._handles.show();
11185
				} )
11186
				.on( "mouseleave", function() {
11187
					if ( o.disabled ) {
11188
						return;
11189
					}
11190
					if ( !that.resizing ) {
11191
						that._addClass( "ui-resizable-autohide" );
11192
						that._handles.hide();
11193
					}
11194
				} );
11195
		}
11196
 
11197
		this._mouseInit();
11198
	},
11199
 
11200
	_destroy: function() {
11201
 
11202
		this._mouseDestroy();
11203
		this._addedHandles.remove();
11204
 
11205
		var wrapper,
11206
			_destroy = function( exp ) {
11207
				$( exp )
11208
					.removeData( "resizable" )
11209
					.removeData( "ui-resizable" )
11210
					.off( ".resizable" );
11211
			};
11212
 
11213
		// TODO: Unwrap at same DOM position
11214
		if ( this.elementIsWrapper ) {
11215
			_destroy( this.element );
11216
			wrapper = this.element;
11217
			this.originalElement.css( {
11218
				position: wrapper.css( "position" ),
11219
				width: wrapper.outerWidth(),
11220
				height: wrapper.outerHeight(),
11221
				top: wrapper.css( "top" ),
11222
				left: wrapper.css( "left" )
11223
			} ).insertAfter( wrapper );
11224
			wrapper.remove();
11225
		}
11226
 
11227
		this.originalElement.css( "resize", this.originalResizeStyle );
11228
		_destroy( this.originalElement );
11229
 
11230
		return this;
11231
	},
11232
 
11233
	_setOption: function( key, value ) {
11234
		this._super( key, value );
11235
 
11236
		switch ( key ) {
11237
		case "handles":
11238
			this._removeHandles();
11239
			this._setupHandles();
11240
			break;
11241
		case "aspectRatio":
11242
			this._aspectRatio = !!value;
11243
			break;
11244
		default:
11245
			break;
11246
		}
11247
	},
11248
 
11249
	_setupHandles: function() {
11250
		var o = this.options, handle, i, n, hname, axis, that = this;
11251
		this.handles = o.handles ||
11252
			( !$( ".ui-resizable-handle", this.element ).length ?
11253
				"e,s,se" : {
11254
					n: ".ui-resizable-n",
11255
					e: ".ui-resizable-e",
11256
					s: ".ui-resizable-s",
11257
					w: ".ui-resizable-w",
11258
					se: ".ui-resizable-se",
11259
					sw: ".ui-resizable-sw",
11260
					ne: ".ui-resizable-ne",
11261
					nw: ".ui-resizable-nw"
11262
				} );
11263
 
11264
		this._handles = $();
11265
		this._addedHandles = $();
11266
		if ( this.handles.constructor === String ) {
11267
 
11268
			if ( this.handles === "all" ) {
11269
				this.handles = "n,e,s,w,se,sw,ne,nw";
11270
			}
11271
 
11272
			n = this.handles.split( "," );
11273
			this.handles = {};
11274
 
11275
			for ( i = 0; i < n.length; i++ ) {
11276
 
11277
				handle = String.prototype.trim.call( n[ i ] );
11278
				hname = "ui-resizable-" + handle;
11279
				axis = $( "<div>" );
11280
				this._addClass( axis, "ui-resizable-handle " + hname );
11281
 
11282
				axis.css( { zIndex: o.zIndex } );
11283
 
11284
				this.handles[ handle ] = ".ui-resizable-" + handle;
11285
				if ( !this.element.children( this.handles[ handle ] ).length ) {
11286
					this.element.append( axis );
11287
					this._addedHandles = this._addedHandles.add( axis );
11288
				}
11289
			}
11290
 
11291
		}
11292
 
11293
		this._renderAxis = function( target ) {
11294
 
11295
			var i, axis, padPos, padWrapper;
11296
 
11297
			target = target || this.element;
11298
 
11299
			for ( i in this.handles ) {
11300
 
11301
				if ( this.handles[ i ].constructor === String ) {
11302
					this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show();
11303
				} else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
11304
					this.handles[ i ] = $( this.handles[ i ] );
11305
					this._on( this.handles[ i ], { "mousedown": that._mouseDown } );
11306
				}
11307
 
11308
				if ( this.elementIsWrapper &&
11309
						this.originalElement[ 0 ]
11310
							.nodeName
11311
							.match( /^(textarea|input|select|button)$/i ) ) {
11312
					axis = $( this.handles[ i ], this.element );
11313
 
11314
					padWrapper = /sw|ne|nw|se|n|s/.test( i ) ?
11315
						axis.outerHeight() :
11316
						axis.outerWidth();
11317
 
11318
					padPos = [ "padding",
11319
						/ne|nw|n/.test( i ) ? "Top" :
11320
						/se|sw|s/.test( i ) ? "Bottom" :
11321
						/^e$/.test( i ) ? "Right" : "Left" ].join( "" );
11322
 
11323
					target.css( padPos, padWrapper );
11324
 
11325
					this._proportionallyResize();
11326
				}
11327
 
11328
				this._handles = this._handles.add( this.handles[ i ] );
11329
			}
11330
		};
11331
 
11332
		// TODO: make renderAxis a prototype function
11333
		this._renderAxis( this.element );
11334
 
11335
		this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
11336
		this._handles.disableSelection();
11337
 
11338
		this._handles.on( "mouseover", function() {
11339
			if ( !that.resizing ) {
11340
				if ( this.className ) {
11341
					axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i );
11342
				}
11343
				that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se";
11344
			}
11345
		} );
11346
 
11347
		if ( o.autoHide ) {
11348
			this._handles.hide();
11349
			this._addClass( "ui-resizable-autohide" );
11350
		}
11351
	},
11352
 
11353
	_removeHandles: function() {
11354
		this._addedHandles.remove();
11355
	},
11356
 
11357
	_mouseCapture: function( event ) {
11358
		var i, handle,
11359
			capture = false;
11360
 
11361
		for ( i in this.handles ) {
11362
			handle = $( this.handles[ i ] )[ 0 ];
11363
			if ( handle === event.target || $.contains( handle, event.target ) ) {
11364
				capture = true;
11365
			}
11366
		}
11367
 
11368
		return !this.options.disabled && capture;
11369
	},
11370
 
11371
	_mouseStart: function( event ) {
11372
 
11373
		var curleft, curtop, cursor,
11374
			o = this.options,
11375
			el = this.element;
11376
 
11377
		this.resizing = true;
11378
 
11379
		this._renderProxy();
11380
 
11381
		curleft = this._num( this.helper.css( "left" ) );
11382
		curtop = this._num( this.helper.css( "top" ) );
11383
 
11384
		if ( o.containment ) {
11385
			curleft += $( o.containment ).scrollLeft() || 0;
11386
			curtop += $( o.containment ).scrollTop() || 0;
11387
		}
11388
 
11389
		this.offset = this.helper.offset();
11390
		this.position = { left: curleft, top: curtop };
11391
 
11392
		this.size = this._helper ? {
11393
				width: this.helper.width(),
11394
				height: this.helper.height()
11395
			} : {
11396
				width: el.width(),
11397
				height: el.height()
11398
			};
11399
 
11400
		this.originalSize = this._helper ? {
11401
				width: el.outerWidth(),
11402
				height: el.outerHeight()
11403
			} : {
11404
				width: el.width(),
11405
				height: el.height()
11406
			};
11407
 
11408
		this.sizeDiff = {
11409
			width: el.outerWidth() - el.width(),
11410
			height: el.outerHeight() - el.height()
11411
		};
11412
 
11413
		this.originalPosition = { left: curleft, top: curtop };
11414
		this.originalMousePosition = { left: event.pageX, top: event.pageY };
11415
 
11416
		this.aspectRatio = ( typeof o.aspectRatio === "number" ) ?
11417
			o.aspectRatio :
11418
			( ( this.originalSize.width / this.originalSize.height ) || 1 );
11419
 
11420
		cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" );
11421
		$( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor );
11422
 
11423
		this._addClass( "ui-resizable-resizing" );
11424
		this._propagate( "start", event );
11425
		return true;
11426
	},
11427
 
11428
	_mouseDrag: function( event ) {
11429
 
11430
		var data, props,
11431
			smp = this.originalMousePosition,
11432
			a = this.axis,
11433
			dx = ( event.pageX - smp.left ) || 0,
11434
			dy = ( event.pageY - smp.top ) || 0,
11435
			trigger = this._change[ a ];
11436
 
11437
		this._updatePrevProperties();
11438
 
11439
		if ( !trigger ) {
11440
			return false;
11441
		}
11442
 
11443
		data = trigger.apply( this, [ event, dx, dy ] );
11444
 
11445
		this._updateVirtualBoundaries( event.shiftKey );
11446
		if ( this._aspectRatio || event.shiftKey ) {
11447
			data = this._updateRatio( data, event );
11448
		}
11449
 
11450
		data = this._respectSize( data, event );
11451
 
11452
		this._updateCache( data );
11453
 
11454
		this._propagate( "resize", event );
11455
 
11456
		props = this._applyChanges();
11457
 
11458
		if ( !this._helper && this._proportionallyResizeElements.length ) {
11459
			this._proportionallyResize();
11460
		}
11461
 
11462
		if ( !$.isEmptyObject( props ) ) {
11463
			this._updatePrevProperties();
11464
			this._trigger( "resize", event, this.ui() );
11465
			this._applyChanges();
11466
		}
11467
 
11468
		return false;
11469
	},
11470
 
11471
	_mouseStop: function( event ) {
11472
 
11473
		this.resizing = false;
11474
		var pr, ista, soffseth, soffsetw, s, left, top,
11475
			o = this.options, that = this;
11476
 
11477
		if ( this._helper ) {
11478
 
11479
			pr = this._proportionallyResizeElements;
11480
			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName );
11481
			soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height;
11482
			soffsetw = ista ? 0 : that.sizeDiff.width;
11483
 
11484
			s = {
11485
				width: ( that.helper.width()  - soffsetw ),
11486
				height: ( that.helper.height() - soffseth )
11487
			};
11488
			left = ( parseFloat( that.element.css( "left" ) ) +
11489
				( that.position.left - that.originalPosition.left ) ) || null;
11490
			top = ( parseFloat( that.element.css( "top" ) ) +
11491
				( that.position.top - that.originalPosition.top ) ) || null;
11492
 
11493
			if ( !o.animate ) {
11494
				this.element.css( $.extend( s, { top: top, left: left } ) );
11495
			}
11496
 
11497
			that.helper.height( that.size.height );
11498
			that.helper.width( that.size.width );
11499
 
11500
			if ( this._helper && !o.animate ) {
11501
				this._proportionallyResize();
11502
			}
11503
		}
11504
 
11505
		$( "body" ).css( "cursor", "auto" );
11506
 
11507
		this._removeClass( "ui-resizable-resizing" );
11508
 
11509
		this._propagate( "stop", event );
11510
 
11511
		if ( this._helper ) {
11512
			this.helper.remove();
11513
		}
11514
 
11515
		return false;
11516
 
11517
	},
11518
 
11519
	_updatePrevProperties: function() {
11520
		this.prevPosition = {
11521
			top: this.position.top,
11522
			left: this.position.left
11523
		};
11524
		this.prevSize = {
11525
			width: this.size.width,
11526
			height: this.size.height
11527
		};
11528
	},
11529
 
11530
	_applyChanges: function() {
11531
		var props = {};
11532
 
11533
		if ( this.position.top !== this.prevPosition.top ) {
11534
			props.top = this.position.top + "px";
11535
		}
11536
		if ( this.position.left !== this.prevPosition.left ) {
11537
			props.left = this.position.left + "px";
11538
		}
11539
		if ( this.size.width !== this.prevSize.width ) {
11540
			props.width = this.size.width + "px";
11541
		}
11542
		if ( this.size.height !== this.prevSize.height ) {
11543
			props.height = this.size.height + "px";
11544
		}
11545
 
11546
		this.helper.css( props );
11547
 
11548
		return props;
11549
	},
11550
 
11551
	_updateVirtualBoundaries: function( forceAspectRatio ) {
11552
		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
11553
			o = this.options;
11554
 
11555
		b = {
11556
			minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0,
11557
			maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity,
11558
			minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0,
11559
			maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity
11560
		};
11561
 
11562
		if ( this._aspectRatio || forceAspectRatio ) {
11563
			pMinWidth = b.minHeight * this.aspectRatio;
11564
			pMinHeight = b.minWidth / this.aspectRatio;
11565
			pMaxWidth = b.maxHeight * this.aspectRatio;
11566
			pMaxHeight = b.maxWidth / this.aspectRatio;
11567
 
11568
			if ( pMinWidth > b.minWidth ) {
11569
				b.minWidth = pMinWidth;
11570
			}
11571
			if ( pMinHeight > b.minHeight ) {
11572
				b.minHeight = pMinHeight;
11573
			}
11574
			if ( pMaxWidth < b.maxWidth ) {
11575
				b.maxWidth = pMaxWidth;
11576
			}
11577
			if ( pMaxHeight < b.maxHeight ) {
11578
				b.maxHeight = pMaxHeight;
11579
			}
11580
		}
11581
		this._vBoundaries = b;
11582
	},
11583
 
11584
	_updateCache: function( data ) {
11585
		this.offset = this.helper.offset();
11586
		if ( this._isNumber( data.left ) ) {
11587
			this.position.left = data.left;
11588
		}
11589
		if ( this._isNumber( data.top ) ) {
11590
			this.position.top = data.top;
11591
		}
11592
		if ( this._isNumber( data.height ) ) {
11593
			this.size.height = data.height;
11594
		}
11595
		if ( this._isNumber( data.width ) ) {
11596
			this.size.width = data.width;
11597
		}
11598
	},
11599
 
11600
	_updateRatio: function( data ) {
11601
 
11602
		var cpos = this.position,
11603
			csize = this.size,
11604
			a = this.axis;
11605
 
11606
		if ( this._isNumber( data.height ) ) {
11607
			data.width = ( data.height * this.aspectRatio );
11608
		} else if ( this._isNumber( data.width ) ) {
11609
			data.height = ( data.width / this.aspectRatio );
11610
		}
11611
 
11612
		if ( a === "sw" ) {
11613
			data.left = cpos.left + ( csize.width - data.width );
11614
			data.top = null;
11615
		}
11616
		if ( a === "nw" ) {
11617
			data.top = cpos.top + ( csize.height - data.height );
11618
			data.left = cpos.left + ( csize.width - data.width );
11619
		}
11620
 
11621
		return data;
11622
	},
11623
 
11624
	_respectSize: function( data ) {
11625
 
11626
		var o = this._vBoundaries,
11627
			a = this.axis,
11628
			ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ),
11629
			ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ),
11630
			isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ),
11631
			isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ),
11632
			dw = this.originalPosition.left + this.originalSize.width,
11633
			dh = this.originalPosition.top + this.originalSize.height,
11634
			cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a );
11635
		if ( isminw ) {
11636
			data.width = o.minWidth;
11637
		}
11638
		if ( isminh ) {
11639
			data.height = o.minHeight;
11640
		}
11641
		if ( ismaxw ) {
11642
			data.width = o.maxWidth;
11643
		}
11644
		if ( ismaxh ) {
11645
			data.height = o.maxHeight;
11646
		}
11647
 
11648
		if ( isminw && cw ) {
11649
			data.left = dw - o.minWidth;
11650
		}
11651
		if ( ismaxw && cw ) {
11652
			data.left = dw - o.maxWidth;
11653
		}
11654
		if ( isminh && ch ) {
11655
			data.top = dh - o.minHeight;
11656
		}
11657
		if ( ismaxh && ch ) {
11658
			data.top = dh - o.maxHeight;
11659
		}
11660
 
11661
		// Fixing jump error on top/left - bug #2330
11662
		if ( !data.width && !data.height && !data.left && data.top ) {
11663
			data.top = null;
11664
		} else if ( !data.width && !data.height && !data.top && data.left ) {
11665
			data.left = null;
11666
		}
11667
 
11668
		return data;
11669
	},
11670
 
11671
	_getPaddingPlusBorderDimensions: function( element ) {
11672
		var i = 0,
11673
			widths = [],
11674
			borders = [
11675
				element.css( "borderTopWidth" ),
11676
				element.css( "borderRightWidth" ),
11677
				element.css( "borderBottomWidth" ),
11678
				element.css( "borderLeftWidth" )
11679
			],
11680
			paddings = [
11681
				element.css( "paddingTop" ),
11682
				element.css( "paddingRight" ),
11683
				element.css( "paddingBottom" ),
11684
				element.css( "paddingLeft" )
11685
			];
11686
 
11687
		for ( ; i < 4; i++ ) {
11688
			widths[ i ] = ( parseFloat( borders[ i ] ) || 0 );
11689
			widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 );
11690
		}
11691
 
11692
		return {
11693
			height: widths[ 0 ] + widths[ 2 ],
11694
			width: widths[ 1 ] + widths[ 3 ]
11695
		};
11696
	},
11697
 
11698
	_proportionallyResize: function() {
11699
 
11700
		if ( !this._proportionallyResizeElements.length ) {
11701
			return;
11702
		}
11703
 
11704
		var prel,
11705
			i = 0,
11706
			element = this.helper || this.element;
11707
 
11708
		for ( ; i < this._proportionallyResizeElements.length; i++ ) {
11709
 
11710
			prel = this._proportionallyResizeElements[ i ];
11711
 
11712
			// TODO: Seems like a bug to cache this.outerDimensions
11713
			// considering that we are in a loop.
11714
			if ( !this.outerDimensions ) {
11715
				this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
11716
			}
11717
 
11718
			prel.css( {
11719
				height: ( element.height() - this.outerDimensions.height ) || 0,
11720
				width: ( element.width() - this.outerDimensions.width ) || 0
11721
			} );
11722
 
11723
		}
11724
 
11725
	},
11726
 
11727
	_renderProxy: function() {
11728
 
11729
		var el = this.element, o = this.options;
11730
		this.elementOffset = el.offset();
11731
 
11732
		if ( this._helper ) {
11733
 
11734
			this.helper = this.helper || $( "<div></div>" ).css( { overflow: "hidden" } );
11735
 
11736
			this._addClass( this.helper, this._helper );
11737
			this.helper.css( {
11738
				width: this.element.outerWidth(),
11739
				height: this.element.outerHeight(),
11740
				position: "absolute",
11741
				left: this.elementOffset.left + "px",
11742
				top: this.elementOffset.top + "px",
11743
				zIndex: ++o.zIndex //TODO: Don't modify option
11744
			} );
11745
 
11746
			this.helper
11747
				.appendTo( "body" )
11748
				.disableSelection();
11749
 
11750
		} else {
11751
			this.helper = this.element;
11752
		}
11753
 
11754
	},
11755
 
11756
	_change: {
11757
		e: function( event, dx ) {
11758
			return { width: this.originalSize.width + dx };
11759
		},
11760
		w: function( event, dx ) {
11761
			var cs = this.originalSize, sp = this.originalPosition;
11762
			return { left: sp.left + dx, width: cs.width - dx };
11763
		},
11764
		n: function( event, dx, dy ) {
11765
			var cs = this.originalSize, sp = this.originalPosition;
11766
			return { top: sp.top + dy, height: cs.height - dy };
11767
		},
11768
		s: function( event, dx, dy ) {
11769
			return { height: this.originalSize.height + dy };
11770
		},
11771
		se: function( event, dx, dy ) {
11772
			return $.extend( this._change.s.apply( this, arguments ),
11773
				this._change.e.apply( this, [ event, dx, dy ] ) );
11774
		},
11775
		sw: function( event, dx, dy ) {
11776
			return $.extend( this._change.s.apply( this, arguments ),
11777
				this._change.w.apply( this, [ event, dx, dy ] ) );
11778
		},
11779
		ne: function( event, dx, dy ) {
11780
			return $.extend( this._change.n.apply( this, arguments ),
11781
				this._change.e.apply( this, [ event, dx, dy ] ) );
11782
		},
11783
		nw: function( event, dx, dy ) {
11784
			return $.extend( this._change.n.apply( this, arguments ),
11785
				this._change.w.apply( this, [ event, dx, dy ] ) );
11786
		}
11787
	},
11788
 
11789
	_propagate: function( n, event ) {
11790
		$.ui.plugin.call( this, n, [ event, this.ui() ] );
11791
		if ( n !== "resize" ) {
11792
			this._trigger( n, event, this.ui() );
11793
		}
11794
	},
11795
 
11796
	plugins: {},
11797
 
11798
	ui: function() {
11799
		return {
11800
			originalElement: this.originalElement,
11801
			element: this.element,
11802
			helper: this.helper,
11803
			position: this.position,
11804
			size: this.size,
11805
			originalSize: this.originalSize,
11806
			originalPosition: this.originalPosition
11807
		};
11808
	}
11809
 
11810
} );
11811
 
11812
/*
11813
 * Resizable Extensions
11814
 */
11815
 
11816
$.ui.plugin.add( "resizable", "animate", {
11817
 
11818
	stop: function( event ) {
11819
		var that = $( this ).resizable( "instance" ),
11820
			o = that.options,
11821
			pr = that._proportionallyResizeElements,
11822
			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ),
11823
			soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height,
11824
			soffsetw = ista ? 0 : that.sizeDiff.width,
11825
			style = {
11826
				width: ( that.size.width - soffsetw ),
11827
				height: ( that.size.height - soffseth )
11828
			},
11829
			left = ( parseFloat( that.element.css( "left" ) ) +
11830
				( that.position.left - that.originalPosition.left ) ) || null,
11831
			top = ( parseFloat( that.element.css( "top" ) ) +
11832
				( that.position.top - that.originalPosition.top ) ) || null;
11833
 
11834
		that.element.animate(
11835
			$.extend( style, top && left ? { top: top, left: left } : {} ), {
11836
				duration: o.animateDuration,
11837
				easing: o.animateEasing,
11838
				step: function() {
11839
 
11840
					var data = {
11841
						width: parseFloat( that.element.css( "width" ) ),
11842
						height: parseFloat( that.element.css( "height" ) ),
11843
						top: parseFloat( that.element.css( "top" ) ),
11844
						left: parseFloat( that.element.css( "left" ) )
11845
					};
11846
 
11847
					if ( pr && pr.length ) {
11848
						$( pr[ 0 ] ).css( { width: data.width, height: data.height } );
11849
					}
11850
 
11851
					// Propagating resize, and updating values for each animation step
11852
					that._updateCache( data );
11853
					that._propagate( "resize", event );
11854
 
11855
				}
11856
			}
11857
		);
11858
	}
11859
 
11860
} );
11861
 
11862
$.ui.plugin.add( "resizable", "containment", {
11863
 
11864
	start: function() {
11865
		var element, p, co, ch, cw, width, height,
11866
			that = $( this ).resizable( "instance" ),
11867
			o = that.options,
11868
			el = that.element,
11869
			oc = o.containment,
11870
			ce = ( oc instanceof $ ) ?
11871
				oc.get( 0 ) :
11872
				( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
11873
 
11874
		if ( !ce ) {
11875
			return;
11876
		}
11877
 
11878
		that.containerElement = $( ce );
11879
 
11880
		if ( /document/.test( oc ) || oc === document ) {
11881
			that.containerOffset = {
11882
				left: 0,
11883
				top: 0
11884
			};
11885
			that.containerPosition = {
11886
				left: 0,
11887
				top: 0
11888
			};
11889
 
11890
			that.parentData = {
11891
				element: $( document ),
11892
				left: 0,
11893
				top: 0,
11894
				width: $( document ).width(),
11895
				height: $( document ).height() || document.body.parentNode.scrollHeight
11896
			};
11897
		} else {
11898
			element = $( ce );
11899
			p = [];
11900
			$( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) {
11901
				p[ i ] = that._num( element.css( "padding" + name ) );
11902
			} );
11903
 
11904
			that.containerOffset = element.offset();
11905
			that.containerPosition = element.position();
11906
			that.containerSize = {
11907
				height: ( element.innerHeight() - p[ 3 ] ),
11908
				width: ( element.innerWidth() - p[ 1 ] )
11909
			};
11910
 
11911
			co = that.containerOffset;
11912
			ch = that.containerSize.height;
11913
			cw = that.containerSize.width;
11914
			width = ( that._hasScroll( ce, "left" ) ? ce.scrollWidth : cw );
11915
			height = ( that._hasScroll( ce ) ? ce.scrollHeight : ch );
11916
 
11917
			that.parentData = {
11918
				element: ce,
11919
				left: co.left,
11920
				top: co.top,
11921
				width: width,
11922
				height: height
11923
			};
11924
		}
11925
	},
11926
 
11927
	resize: function( event ) {
11928
		var woset, hoset, isParent, isOffsetRelative,
11929
			that = $( this ).resizable( "instance" ),
11930
			o = that.options,
11931
			co = that.containerOffset,
11932
			cp = that.position,
11933
			pRatio = that._aspectRatio || event.shiftKey,
11934
			cop = {
11935
				top: 0,
11936
				left: 0
11937
			},
11938
			ce = that.containerElement,
11939
			continueResize = true;
11940
 
11941
		if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
11942
			cop = co;
11943
		}
11944
 
11945
		if ( cp.left < ( that._helper ? co.left : 0 ) ) {
11946
			that.size.width = that.size.width +
11947
				( that._helper ?
11948
					( that.position.left - co.left ) :
11949
					( that.position.left - cop.left ) );
11950
 
11951
			if ( pRatio ) {
11952
				that.size.height = that.size.width / that.aspectRatio;
11953
				continueResize = false;
11954
			}
11955
			that.position.left = o.helper ? co.left : 0;
11956
		}
11957
 
11958
		if ( cp.top < ( that._helper ? co.top : 0 ) ) {
11959
			that.size.height = that.size.height +
11960
				( that._helper ?
11961
					( that.position.top - co.top ) :
11962
					that.position.top );
11963
 
11964
			if ( pRatio ) {
11965
				that.size.width = that.size.height * that.aspectRatio;
11966
				continueResize = false;
11967
			}
11968
			that.position.top = that._helper ? co.top : 0;
11969
		}
11970
 
11971
		isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
11972
		isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
11973
 
11974
		if ( isParent && isOffsetRelative ) {
11975
			that.offset.left = that.parentData.left + that.position.left;
11976
			that.offset.top = that.parentData.top + that.position.top;
11977
		} else {
11978
			that.offset.left = that.element.offset().left;
11979
			that.offset.top = that.element.offset().top;
11980
		}
11981
 
11982
		woset = Math.abs( that.sizeDiff.width +
11983
			( that._helper ?
11984
				that.offset.left - cop.left :
11985
				( that.offset.left - co.left ) ) );
11986
 
11987
		hoset = Math.abs( that.sizeDiff.height +
11988
			( that._helper ?
11989
				that.offset.top - cop.top :
11990
				( that.offset.top - co.top ) ) );
11991
 
11992
		if ( woset + that.size.width >= that.parentData.width ) {
11993
			that.size.width = that.parentData.width - woset;
11994
			if ( pRatio ) {
11995
				that.size.height = that.size.width / that.aspectRatio;
11996
				continueResize = false;
11997
			}
11998
		}
11999
 
12000
		if ( hoset + that.size.height >= that.parentData.height ) {
12001
			that.size.height = that.parentData.height - hoset;
12002
			if ( pRatio ) {
12003
				that.size.width = that.size.height * that.aspectRatio;
12004
				continueResize = false;
12005
			}
12006
		}
12007
 
12008
		if ( !continueResize ) {
12009
			that.position.left = that.prevPosition.left;
12010
			that.position.top = that.prevPosition.top;
12011
			that.size.width = that.prevSize.width;
12012
			that.size.height = that.prevSize.height;
12013
		}
12014
	},
12015
 
12016
	stop: function() {
12017
		var that = $( this ).resizable( "instance" ),
12018
			o = that.options,
12019
			co = that.containerOffset,
12020
			cop = that.containerPosition,
12021
			ce = that.containerElement,
12022
			helper = $( that.helper ),
12023
			ho = helper.offset(),
12024
			w = helper.outerWidth() - that.sizeDiff.width,
12025
			h = helper.outerHeight() - that.sizeDiff.height;
12026
 
12027
		if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
12028
			$( this ).css( {
12029
				left: ho.left - cop.left - co.left,
12030
				width: w,
12031
				height: h
12032
			} );
12033
		}
12034
 
12035
		if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
12036
			$( this ).css( {
12037
				left: ho.left - cop.left - co.left,
12038
				width: w,
12039
				height: h
12040
			} );
12041
		}
12042
	}
12043
} );
12044
 
12045
$.ui.plugin.add( "resizable", "alsoResize", {
12046
 
12047
	start: function() {
12048
		var that = $( this ).resizable( "instance" ),
12049
			o = that.options;
12050
 
12051
		$( o.alsoResize ).each( function() {
12052
			var el = $( this );
12053
			el.data( "ui-resizable-alsoresize", {
12054
				width: parseFloat( el.width() ), height: parseFloat( el.height() ),
12055
				left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
12056
			} );
12057
		} );
12058
	},
12059
 
12060
	resize: function( event, ui ) {
12061
		var that = $( this ).resizable( "instance" ),
12062
			o = that.options,
12063
			os = that.originalSize,
12064
			op = that.originalPosition,
12065
			delta = {
12066
				height: ( that.size.height - os.height ) || 0,
12067
				width: ( that.size.width - os.width ) || 0,
12068
				top: ( that.position.top - op.top ) || 0,
12069
				left: ( that.position.left - op.left ) || 0
12070
			};
12071
 
12072
			$( o.alsoResize ).each( function() {
12073
				var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {},
12074
					css = el.parents( ui.originalElement[ 0 ] ).length ?
12075
							[ "width", "height" ] :
12076
							[ "width", "height", "top", "left" ];
12077
 
12078
				$.each( css, function( i, prop ) {
12079
					var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 );
12080
					if ( sum && sum >= 0 ) {
12081
						style[ prop ] = sum || null;
12082
					}
12083
				} );
12084
 
12085
				el.css( style );
12086
			} );
12087
	},
12088
 
12089
	stop: function() {
12090
		$( this ).removeData( "ui-resizable-alsoresize" );
12091
	}
12092
} );
12093
 
12094
$.ui.plugin.add( "resizable", "ghost", {
12095
 
12096
	start: function() {
12097
 
12098
		var that = $( this ).resizable( "instance" ), cs = that.size;
12099
 
12100
		that.ghost = that.originalElement.clone();
12101
		that.ghost.css( {
12102
			opacity: 0.25,
12103
			display: "block",
12104
			position: "relative",
12105
			height: cs.height,
12106
			width: cs.width,
12107
			margin: 0,
12108
			left: 0,
12109
			top: 0
12110
		} );
12111
 
12112
		that._addClass( that.ghost, "ui-resizable-ghost" );
12113
 
12114
		// DEPRECATED
12115
		// TODO: remove after 1.12
12116
		if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) {
12117
 
12118
			// Ghost option
12119
			that.ghost.addClass( this.options.ghost );
12120
		}
12121
 
12122
		that.ghost.appendTo( that.helper );
12123
 
12124
	},
12125
 
12126
	resize: function() {
12127
		var that = $( this ).resizable( "instance" );
12128
		if ( that.ghost ) {
12129
			that.ghost.css( {
12130
				position: "relative",
12131
				height: that.size.height,
12132
				width: that.size.width
12133
			} );
12134
		}
12135
	},
12136
 
12137
	stop: function() {
12138
		var that = $( this ).resizable( "instance" );
12139
		if ( that.ghost && that.helper ) {
12140
			that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) );
12141
		}
12142
	}
12143
 
12144
} );
12145
 
12146
$.ui.plugin.add( "resizable", "grid", {
12147
 
12148
	resize: function() {
12149
		var outerDimensions,
12150
			that = $( this ).resizable( "instance" ),
12151
			o = that.options,
12152
			cs = that.size,
12153
			os = that.originalSize,
12154
			op = that.originalPosition,
12155
			a = that.axis,
12156
			grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
12157
			gridX = ( grid[ 0 ] || 1 ),
12158
			gridY = ( grid[ 1 ] || 1 ),
12159
			ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX,
12160
			oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY,
12161
			newWidth = os.width + ox,
12162
			newHeight = os.height + oy,
12163
			isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ),
12164
			isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ),
12165
			isMinWidth = o.minWidth && ( o.minWidth > newWidth ),
12166
			isMinHeight = o.minHeight && ( o.minHeight > newHeight );
12167
 
12168
		o.grid = grid;
12169
 
12170
		if ( isMinWidth ) {
12171
			newWidth += gridX;
12172
		}
12173
		if ( isMinHeight ) {
12174
			newHeight += gridY;
12175
		}
12176
		if ( isMaxWidth ) {
12177
			newWidth -= gridX;
12178
		}
12179
		if ( isMaxHeight ) {
12180
			newHeight -= gridY;
12181
		}
12182
 
12183
		if ( /^(se|s|e)$/.test( a ) ) {
12184
			that.size.width = newWidth;
12185
			that.size.height = newHeight;
12186
		} else if ( /^(ne)$/.test( a ) ) {
12187
			that.size.width = newWidth;
12188
			that.size.height = newHeight;
12189
			that.position.top = op.top - oy;
12190
		} else if ( /^(sw)$/.test( a ) ) {
12191
			that.size.width = newWidth;
12192
			that.size.height = newHeight;
12193
			that.position.left = op.left - ox;
12194
		} else {
12195
			if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) {
12196
				outerDimensions = that._getPaddingPlusBorderDimensions( this );
12197
			}
12198
 
12199
			if ( newHeight - gridY > 0 ) {
12200
				that.size.height = newHeight;
12201
				that.position.top = op.top - oy;
12202
			} else {
12203
				newHeight = gridY - outerDimensions.height;
12204
				that.size.height = newHeight;
12205
				that.position.top = op.top + os.height - newHeight;
12206
			}
12207
			if ( newWidth - gridX > 0 ) {
12208
				that.size.width = newWidth;
12209
				that.position.left = op.left - ox;
12210
			} else {
12211
				newWidth = gridX - outerDimensions.width;
12212
				that.size.width = newWidth;
12213
				that.position.left = op.left + os.width - newWidth;
12214
			}
12215
		}
12216
	}
12217
 
12218
} );
12219
 
12220
var widgetsResizable = $.ui.resizable;
12221
 
12222
 
12223
/*!
12224
 * jQuery UI Dialog 1.13.2
12225
 * http://jqueryui.com
12226
 *
12227
 * Copyright jQuery Foundation and other contributors
12228
 * Released under the MIT license.
12229
 * http://jquery.org/license
12230
 */
12231
 
12232
//>>label: Dialog
12233
//>>group: Widgets
12234
//>>description: Displays customizable dialog windows.
12235
//>>docs: http://api.jqueryui.com/dialog/
12236
//>>demos: http://jqueryui.com/dialog/
12237
//>>css.structure: ../../themes/base/core.css
12238
//>>css.structure: ../../themes/base/dialog.css
12239
//>>css.theme: ../../themes/base/theme.css
12240
 
12241
 
12242
$.widget( "ui.dialog", {
12243
	version: "1.13.2",
12244
	options: {
12245
		appendTo: "body",
12246
		autoOpen: true,
12247
		buttons: [],
12248
		classes: {
12249
			"ui-dialog": "ui-corner-all",
12250
			"ui-dialog-titlebar": "ui-corner-all"
12251
		},
12252
		closeOnEscape: true,
12253
		closeText: "Close",
12254
		draggable: true,
12255
		hide: null,
12256
		height: "auto",
12257
		maxHeight: null,
12258
		maxWidth: null,
12259
		minHeight: 150,
12260
		minWidth: 150,
12261
		modal: false,
12262
		position: {
12263
			my: "center",
12264
			at: "center",
12265
			of: window,
12266
			collision: "fit",
12267
 
12268
			// Ensure the titlebar is always visible
12269
			using: function( pos ) {
12270
				var topOffset = $( this ).css( pos ).offset().top;
12271
				if ( topOffset < 0 ) {
12272
					$( this ).css( "top", pos.top - topOffset );
12273
				}
12274
			}
12275
		},
12276
		resizable: true,
12277
		show: null,
12278
		title: null,
12279
		width: 300,
12280
 
12281
		// Callbacks
12282
		beforeClose: null,
12283
		close: null,
12284
		drag: null,
12285
		dragStart: null,
12286
		dragStop: null,
12287
		focus: null,
12288
		open: null,
12289
		resize: null,
12290
		resizeStart: null,
12291
		resizeStop: null
12292
	},
12293
 
12294
	sizeRelatedOptions: {
12295
		buttons: true,
12296
		height: true,
12297
		maxHeight: true,
12298
		maxWidth: true,
12299
		minHeight: true,
12300
		minWidth: true,
12301
		width: true
12302
	},
12303
 
12304
	resizableRelatedOptions: {
12305
		maxHeight: true,
12306
		maxWidth: true,
12307
		minHeight: true,
12308
		minWidth: true
12309
	},
12310
 
12311
	_create: function() {
12312
		this.originalCss = {
12313
			display: this.element[ 0 ].style.display,
12314
			width: this.element[ 0 ].style.width,
12315
			minHeight: this.element[ 0 ].style.minHeight,
12316
			maxHeight: this.element[ 0 ].style.maxHeight,
12317
			height: this.element[ 0 ].style.height
12318
		};
12319
		this.originalPosition = {
12320
			parent: this.element.parent(),
12321
			index: this.element.parent().children().index( this.element )
12322
		};
12323
		this.originalTitle = this.element.attr( "title" );
12324
		if ( this.options.title == null && this.originalTitle != null ) {
12325
			this.options.title = this.originalTitle;
12326
		}
12327
 
12328
		// Dialogs can't be disabled
12329
		if ( this.options.disabled ) {
12330
			this.options.disabled = false;
12331
		}
12332
 
12333
		this._createWrapper();
12334
 
12335
		this.element
12336
			.show()
12337
			.removeAttr( "title" )
12338
			.appendTo( this.uiDialog );
12339
 
12340
		this._addClass( "ui-dialog-content", "ui-widget-content" );
12341
 
12342
		this._createTitlebar();
12343
		this._createButtonPane();
12344
 
12345
		if ( this.options.draggable && $.fn.draggable ) {
12346
			this._makeDraggable();
12347
		}
12348
		if ( this.options.resizable && $.fn.resizable ) {
12349
			this._makeResizable();
12350
		}
12351
 
12352
		this._isOpen = false;
12353
 
12354
		this._trackFocus();
12355
	},
12356
 
12357
	_init: function() {
12358
		if ( this.options.autoOpen ) {
12359
			this.open();
12360
		}
12361
	},
12362
 
12363
	_appendTo: function() {
12364
		var element = this.options.appendTo;
12365
		if ( element && ( element.jquery || element.nodeType ) ) {
12366
			return $( element );
12367
		}
12368
		return this.document.find( element || "body" ).eq( 0 );
12369
	},
12370
 
12371
	_destroy: function() {
12372
		var next,
12373
			originalPosition = this.originalPosition;
12374
 
12375
		this._untrackInstance();
12376
		this._destroyOverlay();
12377
 
12378
		this.element
12379
			.removeUniqueId()
12380
			.css( this.originalCss )
12381
 
12382
			// Without detaching first, the following becomes really slow
12383
			.detach();
12384
 
12385
		this.uiDialog.remove();
12386
 
12387
		if ( this.originalTitle ) {
12388
			this.element.attr( "title", this.originalTitle );
12389
		}
12390
 
12391
		next = originalPosition.parent.children().eq( originalPosition.index );
12392
 
12393
		// Don't try to place the dialog next to itself (#8613)
12394
		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
12395
			next.before( this.element );
12396
		} else {
12397
			originalPosition.parent.append( this.element );
12398
		}
12399
	},
12400
 
12401
	widget: function() {
12402
		return this.uiDialog;
12403
	},
12404
 
12405
	disable: $.noop,
12406
	enable: $.noop,
12407
 
12408
	close: function( event ) {
12409
		var that = this;
12410
 
12411
		if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
12412
			return;
12413
		}
12414
 
12415
		this._isOpen = false;
12416
		this._focusedElement = null;
12417
		this._destroyOverlay();
12418
		this._untrackInstance();
12419
 
12420
		if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) {
12421
 
12422
			// Hiding a focused element doesn't trigger blur in WebKit
12423
			// so in case we have nothing to focus on, explicitly blur the active element
12424
			// https://bugs.webkit.org/show_bug.cgi?id=47182
12425
			$.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) );
12426
		}
12427
 
12428
		this._hide( this.uiDialog, this.options.hide, function() {
12429
			that._trigger( "close", event );
12430
		} );
12431
	},
12432
 
12433
	isOpen: function() {
12434
		return this._isOpen;
12435
	},
12436
 
12437
	moveToTop: function() {
12438
		this._moveToTop();
12439
	},
12440
 
12441
	_moveToTop: function( event, silent ) {
12442
		var moved = false,
12443
			zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() {
12444
				return +$( this ).css( "z-index" );
12445
			} ).get(),
12446
			zIndexMax = Math.max.apply( null, zIndices );
12447
 
12448
		if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
12449
			this.uiDialog.css( "z-index", zIndexMax + 1 );
12450
			moved = true;
12451
		}
12452
 
12453
		if ( moved && !silent ) {
12454
			this._trigger( "focus", event );
12455
		}
12456
		return moved;
12457
	},
12458
 
12459
	open: function() {
12460
		var that = this;
12461
		if ( this._isOpen ) {
12462
			if ( this._moveToTop() ) {
12463
				this._focusTabbable();
12464
			}
12465
			return;
12466
		}
12467
 
12468
		this._isOpen = true;
12469
		this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
12470
 
12471
		this._size();
12472
		this._position();
12473
		this._createOverlay();
12474
		this._moveToTop( null, true );
12475
 
12476
		// Ensure the overlay is moved to the top with the dialog, but only when
12477
		// opening. The overlay shouldn't move after the dialog is open so that
12478
		// modeless dialogs opened after the modal dialog stack properly.
12479
		if ( this.overlay ) {
12480
			this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
12481
		}
12482
 
12483
		this._show( this.uiDialog, this.options.show, function() {
12484
			that._focusTabbable();
12485
			that._trigger( "focus" );
12486
		} );
12487
 
12488
		// Track the dialog immediately upon opening in case a focus event
12489
		// somehow occurs outside of the dialog before an element inside the
12490
		// dialog is focused (#10152)
12491
		this._makeFocusTarget();
12492
 
12493
		this._trigger( "open" );
12494
	},
12495
 
12496
	_focusTabbable: function() {
12497
 
12498
		// Set focus to the first match:
12499
		// 1. An element that was focused previously
12500
		// 2. First element inside the dialog matching [autofocus]
12501
		// 3. Tabbable element inside the content element
12502
		// 4. Tabbable element inside the buttonpane
12503
		// 5. The close button
12504
		// 6. The dialog itself
12505
		var hasFocus = this._focusedElement;
12506
		if ( !hasFocus ) {
12507
			hasFocus = this.element.find( "[autofocus]" );
12508
		}
12509
		if ( !hasFocus.length ) {
12510
			hasFocus = this.element.find( ":tabbable" );
12511
		}
12512
		if ( !hasFocus.length ) {
12513
			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
12514
		}
12515
		if ( !hasFocus.length ) {
12516
			hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
12517
		}
12518
		if ( !hasFocus.length ) {
12519
			hasFocus = this.uiDialog;
12520
		}
12521
		hasFocus.eq( 0 ).trigger( "focus" );
12522
	},
12523
 
12524
	_restoreTabbableFocus: function() {
12525
		var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
12526
			isActive = this.uiDialog[ 0 ] === activeElement ||
12527
				$.contains( this.uiDialog[ 0 ], activeElement );
12528
		if ( !isActive ) {
12529
			this._focusTabbable();
12530
		}
12531
	},
12532
 
12533
	_keepFocus: function( event ) {
12534
		event.preventDefault();
12535
		this._restoreTabbableFocus();
12536
 
12537
		// support: IE
12538
		// IE <= 8 doesn't prevent moving focus even with event.preventDefault()
12539
		// so we check again later
12540
		this._delay( this._restoreTabbableFocus );
12541
	},
12542
 
12543
	_createWrapper: function() {
12544
		this.uiDialog = $( "<div>" )
12545
			.hide()
12546
			.attr( {
12547
 
12548
				// Setting tabIndex makes the div focusable
12549
				tabIndex: -1,
12550
				role: "dialog"
12551
			} )
12552
			.appendTo( this._appendTo() );
12553
 
12554
		this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" );
12555
		this._on( this.uiDialog, {
12556
			keydown: function( event ) {
12557
				if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
12558
						event.keyCode === $.ui.keyCode.ESCAPE ) {
12559
					event.preventDefault();
12560
					this.close( event );
12561
					return;
12562
				}
12563
 
12564
				// Prevent tabbing out of dialogs
12565
				if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
12566
					return;
12567
				}
12568
				var tabbables = this.uiDialog.find( ":tabbable" ),
12569
					first = tabbables.first(),
12570
					last = tabbables.last();
12571
 
12572
				if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) &&
12573
						!event.shiftKey ) {
12574
					this._delay( function() {
12575
						first.trigger( "focus" );
12576
					} );
12577
					event.preventDefault();
12578
				} else if ( ( event.target === first[ 0 ] ||
12579
						event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) {
12580
					this._delay( function() {
12581
						last.trigger( "focus" );
12582
					} );
12583
					event.preventDefault();
12584
				}
12585
			},
12586
			mousedown: function( event ) {
12587
				if ( this._moveToTop( event ) ) {
12588
					this._focusTabbable();
12589
				}
12590
			}
12591
		} );
12592
 
12593
		// We assume that any existing aria-describedby attribute means
12594
		// that the dialog content is marked up properly
12595
		// otherwise we brute force the content as the description
12596
		if ( !this.element.find( "[aria-describedby]" ).length ) {
12597
			this.uiDialog.attr( {
12598
				"aria-describedby": this.element.uniqueId().attr( "id" )
12599
			} );
12600
		}
12601
	},
12602
 
12603
	_createTitlebar: function() {
12604
		var uiDialogTitle;
12605
 
12606
		this.uiDialogTitlebar = $( "<div>" );
12607
		this._addClass( this.uiDialogTitlebar,
12608
			"ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" );
12609
		this._on( this.uiDialogTitlebar, {
12610
			mousedown: function( event ) {
12611
 
12612
				// Don't prevent click on close button (#8838)
12613
				// Focusing a dialog that is partially scrolled out of view
12614
				// causes the browser to scroll it into view, preventing the click event
12615
				if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
12616
 
12617
					// Dialog isn't getting focus when dragging (#8063)
12618
					this.uiDialog.trigger( "focus" );
12619
				}
12620
			}
12621
		} );
12622
 
12623
		// Support: IE
12624
		// Use type="button" to prevent enter keypresses in textboxes from closing the
12625
		// dialog in IE (#9312)
12626
		this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
12627
			.button( {
12628
				label: $( "<a>" ).text( this.options.closeText ).html(),
12629
				icon: "ui-icon-closethick",
12630
				showLabel: false
12631
			} )
12632
			.appendTo( this.uiDialogTitlebar );
12633
 
12634
		this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" );
12635
		this._on( this.uiDialogTitlebarClose, {
12636
			click: function( event ) {
12637
				event.preventDefault();
12638
				this.close( event );
12639
			}
12640
		} );
12641
 
12642
		uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar );
12643
		this._addClass( uiDialogTitle, "ui-dialog-title" );
12644
		this._title( uiDialogTitle );
12645
 
12646
		this.uiDialogTitlebar.prependTo( this.uiDialog );
12647
 
12648
		this.uiDialog.attr( {
12649
			"aria-labelledby": uiDialogTitle.attr( "id" )
12650
		} );
12651
	},
12652
 
12653
	_title: function( title ) {
12654
		if ( this.options.title ) {
12655
			title.text( this.options.title );
12656
		} else {
12657
			title.html( "&#160;" );
12658
		}
12659
	},
12660
 
12661
	_createButtonPane: function() {
12662
		this.uiDialogButtonPane = $( "<div>" );
12663
		this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane",
12664
			"ui-widget-content ui-helper-clearfix" );
12665
 
12666
		this.uiButtonSet = $( "<div>" )
12667
			.appendTo( this.uiDialogButtonPane );
12668
		this._addClass( this.uiButtonSet, "ui-dialog-buttonset" );
12669
 
12670
		this._createButtons();
12671
	},
12672
 
12673
	_createButtons: function() {
12674
		var that = this,
12675
			buttons = this.options.buttons;
12676
 
12677
		// If we already have a button pane, remove it
12678
		this.uiDialogButtonPane.remove();
12679
		this.uiButtonSet.empty();
12680
 
12681
		if ( $.isEmptyObject( buttons ) || ( Array.isArray( buttons ) && !buttons.length ) ) {
12682
			this._removeClass( this.uiDialog, "ui-dialog-buttons" );
12683
			return;
12684
		}
12685
 
12686
		$.each( buttons, function( name, props ) {
12687
			var click, buttonOptions;
12688
			props = typeof props === "function" ?
12689
				{ click: props, text: name } :
12690
				props;
12691
 
12692
			// Default to a non-submitting button
12693
			props = $.extend( { type: "button" }, props );
12694
 
12695
			// Change the context for the click callback to be the main element
12696
			click = props.click;
12697
			buttonOptions = {
12698
				icon: props.icon,
12699
				iconPosition: props.iconPosition,
12700
				showLabel: props.showLabel,
12701
 
12702
				// Deprecated options
12703
				icons: props.icons,
12704
				text: props.text
12705
			};
12706
 
12707
			delete props.click;
12708
			delete props.icon;
12709
			delete props.iconPosition;
12710
			delete props.showLabel;
12711
 
12712
			// Deprecated options
12713
			delete props.icons;
12714
			if ( typeof props.text === "boolean" ) {
12715
				delete props.text;
12716
			}
12717
 
12718
			$( "<button></button>", props )
12719
				.button( buttonOptions )
12720
				.appendTo( that.uiButtonSet )
12721
				.on( "click", function() {
12722
					click.apply( that.element[ 0 ], arguments );
12723
				} );
12724
		} );
12725
		this._addClass( this.uiDialog, "ui-dialog-buttons" );
12726
		this.uiDialogButtonPane.appendTo( this.uiDialog );
12727
	},
12728
 
12729
	_makeDraggable: function() {
12730
		var that = this,
12731
			options = this.options;
12732
 
12733
		function filteredUi( ui ) {
12734
			return {
12735
				position: ui.position,
12736
				offset: ui.offset
12737
			};
12738
		}
12739
 
12740
		this.uiDialog.draggable( {
12741
			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
12742
			handle: ".ui-dialog-titlebar",
12743
			containment: "document",
12744
			start: function( event, ui ) {
12745
				that._addClass( $( this ), "ui-dialog-dragging" );
12746
				that._blockFrames();
12747
				that._trigger( "dragStart", event, filteredUi( ui ) );
12748
			},
12749
			drag: function( event, ui ) {
12750
				that._trigger( "drag", event, filteredUi( ui ) );
12751
			},
12752
			stop: function( event, ui ) {
12753
				var left = ui.offset.left - that.document.scrollLeft(),
12754
					top = ui.offset.top - that.document.scrollTop();
12755
 
12756
				options.position = {
12757
					my: "left top",
12758
					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12759
						"top" + ( top >= 0 ? "+" : "" ) + top,
12760
					of: that.window
12761
				};
12762
				that._removeClass( $( this ), "ui-dialog-dragging" );
12763
				that._unblockFrames();
12764
				that._trigger( "dragStop", event, filteredUi( ui ) );
12765
			}
12766
		} );
12767
	},
12768
 
12769
	_makeResizable: function() {
12770
		var that = this,
12771
			options = this.options,
12772
			handles = options.resizable,
12773
 
12774
			// .ui-resizable has position: relative defined in the stylesheet
12775
			// but dialogs have to use absolute or fixed positioning
12776
			position = this.uiDialog.css( "position" ),
12777
			resizeHandles = typeof handles === "string" ?
12778
				handles :
12779
				"n,e,s,w,se,sw,ne,nw";
12780
 
12781
		function filteredUi( ui ) {
12782
			return {
12783
				originalPosition: ui.originalPosition,
12784
				originalSize: ui.originalSize,
12785
				position: ui.position,
12786
				size: ui.size
12787
			};
12788
		}
12789
 
12790
		this.uiDialog.resizable( {
12791
			cancel: ".ui-dialog-content",
12792
			containment: "document",
12793
			alsoResize: this.element,
12794
			maxWidth: options.maxWidth,
12795
			maxHeight: options.maxHeight,
12796
			minWidth: options.minWidth,
12797
			minHeight: this._minHeight(),
12798
			handles: resizeHandles,
12799
			start: function( event, ui ) {
12800
				that._addClass( $( this ), "ui-dialog-resizing" );
12801
				that._blockFrames();
12802
				that._trigger( "resizeStart", event, filteredUi( ui ) );
12803
			},
12804
			resize: function( event, ui ) {
12805
				that._trigger( "resize", event, filteredUi( ui ) );
12806
			},
12807
			stop: function( event, ui ) {
12808
				var offset = that.uiDialog.offset(),
12809
					left = offset.left - that.document.scrollLeft(),
12810
					top = offset.top - that.document.scrollTop();
12811
 
12812
				options.height = that.uiDialog.height();
12813
				options.width = that.uiDialog.width();
12814
				options.position = {
12815
					my: "left top",
12816
					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12817
						"top" + ( top >= 0 ? "+" : "" ) + top,
12818
					of: that.window
12819
				};
12820
				that._removeClass( $( this ), "ui-dialog-resizing" );
12821
				that._unblockFrames();
12822
				that._trigger( "resizeStop", event, filteredUi( ui ) );
12823
			}
12824
		} )
12825
			.css( "position", position );
12826
	},
12827
 
12828
	_trackFocus: function() {
12829
		this._on( this.widget(), {
12830
			focusin: function( event ) {
12831
				this._makeFocusTarget();
12832
				this._focusedElement = $( event.target );
12833
			}
12834
		} );
12835
	},
12836
 
12837
	_makeFocusTarget: function() {
12838
		this._untrackInstance();
12839
		this._trackingInstances().unshift( this );
12840
	},
12841
 
12842
	_untrackInstance: function() {
12843
		var instances = this._trackingInstances(),
12844
			exists = $.inArray( this, instances );
12845
		if ( exists !== -1 ) {
12846
			instances.splice( exists, 1 );
12847
		}
12848
	},
12849
 
12850
	_trackingInstances: function() {
12851
		var instances = this.document.data( "ui-dialog-instances" );
12852
		if ( !instances ) {
12853
			instances = [];
12854
			this.document.data( "ui-dialog-instances", instances );
12855
		}
12856
		return instances;
12857
	},
12858
 
12859
	_minHeight: function() {
12860
		var options = this.options;
12861
 
12862
		return options.height === "auto" ?
12863
			options.minHeight :
12864
			Math.min( options.minHeight, options.height );
12865
	},
12866
 
12867
	_position: function() {
12868
 
12869
		// Need to show the dialog to get the actual offset in the position plugin
12870
		var isVisible = this.uiDialog.is( ":visible" );
12871
		if ( !isVisible ) {
12872
			this.uiDialog.show();
12873
		}
12874
		this.uiDialog.position( this.options.position );
12875
		if ( !isVisible ) {
12876
			this.uiDialog.hide();
12877
		}
12878
	},
12879
 
12880
	_setOptions: function( options ) {
12881
		var that = this,
12882
			resize = false,
12883
			resizableOptions = {};
12884
 
12885
		$.each( options, function( key, value ) {
12886
			that._setOption( key, value );
12887
 
12888
			if ( key in that.sizeRelatedOptions ) {
12889
				resize = true;
12890
			}
12891
			if ( key in that.resizableRelatedOptions ) {
12892
				resizableOptions[ key ] = value;
12893
			}
12894
		} );
12895
 
12896
		if ( resize ) {
12897
			this._size();
12898
			this._position();
12899
		}
12900
		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12901
			this.uiDialog.resizable( "option", resizableOptions );
12902
		}
12903
	},
12904
 
12905
	_setOption: function( key, value ) {
12906
		var isDraggable, isResizable,
12907
			uiDialog = this.uiDialog;
12908
 
12909
		if ( key === "disabled" ) {
12910
			return;
12911
		}
12912
 
12913
		this._super( key, value );
12914
 
12915
		if ( key === "appendTo" ) {
12916
			this.uiDialog.appendTo( this._appendTo() );
12917
		}
12918
 
12919
		if ( key === "buttons" ) {
12920
			this._createButtons();
12921
		}
12922
 
12923
		if ( key === "closeText" ) {
12924
			this.uiDialogTitlebarClose.button( {
12925
 
12926
				// Ensure that we always pass a string
12927
				label: $( "<a>" ).text( "" + this.options.closeText ).html()
12928
			} );
12929
		}
12930
 
12931
		if ( key === "draggable" ) {
12932
			isDraggable = uiDialog.is( ":data(ui-draggable)" );
12933
			if ( isDraggable && !value ) {
12934
				uiDialog.draggable( "destroy" );
12935
			}
12936
 
12937
			if ( !isDraggable && value ) {
12938
				this._makeDraggable();
12939
			}
12940
		}
12941
 
12942
		if ( key === "position" ) {
12943
			this._position();
12944
		}
12945
 
12946
		if ( key === "resizable" ) {
12947
 
12948
			// currently resizable, becoming non-resizable
12949
			isResizable = uiDialog.is( ":data(ui-resizable)" );
12950
			if ( isResizable && !value ) {
12951
				uiDialog.resizable( "destroy" );
12952
			}
12953
 
12954
			// Currently resizable, changing handles
12955
			if ( isResizable && typeof value === "string" ) {
12956
				uiDialog.resizable( "option", "handles", value );
12957
			}
12958
 
12959
			// Currently non-resizable, becoming resizable
12960
			if ( !isResizable && value !== false ) {
12961
				this._makeResizable();
12962
			}
12963
		}
12964
 
12965
		if ( key === "title" ) {
12966
			this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
12967
		}
12968
	},
12969
 
12970
	_size: function() {
12971
 
12972
		// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
12973
		// divs will both have width and height set, so we need to reset them
12974
		var nonContentHeight, minContentHeight, maxContentHeight,
12975
			options = this.options;
12976
 
12977
		// Reset content sizing
12978
		this.element.show().css( {
12979
			width: "auto",
12980
			minHeight: 0,
12981
			maxHeight: "none",
12982
			height: 0
12983
		} );
12984
 
12985
		if ( options.minWidth > options.width ) {
12986
			options.width = options.minWidth;
12987
		}
12988
 
12989
		// Reset wrapper sizing
12990
		// determine the height of all the non-content elements
12991
		nonContentHeight = this.uiDialog.css( {
12992
			height: "auto",
12993
			width: options.width
12994
		} )
12995
			.outerHeight();
12996
		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
12997
		maxContentHeight = typeof options.maxHeight === "number" ?
12998
			Math.max( 0, options.maxHeight - nonContentHeight ) :
12999
			"none";
13000
 
13001
		if ( options.height === "auto" ) {
13002
			this.element.css( {
13003
				minHeight: minContentHeight,
13004
				maxHeight: maxContentHeight,
13005
				height: "auto"
13006
			} );
13007
		} else {
13008
			this.element.height( Math.max( 0, options.height - nonContentHeight ) );
13009
		}
13010
 
13011
		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
13012
			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
13013
		}
13014
	},
13015
 
13016
	_blockFrames: function() {
13017
		this.iframeBlocks = this.document.find( "iframe" ).map( function() {
13018
			var iframe = $( this );
13019
 
13020
			return $( "<div>" )
13021
				.css( {
13022
					position: "absolute",
13023
					width: iframe.outerWidth(),
13024
					height: iframe.outerHeight()
13025
				} )
13026
				.appendTo( iframe.parent() )
13027
				.offset( iframe.offset() )[ 0 ];
13028
		} );
13029
	},
13030
 
13031
	_unblockFrames: function() {
13032
		if ( this.iframeBlocks ) {
13033
			this.iframeBlocks.remove();
13034
			delete this.iframeBlocks;
13035
		}
13036
	},
13037
 
13038
	_allowInteraction: function( event ) {
13039
		if ( $( event.target ).closest( ".ui-dialog" ).length ) {
13040
			return true;
13041
		}
13042
 
13043
		// TODO: Remove hack when datepicker implements
13044
		// the .ui-front logic (#8989)
13045
		return !!$( event.target ).closest( ".ui-datepicker" ).length;
13046
	},
13047
 
13048
	_createOverlay: function() {
13049
		if ( !this.options.modal ) {
13050
			return;
13051
		}
13052
 
13053
		var jqMinor = $.fn.jquery.substring( 0, 4 );
13054
 
13055
		// We use a delay in case the overlay is created from an
13056
		// event that we're going to be cancelling (#2804)
13057
		var isOpening = true;
13058
		this._delay( function() {
13059
			isOpening = false;
13060
		} );
13061
 
13062
		if ( !this.document.data( "ui-dialog-overlays" ) ) {
13063
 
13064
			// Prevent use of anchors and inputs
13065
			// This doesn't use `_on()` because it is a shared event handler
13066
			// across all open modal dialogs.
13067
			this.document.on( "focusin.ui-dialog", function( event ) {
13068
				if ( isOpening ) {
13069
					return;
13070
				}
13071
 
13072
				var instance = this._trackingInstances()[ 0 ];
13073
				if ( !instance._allowInteraction( event ) ) {
13074
					event.preventDefault();
13075
					instance._focusTabbable();
13076
 
13077
					// Support: jQuery >=3.4 <3.6 only
13078
					// Focus re-triggering in jQuery 3.4/3.5 makes the original element
13079
					// have its focus event propagated last, breaking the re-targeting.
13080
					// Trigger focus in a delay in addition if needed to avoid the issue
13081
					// See https://github.com/jquery/jquery/issues/4382
13082
					if ( jqMinor === "3.4." || jqMinor === "3.5." ) {
13083
						instance._delay( instance._restoreTabbableFocus );
13084
					}
13085
				}
13086
			}.bind( this ) );
13087
		}
13088
 
13089
		this.overlay = $( "<div>" )
13090
			.appendTo( this._appendTo() );
13091
 
13092
		this._addClass( this.overlay, null, "ui-widget-overlay ui-front" );
13093
		this._on( this.overlay, {
13094
			mousedown: "_keepFocus"
13095
		} );
13096
		this.document.data( "ui-dialog-overlays",
13097
			( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 );
13098
	},
13099
 
13100
	_destroyOverlay: function() {
13101
		if ( !this.options.modal ) {
13102
			return;
13103
		}
13104
 
13105
		if ( this.overlay ) {
13106
			var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
13107
 
13108
			if ( !overlays ) {
13109
				this.document.off( "focusin.ui-dialog" );
13110
				this.document.removeData( "ui-dialog-overlays" );
13111
			} else {
13112
				this.document.data( "ui-dialog-overlays", overlays );
13113
			}
13114
 
13115
			this.overlay.remove();
13116
			this.overlay = null;
13117
		}
13118
	}
13119
} );
13120
 
13121
// DEPRECATED
13122
// TODO: switch return back to widget declaration at top of file when this is removed
13123
if ( $.uiBackCompat !== false ) {
13124
 
13125
	// Backcompat for dialogClass option
13126
	$.widget( "ui.dialog", $.ui.dialog, {
13127
		options: {
13128
			dialogClass: ""
13129
		},
13130
		_createWrapper: function() {
13131
			this._super();
13132
			this.uiDialog.addClass( this.options.dialogClass );
13133
		},
13134
		_setOption: function( key, value ) {
13135
			if ( key === "dialogClass" ) {
13136
				this.uiDialog
13137
					.removeClass( this.options.dialogClass )
13138
					.addClass( value );
13139
			}
13140
			this._superApply( arguments );
13141
		}
13142
	} );
13143
}
13144
 
13145
var widgetsDialog = $.ui.dialog;
13146
 
13147
 
13148
/*!
13149
 * jQuery UI Droppable 1.13.2
13150
 * http://jqueryui.com
13151
 *
13152
 * Copyright jQuery Foundation and other contributors
13153
 * Released under the MIT license.
13154
 * http://jquery.org/license
13155
 */
13156
 
13157
//>>label: Droppable
13158
//>>group: Interactions
13159
//>>description: Enables drop targets for draggable elements.
13160
//>>docs: http://api.jqueryui.com/droppable/
13161
//>>demos: http://jqueryui.com/droppable/
13162
 
13163
 
13164
$.widget( "ui.droppable", {
13165
	version: "1.13.2",
13166
	widgetEventPrefix: "drop",
13167
	options: {
13168
		accept: "*",
13169
		addClasses: true,
13170
		greedy: false,
13171
		scope: "default",
13172
		tolerance: "intersect",
13173
 
13174
		// Callbacks
13175
		activate: null,
13176
		deactivate: null,
13177
		drop: null,
13178
		out: null,
13179
		over: null
13180
	},
13181
	_create: function() {
13182
 
13183
		var proportions,
13184
			o = this.options,
13185
			accept = o.accept;
13186
 
13187
		this.isover = false;
13188
		this.isout = true;
13189
 
13190
		this.accept = typeof accept === "function" ? accept : function( d ) {
13191
			return d.is( accept );
13192
		};
13193
 
13194
		this.proportions = function( /* valueToWrite */ ) {
13195
			if ( arguments.length ) {
13196
 
13197
				// Store the droppable's proportions
13198
				proportions = arguments[ 0 ];
13199
			} else {
13200
 
13201
				// Retrieve or derive the droppable's proportions
13202
				return proportions ?
13203
					proportions :
13204
					proportions = {
13205
						width: this.element[ 0 ].offsetWidth,
13206
						height: this.element[ 0 ].offsetHeight
13207
					};
13208
			}
13209
		};
13210
 
13211
		this._addToManager( o.scope );
13212
 
13213
		if ( o.addClasses ) {
13214
			this._addClass( "ui-droppable" );
13215
		}
13216
 
13217
	},
13218
 
13219
	_addToManager: function( scope ) {
13220
 
13221
		// Add the reference and positions to the manager
13222
		$.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
13223
		$.ui.ddmanager.droppables[ scope ].push( this );
13224
	},
13225
 
13226
	_splice: function( drop ) {
13227
		var i = 0;
13228
		for ( ; i < drop.length; i++ ) {
13229
			if ( drop[ i ] === this ) {
13230
				drop.splice( i, 1 );
13231
			}
13232
		}
13233
	},
13234
 
13235
	_destroy: function() {
13236
		var drop = $.ui.ddmanager.droppables[ this.options.scope ];
13237
 
13238
		this._splice( drop );
13239
	},
13240
 
13241
	_setOption: function( key, value ) {
13242
 
13243
		if ( key === "accept" ) {
13244
			this.accept = typeof value === "function" ? value : function( d ) {
13245
				return d.is( value );
13246
			};
13247
		} else if ( key === "scope" ) {
13248
			var drop = $.ui.ddmanager.droppables[ this.options.scope ];
13249
 
13250
			this._splice( drop );
13251
			this._addToManager( value );
13252
		}
13253
 
13254
		this._super( key, value );
13255
	},
13256
 
13257
	_activate: function( event ) {
13258
		var draggable = $.ui.ddmanager.current;
13259
 
13260
		this._addActiveClass();
13261
		if ( draggable ) {
13262
			this._trigger( "activate", event, this.ui( draggable ) );
13263
		}
13264
	},
13265
 
13266
	_deactivate: function( event ) {
13267
		var draggable = $.ui.ddmanager.current;
13268
 
13269
		this._removeActiveClass();
13270
		if ( draggable ) {
13271
			this._trigger( "deactivate", event, this.ui( draggable ) );
13272
		}
13273
	},
13274
 
13275
	_over: function( event ) {
13276
 
13277
		var draggable = $.ui.ddmanager.current;
13278
 
13279
		// Bail if draggable and droppable are same element
13280
		if ( !draggable || ( draggable.currentItem ||
13281
				draggable.element )[ 0 ] === this.element[ 0 ] ) {
13282
			return;
13283
		}
13284
 
13285
		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
13286
				draggable.element ) ) ) {
13287
			this._addHoverClass();
13288
			this._trigger( "over", event, this.ui( draggable ) );
13289
		}
13290
 
13291
	},
13292
 
13293
	_out: function( event ) {
13294
 
13295
		var draggable = $.ui.ddmanager.current;
13296
 
13297
		// Bail if draggable and droppable are same element
13298
		if ( !draggable || ( draggable.currentItem ||
13299
				draggable.element )[ 0 ] === this.element[ 0 ] ) {
13300
			return;
13301
		}
13302
 
13303
		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
13304
				draggable.element ) ) ) {
13305
			this._removeHoverClass();
13306
			this._trigger( "out", event, this.ui( draggable ) );
13307
		}
13308
 
13309
	},
13310
 
13311
	_drop: function( event, custom ) {
13312
 
13313
		var draggable = custom || $.ui.ddmanager.current,
13314
			childrenIntersection = false;
13315
 
13316
		// Bail if draggable and droppable are same element
13317
		if ( !draggable || ( draggable.currentItem ||
13318
				draggable.element )[ 0 ] === this.element[ 0 ] ) {
13319
			return false;
13320
		}
13321
 
13322
		this.element
13323
			.find( ":data(ui-droppable)" )
13324
			.not( ".ui-draggable-dragging" )
13325
			.each( function() {
13326
				var inst = $( this ).droppable( "instance" );
13327
				if (
13328
					inst.options.greedy &&
13329
					!inst.options.disabled &&
13330
					inst.options.scope === draggable.options.scope &&
13331
					inst.accept.call(
13332
						inst.element[ 0 ], ( draggable.currentItem || draggable.element )
13333
					) &&
13334
					$.ui.intersect(
13335
						draggable,
13336
						$.extend( inst, { offset: inst.element.offset() } ),
13337
						inst.options.tolerance, event
13338
					)
13339
				) {
13340
					childrenIntersection = true;
13341
					return false;
13342
				}
13343
			} );
13344
		if ( childrenIntersection ) {
13345
			return false;
13346
		}
13347
 
13348
		if ( this.accept.call( this.element[ 0 ],
13349
				( draggable.currentItem || draggable.element ) ) ) {
13350
			this._removeActiveClass();
13351
			this._removeHoverClass();
13352
 
13353
			this._trigger( "drop", event, this.ui( draggable ) );
13354
			return this.element;
13355
		}
13356
 
13357
		return false;
13358
 
13359
	},
13360
 
13361
	ui: function( c ) {
13362
		return {
13363
			draggable: ( c.currentItem || c.element ),
13364
			helper: c.helper,
13365
			position: c.position,
13366
			offset: c.positionAbs
13367
		};
13368
	},
13369
 
13370
	// Extension points just to make backcompat sane and avoid duplicating logic
13371
	// TODO: Remove in 1.14 along with call to it below
13372
	_addHoverClass: function() {
13373
		this._addClass( "ui-droppable-hover" );
13374
	},
13375
 
13376
	_removeHoverClass: function() {
13377
		this._removeClass( "ui-droppable-hover" );
13378
	},
13379
 
13380
	_addActiveClass: function() {
13381
		this._addClass( "ui-droppable-active" );
13382
	},
13383
 
13384
	_removeActiveClass: function() {
13385
		this._removeClass( "ui-droppable-active" );
13386
	}
13387
} );
13388
 
13389
$.ui.intersect = ( function() {
13390
	function isOverAxis( x, reference, size ) {
13391
		return ( x >= reference ) && ( x < ( reference + size ) );
13392
	}
13393
 
13394
	return function( draggable, droppable, toleranceMode, event ) {
13395
 
13396
		if ( !droppable.offset ) {
13397
			return false;
13398
		}
13399
 
13400
		var x1 = ( draggable.positionAbs ||
13401
				draggable.position.absolute ).left + draggable.margins.left,
13402
			y1 = ( draggable.positionAbs ||
13403
				draggable.position.absolute ).top + draggable.margins.top,
13404
			x2 = x1 + draggable.helperProportions.width,
13405
			y2 = y1 + draggable.helperProportions.height,
13406
			l = droppable.offset.left,
13407
			t = droppable.offset.top,
13408
			r = l + droppable.proportions().width,
13409
			b = t + droppable.proportions().height;
13410
 
13411
		switch ( toleranceMode ) {
13412
		case "fit":
13413
			return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
13414
		case "intersect":
13415
			return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
13416
				x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
13417
				t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
13418
				y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
13419
		case "pointer":
13420
			return isOverAxis( event.pageY, t, droppable.proportions().height ) &&
13421
				isOverAxis( event.pageX, l, droppable.proportions().width );
13422
		case "touch":
13423
			return (
13424
				( y1 >= t && y1 <= b ) || // Top edge touching
13425
				( y2 >= t && y2 <= b ) || // Bottom edge touching
13426
				( y1 < t && y2 > b ) // Surrounded vertically
13427
			) && (
13428
				( x1 >= l && x1 <= r ) || // Left edge touching
13429
				( x2 >= l && x2 <= r ) || // Right edge touching
13430
				( x1 < l && x2 > r ) // Surrounded horizontally
13431
			);
13432
		default:
13433
			return false;
13434
		}
13435
	};
13436
} )();
13437
 
13438
/*
13439
	This manager tracks offsets of draggables and droppables
13440
*/
13441
$.ui.ddmanager = {
13442
	current: null,
13443
	droppables: { "default": [] },
13444
	prepareOffsets: function( t, event ) {
13445
 
13446
		var i, j,
13447
			m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
13448
			type = event ? event.type : null, // workaround for #2317
13449
			list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
13450
 
13451
		droppablesLoop: for ( i = 0; i < m.length; i++ ) {
13452
 
13453
			// No disabled and non-accepted
13454
			if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ],
13455
					( t.currentItem || t.element ) ) ) ) {
13456
				continue;
13457
			}
13458
 
13459
			// Filter out elements in the current dragged item
13460
			for ( j = 0; j < list.length; j++ ) {
13461
				if ( list[ j ] === m[ i ].element[ 0 ] ) {
13462
					m[ i ].proportions().height = 0;
13463
					continue droppablesLoop;
13464
				}
13465
			}
13466
 
13467
			m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
13468
			if ( !m[ i ].visible ) {
13469
				continue;
13470
			}
13471
 
13472
			// Activate the droppable if used directly from draggables
13473
			if ( type === "mousedown" ) {
13474
				m[ i ]._activate.call( m[ i ], event );
13475
			}
13476
 
13477
			m[ i ].offset = m[ i ].element.offset();
13478
			m[ i ].proportions( {
13479
				width: m[ i ].element[ 0 ].offsetWidth,
13480
				height: m[ i ].element[ 0 ].offsetHeight
13481
			} );
13482
 
13483
		}
13484
 
13485
	},
13486
	drop: function( draggable, event ) {
13487
 
13488
		var dropped = false;
13489
 
13490
		// Create a copy of the droppables in case the list changes during the drop (#9116)
13491
		$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
13492
 
13493
			if ( !this.options ) {
13494
				return;
13495
			}
13496
			if ( !this.options.disabled && this.visible &&
13497
					$.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
13498
				dropped = this._drop.call( this, event ) || dropped;
13499
			}
13500
 
13501
			if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ],
13502
					( draggable.currentItem || draggable.element ) ) ) {
13503
				this.isout = true;
13504
				this.isover = false;
13505
				this._deactivate.call( this, event );
13506
			}
13507
 
13508
		} );
13509
		return dropped;
13510
 
13511
	},
13512
	dragStart: function( draggable, event ) {
13513
 
13514
		// Listen for scrolling so that if the dragging causes scrolling the position of the
13515
		// droppables can be recalculated (see #5003)
13516
		draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() {
13517
			if ( !draggable.options.refreshPositions ) {
13518
				$.ui.ddmanager.prepareOffsets( draggable, event );
13519
			}
13520
		} );
13521
	},
13522
	drag: function( draggable, event ) {
13523
 
13524
		// If you have a highly dynamic page, you might try this option. It renders positions
13525
		// every time you move the mouse.
13526
		if ( draggable.options.refreshPositions ) {
13527
			$.ui.ddmanager.prepareOffsets( draggable, event );
13528
		}
13529
 
13530
		// Run through all droppables and check their positions based on specific tolerance options
13531
		$.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
13532
 
13533
			if ( this.options.disabled || this.greedyChild || !this.visible ) {
13534
				return;
13535
			}
13536
 
13537
			var parentInstance, scope, parent,
13538
				intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
13539
				c = !intersects && this.isover ?
13540
					"isout" :
13541
					( intersects && !this.isover ? "isover" : null );
13542
			if ( !c ) {
13543
				return;
13544
			}
13545
 
13546
			if ( this.options.greedy ) {
13547
 
13548
				// find droppable parents with same scope
13549
				scope = this.options.scope;
13550
				parent = this.element.parents( ":data(ui-droppable)" ).filter( function() {
13551
					return $( this ).droppable( "instance" ).options.scope === scope;
13552
				} );
13553
 
13554
				if ( parent.length ) {
13555
					parentInstance = $( parent[ 0 ] ).droppable( "instance" );
13556
					parentInstance.greedyChild = ( c === "isover" );
13557
				}
13558
			}
13559
 
13560
			// We just moved into a greedy child
13561
			if ( parentInstance && c === "isover" ) {
13562
				parentInstance.isover = false;
13563
				parentInstance.isout = true;
13564
				parentInstance._out.call( parentInstance, event );
13565
			}
13566
 
13567
			this[ c ] = true;
13568
			this[ c === "isout" ? "isover" : "isout" ] = false;
13569
			this[ c === "isover" ? "_over" : "_out" ].call( this, event );
13570
 
13571
			// We just moved out of a greedy child
13572
			if ( parentInstance && c === "isout" ) {
13573
				parentInstance.isout = false;
13574
				parentInstance.isover = true;
13575
				parentInstance._over.call( parentInstance, event );
13576
			}
13577
		} );
13578
 
13579
	},
13580
	dragStop: function( draggable, event ) {
13581
		draggable.element.parentsUntil( "body" ).off( "scroll.droppable" );
13582
 
13583
		// Call prepareOffsets one final time since IE does not fire return scroll events when
13584
		// overflow was caused by drag (see #5003)
13585
		if ( !draggable.options.refreshPositions ) {
13586
			$.ui.ddmanager.prepareOffsets( draggable, event );
13587
		}
13588
	}
13589
};
13590
 
13591
// DEPRECATED
13592
// TODO: switch return back to widget declaration at top of file when this is removed
13593
if ( $.uiBackCompat !== false ) {
13594
 
13595
	// Backcompat for activeClass and hoverClass options
13596
	$.widget( "ui.droppable", $.ui.droppable, {
13597
		options: {
13598
			hoverClass: false,
13599
			activeClass: false
13600
		},
13601
		_addActiveClass: function() {
13602
			this._super();
13603
			if ( this.options.activeClass ) {
13604
				this.element.addClass( this.options.activeClass );
13605
			}
13606
		},
13607
		_removeActiveClass: function() {
13608
			this._super();
13609
			if ( this.options.activeClass ) {
13610
				this.element.removeClass( this.options.activeClass );
13611
			}
13612
		},
13613
		_addHoverClass: function() {
13614
			this._super();
13615
			if ( this.options.hoverClass ) {
13616
				this.element.addClass( this.options.hoverClass );
13617
			}
13618
		},
13619
		_removeHoverClass: function() {
13620
			this._super();
13621
			if ( this.options.hoverClass ) {
13622
				this.element.removeClass( this.options.hoverClass );
13623
			}
13624
		}
13625
	} );
13626
}
13627
 
13628
var widgetsDroppable = $.ui.droppable;
13629
 
13630
 
13631
/*!
13632
 * jQuery UI Progressbar 1.13.2
13633
 * http://jqueryui.com
13634
 *
13635
 * Copyright jQuery Foundation and other contributors
13636
 * Released under the MIT license.
13637
 * http://jquery.org/license
13638
 */
13639
 
13640
//>>label: Progressbar
13641
//>>group: Widgets
13642
/* eslint-disable max-len */
13643
//>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators.
13644
/* eslint-enable max-len */
13645
//>>docs: http://api.jqueryui.com/progressbar/
13646
//>>demos: http://jqueryui.com/progressbar/
13647
//>>css.structure: ../../themes/base/core.css
13648
//>>css.structure: ../../themes/base/progressbar.css
13649
//>>css.theme: ../../themes/base/theme.css
13650
 
13651
 
13652
var widgetsProgressbar = $.widget( "ui.progressbar", {
13653
	version: "1.13.2",
13654
	options: {
13655
		classes: {
13656
			"ui-progressbar": "ui-corner-all",
13657
			"ui-progressbar-value": "ui-corner-left",
13658
			"ui-progressbar-complete": "ui-corner-right"
13659
		},
13660
		max: 100,
13661
		value: 0,
13662
 
13663
		change: null,
13664
		complete: null
13665
	},
13666
 
13667
	min: 0,
13668
 
13669
	_create: function() {
13670
 
13671
		// Constrain initial value
13672
		this.oldValue = this.options.value = this._constrainedValue();
13673
 
13674
		this.element.attr( {
13675
 
13676
			// Only set static values; aria-valuenow and aria-valuemax are
13677
			// set inside _refreshValue()
13678
			role: "progressbar",
13679
			"aria-valuemin": this.min
13680
		} );
13681
		this._addClass( "ui-progressbar", "ui-widget ui-widget-content" );
13682
 
13683
		this.valueDiv = $( "<div>" ).appendTo( this.element );
13684
		this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" );
13685
		this._refreshValue();
13686
	},
13687
 
13688
	_destroy: function() {
13689
		this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" );
13690
 
13691
		this.valueDiv.remove();
13692
	},
13693
 
13694
	value: function( newValue ) {
13695
		if ( newValue === undefined ) {
13696
			return this.options.value;
13697
		}
13698
 
13699
		this.options.value = this._constrainedValue( newValue );
13700
		this._refreshValue();
13701
	},
13702
 
13703
	_constrainedValue: function( newValue ) {
13704
		if ( newValue === undefined ) {
13705
			newValue = this.options.value;
13706
		}
13707
 
13708
		this.indeterminate = newValue === false;
13709
 
13710
		// Sanitize value
13711
		if ( typeof newValue !== "number" ) {
13712
			newValue = 0;
13713
		}
13714
 
13715
		return this.indeterminate ? false :
13716
			Math.min( this.options.max, Math.max( this.min, newValue ) );
13717
	},
13718
 
13719
	_setOptions: function( options ) {
13720
 
13721
		// Ensure "value" option is set after other values (like max)
13722
		var value = options.value;
13723
		delete options.value;
13724
 
13725
		this._super( options );
13726
 
13727
		this.options.value = this._constrainedValue( value );
13728
		this._refreshValue();
13729
	},
13730
 
13731
	_setOption: function( key, value ) {
13732
		if ( key === "max" ) {
13733
 
13734
			// Don't allow a max less than min
13735
			value = Math.max( this.min, value );
13736
		}
13737
		this._super( key, value );
13738
	},
13739
 
13740
	_setOptionDisabled: function( value ) {
13741
		this._super( value );
13742
 
13743
		this.element.attr( "aria-disabled", value );
13744
		this._toggleClass( null, "ui-state-disabled", !!value );
13745
	},
13746
 
13747
	_percentage: function() {
13748
		return this.indeterminate ?
13749
			100 :
13750
			100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
13751
	},
13752
 
13753
	_refreshValue: function() {
13754
		var value = this.options.value,
13755
			percentage = this._percentage();
13756
 
13757
		this.valueDiv
13758
			.toggle( this.indeterminate || value > this.min )
13759
			.width( percentage.toFixed( 0 ) + "%" );
13760
 
13761
		this
13762
			._toggleClass( this.valueDiv, "ui-progressbar-complete", null,
13763
				value === this.options.max )
13764
			._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate );
13765
 
13766
		if ( this.indeterminate ) {
13767
			this.element.removeAttr( "aria-valuenow" );
13768
			if ( !this.overlayDiv ) {
13769
				this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv );
13770
				this._addClass( this.overlayDiv, "ui-progressbar-overlay" );
13771
			}
13772
		} else {
13773
			this.element.attr( {
13774
				"aria-valuemax": this.options.max,
13775
				"aria-valuenow": value
13776
			} );
13777
			if ( this.overlayDiv ) {
13778
				this.overlayDiv.remove();
13779
				this.overlayDiv = null;
13780
			}
13781
		}
13782
 
13783
		if ( this.oldValue !== value ) {
13784
			this.oldValue = value;
13785
			this._trigger( "change" );
13786
		}
13787
		if ( value === this.options.max ) {
13788
			this._trigger( "complete" );
13789
		}
13790
	}
13791
} );
13792
 
13793
 
13794
/*!
13795
 * jQuery UI Selectable 1.13.2
13796
 * http://jqueryui.com
13797
 *
13798
 * Copyright jQuery Foundation and other contributors
13799
 * Released under the MIT license.
13800
 * http://jquery.org/license
13801
 */
13802
 
13803
//>>label: Selectable
13804
//>>group: Interactions
13805
//>>description: Allows groups of elements to be selected with the mouse.
13806
//>>docs: http://api.jqueryui.com/selectable/
13807
//>>demos: http://jqueryui.com/selectable/
13808
//>>css.structure: ../../themes/base/selectable.css
13809
 
13810
 
13811
var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, {
13812
	version: "1.13.2",
13813
	options: {
13814
		appendTo: "body",
13815
		autoRefresh: true,
13816
		distance: 0,
13817
		filter: "*",
13818
		tolerance: "touch",
13819
 
13820
		// Callbacks
13821
		selected: null,
13822
		selecting: null,
13823
		start: null,
13824
		stop: null,
13825
		unselected: null,
13826
		unselecting: null
13827
	},
13828
	_create: function() {
13829
		var that = this;
13830
 
13831
		this._addClass( "ui-selectable" );
13832
 
13833
		this.dragged = false;
13834
 
13835
		// Cache selectee children based on filter
13836
		this.refresh = function() {
13837
			that.elementPos = $( that.element[ 0 ] ).offset();
13838
			that.selectees = $( that.options.filter, that.element[ 0 ] );
13839
			that._addClass( that.selectees, "ui-selectee" );
13840
			that.selectees.each( function() {
13841
				var $this = $( this ),
13842
					selecteeOffset = $this.offset(),
13843
					pos = {
13844
						left: selecteeOffset.left - that.elementPos.left,
13845
						top: selecteeOffset.top - that.elementPos.top
13846
					};
13847
				$.data( this, "selectable-item", {
13848
					element: this,
13849
					$element: $this,
13850
					left: pos.left,
13851
					top: pos.top,
13852
					right: pos.left + $this.outerWidth(),
13853
					bottom: pos.top + $this.outerHeight(),
13854
					startselected: false,
13855
					selected: $this.hasClass( "ui-selected" ),
13856
					selecting: $this.hasClass( "ui-selecting" ),
13857
					unselecting: $this.hasClass( "ui-unselecting" )
13858
				} );
13859
			} );
13860
		};
13861
		this.refresh();
13862
 
13863
		this._mouseInit();
13864
 
13865
		this.helper = $( "<div>" );
13866
		this._addClass( this.helper, "ui-selectable-helper" );
13867
	},
13868
 
13869
	_destroy: function() {
13870
		this.selectees.removeData( "selectable-item" );
13871
		this._mouseDestroy();
13872
	},
13873
 
13874
	_mouseStart: function( event ) {
13875
		var that = this,
13876
			options = this.options;
13877
 
13878
		this.opos = [ event.pageX, event.pageY ];
13879
		this.elementPos = $( this.element[ 0 ] ).offset();
13880
 
13881
		if ( this.options.disabled ) {
13882
			return;
13883
		}
13884
 
13885
		this.selectees = $( options.filter, this.element[ 0 ] );
13886
 
13887
		this._trigger( "start", event );
13888
 
13889
		$( options.appendTo ).append( this.helper );
13890
 
13891
		// position helper (lasso)
13892
		this.helper.css( {
13893
			"left": event.pageX,
13894
			"top": event.pageY,
13895
			"width": 0,
13896
			"height": 0
13897
		} );
13898
 
13899
		if ( options.autoRefresh ) {
13900
			this.refresh();
13901
		}
13902
 
13903
		this.selectees.filter( ".ui-selected" ).each( function() {
13904
			var selectee = $.data( this, "selectable-item" );
13905
			selectee.startselected = true;
13906
			if ( !event.metaKey && !event.ctrlKey ) {
13907
				that._removeClass( selectee.$element, "ui-selected" );
13908
				selectee.selected = false;
13909
				that._addClass( selectee.$element, "ui-unselecting" );
13910
				selectee.unselecting = true;
13911
 
13912
				// selectable UNSELECTING callback
13913
				that._trigger( "unselecting", event, {
13914
					unselecting: selectee.element
13915
				} );
13916
			}
13917
		} );
13918
 
13919
		$( event.target ).parents().addBack().each( function() {
13920
			var doSelect,
13921
				selectee = $.data( this, "selectable-item" );
13922
			if ( selectee ) {
13923
				doSelect = ( !event.metaKey && !event.ctrlKey ) ||
13924
					!selectee.$element.hasClass( "ui-selected" );
13925
				that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
13926
					._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
13927
				selectee.unselecting = !doSelect;
13928
				selectee.selecting = doSelect;
13929
				selectee.selected = doSelect;
13930
 
13931
				// selectable (UN)SELECTING callback
13932
				if ( doSelect ) {
13933
					that._trigger( "selecting", event, {
13934
						selecting: selectee.element
13935
					} );
13936
				} else {
13937
					that._trigger( "unselecting", event, {
13938
						unselecting: selectee.element
13939
					} );
13940
				}
13941
				return false;
13942
			}
13943
		} );
13944
 
13945
	},
13946
 
13947
	_mouseDrag: function( event ) {
13948
 
13949
		this.dragged = true;
13950
 
13951
		if ( this.options.disabled ) {
13952
			return;
13953
		}
13954
 
13955
		var tmp,
13956
			that = this,
13957
			options = this.options,
13958
			x1 = this.opos[ 0 ],
13959
			y1 = this.opos[ 1 ],
13960
			x2 = event.pageX,
13961
			y2 = event.pageY;
13962
 
13963
		if ( x1 > x2 ) {
13964
			tmp = x2; x2 = x1; x1 = tmp;
13965
		}
13966
		if ( y1 > y2 ) {
13967
			tmp = y2; y2 = y1; y1 = tmp;
13968
		}
13969
		this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
13970
 
13971
		this.selectees.each( function() {
13972
			var selectee = $.data( this, "selectable-item" ),
13973
				hit = false,
13974
				offset = {};
13975
 
13976
			//prevent helper from being selected if appendTo: selectable
13977
			if ( !selectee || selectee.element === that.element[ 0 ] ) {
13978
				return;
13979
			}
13980
 
13981
			offset.left   = selectee.left   + that.elementPos.left;
13982
			offset.right  = selectee.right  + that.elementPos.left;
13983
			offset.top    = selectee.top    + that.elementPos.top;
13984
			offset.bottom = selectee.bottom + that.elementPos.top;
13985
 
13986
			if ( options.tolerance === "touch" ) {
13987
				hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
13988
                    offset.bottom < y1 ) );
13989
			} else if ( options.tolerance === "fit" ) {
13990
				hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
13991
                    offset.bottom < y2 );
13992
			}
13993
 
13994
			if ( hit ) {
13995
 
13996
				// SELECT
13997
				if ( selectee.selected ) {
13998
					that._removeClass( selectee.$element, "ui-selected" );
13999
					selectee.selected = false;
14000
				}
14001
				if ( selectee.unselecting ) {
14002
					that._removeClass( selectee.$element, "ui-unselecting" );
14003
					selectee.unselecting = false;
14004
				}
14005
				if ( !selectee.selecting ) {
14006
					that._addClass( selectee.$element, "ui-selecting" );
14007
					selectee.selecting = true;
14008
 
14009
					// selectable SELECTING callback
14010
					that._trigger( "selecting", event, {
14011
						selecting: selectee.element
14012
					} );
14013
				}
14014
			} else {
14015
 
14016
				// UNSELECT
14017
				if ( selectee.selecting ) {
14018
					if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
14019
						that._removeClass( selectee.$element, "ui-selecting" );
14020
						selectee.selecting = false;
14021
						that._addClass( selectee.$element, "ui-selected" );
14022
						selectee.selected = true;
14023
					} else {
14024
						that._removeClass( selectee.$element, "ui-selecting" );
14025
						selectee.selecting = false;
14026
						if ( selectee.startselected ) {
14027
							that._addClass( selectee.$element, "ui-unselecting" );
14028
							selectee.unselecting = true;
14029
						}
14030
 
14031
						// selectable UNSELECTING callback
14032
						that._trigger( "unselecting", event, {
14033
							unselecting: selectee.element
14034
						} );
14035
					}
14036
				}
14037
				if ( selectee.selected ) {
14038
					if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
14039
						that._removeClass( selectee.$element, "ui-selected" );
14040
						selectee.selected = false;
14041
 
14042
						that._addClass( selectee.$element, "ui-unselecting" );
14043
						selectee.unselecting = true;
14044
 
14045
						// selectable UNSELECTING callback
14046
						that._trigger( "unselecting", event, {
14047
							unselecting: selectee.element
14048
						} );
14049
					}
14050
				}
14051
			}
14052
		} );
14053
 
14054
		return false;
14055
	},
14056
 
14057
	_mouseStop: function( event ) {
14058
		var that = this;
14059
 
14060
		this.dragged = false;
14061
 
14062
		$( ".ui-unselecting", this.element[ 0 ] ).each( function() {
14063
			var selectee = $.data( this, "selectable-item" );
14064
			that._removeClass( selectee.$element, "ui-unselecting" );
14065
			selectee.unselecting = false;
14066
			selectee.startselected = false;
14067
			that._trigger( "unselected", event, {
14068
				unselected: selectee.element
14069
			} );
14070
		} );
14071
		$( ".ui-selecting", this.element[ 0 ] ).each( function() {
14072
			var selectee = $.data( this, "selectable-item" );
14073
			that._removeClass( selectee.$element, "ui-selecting" )
14074
				._addClass( selectee.$element, "ui-selected" );
14075
			selectee.selecting = false;
14076
			selectee.selected = true;
14077
			selectee.startselected = true;
14078
			that._trigger( "selected", event, {
14079
				selected: selectee.element
14080
			} );
14081
		} );
14082
		this._trigger( "stop", event );
14083
 
14084
		this.helper.remove();
14085
 
14086
		return false;
14087
	}
14088
 
14089
} );
14090
 
14091
 
14092
/*!
14093
 * jQuery UI Selectmenu 1.13.2
14094
 * http://jqueryui.com
14095
 *
14096
 * Copyright jQuery Foundation and other contributors
14097
 * Released under the MIT license.
14098
 * http://jquery.org/license
14099
 */
14100
 
14101
//>>label: Selectmenu
14102
//>>group: Widgets
14103
/* eslint-disable max-len */
14104
//>>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.
14105
/* eslint-enable max-len */
14106
//>>docs: http://api.jqueryui.com/selectmenu/
14107
//>>demos: http://jqueryui.com/selectmenu/
14108
//>>css.structure: ../../themes/base/core.css
14109
//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css
14110
//>>css.theme: ../../themes/base/theme.css
14111
 
14112
 
14113
var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
14114
	version: "1.13.2",
14115
	defaultElement: "<select>",
14116
	options: {
14117
		appendTo: null,
14118
		classes: {
14119
			"ui-selectmenu-button-open": "ui-corner-top",
14120
			"ui-selectmenu-button-closed": "ui-corner-all"
14121
		},
14122
		disabled: null,
14123
		icons: {
14124
			button: "ui-icon-triangle-1-s"
14125
		},
14126
		position: {
14127
			my: "left top",
14128
			at: "left bottom",
14129
			collision: "none"
14130
		},
14131
		width: false,
14132
 
14133
		// Callbacks
14134
		change: null,
14135
		close: null,
14136
		focus: null,
14137
		open: null,
14138
		select: null
14139
	},
14140
 
14141
	_create: function() {
14142
		var selectmenuId = this.element.uniqueId().attr( "id" );
14143
		this.ids = {
14144
			element: selectmenuId,
14145
			button: selectmenuId + "-button",
14146
			menu: selectmenuId + "-menu"
14147
		};
14148
 
14149
		this._drawButton();
14150
		this._drawMenu();
14151
		this._bindFormResetHandler();
14152
 
14153
		this._rendered = false;
14154
		this.menuItems = $();
14155
	},
14156
 
14157
	_drawButton: function() {
14158
		var icon,
14159
			that = this,
14160
			item = this._parseOption(
14161
				this.element.find( "option:selected" ),
14162
				this.element[ 0 ].selectedIndex
14163
			);
14164
 
14165
		// Associate existing label with the new button
14166
		this.labels = this.element.labels().attr( "for", this.ids.button );
14167
		this._on( this.labels, {
14168
			click: function( event ) {
14169
				this.button.trigger( "focus" );
14170
				event.preventDefault();
14171
			}
14172
		} );
14173
 
14174
		// Hide original select element
14175
		this.element.hide();
14176
 
14177
		// Create button
14178
		this.button = $( "<span>", {
14179
			tabindex: this.options.disabled ? -1 : 0,
14180
			id: this.ids.button,
14181
			role: "combobox",
14182
			"aria-expanded": "false",
14183
			"aria-autocomplete": "list",
14184
			"aria-owns": this.ids.menu,
14185
			"aria-haspopup": "true",
14186
			title: this.element.attr( "title" )
14187
		} )
14188
			.insertAfter( this.element );
14189
 
14190
		this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed",
14191
			"ui-button ui-widget" );
14192
 
14193
		icon = $( "<span>" ).appendTo( this.button );
14194
		this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button );
14195
		this.buttonItem = this._renderButtonItem( item )
14196
			.appendTo( this.button );
14197
 
14198
		if ( this.options.width !== false ) {
14199
			this._resizeButton();
14200
		}
14201
 
14202
		this._on( this.button, this._buttonEvents );
14203
		this.button.one( "focusin", function() {
14204
 
14205
			// Delay rendering the menu items until the button receives focus.
14206
			// The menu may have already been rendered via a programmatic open.
14207
			if ( !that._rendered ) {
14208
				that._refreshMenu();
14209
			}
14210
		} );
14211
	},
14212
 
14213
	_drawMenu: function() {
14214
		var that = this;
14215
 
14216
		// Create menu
14217
		this.menu = $( "<ul>", {
14218
			"aria-hidden": "true",
14219
			"aria-labelledby": this.ids.button,
14220
			id: this.ids.menu
14221
		} );
14222
 
14223
		// Wrap menu
14224
		this.menuWrap = $( "<div>" ).append( this.menu );
14225
		this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" );
14226
		this.menuWrap.appendTo( this._appendTo() );
14227
 
14228
		// Initialize menu widget
14229
		this.menuInstance = this.menu
14230
			.menu( {
14231
				classes: {
14232
					"ui-menu": "ui-corner-bottom"
14233
				},
14234
				role: "listbox",
14235
				select: function( event, ui ) {
14236
					event.preventDefault();
14237
 
14238
					// Support: IE8
14239
					// If the item was selected via a click, the text selection
14240
					// will be destroyed in IE
14241
					that._setSelection();
14242
 
14243
					that._select( ui.item.data( "ui-selectmenu-item" ), event );
14244
				},
14245
				focus: function( event, ui ) {
14246
					var item = ui.item.data( "ui-selectmenu-item" );
14247
 
14248
					// Prevent inital focus from firing and check if its a newly focused item
14249
					if ( that.focusIndex != null && item.index !== that.focusIndex ) {
14250
						that._trigger( "focus", event, { item: item } );
14251
						if ( !that.isOpen ) {
14252
							that._select( item, event );
14253
						}
14254
					}
14255
					that.focusIndex = item.index;
14256
 
14257
					that.button.attr( "aria-activedescendant",
14258
						that.menuItems.eq( item.index ).attr( "id" ) );
14259
				}
14260
			} )
14261
			.menu( "instance" );
14262
 
14263
		// Don't close the menu on mouseleave
14264
		this.menuInstance._off( this.menu, "mouseleave" );
14265
 
14266
		// Cancel the menu's collapseAll on document click
14267
		this.menuInstance._closeOnDocumentClick = function() {
14268
			return false;
14269
		};
14270
 
14271
		// Selects often contain empty items, but never contain dividers
14272
		this.menuInstance._isDivider = function() {
14273
			return false;
14274
		};
14275
	},
14276
 
14277
	refresh: function() {
14278
		this._refreshMenu();
14279
		this.buttonItem.replaceWith(
14280
			this.buttonItem = this._renderButtonItem(
14281
 
14282
				// Fall back to an empty object in case there are no options
14283
				this._getSelectedItem().data( "ui-selectmenu-item" ) || {}
14284
			)
14285
		);
14286
		if ( this.options.width === null ) {
14287
			this._resizeButton();
14288
		}
14289
	},
14290
 
14291
	_refreshMenu: function() {
14292
		var item,
14293
			options = this.element.find( "option" );
14294
 
14295
		this.menu.empty();
14296
 
14297
		this._parseOptions( options );
14298
		this._renderMenu( this.menu, this.items );
14299
 
14300
		this.menuInstance.refresh();
14301
		this.menuItems = this.menu.find( "li" )
14302
			.not( ".ui-selectmenu-optgroup" )
14303
				.find( ".ui-menu-item-wrapper" );
14304
 
14305
		this._rendered = true;
14306
 
14307
		if ( !options.length ) {
14308
			return;
14309
		}
14310
 
14311
		item = this._getSelectedItem();
14312
 
14313
		// Update the menu to have the correct item focused
14314
		this.menuInstance.focus( null, item );
14315
		this._setAria( item.data( "ui-selectmenu-item" ) );
14316
 
14317
		// Set disabled state
14318
		this._setOption( "disabled", this.element.prop( "disabled" ) );
14319
	},
14320
 
14321
	open: function( event ) {
14322
		if ( this.options.disabled ) {
14323
			return;
14324
		}
14325
 
14326
		// If this is the first time the menu is being opened, render the items
14327
		if ( !this._rendered ) {
14328
			this._refreshMenu();
14329
		} else {
14330
 
14331
			// Menu clears focus on close, reset focus to selected item
14332
			this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" );
14333
			this.menuInstance.focus( null, this._getSelectedItem() );
14334
		}
14335
 
14336
		// If there are no options, don't open the menu
14337
		if ( !this.menuItems.length ) {
14338
			return;
14339
		}
14340
 
14341
		this.isOpen = true;
14342
		this._toggleAttr();
14343
		this._resizeMenu();
14344
		this._position();
14345
 
14346
		this._on( this.document, this._documentClick );
14347
 
14348
		this._trigger( "open", event );
14349
	},
14350
 
14351
	_position: function() {
14352
		this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
14353
	},
14354
 
14355
	close: function( event ) {
14356
		if ( !this.isOpen ) {
14357
			return;
14358
		}
14359
 
14360
		this.isOpen = false;
14361
		this._toggleAttr();
14362
 
14363
		this.range = null;
14364
		this._off( this.document );
14365
 
14366
		this._trigger( "close", event );
14367
	},
14368
 
14369
	widget: function() {
14370
		return this.button;
14371
	},
14372
 
14373
	menuWidget: function() {
14374
		return this.menu;
14375
	},
14376
 
14377
	_renderButtonItem: function( item ) {
14378
		var buttonItem = $( "<span>" );
14379
 
14380
		this._setText( buttonItem, item.label );
14381
		this._addClass( buttonItem, "ui-selectmenu-text" );
14382
 
14383
		return buttonItem;
14384
	},
14385
 
14386
	_renderMenu: function( ul, items ) {
14387
		var that = this,
14388
			currentOptgroup = "";
14389
 
14390
		$.each( items, function( index, item ) {
14391
			var li;
14392
 
14393
			if ( item.optgroup !== currentOptgroup ) {
14394
				li = $( "<li>", {
14395
					text: item.optgroup
14396
				} );
14397
				that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" +
14398
					( item.element.parent( "optgroup" ).prop( "disabled" ) ?
14399
						" ui-state-disabled" :
14400
						"" ) );
14401
 
14402
				li.appendTo( ul );
14403
 
14404
				currentOptgroup = item.optgroup;
14405
			}
14406
 
14407
			that._renderItemData( ul, item );
14408
		} );
14409
	},
14410
 
14411
	_renderItemData: function( ul, item ) {
14412
		return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
14413
	},
14414
 
14415
	_renderItem: function( ul, item ) {
14416
		var li = $( "<li>" ),
14417
			wrapper = $( "<div>", {
14418
				title: item.element.attr( "title" )
14419
			} );
14420
 
14421
		if ( item.disabled ) {
14422
			this._addClass( li, null, "ui-state-disabled" );
14423
		}
14424
		this._setText( wrapper, item.label );
14425
 
14426
		return li.append( wrapper ).appendTo( ul );
14427
	},
14428
 
14429
	_setText: function( element, value ) {
14430
		if ( value ) {
14431
			element.text( value );
14432
		} else {
14433
			element.html( "&#160;" );
14434
		}
14435
	},
14436
 
14437
	_move: function( direction, event ) {
14438
		var item, next,
14439
			filter = ".ui-menu-item";
14440
 
14441
		if ( this.isOpen ) {
14442
			item = this.menuItems.eq( this.focusIndex ).parent( "li" );
14443
		} else {
14444
			item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
14445
			filter += ":not(.ui-state-disabled)";
14446
		}
14447
 
14448
		if ( direction === "first" || direction === "last" ) {
14449
			next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
14450
		} else {
14451
			next = item[ direction + "All" ]( filter ).eq( 0 );
14452
		}
14453
 
14454
		if ( next.length ) {
14455
			this.menuInstance.focus( event, next );
14456
		}
14457
	},
14458
 
14459
	_getSelectedItem: function() {
14460
		return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
14461
	},
14462
 
14463
	_toggle: function( event ) {
14464
		this[ this.isOpen ? "close" : "open" ]( event );
14465
	},
14466
 
14467
	_setSelection: function() {
14468
		var selection;
14469
 
14470
		if ( !this.range ) {
14471
			return;
14472
		}
14473
 
14474
		if ( window.getSelection ) {
14475
			selection = window.getSelection();
14476
			selection.removeAllRanges();
14477
			selection.addRange( this.range );
14478
 
14479
		// Support: IE8
14480
		} else {
14481
			this.range.select();
14482
		}
14483
 
14484
		// Support: IE
14485
		// Setting the text selection kills the button focus in IE, but
14486
		// restoring the focus doesn't kill the selection.
14487
		this.button.trigger( "focus" );
14488
	},
14489
 
14490
	_documentClick: {
14491
		mousedown: function( event ) {
14492
			if ( !this.isOpen ) {
14493
				return;
14494
			}
14495
 
14496
			if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" +
14497
				$.escapeSelector( this.ids.button ) ).length ) {
14498
				this.close( event );
14499
			}
14500
		}
14501
	},
14502
 
14503
	_buttonEvents: {
14504
 
14505
		// Prevent text selection from being reset when interacting with the selectmenu (#10144)
14506
		mousedown: function() {
14507
			var selection;
14508
 
14509
			if ( window.getSelection ) {
14510
				selection = window.getSelection();
14511
				if ( selection.rangeCount ) {
14512
					this.range = selection.getRangeAt( 0 );
14513
				}
14514
 
14515
			// Support: IE8
14516
			} else {
14517
				this.range = document.selection.createRange();
14518
			}
14519
		},
14520
 
14521
		click: function( event ) {
14522
			this._setSelection();
14523
			this._toggle( event );
14524
		},
14525
 
14526
		keydown: function( event ) {
14527
			var preventDefault = true;
14528
			switch ( event.keyCode ) {
14529
			case $.ui.keyCode.TAB:
14530
			case $.ui.keyCode.ESCAPE:
14531
				this.close( event );
14532
				preventDefault = false;
14533
				break;
14534
			case $.ui.keyCode.ENTER:
14535
				if ( this.isOpen ) {
14536
					this._selectFocusedItem( event );
14537
				}
14538
				break;
14539
			case $.ui.keyCode.UP:
14540
				if ( event.altKey ) {
14541
					this._toggle( event );
14542
				} else {
14543
					this._move( "prev", event );
14544
				}
14545
				break;
14546
			case $.ui.keyCode.DOWN:
14547
				if ( event.altKey ) {
14548
					this._toggle( event );
14549
				} else {
14550
					this._move( "next", event );
14551
				}
14552
				break;
14553
			case $.ui.keyCode.SPACE:
14554
				if ( this.isOpen ) {
14555
					this._selectFocusedItem( event );
14556
				} else {
14557
					this._toggle( event );
14558
				}
14559
				break;
14560
			case $.ui.keyCode.LEFT:
14561
				this._move( "prev", event );
14562
				break;
14563
			case $.ui.keyCode.RIGHT:
14564
				this._move( "next", event );
14565
				break;
14566
			case $.ui.keyCode.HOME:
14567
			case $.ui.keyCode.PAGE_UP:
14568
				this._move( "first", event );
14569
				break;
14570
			case $.ui.keyCode.END:
14571
			case $.ui.keyCode.PAGE_DOWN:
14572
				this._move( "last", event );
14573
				break;
14574
			default:
14575
				this.menu.trigger( event );
14576
				preventDefault = false;
14577
			}
14578
 
14579
			if ( preventDefault ) {
14580
				event.preventDefault();
14581
			}
14582
		}
14583
	},
14584
 
14585
	_selectFocusedItem: function( event ) {
14586
		var item = this.menuItems.eq( this.focusIndex ).parent( "li" );
14587
		if ( !item.hasClass( "ui-state-disabled" ) ) {
14588
			this._select( item.data( "ui-selectmenu-item" ), event );
14589
		}
14590
	},
14591
 
14592
	_select: function( item, event ) {
14593
		var oldIndex = this.element[ 0 ].selectedIndex;
14594
 
14595
		// Change native select element
14596
		this.element[ 0 ].selectedIndex = item.index;
14597
		this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) );
14598
		this._setAria( item );
14599
		this._trigger( "select", event, { item: item } );
14600
 
14601
		if ( item.index !== oldIndex ) {
14602
			this._trigger( "change", event, { item: item } );
14603
		}
14604
 
14605
		this.close( event );
14606
	},
14607
 
14608
	_setAria: function( item ) {
14609
		var id = this.menuItems.eq( item.index ).attr( "id" );
14610
 
14611
		this.button.attr( {
14612
			"aria-labelledby": id,
14613
			"aria-activedescendant": id
14614
		} );
14615
		this.menu.attr( "aria-activedescendant", id );
14616
	},
14617
 
14618
	_setOption: function( key, value ) {
14619
		if ( key === "icons" ) {
14620
			var icon = this.button.find( "span.ui-icon" );
14621
			this._removeClass( icon, null, this.options.icons.button )
14622
				._addClass( icon, null, value.button );
14623
		}
14624
 
14625
		this._super( key, value );
14626
 
14627
		if ( key === "appendTo" ) {
14628
			this.menuWrap.appendTo( this._appendTo() );
14629
		}
14630
 
14631
		if ( key === "width" ) {
14632
			this._resizeButton();
14633
		}
14634
	},
14635
 
14636
	_setOptionDisabled: function( value ) {
14637
		this._super( value );
14638
 
14639
		this.menuInstance.option( "disabled", value );
14640
		this.button.attr( "aria-disabled", value );
14641
		this._toggleClass( this.button, null, "ui-state-disabled", value );
14642
 
14643
		this.element.prop( "disabled", value );
14644
		if ( value ) {
14645
			this.button.attr( "tabindex", -1 );
14646
			this.close();
14647
		} else {
14648
			this.button.attr( "tabindex", 0 );
14649
		}
14650
	},
14651
 
14652
	_appendTo: function() {
14653
		var element = this.options.appendTo;
14654
 
14655
		if ( element ) {
14656
			element = element.jquery || element.nodeType ?
14657
				$( element ) :
14658
				this.document.find( element ).eq( 0 );
14659
		}
14660
 
14661
		if ( !element || !element[ 0 ] ) {
14662
			element = this.element.closest( ".ui-front, dialog" );
14663
		}
14664
 
14665
		if ( !element.length ) {
14666
			element = this.document[ 0 ].body;
14667
		}
14668
 
14669
		return element;
14670
	},
14671
 
14672
	_toggleAttr: function() {
14673
		this.button.attr( "aria-expanded", this.isOpen );
14674
 
14675
		// We can't use two _toggleClass() calls here, because we need to make sure
14676
		// we always remove classes first and add them second, otherwise if both classes have the
14677
		// same theme class, it will be removed after we add it.
14678
		this._removeClass( this.button, "ui-selectmenu-button-" +
14679
			( this.isOpen ? "closed" : "open" ) )
14680
			._addClass( this.button, "ui-selectmenu-button-" +
14681
				( this.isOpen ? "open" : "closed" ) )
14682
			._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen );
14683
 
14684
		this.menu.attr( "aria-hidden", !this.isOpen );
14685
	},
14686
 
14687
	_resizeButton: function() {
14688
		var width = this.options.width;
14689
 
14690
		// For `width: false`, just remove inline style and stop
14691
		if ( width === false ) {
14692
			this.button.css( "width", "" );
14693
			return;
14694
		}
14695
 
14696
		// For `width: null`, match the width of the original element
14697
		if ( width === null ) {
14698
			width = this.element.show().outerWidth();
14699
			this.element.hide();
14700
		}
14701
 
14702
		this.button.outerWidth( width );
14703
	},
14704
 
14705
	_resizeMenu: function() {
14706
		this.menu.outerWidth( Math.max(
14707
			this.button.outerWidth(),
14708
 
14709
			// Support: IE10
14710
			// IE10 wraps long text (possibly a rounding bug)
14711
			// so we add 1px to avoid the wrapping
14712
			this.menu.width( "" ).outerWidth() + 1
14713
		) );
14714
	},
14715
 
14716
	_getCreateOptions: function() {
14717
		var options = this._super();
14718
 
14719
		options.disabled = this.element.prop( "disabled" );
14720
 
14721
		return options;
14722
	},
14723
 
14724
	_parseOptions: function( options ) {
14725
		var that = this,
14726
			data = [];
14727
		options.each( function( index, item ) {
14728
			if ( item.hidden ) {
14729
				return;
14730
			}
14731
 
14732
			data.push( that._parseOption( $( item ), index ) );
14733
		} );
14734
		this.items = data;
14735
	},
14736
 
14737
	_parseOption: function( option, index ) {
14738
		var optgroup = option.parent( "optgroup" );
14739
 
14740
		return {
14741
			element: option,
14742
			index: index,
14743
			value: option.val(),
14744
			label: option.text(),
14745
			optgroup: optgroup.attr( "label" ) || "",
14746
			disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
14747
		};
14748
	},
14749
 
14750
	_destroy: function() {
14751
		this._unbindFormResetHandler();
14752
		this.menuWrap.remove();
14753
		this.button.remove();
14754
		this.element.show();
14755
		this.element.removeUniqueId();
14756
		this.labels.attr( "for", this.ids.element );
14757
	}
14758
} ] );
14759
 
14760
 
14761
/*!
14762
 * jQuery UI Slider 1.13.2
14763
 * http://jqueryui.com
14764
 *
14765
 * Copyright jQuery Foundation and other contributors
14766
 * Released under the MIT license.
14767
 * http://jquery.org/license
14768
 */
14769
 
14770
//>>label: Slider
14771
//>>group: Widgets
14772
//>>description: Displays a flexible slider with ranges and accessibility via keyboard.
14773
//>>docs: http://api.jqueryui.com/slider/
14774
//>>demos: http://jqueryui.com/slider/
14775
//>>css.structure: ../../themes/base/core.css
14776
//>>css.structure: ../../themes/base/slider.css
14777
//>>css.theme: ../../themes/base/theme.css
14778
 
14779
 
14780
var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, {
14781
	version: "1.13.2",
14782
	widgetEventPrefix: "slide",
14783
 
14784
	options: {
14785
		animate: false,
14786
		classes: {
14787
			"ui-slider": "ui-corner-all",
14788
			"ui-slider-handle": "ui-corner-all",
14789
 
14790
			// Note: ui-widget-header isn't the most fittingly semantic framework class for this
14791
			// element, but worked best visually with a variety of themes
14792
			"ui-slider-range": "ui-corner-all ui-widget-header"
14793
		},
14794
		distance: 0,
14795
		max: 100,
14796
		min: 0,
14797
		orientation: "horizontal",
14798
		range: false,
14799
		step: 1,
14800
		value: 0,
14801
		values: null,
14802
 
14803
		// Callbacks
14804
		change: null,
14805
		slide: null,
14806
		start: null,
14807
		stop: null
14808
	},
14809
 
14810
	// Number of pages in a slider
14811
	// (how many times can you page up/down to go through the whole range)
14812
	numPages: 5,
14813
 
14814
	_create: function() {
14815
		this._keySliding = false;
14816
		this._mouseSliding = false;
14817
		this._animateOff = true;
14818
		this._handleIndex = null;
14819
		this._detectOrientation();
14820
		this._mouseInit();
14821
		this._calculateNewMax();
14822
 
14823
		this._addClass( "ui-slider ui-slider-" + this.orientation,
14824
			"ui-widget ui-widget-content" );
14825
 
14826
		this._refresh();
14827
 
14828
		this._animateOff = false;
14829
	},
14830
 
14831
	_refresh: function() {
14832
		this._createRange();
14833
		this._createHandles();
14834
		this._setupEvents();
14835
		this._refreshValue();
14836
	},
14837
 
14838
	_createHandles: function() {
14839
		var i, handleCount,
14840
			options = this.options,
14841
			existingHandles = this.element.find( ".ui-slider-handle" ),
14842
			handle = "<span tabindex='0'></span>",
14843
			handles = [];
14844
 
14845
		handleCount = ( options.values && options.values.length ) || 1;
14846
 
14847
		if ( existingHandles.length > handleCount ) {
14848
			existingHandles.slice( handleCount ).remove();
14849
			existingHandles = existingHandles.slice( 0, handleCount );
14850
		}
14851
 
14852
		for ( i = existingHandles.length; i < handleCount; i++ ) {
14853
			handles.push( handle );
14854
		}
14855
 
14856
		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
14857
 
14858
		this._addClass( this.handles, "ui-slider-handle", "ui-state-default" );
14859
 
14860
		this.handle = this.handles.eq( 0 );
14861
 
14862
		this.handles.each( function( i ) {
14863
			$( this )
14864
				.data( "ui-slider-handle-index", i )
14865
				.attr( "tabIndex", 0 );
14866
		} );
14867
	},
14868
 
14869
	_createRange: function() {
14870
		var options = this.options;
14871
 
14872
		if ( options.range ) {
14873
			if ( options.range === true ) {
14874
				if ( !options.values ) {
14875
					options.values = [ this._valueMin(), this._valueMin() ];
14876
				} else if ( options.values.length && options.values.length !== 2 ) {
14877
					options.values = [ options.values[ 0 ], options.values[ 0 ] ];
14878
				} else if ( Array.isArray( options.values ) ) {
14879
					options.values = options.values.slice( 0 );
14880
				}
14881
			}
14882
 
14883
			if ( !this.range || !this.range.length ) {
14884
				this.range = $( "<div>" )
14885
					.appendTo( this.element );
14886
 
14887
				this._addClass( this.range, "ui-slider-range" );
14888
			} else {
14889
				this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" );
14890
 
14891
				// Handle range switching from true to min/max
14892
				this.range.css( {
14893
					"left": "",
14894
					"bottom": ""
14895
				} );
14896
			}
14897
			if ( options.range === "min" || options.range === "max" ) {
14898
				this._addClass( this.range, "ui-slider-range-" + options.range );
14899
			}
14900
		} else {
14901
			if ( this.range ) {
14902
				this.range.remove();
14903
			}
14904
			this.range = null;
14905
		}
14906
	},
14907
 
14908
	_setupEvents: function() {
14909
		this._off( this.handles );
14910
		this._on( this.handles, this._handleEvents );
14911
		this._hoverable( this.handles );
14912
		this._focusable( this.handles );
14913
	},
14914
 
14915
	_destroy: function() {
14916
		this.handles.remove();
14917
		if ( this.range ) {
14918
			this.range.remove();
14919
		}
14920
 
14921
		this._mouseDestroy();
14922
	},
14923
 
14924
	_mouseCapture: function( event ) {
14925
		var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
14926
			that = this,
14927
			o = this.options;
14928
 
14929
		if ( o.disabled ) {
14930
			return false;
14931
		}
14932
 
14933
		this.elementSize = {
14934
			width: this.element.outerWidth(),
14935
			height: this.element.outerHeight()
14936
		};
14937
		this.elementOffset = this.element.offset();
14938
 
14939
		position = { x: event.pageX, y: event.pageY };
14940
		normValue = this._normValueFromMouse( position );
14941
		distance = this._valueMax() - this._valueMin() + 1;
14942
		this.handles.each( function( i ) {
14943
			var thisDistance = Math.abs( normValue - that.values( i ) );
14944
			if ( ( distance > thisDistance ) ||
14945
				( distance === thisDistance &&
14946
					( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) {
14947
				distance = thisDistance;
14948
				closestHandle = $( this );
14949
				index = i;
14950
			}
14951
		} );
14952
 
14953
		allowed = this._start( event, index );
14954
		if ( allowed === false ) {
14955
			return false;
14956
		}
14957
		this._mouseSliding = true;
14958
 
14959
		this._handleIndex = index;
14960
 
14961
		this._addClass( closestHandle, null, "ui-state-active" );
14962
		closestHandle.trigger( "focus" );
14963
 
14964
		offset = closestHandle.offset();
14965
		mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
14966
		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
14967
			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
14968
			top: event.pageY - offset.top -
14969
				( closestHandle.height() / 2 ) -
14970
				( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) -
14971
				( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) +
14972
				( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 )
14973
		};
14974
 
14975
		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
14976
			this._slide( event, index, normValue );
14977
		}
14978
		this._animateOff = true;
14979
		return true;
14980
	},
14981
 
14982
	_mouseStart: function() {
14983
		return true;
14984
	},
14985
 
14986
	_mouseDrag: function( event ) {
14987
		var position = { x: event.pageX, y: event.pageY },
14988
			normValue = this._normValueFromMouse( position );
14989
 
14990
		this._slide( event, this._handleIndex, normValue );
14991
 
14992
		return false;
14993
	},
14994
 
14995
	_mouseStop: function( event ) {
14996
		this._removeClass( this.handles, null, "ui-state-active" );
14997
		this._mouseSliding = false;
14998
 
14999
		this._stop( event, this._handleIndex );
15000
		this._change( event, this._handleIndex );
15001
 
15002
		this._handleIndex = null;
15003
		this._clickOffset = null;
15004
		this._animateOff = false;
15005
 
15006
		return false;
15007
	},
15008
 
15009
	_detectOrientation: function() {
15010
		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
15011
	},
15012
 
15013
	_normValueFromMouse: function( position ) {
15014
		var pixelTotal,
15015
			pixelMouse,
15016
			percentMouse,
15017
			valueTotal,
15018
			valueMouse;
15019
 
15020
		if ( this.orientation === "horizontal" ) {
15021
			pixelTotal = this.elementSize.width;
15022
			pixelMouse = position.x - this.elementOffset.left -
15023
				( this._clickOffset ? this._clickOffset.left : 0 );
15024
		} else {
15025
			pixelTotal = this.elementSize.height;
15026
			pixelMouse = position.y - this.elementOffset.top -
15027
				( this._clickOffset ? this._clickOffset.top : 0 );
15028
		}
15029
 
15030
		percentMouse = ( pixelMouse / pixelTotal );
15031
		if ( percentMouse > 1 ) {
15032
			percentMouse = 1;
15033
		}
15034
		if ( percentMouse < 0 ) {
15035
			percentMouse = 0;
15036
		}
15037
		if ( this.orientation === "vertical" ) {
15038
			percentMouse = 1 - percentMouse;
15039
		}
15040
 
15041
		valueTotal = this._valueMax() - this._valueMin();
15042
		valueMouse = this._valueMin() + percentMouse * valueTotal;
15043
 
15044
		return this._trimAlignValue( valueMouse );
15045
	},
15046
 
15047
	_uiHash: function( index, value, values ) {
15048
		var uiHash = {
15049
			handle: this.handles[ index ],
15050
			handleIndex: index,
15051
			value: value !== undefined ? value : this.value()
15052
		};
15053
 
15054
		if ( this._hasMultipleValues() ) {
15055
			uiHash.value = value !== undefined ? value : this.values( index );
15056
			uiHash.values = values || this.values();
15057
		}
15058
 
15059
		return uiHash;
15060
	},
15061
 
15062
	_hasMultipleValues: function() {
15063
		return this.options.values && this.options.values.length;
15064
	},
15065
 
15066
	_start: function( event, index ) {
15067
		return this._trigger( "start", event, this._uiHash( index ) );
15068
	},
15069
 
15070
	_slide: function( event, index, newVal ) {
15071
		var allowed, otherVal,
15072
			currentValue = this.value(),
15073
			newValues = this.values();
15074
 
15075
		if ( this._hasMultipleValues() ) {
15076
			otherVal = this.values( index ? 0 : 1 );
15077
			currentValue = this.values( index );
15078
 
15079
			if ( this.options.values.length === 2 && this.options.range === true ) {
15080
				newVal =  index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal );
15081
			}
15082
 
15083
			newValues[ index ] = newVal;
15084
		}
15085
 
15086
		if ( newVal === currentValue ) {
15087
			return;
15088
		}
15089
 
15090
		allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) );
15091
 
15092
		// A slide can be canceled by returning false from the slide callback
15093
		if ( allowed === false ) {
15094
			return;
15095
		}
15096
 
15097
		if ( this._hasMultipleValues() ) {
15098
			this.values( index, newVal );
15099
		} else {
15100
			this.value( newVal );
15101
		}
15102
	},
15103
 
15104
	_stop: function( event, index ) {
15105
		this._trigger( "stop", event, this._uiHash( index ) );
15106
	},
15107
 
15108
	_change: function( event, index ) {
15109
		if ( !this._keySliding && !this._mouseSliding ) {
15110
 
15111
			//store the last changed value index for reference when handles overlap
15112
			this._lastChangedValue = index;
15113
			this._trigger( "change", event, this._uiHash( index ) );
15114
		}
15115
	},
15116
 
15117
	value: function( newValue ) {
15118
		if ( arguments.length ) {
15119
			this.options.value = this._trimAlignValue( newValue );
15120
			this._refreshValue();
15121
			this._change( null, 0 );
15122
			return;
15123
		}
15124
 
15125
		return this._value();
15126
	},
15127
 
15128
	values: function( index, newValue ) {
15129
		var vals,
15130
			newValues,
15131
			i;
15132
 
15133
		if ( arguments.length > 1 ) {
15134
			this.options.values[ index ] = this._trimAlignValue( newValue );
15135
			this._refreshValue();
15136
			this._change( null, index );
15137
			return;
15138
		}
15139
 
15140
		if ( arguments.length ) {
15141
			if ( Array.isArray( arguments[ 0 ] ) ) {
15142
				vals = this.options.values;
15143
				newValues = arguments[ 0 ];
15144
				for ( i = 0; i < vals.length; i += 1 ) {
15145
					vals[ i ] = this._trimAlignValue( newValues[ i ] );
15146
					this._change( null, i );
15147
				}
15148
				this._refreshValue();
15149
			} else {
15150
				if ( this._hasMultipleValues() ) {
15151
					return this._values( index );
15152
				} else {
15153
					return this.value();
15154
				}
15155
			}
15156
		} else {
15157
			return this._values();
15158
		}
15159
	},
15160
 
15161
	_setOption: function( key, value ) {
15162
		var i,
15163
			valsLength = 0;
15164
 
15165
		if ( key === "range" && this.options.range === true ) {
15166
			if ( value === "min" ) {
15167
				this.options.value = this._values( 0 );
15168
				this.options.values = null;
15169
			} else if ( value === "max" ) {
15170
				this.options.value = this._values( this.options.values.length - 1 );
15171
				this.options.values = null;
15172
			}
15173
		}
15174
 
15175
		if ( Array.isArray( this.options.values ) ) {
15176
			valsLength = this.options.values.length;
15177
		}
15178
 
15179
		this._super( key, value );
15180
 
15181
		switch ( key ) {
15182
			case "orientation":
15183
				this._detectOrientation();
15184
				this._removeClass( "ui-slider-horizontal ui-slider-vertical" )
15185
					._addClass( "ui-slider-" + this.orientation );
15186
				this._refreshValue();
15187
				if ( this.options.range ) {
15188
					this._refreshRange( value );
15189
				}
15190
 
15191
				// Reset positioning from previous orientation
15192
				this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
15193
				break;
15194
			case "value":
15195
				this._animateOff = true;
15196
				this._refreshValue();
15197
				this._change( null, 0 );
15198
				this._animateOff = false;
15199
				break;
15200
			case "values":
15201
				this._animateOff = true;
15202
				this._refreshValue();
15203
 
15204
				// Start from the last handle to prevent unreachable handles (#9046)
15205
				for ( i = valsLength - 1; i >= 0; i-- ) {
15206
					this._change( null, i );
15207
				}
15208
				this._animateOff = false;
15209
				break;
15210
			case "step":
15211
			case "min":
15212
			case "max":
15213
				this._animateOff = true;
15214
				this._calculateNewMax();
15215
				this._refreshValue();
15216
				this._animateOff = false;
15217
				break;
15218
			case "range":
15219
				this._animateOff = true;
15220
				this._refresh();
15221
				this._animateOff = false;
15222
				break;
15223
		}
15224
	},
15225
 
15226
	_setOptionDisabled: function( value ) {
15227
		this._super( value );
15228
 
15229
		this._toggleClass( null, "ui-state-disabled", !!value );
15230
	},
15231
 
15232
	//internal value getter
15233
	// _value() returns value trimmed by min and max, aligned by step
15234
	_value: function() {
15235
		var val = this.options.value;
15236
		val = this._trimAlignValue( val );
15237
 
15238
		return val;
15239
	},
15240
 
15241
	//internal values getter
15242
	// _values() returns array of values trimmed by min and max, aligned by step
15243
	// _values( index ) returns single value trimmed by min and max, aligned by step
15244
	_values: function( index ) {
15245
		var val,
15246
			vals,
15247
			i;
15248
 
15249
		if ( arguments.length ) {
15250
			val = this.options.values[ index ];
15251
			val = this._trimAlignValue( val );
15252
 
15253
			return val;
15254
		} else if ( this._hasMultipleValues() ) {
15255
 
15256
			// .slice() creates a copy of the array
15257
			// this copy gets trimmed by min and max and then returned
15258
			vals = this.options.values.slice();
15259
			for ( i = 0; i < vals.length; i += 1 ) {
15260
				vals[ i ] = this._trimAlignValue( vals[ i ] );
15261
			}
15262
 
15263
			return vals;
15264
		} else {
15265
			return [];
15266
		}
15267
	},
15268
 
15269
	// Returns the step-aligned value that val is closest to, between (inclusive) min and max
15270
	_trimAlignValue: function( val ) {
15271
		if ( val <= this._valueMin() ) {
15272
			return this._valueMin();
15273
		}
15274
		if ( val >= this._valueMax() ) {
15275
			return this._valueMax();
15276
		}
15277
		var step = ( this.options.step > 0 ) ? this.options.step : 1,
15278
			valModStep = ( val - this._valueMin() ) % step,
15279
			alignValue = val - valModStep;
15280
 
15281
		if ( Math.abs( valModStep ) * 2 >= step ) {
15282
			alignValue += ( valModStep > 0 ) ? step : ( -step );
15283
		}
15284
 
15285
		// Since JavaScript has problems with large floats, round
15286
		// the final value to 5 digits after the decimal point (see #4124)
15287
		return parseFloat( alignValue.toFixed( 5 ) );
15288
	},
15289
 
15290
	_calculateNewMax: function() {
15291
		var max = this.options.max,
15292
			min = this._valueMin(),
15293
			step = this.options.step,
15294
			aboveMin = Math.round( ( max - min ) / step ) * step;
15295
		max = aboveMin + min;
15296
		if ( max > this.options.max ) {
15297
 
15298
			//If max is not divisible by step, rounding off may increase its value
15299
			max -= step;
15300
		}
15301
		this.max = parseFloat( max.toFixed( this._precision() ) );
15302
	},
15303
 
15304
	_precision: function() {
15305
		var precision = this._precisionOf( this.options.step );
15306
		if ( this.options.min !== null ) {
15307
			precision = Math.max( precision, this._precisionOf( this.options.min ) );
15308
		}
15309
		return precision;
15310
	},
15311
 
15312
	_precisionOf: function( num ) {
15313
		var str = num.toString(),
15314
			decimal = str.indexOf( "." );
15315
		return decimal === -1 ? 0 : str.length - decimal - 1;
15316
	},
15317
 
15318
	_valueMin: function() {
15319
		return this.options.min;
15320
	},
15321
 
15322
	_valueMax: function() {
15323
		return this.max;
15324
	},
15325
 
15326
	_refreshRange: function( orientation ) {
15327
		if ( orientation === "vertical" ) {
15328
			this.range.css( { "width": "", "left": "" } );
15329
		}
15330
		if ( orientation === "horizontal" ) {
15331
			this.range.css( { "height": "", "bottom": "" } );
15332
		}
15333
	},
15334
 
15335
	_refreshValue: function() {
15336
		var lastValPercent, valPercent, value, valueMin, valueMax,
15337
			oRange = this.options.range,
15338
			o = this.options,
15339
			that = this,
15340
			animate = ( !this._animateOff ) ? o.animate : false,
15341
			_set = {};
15342
 
15343
		if ( this._hasMultipleValues() ) {
15344
			this.handles.each( function( i ) {
15345
				valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() -
15346
					that._valueMin() ) * 100;
15347
				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
15348
				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
15349
				if ( that.options.range === true ) {
15350
					if ( that.orientation === "horizontal" ) {
15351
						if ( i === 0 ) {
15352
							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15353
								left: valPercent + "%"
15354
							}, o.animate );
15355
						}
15356
						if ( i === 1 ) {
15357
							that.range[ animate ? "animate" : "css" ]( {
15358
								width: ( valPercent - lastValPercent ) + "%"
15359
							}, {
15360
								queue: false,
15361
								duration: o.animate
15362
							} );
15363
						}
15364
					} else {
15365
						if ( i === 0 ) {
15366
							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15367
								bottom: ( valPercent ) + "%"
15368
							}, o.animate );
15369
						}
15370
						if ( i === 1 ) {
15371
							that.range[ animate ? "animate" : "css" ]( {
15372
								height: ( valPercent - lastValPercent ) + "%"
15373
							}, {
15374
								queue: false,
15375
								duration: o.animate
15376
							} );
15377
						}
15378
					}
15379
				}
15380
				lastValPercent = valPercent;
15381
			} );
15382
		} else {
15383
			value = this.value();
15384
			valueMin = this._valueMin();
15385
			valueMax = this._valueMax();
15386
			valPercent = ( valueMax !== valueMin ) ?
15387
					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
15388
					0;
15389
			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
15390
			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
15391
 
15392
			if ( oRange === "min" && this.orientation === "horizontal" ) {
15393
				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15394
					width: valPercent + "%"
15395
				}, o.animate );
15396
			}
15397
			if ( oRange === "max" && this.orientation === "horizontal" ) {
15398
				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15399
					width: ( 100 - valPercent ) + "%"
15400
				}, o.animate );
15401
			}
15402
			if ( oRange === "min" && this.orientation === "vertical" ) {
15403
				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15404
					height: valPercent + "%"
15405
				}, o.animate );
15406
			}
15407
			if ( oRange === "max" && this.orientation === "vertical" ) {
15408
				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15409
					height: ( 100 - valPercent ) + "%"
15410
				}, o.animate );
15411
			}
15412
		}
15413
	},
15414
 
15415
	_handleEvents: {
15416
		keydown: function( event ) {
15417
			var allowed, curVal, newVal, step,
15418
				index = $( event.target ).data( "ui-slider-handle-index" );
15419
 
15420
			switch ( event.keyCode ) {
15421
				case $.ui.keyCode.HOME:
15422
				case $.ui.keyCode.END:
15423
				case $.ui.keyCode.PAGE_UP:
15424
				case $.ui.keyCode.PAGE_DOWN:
15425
				case $.ui.keyCode.UP:
15426
				case $.ui.keyCode.RIGHT:
15427
				case $.ui.keyCode.DOWN:
15428
				case $.ui.keyCode.LEFT:
15429
					event.preventDefault();
15430
					if ( !this._keySliding ) {
15431
						this._keySliding = true;
15432
						this._addClass( $( event.target ), null, "ui-state-active" );
15433
						allowed = this._start( event, index );
15434
						if ( allowed === false ) {
15435
							return;
15436
						}
15437
					}
15438
					break;
15439
			}
15440
 
15441
			step = this.options.step;
15442
			if ( this._hasMultipleValues() ) {
15443
				curVal = newVal = this.values( index );
15444
			} else {
15445
				curVal = newVal = this.value();
15446
			}
15447
 
15448
			switch ( event.keyCode ) {
15449
				case $.ui.keyCode.HOME:
15450
					newVal = this._valueMin();
15451
					break;
15452
				case $.ui.keyCode.END:
15453
					newVal = this._valueMax();
15454
					break;
15455
				case $.ui.keyCode.PAGE_UP:
15456
					newVal = this._trimAlignValue(
15457
						curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
15458
					);
15459
					break;
15460
				case $.ui.keyCode.PAGE_DOWN:
15461
					newVal = this._trimAlignValue(
15462
						curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) );
15463
					break;
15464
				case $.ui.keyCode.UP:
15465
				case $.ui.keyCode.RIGHT:
15466
					if ( curVal === this._valueMax() ) {
15467
						return;
15468
					}
15469
					newVal = this._trimAlignValue( curVal + step );
15470
					break;
15471
				case $.ui.keyCode.DOWN:
15472
				case $.ui.keyCode.LEFT:
15473
					if ( curVal === this._valueMin() ) {
15474
						return;
15475
					}
15476
					newVal = this._trimAlignValue( curVal - step );
15477
					break;
15478
			}
15479
 
15480
			this._slide( event, index, newVal );
15481
		},
15482
		keyup: function( event ) {
15483
			var index = $( event.target ).data( "ui-slider-handle-index" );
15484
 
15485
			if ( this._keySliding ) {
15486
				this._keySliding = false;
15487
				this._stop( event, index );
15488
				this._change( event, index );
15489
				this._removeClass( $( event.target ), null, "ui-state-active" );
15490
			}
15491
		}
15492
	}
15493
} );
15494
 
15495
 
15496
/*!
15497
 * jQuery UI Sortable 1.13.2
15498
 * http://jqueryui.com
15499
 *
15500
 * Copyright jQuery Foundation and other contributors
15501
 * Released under the MIT license.
15502
 * http://jquery.org/license
15503
 */
15504
 
15505
//>>label: Sortable
15506
//>>group: Interactions
15507
//>>description: Enables items in a list to be sorted using the mouse.
15508
//>>docs: http://api.jqueryui.com/sortable/
15509
//>>demos: http://jqueryui.com/sortable/
15510
//>>css.structure: ../../themes/base/sortable.css
15511
 
15512
 
15513
var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, {
15514
	version: "1.13.2",
15515
	widgetEventPrefix: "sort",
15516
	ready: false,
15517
	options: {
15518
		appendTo: "parent",
15519
		axis: false,
15520
		connectWith: false,
15521
		containment: false,
15522
		cursor: "auto",
15523
		cursorAt: false,
15524
		dropOnEmpty: true,
15525
		forcePlaceholderSize: false,
15526
		forceHelperSize: false,
15527
		grid: false,
15528
		handle: false,
15529
		helper: "original",
15530
		items: "> *",
15531
		opacity: false,
15532
		placeholder: false,
15533
		revert: false,
15534
		scroll: true,
15535
		scrollSensitivity: 20,
15536
		scrollSpeed: 20,
15537
		scope: "default",
15538
		tolerance: "intersect",
15539
		zIndex: 1000,
15540
 
15541
		// Callbacks
15542
		activate: null,
15543
		beforeStop: null,
15544
		change: null,
15545
		deactivate: null,
15546
		out: null,
15547
		over: null,
15548
		receive: null,
15549
		remove: null,
15550
		sort: null,
15551
		start: null,
15552
		stop: null,
15553
		update: null
15554
	},
15555
 
15556
	_isOverAxis: function( x, reference, size ) {
15557
		return ( x >= reference ) && ( x < ( reference + size ) );
15558
	},
15559
 
15560
	_isFloating: function( item ) {
15561
		return ( /left|right/ ).test( item.css( "float" ) ) ||
15562
			( /inline|table-cell/ ).test( item.css( "display" ) );
15563
	},
15564
 
15565
	_create: function() {
15566
		this.containerCache = {};
15567
		this._addClass( "ui-sortable" );
15568
 
15569
		//Get the items
15570
		this.refresh();
15571
 
15572
		//Let's determine the parent's offset
15573
		this.offset = this.element.offset();
15574
 
15575
		//Initialize mouse events for interaction
15576
		this._mouseInit();
15577
 
15578
		this._setHandleClassName();
15579
 
15580
		//We're ready to go
15581
		this.ready = true;
15582
 
15583
	},
15584
 
15585
	_setOption: function( key, value ) {
15586
		this._super( key, value );
15587
 
15588
		if ( key === "handle" ) {
15589
			this._setHandleClassName();
15590
		}
15591
	},
15592
 
15593
	_setHandleClassName: function() {
15594
		var that = this;
15595
		this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" );
15596
		$.each( this.items, function() {
15597
			that._addClass(
15598
				this.instance.options.handle ?
15599
					this.item.find( this.instance.options.handle ) :
15600
					this.item,
15601
				"ui-sortable-handle"
15602
			);
15603
		} );
15604
	},
15605
 
15606
	_destroy: function() {
15607
		this._mouseDestroy();
15608
 
15609
		for ( var i = this.items.length - 1; i >= 0; i-- ) {
15610
			this.items[ i ].item.removeData( this.widgetName + "-item" );
15611
		}
15612
 
15613
		return this;
15614
	},
15615
 
15616
	_mouseCapture: function( event, overrideHandle ) {
15617
		var currentItem = null,
15618
			validHandle = false,
15619
			that = this;
15620
 
15621
		if ( this.reverting ) {
15622
			return false;
15623
		}
15624
 
15625
		if ( this.options.disabled || this.options.type === "static" ) {
15626
			return false;
15627
		}
15628
 
15629
		//We have to refresh the items data once first
15630
		this._refreshItems( event );
15631
 
15632
		//Find out if the clicked node (or one of its parents) is a actual item in this.items
15633
		$( event.target ).parents().each( function() {
15634
			if ( $.data( this, that.widgetName + "-item" ) === that ) {
15635
				currentItem = $( this );
15636
				return false;
15637
			}
15638
		} );
15639
		if ( $.data( event.target, that.widgetName + "-item" ) === that ) {
15640
			currentItem = $( event.target );
15641
		}
15642
 
15643
		if ( !currentItem ) {
15644
			return false;
15645
		}
15646
		if ( this.options.handle && !overrideHandle ) {
15647
			$( this.options.handle, currentItem ).find( "*" ).addBack().each( function() {
15648
				if ( this === event.target ) {
15649
					validHandle = true;
15650
				}
15651
			} );
15652
			if ( !validHandle ) {
15653
				return false;
15654
			}
15655
		}
15656
 
15657
		this.currentItem = currentItem;
15658
		this._removeCurrentsFromItems();
15659
		return true;
15660
 
15661
	},
15662
 
15663
	_mouseStart: function( event, overrideHandle, noActivation ) {
15664
 
15665
		var i, body,
15666
			o = this.options;
15667
 
15668
		this.currentContainer = this;
15669
 
15670
		//We only need to call refreshPositions, because the refreshItems call has been moved to
15671
		// mouseCapture
15672
		this.refreshPositions();
15673
 
15674
		//Prepare the dragged items parent
15675
		this.appendTo = $( o.appendTo !== "parent" ?
15676
				o.appendTo :
15677
				this.currentItem.parent() );
15678
 
15679
		//Create and append the visible helper
15680
		this.helper = this._createHelper( event );
15681
 
15682
		//Cache the helper size
15683
		this._cacheHelperProportions();
15684
 
15685
		/*
15686
		 * - Position generation -
15687
		 * This block generates everything position related - it's the core of draggables.
15688
		 */
15689
 
15690
		//Cache the margins of the original element
15691
		this._cacheMargins();
15692
 
15693
		//The element's absolute position on the page minus margins
15694
		this.offset = this.currentItem.offset();
15695
		this.offset = {
15696
			top: this.offset.top - this.margins.top,
15697
			left: this.offset.left - this.margins.left
15698
		};
15699
 
15700
		$.extend( this.offset, {
15701
			click: { //Where the click happened, relative to the element
15702
				left: event.pageX - this.offset.left,
15703
				top: event.pageY - this.offset.top
15704
			},
15705
 
15706
			// This is a relative to absolute position minus the actual position calculation -
15707
			// only used for relative positioned helper
15708
			relative: this._getRelativeOffset()
15709
		} );
15710
 
15711
		// After we get the helper offset, but before we get the parent offset we can
15712
		// change the helper's position to absolute
15713
		// TODO: Still need to figure out a way to make relative sorting possible
15714
		this.helper.css( "position", "absolute" );
15715
		this.cssPosition = this.helper.css( "position" );
15716
 
15717
		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
15718
		if ( o.cursorAt ) {
15719
			this._adjustOffsetFromHelper( o.cursorAt );
15720
		}
15721
 
15722
		//Cache the former DOM position
15723
		this.domPosition = {
15724
			prev: this.currentItem.prev()[ 0 ],
15725
			parent: this.currentItem.parent()[ 0 ]
15726
		};
15727
 
15728
		// If the helper is not the original, hide the original so it's not playing any role during
15729
		// the drag, won't cause anything bad this way
15730
		if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
15731
			this.currentItem.hide();
15732
		}
15733
 
15734
		//Create the placeholder
15735
		this._createPlaceholder();
15736
 
15737
		//Get the next scrolling parent
15738
		this.scrollParent = this.placeholder.scrollParent();
15739
 
15740
		$.extend( this.offset, {
15741
			parent: this._getParentOffset()
15742
		} );
15743
 
15744
		//Set a containment if given in the options
15745
		if ( o.containment ) {
15746
			this._setContainment();
15747
		}
15748
 
15749
		if ( o.cursor && o.cursor !== "auto" ) { // cursor option
15750
			body = this.document.find( "body" );
15751
 
15752
			// Support: IE
15753
			this.storedCursor = body.css( "cursor" );
15754
			body.css( "cursor", o.cursor );
15755
 
15756
			this.storedStylesheet =
15757
				$( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body );
15758
		}
15759
 
15760
		// We need to make sure to grab the zIndex before setting the
15761
		// opacity, because setting the opacity to anything lower than 1
15762
		// causes the zIndex to change from "auto" to 0.
15763
		if ( o.zIndex ) { // zIndex option
15764
			if ( this.helper.css( "zIndex" ) ) {
15765
				this._storedZIndex = this.helper.css( "zIndex" );
15766
			}
15767
			this.helper.css( "zIndex", o.zIndex );
15768
		}
15769
 
15770
		if ( o.opacity ) { // opacity option
15771
			if ( this.helper.css( "opacity" ) ) {
15772
				this._storedOpacity = this.helper.css( "opacity" );
15773
			}
15774
			this.helper.css( "opacity", o.opacity );
15775
		}
15776
 
15777
		//Prepare scrolling
15778
		if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
15779
				this.scrollParent[ 0 ].tagName !== "HTML" ) {
15780
			this.overflowOffset = this.scrollParent.offset();
15781
		}
15782
 
15783
		//Call callbacks
15784
		this._trigger( "start", event, this._uiHash() );
15785
 
15786
		//Recache the helper size
15787
		if ( !this._preserveHelperProportions ) {
15788
			this._cacheHelperProportions();
15789
		}
15790
 
15791
		//Post "activate" events to possible containers
15792
		if ( !noActivation ) {
15793
			for ( i = this.containers.length - 1; i >= 0; i-- ) {
15794
				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
15795
			}
15796
		}
15797
 
15798
		//Prepare possible droppables
15799
		if ( $.ui.ddmanager ) {
15800
			$.ui.ddmanager.current = this;
15801
		}
15802
 
15803
		if ( $.ui.ddmanager && !o.dropBehaviour ) {
15804
			$.ui.ddmanager.prepareOffsets( this, event );
15805
		}
15806
 
15807
		this.dragging = true;
15808
 
15809
		this._addClass( this.helper, "ui-sortable-helper" );
15810
 
15811
		//Move the helper, if needed
15812
		if ( !this.helper.parent().is( this.appendTo ) ) {
15813
			this.helper.detach().appendTo( this.appendTo );
15814
 
15815
			//Update position
15816
			this.offset.parent = this._getParentOffset();
15817
		}
15818
 
15819
		//Generate the original position
15820
		this.position = this.originalPosition = this._generatePosition( event );
15821
		this.originalPageX = event.pageX;
15822
		this.originalPageY = event.pageY;
15823
		this.lastPositionAbs = this.positionAbs = this._convertPositionTo( "absolute" );
15824
 
15825
		this._mouseDrag( event );
15826
 
15827
		return true;
15828
 
15829
	},
15830
 
15831
	_scroll: function( event ) {
15832
		var o = this.options,
15833
			scrolled = false;
15834
 
15835
		if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
15836
				this.scrollParent[ 0 ].tagName !== "HTML" ) {
15837
 
15838
			if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -
15839
					event.pageY < o.scrollSensitivity ) {
15840
				this.scrollParent[ 0 ].scrollTop =
15841
					scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;
15842
			} else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {
15843
				this.scrollParent[ 0 ].scrollTop =
15844
					scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;
15845
			}
15846
 
15847
			if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -
15848
					event.pageX < o.scrollSensitivity ) {
15849
				this.scrollParent[ 0 ].scrollLeft = scrolled =
15850
					this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;
15851
			} else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {
15852
				this.scrollParent[ 0 ].scrollLeft = scrolled =
15853
					this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;
15854
			}
15855
 
15856
		} else {
15857
 
15858
			if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {
15859
				scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );
15860
			} else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <
15861
					o.scrollSensitivity ) {
15862
				scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );
15863
			}
15864
 
15865
			if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {
15866
				scrolled = this.document.scrollLeft(
15867
					this.document.scrollLeft() - o.scrollSpeed
15868
				);
15869
			} else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <
15870
					o.scrollSensitivity ) {
15871
				scrolled = this.document.scrollLeft(
15872
					this.document.scrollLeft() + o.scrollSpeed
15873
				);
15874
			}
15875
 
15876
		}
15877
 
15878
		return scrolled;
15879
	},
15880
 
15881
	_mouseDrag: function( event ) {
15882
		var i, item, itemElement, intersection,
15883
			o = this.options;
15884
 
15885
		//Compute the helpers position
15886
		this.position = this._generatePosition( event );
15887
		this.positionAbs = this._convertPositionTo( "absolute" );
15888
 
15889
		//Set the helper position
15890
		if ( !this.options.axis || this.options.axis !== "y" ) {
15891
			this.helper[ 0 ].style.left = this.position.left + "px";
15892
		}
15893
		if ( !this.options.axis || this.options.axis !== "x" ) {
15894
			this.helper[ 0 ].style.top = this.position.top + "px";
15895
		}
15896
 
15897
		//Do scrolling
15898
		if ( o.scroll ) {
15899
			if ( this._scroll( event ) !== false ) {
15900
 
15901
				//Update item positions used in position checks
15902
				this._refreshItemPositions( true );
15903
 
15904
				if ( $.ui.ddmanager && !o.dropBehaviour ) {
15905
					$.ui.ddmanager.prepareOffsets( this, event );
15906
				}
15907
			}
15908
		}
15909
 
15910
		this.dragDirection = {
15911
			vertical: this._getDragVerticalDirection(),
15912
			horizontal: this._getDragHorizontalDirection()
15913
		};
15914
 
15915
		//Rearrange
15916
		for ( i = this.items.length - 1; i >= 0; i-- ) {
15917
 
15918
			//Cache variables and intersection, continue if no intersection
15919
			item = this.items[ i ];
15920
			itemElement = item.item[ 0 ];
15921
			intersection = this._intersectsWithPointer( item );
15922
			if ( !intersection ) {
15923
				continue;
15924
			}
15925
 
15926
			// Only put the placeholder inside the current Container, skip all
15927
			// items from other containers. This works because when moving
15928
			// an item from one container to another the
15929
			// currentContainer is switched before the placeholder is moved.
15930
			//
15931
			// Without this, moving items in "sub-sortables" can cause
15932
			// the placeholder to jitter between the outer and inner container.
15933
			if ( item.instance !== this.currentContainer ) {
15934
				continue;
15935
			}
15936
 
15937
			// Cannot intersect with itself
15938
			// no useless actions that have been done before
15939
			// no action if the item moved is the parent of the item checked
15940
			if ( itemElement !== this.currentItem[ 0 ] &&
15941
				this.placeholder[ intersection === 1 ?
15942
				"next" : "prev" ]()[ 0 ] !== itemElement &&
15943
				!$.contains( this.placeholder[ 0 ], itemElement ) &&
15944
				( this.options.type === "semi-dynamic" ?
15945
					!$.contains( this.element[ 0 ], itemElement ) :
15946
					true
15947
				)
15948
			) {
15949
 
15950
				this.direction = intersection === 1 ? "down" : "up";
15951
 
15952
				if ( this.options.tolerance === "pointer" ||
15953
						this._intersectsWithSides( item ) ) {
15954
					this._rearrange( event, item );
15955
				} else {
15956
					break;
15957
				}
15958
 
15959
				this._trigger( "change", event, this._uiHash() );
15960
				break;
15961
			}
15962
		}
15963
 
15964
		//Post events to containers
15965
		this._contactContainers( event );
15966
 
15967
		//Interconnect with droppables
15968
		if ( $.ui.ddmanager ) {
15969
			$.ui.ddmanager.drag( this, event );
15970
		}
15971
 
15972
		//Call callbacks
15973
		this._trigger( "sort", event, this._uiHash() );
15974
 
15975
		this.lastPositionAbs = this.positionAbs;
15976
		return false;
15977
 
15978
	},
15979
 
15980
	_mouseStop: function( event, noPropagation ) {
15981
 
15982
		if ( !event ) {
15983
			return;
15984
		}
15985
 
15986
		//If we are using droppables, inform the manager about the drop
15987
		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
15988
			$.ui.ddmanager.drop( this, event );
15989
		}
15990
 
15991
		if ( this.options.revert ) {
15992
			var that = this,
15993
				cur = this.placeholder.offset(),
15994
				axis = this.options.axis,
15995
				animation = {};
15996
 
15997
			if ( !axis || axis === "x" ) {
15998
				animation.left = cur.left - this.offset.parent.left - this.margins.left +
15999
					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
16000
 
16001
						this.offsetParent[ 0 ].scrollLeft
16002
					);
16003
			}
16004
			if ( !axis || axis === "y" ) {
16005
				animation.top = cur.top - this.offset.parent.top - this.margins.top +
16006
					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
16007
 
16008
						this.offsetParent[ 0 ].scrollTop
16009
					);
16010
			}
16011
			this.reverting = true;
16012
			$( this.helper ).animate(
16013
				animation,
16014
				parseInt( this.options.revert, 10 ) || 500,
16015
				function() {
16016
					that._clear( event );
16017
				}
16018
			);
16019
		} else {
16020
			this._clear( event, noPropagation );
16021
		}
16022
 
16023
		return false;
16024
 
16025
	},
16026
 
16027
	cancel: function() {
16028
 
16029
		if ( this.dragging ) {
16030
 
16031
			this._mouseUp( new $.Event( "mouseup", { target: null } ) );
16032
 
16033
			if ( this.options.helper === "original" ) {
16034
				this.currentItem.css( this._storedCSS );
16035
				this._removeClass( this.currentItem, "ui-sortable-helper" );
16036
			} else {
16037
				this.currentItem.show();
16038
			}
16039
 
16040
			//Post deactivating events to containers
16041
			for ( var i = this.containers.length - 1; i >= 0; i-- ) {
16042
				this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) );
16043
				if ( this.containers[ i ].containerCache.over ) {
16044
					this.containers[ i ]._trigger( "out", null, this._uiHash( this ) );
16045
					this.containers[ i ].containerCache.over = 0;
16046
				}
16047
			}
16048
 
16049
		}
16050
 
16051
		if ( this.placeholder ) {
16052
 
16053
			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
16054
			// it unbinds ALL events from the original node!
16055
			if ( this.placeholder[ 0 ].parentNode ) {
16056
				this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
16057
			}
16058
			if ( this.options.helper !== "original" && this.helper &&
16059
					this.helper[ 0 ].parentNode ) {
16060
				this.helper.remove();
16061
			}
16062
 
16063
			$.extend( this, {
16064
				helper: null,
16065
				dragging: false,
16066
				reverting: false,
16067
				_noFinalSort: null
16068
			} );
16069
 
16070
			if ( this.domPosition.prev ) {
16071
				$( this.domPosition.prev ).after( this.currentItem );
16072
			} else {
16073
				$( this.domPosition.parent ).prepend( this.currentItem );
16074
			}
16075
		}
16076
 
16077
		return this;
16078
 
16079
	},
16080
 
16081
	serialize: function( o ) {
16082
 
16083
		var items = this._getItemsAsjQuery( o && o.connected ),
16084
			str = [];
16085
		o = o || {};
16086
 
16087
		$( items ).each( function() {
16088
			var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" )
16089
				.match( o.expression || ( /(.+)[\-=_](.+)/ ) );
16090
			if ( res ) {
16091
				str.push(
16092
					( o.key || res[ 1 ] + "[]" ) +
16093
					"=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );
16094
			}
16095
		} );
16096
 
16097
		if ( !str.length && o.key ) {
16098
			str.push( o.key + "=" );
16099
		}
16100
 
16101
		return str.join( "&" );
16102
 
16103
	},
16104
 
16105
	toArray: function( o ) {
16106
 
16107
		var items = this._getItemsAsjQuery( o && o.connected ),
16108
			ret = [];
16109
 
16110
		o = o || {};
16111
 
16112
		items.each( function() {
16113
			ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" );
16114
		} );
16115
		return ret;
16116
 
16117
	},
16118
 
16119
	/* Be careful with the following core functions */
16120
	_intersectsWith: function( item ) {
16121
 
16122
		var x1 = this.positionAbs.left,
16123
			x2 = x1 + this.helperProportions.width,
16124
			y1 = this.positionAbs.top,
16125
			y2 = y1 + this.helperProportions.height,
16126
			l = item.left,
16127
			r = l + item.width,
16128
			t = item.top,
16129
			b = t + item.height,
16130
			dyClick = this.offset.click.top,
16131
			dxClick = this.offset.click.left,
16132
			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t &&
16133
				( y1 + dyClick ) < b ),
16134
			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l &&
16135
				( x1 + dxClick ) < r ),
16136
			isOverElement = isOverElementHeight && isOverElementWidth;
16137
 
16138
		if ( this.options.tolerance === "pointer" ||
16139
			this.options.forcePointerForContainers ||
16140
			( this.options.tolerance !== "pointer" &&
16141
				this.helperProportions[ this.floating ? "width" : "height" ] >
16142
				item[ this.floating ? "width" : "height" ] )
16143
		) {
16144
			return isOverElement;
16145
		} else {
16146
 
16147
			return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half
16148
				x2 - ( this.helperProportions.width / 2 ) < r && // Left Half
16149
				t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half
16150
				y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half
16151
 
16152
		}
16153
	},
16154
 
16155
	_intersectsWithPointer: function( item ) {
16156
		var verticalDirection, horizontalDirection,
16157
			isOverElementHeight = ( this.options.axis === "x" ) ||
16158
				this._isOverAxis(
16159
					this.positionAbs.top + this.offset.click.top, item.top, item.height ),
16160
			isOverElementWidth = ( this.options.axis === "y" ) ||
16161
				this._isOverAxis(
16162
					this.positionAbs.left + this.offset.click.left, item.left, item.width ),
16163
			isOverElement = isOverElementHeight && isOverElementWidth;
16164
 
16165
		if ( !isOverElement ) {
16166
			return false;
16167
		}
16168
 
16169
		verticalDirection = this.dragDirection.vertical;
16170
		horizontalDirection = this.dragDirection.horizontal;
16171
 
16172
		return this.floating ?
16173
			( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 ) :
16174
			( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) );
16175
 
16176
	},
16177
 
16178
	_intersectsWithSides: function( item ) {
16179
 
16180
		var isOverBottomHalf = this._isOverAxis( this.positionAbs.top +
16181
				this.offset.click.top, item.top + ( item.height / 2 ), item.height ),
16182
			isOverRightHalf = this._isOverAxis( this.positionAbs.left +
16183
				this.offset.click.left, item.left + ( item.width / 2 ), item.width ),
16184
			verticalDirection = this.dragDirection.vertical,
16185
			horizontalDirection = this.dragDirection.horizontal;
16186
 
16187
		if ( this.floating && horizontalDirection ) {
16188
			return ( ( horizontalDirection === "right" && isOverRightHalf ) ||
16189
				( horizontalDirection === "left" && !isOverRightHalf ) );
16190
		} else {
16191
			return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) ||
16192
				( verticalDirection === "up" && !isOverBottomHalf ) );
16193
		}
16194
 
16195
	},
16196
 
16197
	_getDragVerticalDirection: function() {
16198
		var delta = this.positionAbs.top - this.lastPositionAbs.top;
16199
		return delta !== 0 && ( delta > 0 ? "down" : "up" );
16200
	},
16201
 
16202
	_getDragHorizontalDirection: function() {
16203
		var delta = this.positionAbs.left - this.lastPositionAbs.left;
16204
		return delta !== 0 && ( delta > 0 ? "right" : "left" );
16205
	},
16206
 
16207
	refresh: function( event ) {
16208
		this._refreshItems( event );
16209
		this._setHandleClassName();
16210
		this.refreshPositions();
16211
		return this;
16212
	},
16213
 
16214
	_connectWith: function() {
16215
		var options = this.options;
16216
		return options.connectWith.constructor === String ?
16217
			[ options.connectWith ] :
16218
			options.connectWith;
16219
	},
16220
 
16221
	_getItemsAsjQuery: function( connected ) {
16222
 
16223
		var i, j, cur, inst,
16224
			items = [],
16225
			queries = [],
16226
			connectWith = this._connectWith();
16227
 
16228
		if ( connectWith && connected ) {
16229
			for ( i = connectWith.length - 1; i >= 0; i-- ) {
16230
				cur = $( connectWith[ i ], this.document[ 0 ] );
16231
				for ( j = cur.length - 1; j >= 0; j-- ) {
16232
					inst = $.data( cur[ j ], this.widgetFullName );
16233
					if ( inst && inst !== this && !inst.options.disabled ) {
16234
						queries.push( [ typeof inst.options.items === "function" ?
16235
							inst.options.items.call( inst.element ) :
16236
							$( inst.options.items, inst.element )
16237
								.not( ".ui-sortable-helper" )
16238
								.not( ".ui-sortable-placeholder" ), inst ] );
16239
					}
16240
				}
16241
			}
16242
		}
16243
 
16244
		queries.push( [ typeof this.options.items === "function" ?
16245
			this.options.items
16246
				.call( this.element, null, { options: this.options, item: this.currentItem } ) :
16247
			$( this.options.items, this.element )
16248
				.not( ".ui-sortable-helper" )
16249
				.not( ".ui-sortable-placeholder" ), this ] );
16250
 
16251
		function addItems() {
16252
			items.push( this );
16253
		}
16254
		for ( i = queries.length - 1; i >= 0; i-- ) {
16255
			queries[ i ][ 0 ].each( addItems );
16256
		}
16257
 
16258
		return $( items );
16259
 
16260
	},
16261
 
16262
	_removeCurrentsFromItems: function() {
16263
 
16264
		var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" );
16265
 
16266
		this.items = $.grep( this.items, function( item ) {
16267
			for ( var j = 0; j < list.length; j++ ) {
16268
				if ( list[ j ] === item.item[ 0 ] ) {
16269
					return false;
16270
				}
16271
			}
16272
			return true;
16273
		} );
16274
 
16275
	},
16276
 
16277
	_refreshItems: function( event ) {
16278
 
16279
		this.items = [];
16280
		this.containers = [ this ];
16281
 
16282
		var i, j, cur, inst, targetData, _queries, item, queriesLength,
16283
			items = this.items,
16284
			queries = [ [ typeof this.options.items === "function" ?
16285
				this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :
16286
				$( this.options.items, this.element ), this ] ],
16287
			connectWith = this._connectWith();
16288
 
16289
		//Shouldn't be run the first time through due to massive slow-down
16290
		if ( connectWith && this.ready ) {
16291
			for ( i = connectWith.length - 1; i >= 0; i-- ) {
16292
				cur = $( connectWith[ i ], this.document[ 0 ] );
16293
				for ( j = cur.length - 1; j >= 0; j-- ) {
16294
					inst = $.data( cur[ j ], this.widgetFullName );
16295
					if ( inst && inst !== this && !inst.options.disabled ) {
16296
						queries.push( [ typeof inst.options.items === "function" ?
16297
							inst.options.items
16298
								.call( inst.element[ 0 ], event, { item: this.currentItem } ) :
16299
							$( inst.options.items, inst.element ), inst ] );
16300
						this.containers.push( inst );
16301
					}
16302
				}
16303
			}
16304
		}
16305
 
16306
		for ( i = queries.length - 1; i >= 0; i-- ) {
16307
			targetData = queries[ i ][ 1 ];
16308
			_queries = queries[ i ][ 0 ];
16309
 
16310
			for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {
16311
				item = $( _queries[ j ] );
16312
 
16313
				// Data for target checking (mouse manager)
16314
				item.data( this.widgetName + "-item", targetData );
16315
 
16316
				items.push( {
16317
					item: item,
16318
					instance: targetData,
16319
					width: 0, height: 0,
16320
					left: 0, top: 0
16321
				} );
16322
			}
16323
		}
16324
 
16325
	},
16326
 
16327
	_refreshItemPositions: function( fast ) {
16328
		var i, item, t, p;
16329
 
16330
		for ( i = this.items.length - 1; i >= 0; i-- ) {
16331
			item = this.items[ i ];
16332
 
16333
			//We ignore calculating positions of all connected containers when we're not over them
16334
			if ( this.currentContainer && item.instance !== this.currentContainer &&
16335
					item.item[ 0 ] !== this.currentItem[ 0 ] ) {
16336
				continue;
16337
			}
16338
 
16339
			t = this.options.toleranceElement ?
16340
				$( this.options.toleranceElement, item.item ) :
16341
				item.item;
16342
 
16343
			if ( !fast ) {
16344
				item.width = t.outerWidth();
16345
				item.height = t.outerHeight();
16346
			}
16347
 
16348
			p = t.offset();
16349
			item.left = p.left;
16350
			item.top = p.top;
16351
		}
16352
	},
16353
 
16354
	refreshPositions: function( fast ) {
16355
 
16356
		// Determine whether items are being displayed horizontally
16357
		this.floating = this.items.length ?
16358
			this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
16359
			false;
16360
 
16361
		// This has to be redone because due to the item being moved out/into the offsetParent,
16362
		// the offsetParent's position will change
16363
		if ( this.offsetParent && this.helper ) {
16364
			this.offset.parent = this._getParentOffset();
16365
		}
16366
 
16367
		this._refreshItemPositions( fast );
16368
 
16369
		var i, p;
16370
 
16371
		if ( this.options.custom && this.options.custom.refreshContainers ) {
16372
			this.options.custom.refreshContainers.call( this );
16373
		} else {
16374
			for ( i = this.containers.length - 1; i >= 0; i-- ) {
16375
				p = this.containers[ i ].element.offset();
16376
				this.containers[ i ].containerCache.left = p.left;
16377
				this.containers[ i ].containerCache.top = p.top;
16378
				this.containers[ i ].containerCache.width =
16379
					this.containers[ i ].element.outerWidth();
16380
				this.containers[ i ].containerCache.height =
16381
					this.containers[ i ].element.outerHeight();
16382
			}
16383
		}
16384
 
16385
		return this;
16386
	},
16387
 
16388
	_createPlaceholder: function( that ) {
16389
		that = that || this;
16390
		var className, nodeName,
16391
			o = that.options;
16392
 
16393
		if ( !o.placeholder || o.placeholder.constructor === String ) {
16394
			className = o.placeholder;
16395
			nodeName = that.currentItem[ 0 ].nodeName.toLowerCase();
16396
			o.placeholder = {
16397
				element: function() {
16398
 
16399
					var element = $( "<" + nodeName + ">", that.document[ 0 ] );
16400
 
16401
					that._addClass( element, "ui-sortable-placeholder",
16402
							className || that.currentItem[ 0 ].className )
16403
						._removeClass( element, "ui-sortable-helper" );
16404
 
16405
					if ( nodeName === "tbody" ) {
16406
						that._createTrPlaceholder(
16407
							that.currentItem.find( "tr" ).eq( 0 ),
16408
							$( "<tr>", that.document[ 0 ] ).appendTo( element )
16409
						);
16410
					} else if ( nodeName === "tr" ) {
16411
						that._createTrPlaceholder( that.currentItem, element );
16412
					} else if ( nodeName === "img" ) {
16413
						element.attr( "src", that.currentItem.attr( "src" ) );
16414
					}
16415
 
16416
					if ( !className ) {
16417
						element.css( "visibility", "hidden" );
16418
					}
16419
 
16420
					return element;
16421
				},
16422
				update: function( container, p ) {
16423
 
16424
					// 1. If a className is set as 'placeholder option, we don't force sizes -
16425
					// the class is responsible for that
16426
					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a
16427
					// class name is specified
16428
					if ( className && !o.forcePlaceholderSize ) {
16429
						return;
16430
					}
16431
 
16432
					// If the element doesn't have a actual height or width by itself (without
16433
					// styles coming from a stylesheet), it receives the inline height and width
16434
					// from the dragged item. Or, if it's a tbody or tr, it's going to have a height
16435
					// anyway since we're populating them with <td>s above, but they're unlikely to
16436
					// be the correct height on their own if the row heights are dynamic, so we'll
16437
					// always assign the height of the dragged item given forcePlaceholderSize
16438
					// is true.
16439
					if ( !p.height() || ( o.forcePlaceholderSize &&
16440
							( nodeName === "tbody" || nodeName === "tr" ) ) ) {
16441
						p.height(
16442
							that.currentItem.innerHeight() -
16443
							parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) -
16444
							parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) );
16445
					}
16446
					if ( !p.width() ) {
16447
						p.width(
16448
							that.currentItem.innerWidth() -
16449
							parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) -
16450
							parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) );
16451
					}
16452
				}
16453
			};
16454
		}
16455
 
16456
		//Create the placeholder
16457
		that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );
16458
 
16459
		//Append it after the actual current item
16460
		that.currentItem.after( that.placeholder );
16461
 
16462
		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
16463
		o.placeholder.update( that, that.placeholder );
16464
 
16465
	},
16466
 
16467
	_createTrPlaceholder: function( sourceTr, targetTr ) {
16468
		var that = this;
16469
 
16470
		sourceTr.children().each( function() {
16471
			$( "<td>&#160;</td>", that.document[ 0 ] )
16472
				.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
16473
				.appendTo( targetTr );
16474
		} );
16475
	},
16476
 
16477
	_contactContainers: function( event ) {
16478
		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
16479
			floating, axis,
16480
			innermostContainer = null,
16481
			innermostIndex = null;
16482
 
16483
		// Get innermost container that intersects with item
16484
		for ( i = this.containers.length - 1; i >= 0; i-- ) {
16485
 
16486
			// Never consider a container that's located within the item itself
16487
			if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {
16488
				continue;
16489
			}
16490
 
16491
			if ( this._intersectsWith( this.containers[ i ].containerCache ) ) {
16492
 
16493
				// If we've already found a container and it's more "inner" than this, then continue
16494
				if ( innermostContainer &&
16495
						$.contains(
16496
							this.containers[ i ].element[ 0 ],
16497
							innermostContainer.element[ 0 ] ) ) {
16498
					continue;
16499
				}
16500
 
16501
				innermostContainer = this.containers[ i ];
16502
				innermostIndex = i;
16503
 
16504
			} else {
16505
 
16506
				// container doesn't intersect. trigger "out" event if necessary
16507
				if ( this.containers[ i ].containerCache.over ) {
16508
					this.containers[ i ]._trigger( "out", event, this._uiHash( this ) );
16509
					this.containers[ i ].containerCache.over = 0;
16510
				}
16511
			}
16512
 
16513
		}
16514
 
16515
		// If no intersecting containers found, return
16516
		if ( !innermostContainer ) {
16517
			return;
16518
		}
16519
 
16520
		// Move the item into the container if it's not there already
16521
		if ( this.containers.length === 1 ) {
16522
			if ( !this.containers[ innermostIndex ].containerCache.over ) {
16523
				this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
16524
				this.containers[ innermostIndex ].containerCache.over = 1;
16525
			}
16526
		} else {
16527
 
16528
			// When entering a new container, we will find the item with the least distance and
16529
			// append our item near it
16530
			dist = 10000;
16531
			itemWithLeastDistance = null;
16532
			floating = innermostContainer.floating || this._isFloating( this.currentItem );
16533
			posProperty = floating ? "left" : "top";
16534
			sizeProperty = floating ? "width" : "height";
16535
			axis = floating ? "pageX" : "pageY";
16536
 
16537
			for ( j = this.items.length - 1; j >= 0; j-- ) {
16538
				if ( !$.contains(
16539
						this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )
16540
				) {
16541
					continue;
16542
				}
16543
				if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {
16544
					continue;
16545
				}
16546
 
16547
				cur = this.items[ j ].item.offset()[ posProperty ];
16548
				nearBottom = false;
16549
				if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
16550
					nearBottom = true;
16551
				}
16552
 
16553
				if ( Math.abs( event[ axis ] - cur ) < dist ) {
16554
					dist = Math.abs( event[ axis ] - cur );
16555
					itemWithLeastDistance = this.items[ j ];
16556
					this.direction = nearBottom ? "up" : "down";
16557
				}
16558
			}
16559
 
16560
			//Check if dropOnEmpty is enabled
16561
			if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {
16562
				return;
16563
			}
16564
 
16565
			if ( this.currentContainer === this.containers[ innermostIndex ] ) {
16566
				if ( !this.currentContainer.containerCache.over ) {
16567
					this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
16568
					this.currentContainer.containerCache.over = 1;
16569
				}
16570
				return;
16571
			}
16572
 
16573
			if ( itemWithLeastDistance ) {
16574
				this._rearrange( event, itemWithLeastDistance, null, true );
16575
			} else {
16576
				this._rearrange( event, null, this.containers[ innermostIndex ].element, true );
16577
			}
16578
			this._trigger( "change", event, this._uiHash() );
16579
			this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) );
16580
			this.currentContainer = this.containers[ innermostIndex ];
16581
 
16582
			//Update the placeholder
16583
			this.options.placeholder.update( this.currentContainer, this.placeholder );
16584
 
16585
			//Update scrollParent
16586
			this.scrollParent = this.placeholder.scrollParent();
16587
 
16588
			//Update overflowOffset
16589
			if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16590
					this.scrollParent[ 0 ].tagName !== "HTML" ) {
16591
				this.overflowOffset = this.scrollParent.offset();
16592
			}
16593
 
16594
			this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
16595
			this.containers[ innermostIndex ].containerCache.over = 1;
16596
		}
16597
 
16598
	},
16599
 
16600
	_createHelper: function( event ) {
16601
 
16602
		var o = this.options,
16603
			helper = typeof o.helper === "function" ?
16604
				$( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :
16605
				( o.helper === "clone" ? this.currentItem.clone() : this.currentItem );
16606
 
16607
		//Add the helper to the DOM if that didn't happen already
16608
		if ( !helper.parents( "body" ).length ) {
16609
			this.appendTo[ 0 ].appendChild( helper[ 0 ] );
16610
		}
16611
 
16612
		if ( helper[ 0 ] === this.currentItem[ 0 ] ) {
16613
			this._storedCSS = {
16614
				width: this.currentItem[ 0 ].style.width,
16615
				height: this.currentItem[ 0 ].style.height,
16616
				position: this.currentItem.css( "position" ),
16617
				top: this.currentItem.css( "top" ),
16618
				left: this.currentItem.css( "left" )
16619
			};
16620
		}
16621
 
16622
		if ( !helper[ 0 ].style.width || o.forceHelperSize ) {
16623
			helper.width( this.currentItem.width() );
16624
		}
16625
		if ( !helper[ 0 ].style.height || o.forceHelperSize ) {
16626
			helper.height( this.currentItem.height() );
16627
		}
16628
 
16629
		return helper;
16630
 
16631
	},
16632
 
16633
	_adjustOffsetFromHelper: function( obj ) {
16634
		if ( typeof obj === "string" ) {
16635
			obj = obj.split( " " );
16636
		}
16637
		if ( Array.isArray( obj ) ) {
16638
			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
16639
		}
16640
		if ( "left" in obj ) {
16641
			this.offset.click.left = obj.left + this.margins.left;
16642
		}
16643
		if ( "right" in obj ) {
16644
			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
16645
		}
16646
		if ( "top" in obj ) {
16647
			this.offset.click.top = obj.top + this.margins.top;
16648
		}
16649
		if ( "bottom" in obj ) {
16650
			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
16651
		}
16652
	},
16653
 
16654
	_getParentOffset: function() {
16655
 
16656
		//Get the offsetParent and cache its position
16657
		this.offsetParent = this.helper.offsetParent();
16658
		var po = this.offsetParent.offset();
16659
 
16660
		// This is a special case where we need to modify a offset calculated on start, since the
16661
		// following happened:
16662
		// 1. The position of the helper is absolute, so it's position is calculated based on the
16663
		// next positioned parent
16664
		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
16665
		// the document, which means that the scroll is included in the initial calculation of the
16666
		// offset of the parent, and never recalculated upon drag
16667
		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16668
				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
16669
			po.left += this.scrollParent.scrollLeft();
16670
			po.top += this.scrollParent.scrollTop();
16671
		}
16672
 
16673
		// This needs to be actually done for all browsers, since pageX/pageY includes this
16674
		// information with an ugly IE fix
16675
		if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ||
16676
				( this.offsetParent[ 0 ].tagName &&
16677
				this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) {
16678
			po = { top: 0, left: 0 };
16679
		}
16680
 
16681
		return {
16682
			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
16683
			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
16684
		};
16685
 
16686
	},
16687
 
16688
	_getRelativeOffset: function() {
16689
 
16690
		if ( this.cssPosition === "relative" ) {
16691
			var p = this.currentItem.position();
16692
			return {
16693
				top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
16694
					this.scrollParent.scrollTop(),
16695
				left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
16696
					this.scrollParent.scrollLeft()
16697
			};
16698
		} else {
16699
			return { top: 0, left: 0 };
16700
		}
16701
 
16702
	},
16703
 
16704
	_cacheMargins: function() {
16705
		this.margins = {
16706
			left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ),
16707
			top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 )
16708
		};
16709
	},
16710
 
16711
	_cacheHelperProportions: function() {
16712
		this.helperProportions = {
16713
			width: this.helper.outerWidth(),
16714
			height: this.helper.outerHeight()
16715
		};
16716
	},
16717
 
16718
	_setContainment: function() {
16719
 
16720
		var ce, co, over,
16721
			o = this.options;
16722
		if ( o.containment === "parent" ) {
16723
			o.containment = this.helper[ 0 ].parentNode;
16724
		}
16725
		if ( o.containment === "document" || o.containment === "window" ) {
16726
			this.containment = [
16727
 
16728
 
16729
				o.containment === "document" ?
16730
					this.document.width() :
16731
					this.window.width() - this.helperProportions.width - this.margins.left,
16732
				( o.containment === "document" ?
16733
					( this.document.height() || document.body.parentNode.scrollHeight ) :
16734
					this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight
16735
				) - this.helperProportions.height - this.margins.top
16736
			];
16737
		}
16738
 
16739
		if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {
16740
			ce = $( o.containment )[ 0 ];
16741
			co = $( o.containment ).offset();
16742
			over = ( $( ce ).css( "overflow" ) !== "hidden" );
16743
 
16744
			this.containment = [
16745
				co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) +
16746
					( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left,
16747
				co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) +
16748
					( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top,
16749
				co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
16750
					( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) -
16751
					( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) -
16752
					this.helperProportions.width - this.margins.left,
16753
				co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
16754
					( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) -
16755
					( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) -
16756
					this.helperProportions.height - this.margins.top
16757
			];
16758
		}
16759
 
16760
	},
16761
 
16762
	_convertPositionTo: function( d, pos ) {
16763
 
16764
		if ( !pos ) {
16765
			pos = this.position;
16766
		}
16767
		var mod = d === "absolute" ? 1 : -1,
16768
			scroll = this.cssPosition === "absolute" &&
16769
				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16770
				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
16771
					this.offsetParent :
16772
					this.scrollParent,
16773
			scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
16774
 
16775
		return {
16776
			top: (
16777
 
16778
				// The absolute mouse position
16779
				pos.top	+
16780
 
16781
				// Only for relative positioned nodes: Relative offset from element to offset parent
16782
				this.offset.relative.top * mod +
16783
 
16784
				// The offsetParent's offset without borders (offset + border)
16785
				this.offset.parent.top * mod -
16786
				( ( this.cssPosition === "fixed" ?
16787
					-this.scrollParent.scrollTop() :
16788
					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )
16789
			),
16790
			left: (
16791
 
16792
				// The absolute mouse position
16793
				pos.left +
16794
 
16795
				// Only for relative positioned nodes: Relative offset from element to offset parent
16796
				this.offset.relative.left * mod +
16797
 
16798
				// The offsetParent's offset without borders (offset + border)
16799
				this.offset.parent.left * mod	-
16800
				( ( this.cssPosition === "fixed" ?
16801
					-this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
16802
					scroll.scrollLeft() ) * mod )
16803
			)
16804
		};
16805
 
16806
	},
16807
 
16808
	_generatePosition: function( event ) {
16809
 
16810
		var top, left,
16811
			o = this.options,
16812
			pageX = event.pageX,
16813
			pageY = event.pageY,
16814
			scroll = this.cssPosition === "absolute" &&
16815
				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16816
				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
16817
					this.offsetParent :
16818
					this.scrollParent,
16819
				scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
16820
 
16821
		// This is another very weird special case that only happens for relative elements:
16822
		// 1. If the css position is relative
16823
		// 2. and the scroll parent is the document or similar to the offset parent
16824
		// we have to refresh the relative offset during the scroll so there are no jumps
16825
		if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16826
				this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {
16827
			this.offset.relative = this._getRelativeOffset();
16828
		}
16829
 
16830
		/*
16831
		 * - Position constraining -
16832
		 * Constrain the position to a mix of grid, containment.
16833
		 */
16834
 
16835
		if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options
16836
 
16837
			if ( this.containment ) {
16838
				if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {
16839
					pageX = this.containment[ 0 ] + this.offset.click.left;
16840
				}
16841
				if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {
16842
					pageY = this.containment[ 1 ] + this.offset.click.top;
16843
				}
16844
				if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {
16845
					pageX = this.containment[ 2 ] + this.offset.click.left;
16846
				}
16847
				if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {
16848
					pageY = this.containment[ 3 ] + this.offset.click.top;
16849
				}
16850
			}
16851
 
16852
			if ( o.grid ) {
16853
				top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /
16854
					o.grid[ 1 ] ) * o.grid[ 1 ];
16855
				pageY = this.containment ?
16856
					( ( top - this.offset.click.top >= this.containment[ 1 ] &&
16857
						top - this.offset.click.top <= this.containment[ 3 ] ) ?
16858
							top :
16859
							( ( top - this.offset.click.top >= this.containment[ 1 ] ) ?
16860
								top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) :
16861
								top;
16862
 
16863
				left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /
16864
					o.grid[ 0 ] ) * o.grid[ 0 ];
16865
				pageX = this.containment ?
16866
					( ( left - this.offset.click.left >= this.containment[ 0 ] &&
16867
						left - this.offset.click.left <= this.containment[ 2 ] ) ?
16868
							left :
16869
							( ( left - this.offset.click.left >= this.containment[ 0 ] ) ?
16870
								left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) :
16871
								left;
16872
			}
16873
 
16874
		}
16875
 
16876
		return {
16877
			top: (
16878
 
16879
				// The absolute mouse position
16880
				pageY -
16881
 
16882
				// Click offset (relative to the element)
16883
				this.offset.click.top -
16884
 
16885
				// Only for relative positioned nodes: Relative offset from element to offset parent
16886
				this.offset.relative.top -
16887
 
16888
				// The offsetParent's offset without borders (offset + border)
16889
				this.offset.parent.top +
16890
				( ( this.cssPosition === "fixed" ?
16891
					-this.scrollParent.scrollTop() :
16892
					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )
16893
			),
16894
			left: (
16895
 
16896
				// The absolute mouse position
16897
				pageX -
16898
 
16899
				// Click offset (relative to the element)
16900
				this.offset.click.left -
16901
 
16902
				// Only for relative positioned nodes: Relative offset from element to offset parent
16903
				this.offset.relative.left -
16904
 
16905
				// The offsetParent's offset without borders (offset + border)
16906
				this.offset.parent.left +
16907
				( ( this.cssPosition === "fixed" ?
16908
					-this.scrollParent.scrollLeft() :
16909
					scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
16910
			)
16911
		};
16912
 
16913
	},
16914
 
16915
	_rearrange: function( event, i, a, hardRefresh ) {
16916
 
16917
		if ( a ) {
16918
			a[ 0 ].appendChild( this.placeholder[ 0 ] );
16919
		} else {
16920
			i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ],
16921
				( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) );
16922
		}
16923
 
16924
		//Various things done here to improve the performance:
16925
		// 1. we create a setTimeout, that calls refreshPositions
16926
		// 2. on the instance, we have a counter variable, that get's higher after every append
16927
		// 3. on the local scope, we copy the counter variable, and check in the timeout,
16928
		// if it's still the same
16929
		// 4. this lets only the last addition to the timeout stack through
16930
		this.counter = this.counter ? ++this.counter : 1;
16931
		var counter = this.counter;
16932
 
16933
		this._delay( function() {
16934
			if ( counter === this.counter ) {
16935
 
16936
				//Precompute after each DOM insertion, NOT on mousemove
16937
				this.refreshPositions( !hardRefresh );
16938
			}
16939
		} );
16940
 
16941
	},
16942
 
16943
	_clear: function( event, noPropagation ) {
16944
 
16945
		this.reverting = false;
16946
 
16947
		// We delay all events that have to be triggered to after the point where the placeholder
16948
		// has been removed and everything else normalized again
16949
		var i,
16950
			delayedTriggers = [];
16951
 
16952
		// We first have to update the dom position of the actual currentItem
16953
		// Note: don't do it if the current item is already removed (by a user), or it gets
16954
		// reappended (see #4088)
16955
		if ( !this._noFinalSort && this.currentItem.parent().length ) {
16956
			this.placeholder.before( this.currentItem );
16957
		}
16958
		this._noFinalSort = null;
16959
 
16960
		if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {
16961
			for ( i in this._storedCSS ) {
16962
				if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) {
16963
					this._storedCSS[ i ] = "";
16964
				}
16965
			}
16966
			this.currentItem.css( this._storedCSS );
16967
			this._removeClass( this.currentItem, "ui-sortable-helper" );
16968
		} else {
16969
			this.currentItem.show();
16970
		}
16971
 
16972
		if ( this.fromOutside && !noPropagation ) {
16973
			delayedTriggers.push( function( event ) {
16974
				this._trigger( "receive", event, this._uiHash( this.fromOutside ) );
16975
			} );
16976
		}
16977
		if ( ( this.fromOutside ||
16978
				this.domPosition.prev !==
16979
				this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] ||
16980
				this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {
16981
 
16982
			// Trigger update callback if the DOM position has changed
16983
			delayedTriggers.push( function( event ) {
16984
				this._trigger( "update", event, this._uiHash() );
16985
			} );
16986
		}
16987
 
16988
		// Check if the items Container has Changed and trigger appropriate
16989
		// events.
16990
		if ( this !== this.currentContainer ) {
16991
			if ( !noPropagation ) {
16992
				delayedTriggers.push( function( event ) {
16993
					this._trigger( "remove", event, this._uiHash() );
16994
				} );
16995
				delayedTriggers.push( ( function( c ) {
16996
					return function( event ) {
16997
						c._trigger( "receive", event, this._uiHash( this ) );
16998
					};
16999
				} ).call( this, this.currentContainer ) );
17000
				delayedTriggers.push( ( function( c ) {
17001
					return function( event ) {
17002
						c._trigger( "update", event, this._uiHash( this ) );
17003
					};
17004
				} ).call( this, this.currentContainer ) );
17005
			}
17006
		}
17007
 
17008
		//Post events to containers
17009
		function delayEvent( type, instance, container ) {
17010
			return function( event ) {
17011
				container._trigger( type, event, instance._uiHash( instance ) );
17012
			};
17013
		}
17014
		for ( i = this.containers.length - 1; i >= 0; i-- ) {
17015
			if ( !noPropagation ) {
17016
				delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
17017
			}
17018
			if ( this.containers[ i ].containerCache.over ) {
17019
				delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
17020
				this.containers[ i ].containerCache.over = 0;
17021
			}
17022
		}
17023
 
17024
		//Do what was originally in plugins
17025
		if ( this.storedCursor ) {
17026
			this.document.find( "body" ).css( "cursor", this.storedCursor );
17027
			this.storedStylesheet.remove();
17028
		}
17029
		if ( this._storedOpacity ) {
17030
			this.helper.css( "opacity", this._storedOpacity );
17031
		}
17032
		if ( this._storedZIndex ) {
17033
			this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex );
17034
		}
17035
 
17036
		this.dragging = false;
17037
 
17038
		if ( !noPropagation ) {
17039
			this._trigger( "beforeStop", event, this._uiHash() );
17040
		}
17041
 
17042
		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
17043
		// it unbinds ALL events from the original node!
17044
		this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
17045
 
17046
		if ( !this.cancelHelperRemoval ) {
17047
			if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
17048
				this.helper.remove();
17049
			}
17050
			this.helper = null;
17051
		}
17052
 
17053
		if ( !noPropagation ) {
17054
			for ( i = 0; i < delayedTriggers.length; i++ ) {
17055
 
17056
				// Trigger all delayed events
17057
				delayedTriggers[ i ].call( this, event );
17058
			}
17059
			this._trigger( "stop", event, this._uiHash() );
17060
		}
17061
 
17062
		this.fromOutside = false;
17063
		return !this.cancelHelperRemoval;
17064
 
17065
	},
17066
 
17067
	_trigger: function() {
17068
		if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {
17069
			this.cancel();
17070
		}
17071
	},
17072
 
17073
	_uiHash: function( _inst ) {
17074
		var inst = _inst || this;
17075
		return {
17076
			helper: inst.helper,
17077
			placeholder: inst.placeholder || $( [] ),
17078
			position: inst.position,
17079
			originalPosition: inst.originalPosition,
17080
			offset: inst.positionAbs,
17081
			item: inst.currentItem,
17082
			sender: _inst ? _inst.element : null
17083
		};
17084
	}
17085
 
17086
} );
17087
 
17088
 
17089
/*!
17090
 * jQuery UI Spinner 1.13.2
17091
 * http://jqueryui.com
17092
 *
17093
 * Copyright jQuery Foundation and other contributors
17094
 * Released under the MIT license.
17095
 * http://jquery.org/license
17096
 */
17097
 
17098
//>>label: Spinner
17099
//>>group: Widgets
17100
//>>description: Displays buttons to easily input numbers via the keyboard or mouse.
17101
//>>docs: http://api.jqueryui.com/spinner/
17102
//>>demos: http://jqueryui.com/spinner/
17103
//>>css.structure: ../../themes/base/core.css
17104
//>>css.structure: ../../themes/base/spinner.css
17105
//>>css.theme: ../../themes/base/theme.css
17106
 
17107
 
17108
function spinnerModifier( fn ) {
17109
	return function() {
17110
		var previous = this.element.val();
17111
		fn.apply( this, arguments );
17112
		this._refresh();
17113
		if ( previous !== this.element.val() ) {
17114
			this._trigger( "change" );
17115
		}
17116
	};
17117
}
17118
 
17119
$.widget( "ui.spinner", {
17120
	version: "1.13.2",
17121
	defaultElement: "<input>",
17122
	widgetEventPrefix: "spin",
17123
	options: {
17124
		classes: {
17125
			"ui-spinner": "ui-corner-all",
17126
			"ui-spinner-down": "ui-corner-br",
17127
			"ui-spinner-up": "ui-corner-tr"
17128
		},
17129
		culture: null,
17130
		icons: {
17131
			down: "ui-icon-triangle-1-s",
17132
			up: "ui-icon-triangle-1-n"
17133
		},
17134
		incremental: true,
17135
		max: null,
17136
		min: null,
17137
		numberFormat: null,
17138
		page: 10,
17139
		step: 1,
17140
 
17141
		change: null,
17142
		spin: null,
17143
		start: null,
17144
		stop: null
17145
	},
17146
 
17147
	_create: function() {
17148
 
17149
		// handle string values that need to be parsed
17150
		this._setOption( "max", this.options.max );
17151
		this._setOption( "min", this.options.min );
17152
		this._setOption( "step", this.options.step );
17153
 
17154
		// Only format if there is a value, prevents the field from being marked
17155
		// as invalid in Firefox, see #9573.
17156
		if ( this.value() !== "" ) {
17157
 
17158
			// Format the value, but don't constrain.
17159
			this._value( this.element.val(), true );
17160
		}
17161
 
17162
		this._draw();
17163
		this._on( this._events );
17164
		this._refresh();
17165
 
17166
		// Turning off autocomplete prevents the browser from remembering the
17167
		// value when navigating through history, so we re-enable autocomplete
17168
		// if the page is unloaded before the widget is destroyed. #7790
17169
		this._on( this.window, {
17170
			beforeunload: function() {
17171
				this.element.removeAttr( "autocomplete" );
17172
			}
17173
		} );
17174
	},
17175
 
17176
	_getCreateOptions: function() {
17177
		var options = this._super();
17178
		var element = this.element;
17179
 
17180
		$.each( [ "min", "max", "step" ], function( i, option ) {
17181
			var value = element.attr( option );
17182
			if ( value != null && value.length ) {
17183
				options[ option ] = value;
17184
			}
17185
		} );
17186
 
17187
		return options;
17188
	},
17189
 
17190
	_events: {
17191
		keydown: function( event ) {
17192
			if ( this._start( event ) && this._keydown( event ) ) {
17193
				event.preventDefault();
17194
			}
17195
		},
17196
		keyup: "_stop",
17197
		focus: function() {
17198
			this.previous = this.element.val();
17199
		},
17200
		blur: function( event ) {
17201
			if ( this.cancelBlur ) {
17202
				delete this.cancelBlur;
17203
				return;
17204
			}
17205
 
17206
			this._stop();
17207
			this._refresh();
17208
			if ( this.previous !== this.element.val() ) {
17209
				this._trigger( "change", event );
17210
			}
17211
		},
17212
		mousewheel: function( event, delta ) {
17213
			var activeElement = $.ui.safeActiveElement( this.document[ 0 ] );
17214
			var isActive = this.element[ 0 ] === activeElement;
17215
 
17216
			if ( !isActive || !delta ) {
17217
				return;
17218
			}
17219
 
17220
			if ( !this.spinning && !this._start( event ) ) {
17221
				return false;
17222
			}
17223
 
17224
			this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event );
17225
			clearTimeout( this.mousewheelTimer );
17226
			this.mousewheelTimer = this._delay( function() {
17227
				if ( this.spinning ) {
17228
					this._stop( event );
17229
				}
17230
			}, 100 );
17231
			event.preventDefault();
17232
		},
17233
		"mousedown .ui-spinner-button": function( event ) {
17234
			var previous;
17235
 
17236
			// We never want the buttons to have focus; whenever the user is
17237
			// interacting with the spinner, the focus should be on the input.
17238
			// If the input is focused then this.previous is properly set from
17239
			// when the input first received focus. If the input is not focused
17240
			// then we need to set this.previous based on the value before spinning.
17241
			previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ?
17242
				this.previous : this.element.val();
17243
			function checkFocus() {
17244
				var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] );
17245
				if ( !isActive ) {
17246
					this.element.trigger( "focus" );
17247
					this.previous = previous;
17248
 
17249
					// support: IE
17250
					// IE sets focus asynchronously, so we need to check if focus
17251
					// moved off of the input because the user clicked on the button.
17252
					this._delay( function() {
17253
						this.previous = previous;
17254
					} );
17255
				}
17256
			}
17257
 
17258
			// Ensure focus is on (or stays on) the text field
17259
			event.preventDefault();
17260
			checkFocus.call( this );
17261
 
17262
			// Support: IE
17263
			// IE doesn't prevent moving focus even with event.preventDefault()
17264
			// so we set a flag to know when we should ignore the blur event
17265
			// and check (again) if focus moved off of the input.
17266
			this.cancelBlur = true;
17267
			this._delay( function() {
17268
				delete this.cancelBlur;
17269
				checkFocus.call( this );
17270
			} );
17271
 
17272
			if ( this._start( event ) === false ) {
17273
				return;
17274
			}
17275
 
17276
			this._repeat( null, $( event.currentTarget )
17277
				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
17278
		},
17279
		"mouseup .ui-spinner-button": "_stop",
17280
		"mouseenter .ui-spinner-button": function( event ) {
17281
 
17282
			// button will add ui-state-active if mouse was down while mouseleave and kept down
17283
			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
17284
				return;
17285
			}
17286
 
17287
			if ( this._start( event ) === false ) {
17288
				return false;
17289
			}
17290
			this._repeat( null, $( event.currentTarget )
17291
				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
17292
		},
17293
 
17294
		// TODO: do we really want to consider this a stop?
17295
		// shouldn't we just stop the repeater and wait until mouseup before
17296
		// we trigger the stop event?
17297
		"mouseleave .ui-spinner-button": "_stop"
17298
	},
17299
 
17300
	// Support mobile enhanced option and make backcompat more sane
17301
	_enhance: function() {
17302
		this.uiSpinner = this.element
17303
			.attr( "autocomplete", "off" )
17304
			.wrap( "<span>" )
17305
			.parent()
17306
 
17307
				// Add buttons
17308
				.append(
17309
					"<a></a><a></a>"
17310
				);
17311
	},
17312
 
17313
	_draw: function() {
17314
		this._enhance();
17315
 
17316
		this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" );
17317
		this._addClass( "ui-spinner-input" );
17318
 
17319
		this.element.attr( "role", "spinbutton" );
17320
 
17321
		// Button bindings
17322
		this.buttons = this.uiSpinner.children( "a" )
17323
			.attr( "tabIndex", -1 )
17324
			.attr( "aria-hidden", true )
17325
			.button( {
17326
				classes: {
17327
					"ui-button": ""
17328
				}
17329
			} );
17330
 
17331
		// TODO: Right now button does not support classes this is already updated in button PR
17332
		this._removeClass( this.buttons, "ui-corner-all" );
17333
 
17334
		this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" );
17335
		this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" );
17336
		this.buttons.first().button( {
17337
			"icon": this.options.icons.up,
17338
			"showLabel": false
17339
		} );
17340
		this.buttons.last().button( {
17341
			"icon": this.options.icons.down,
17342
			"showLabel": false
17343
		} );
17344
 
17345
		// IE 6 doesn't understand height: 50% for the buttons
17346
		// unless the wrapper has an explicit height
17347
		if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) &&
17348
				this.uiSpinner.height() > 0 ) {
17349
			this.uiSpinner.height( this.uiSpinner.height() );
17350
		}
17351
	},
17352
 
17353
	_keydown: function( event ) {
17354
		var options = this.options,
17355
			keyCode = $.ui.keyCode;
17356
 
17357
		switch ( event.keyCode ) {
17358
		case keyCode.UP:
17359
			this._repeat( null, 1, event );
17360
			return true;
17361
		case keyCode.DOWN:
17362
			this._repeat( null, -1, event );
17363
			return true;
17364
		case keyCode.PAGE_UP:
17365
			this._repeat( null, options.page, event );
17366
			return true;
17367
		case keyCode.PAGE_DOWN:
17368
			this._repeat( null, -options.page, event );
17369
			return true;
17370
		}
17371
 
17372
		return false;
17373
	},
17374
 
17375
	_start: function( event ) {
17376
		if ( !this.spinning && this._trigger( "start", event ) === false ) {
17377
			return false;
17378
		}
17379
 
17380
		if ( !this.counter ) {
17381
			this.counter = 1;
17382
		}
17383
		this.spinning = true;
17384
		return true;
17385
	},
17386
 
17387
	_repeat: function( i, steps, event ) {
17388
		i = i || 500;
17389
 
17390
		clearTimeout( this.timer );
17391
		this.timer = this._delay( function() {
17392
			this._repeat( 40, steps, event );
17393
		}, i );
17394
 
17395
		this._spin( steps * this.options.step, event );
17396
	},
17397
 
17398
	_spin: function( step, event ) {
17399
		var value = this.value() || 0;
17400
 
17401
		if ( !this.counter ) {
17402
			this.counter = 1;
17403
		}
17404
 
17405
		value = this._adjustValue( value + step * this._increment( this.counter ) );
17406
 
17407
		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) {
17408
			this._value( value );
17409
			this.counter++;
17410
		}
17411
	},
17412
 
17413
	_increment: function( i ) {
17414
		var incremental = this.options.incremental;
17415
 
17416
		if ( incremental ) {
17417
			return typeof incremental === "function" ?
17418
				incremental( i ) :
17419
				Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
17420
		}
17421
 
17422
		return 1;
17423
	},
17424
 
17425
	_precision: function() {
17426
		var precision = this._precisionOf( this.options.step );
17427
		if ( this.options.min !== null ) {
17428
			precision = Math.max( precision, this._precisionOf( this.options.min ) );
17429
		}
17430
		return precision;
17431
	},
17432
 
17433
	_precisionOf: function( num ) {
17434
		var str = num.toString(),
17435
			decimal = str.indexOf( "." );
17436
		return decimal === -1 ? 0 : str.length - decimal - 1;
17437
	},
17438
 
17439
	_adjustValue: function( value ) {
17440
		var base, aboveMin,
17441
			options = this.options;
17442
 
17443
		// Make sure we're at a valid step
17444
		// - find out where we are relative to the base (min or 0)
17445
		base = options.min !== null ? options.min : 0;
17446
		aboveMin = value - base;
17447
 
17448
		// - round to the nearest step
17449
		aboveMin = Math.round( aboveMin / options.step ) * options.step;
17450
 
17451
		// - rounding is based on 0, so adjust back to our base
17452
		value = base + aboveMin;
17453
 
17454
		// Fix precision from bad JS floating point math
17455
		value = parseFloat( value.toFixed( this._precision() ) );
17456
 
17457
		// Clamp the value
17458
		if ( options.max !== null && value > options.max ) {
17459
			return options.max;
17460
		}
17461
		if ( options.min !== null && value < options.min ) {
17462
			return options.min;
17463
		}
17464
 
17465
		return value;
17466
	},
17467
 
17468
	_stop: function( event ) {
17469
		if ( !this.spinning ) {
17470
			return;
17471
		}
17472
 
17473
		clearTimeout( this.timer );
17474
		clearTimeout( this.mousewheelTimer );
17475
		this.counter = 0;
17476
		this.spinning = false;
17477
		this._trigger( "stop", event );
17478
	},
17479
 
17480
	_setOption: function( key, value ) {
17481
		var prevValue, first, last;
17482
 
17483
		if ( key === "culture" || key === "numberFormat" ) {
17484
			prevValue = this._parse( this.element.val() );
17485
			this.options[ key ] = value;
17486
			this.element.val( this._format( prevValue ) );
17487
			return;
17488
		}
17489
 
17490
		if ( key === "max" || key === "min" || key === "step" ) {
17491
			if ( typeof value === "string" ) {
17492
				value = this._parse( value );
17493
			}
17494
		}
17495
		if ( key === "icons" ) {
17496
			first = this.buttons.first().find( ".ui-icon" );
17497
			this._removeClass( first, null, this.options.icons.up );
17498
			this._addClass( first, null, value.up );
17499
			last = this.buttons.last().find( ".ui-icon" );
17500
			this._removeClass( last, null, this.options.icons.down );
17501
			this._addClass( last, null, value.down );
17502
		}
17503
 
17504
		this._super( key, value );
17505
	},
17506
 
17507
	_setOptionDisabled: function( value ) {
17508
		this._super( value );
17509
 
17510
		this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value );
17511
		this.element.prop( "disabled", !!value );
17512
		this.buttons.button( value ? "disable" : "enable" );
17513
	},
17514
 
17515
	_setOptions: spinnerModifier( function( options ) {
17516
		this._super( options );
17517
	} ),
17518
 
17519
	_parse: function( val ) {
17520
		if ( typeof val === "string" && val !== "" ) {
17521
			val = window.Globalize && this.options.numberFormat ?
17522
				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
17523
		}
17524
		return val === "" || isNaN( val ) ? null : val;
17525
	},
17526
 
17527
	_format: function( value ) {
17528
		if ( value === "" ) {
17529
			return "";
17530
		}
17531
		return window.Globalize && this.options.numberFormat ?
17532
			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
17533
			value;
17534
	},
17535
 
17536
	_refresh: function() {
17537
		this.element.attr( {
17538
			"aria-valuemin": this.options.min,
17539
			"aria-valuemax": this.options.max,
17540
 
17541
			// TODO: what should we do with values that can't be parsed?
17542
			"aria-valuenow": this._parse( this.element.val() )
17543
		} );
17544
	},
17545
 
17546
	isValid: function() {
17547
		var value = this.value();
17548
 
17549
		// Null is invalid
17550
		if ( value === null ) {
17551
			return false;
17552
		}
17553
 
17554
		// If value gets adjusted, it's invalid
17555
		return value === this._adjustValue( value );
17556
	},
17557
 
17558
	// Update the value without triggering change
17559
	_value: function( value, allowAny ) {
17560
		var parsed;
17561
		if ( value !== "" ) {
17562
			parsed = this._parse( value );
17563
			if ( parsed !== null ) {
17564
				if ( !allowAny ) {
17565
					parsed = this._adjustValue( parsed );
17566
				}
17567
				value = this._format( parsed );
17568
			}
17569
		}
17570
		this.element.val( value );
17571
		this._refresh();
17572
	},
17573
 
17574
	_destroy: function() {
17575
		this.element
17576
			.prop( "disabled", false )
17577
			.removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" );
17578
 
17579
		this.uiSpinner.replaceWith( this.element );
17580
	},
17581
 
17582
	stepUp: spinnerModifier( function( steps ) {
17583
		this._stepUp( steps );
17584
	} ),
17585
	_stepUp: function( steps ) {
17586
		if ( this._start() ) {
17587
			this._spin( ( steps || 1 ) * this.options.step );
17588
			this._stop();
17589
		}
17590
	},
17591
 
17592
	stepDown: spinnerModifier( function( steps ) {
17593
		this._stepDown( steps );
17594
	} ),
17595
	_stepDown: function( steps ) {
17596
		if ( this._start() ) {
17597
			this._spin( ( steps || 1 ) * -this.options.step );
17598
			this._stop();
17599
		}
17600
	},
17601
 
17602
	pageUp: spinnerModifier( function( pages ) {
17603
		this._stepUp( ( pages || 1 ) * this.options.page );
17604
	} ),
17605
 
17606
	pageDown: spinnerModifier( function( pages ) {
17607
		this._stepDown( ( pages || 1 ) * this.options.page );
17608
	} ),
17609
 
17610
	value: function( newVal ) {
17611
		if ( !arguments.length ) {
17612
			return this._parse( this.element.val() );
17613
		}
17614
		spinnerModifier( this._value ).call( this, newVal );
17615
	},
17616
 
17617
	widget: function() {
17618
		return this.uiSpinner;
17619
	}
17620
} );
17621
 
17622
// DEPRECATED
17623
// TODO: switch return back to widget declaration at top of file when this is removed
17624
if ( $.uiBackCompat !== false ) {
17625
 
17626
	// Backcompat for spinner html extension points
17627
	$.widget( "ui.spinner", $.ui.spinner, {
17628
		_enhance: function() {
17629
			this.uiSpinner = this.element
17630
				.attr( "autocomplete", "off" )
17631
				.wrap( this._uiSpinnerHtml() )
17632
				.parent()
17633
 
17634
					// Add buttons
17635
					.append( this._buttonHtml() );
17636
		},
17637
		_uiSpinnerHtml: function() {
17638
			return "<span>";
17639
		},
17640
 
17641
		_buttonHtml: function() {
17642
			return "<a></a><a></a>";
17643
		}
17644
	} );
17645
}
17646
 
17647
var widgetsSpinner = $.ui.spinner;
17648
 
17649
 
17650
/*!
17651
 * jQuery UI Tabs 1.13.2
17652
 * http://jqueryui.com
17653
 *
17654
 * Copyright jQuery Foundation and other contributors
17655
 * Released under the MIT license.
17656
 * http://jquery.org/license
17657
 */
17658
 
17659
//>>label: Tabs
17660
//>>group: Widgets
17661
//>>description: Transforms a set of container elements into a tab structure.
17662
//>>docs: http://api.jqueryui.com/tabs/
17663
//>>demos: http://jqueryui.com/tabs/
17664
//>>css.structure: ../../themes/base/core.css
17665
//>>css.structure: ../../themes/base/tabs.css
17666
//>>css.theme: ../../themes/base/theme.css
17667
 
17668
 
17669
$.widget( "ui.tabs", {
17670
	version: "1.13.2",
17671
	delay: 300,
17672
	options: {
17673
		active: null,
17674
		classes: {
17675
			"ui-tabs": "ui-corner-all",
17676
			"ui-tabs-nav": "ui-corner-all",
17677
			"ui-tabs-panel": "ui-corner-bottom",
17678
			"ui-tabs-tab": "ui-corner-top"
17679
		},
17680
		collapsible: false,
17681
		event: "click",
17682
		heightStyle: "content",
17683
		hide: null,
17684
		show: null,
17685
 
17686
		// Callbacks
17687
		activate: null,
17688
		beforeActivate: null,
17689
		beforeLoad: null,
17690
		load: null
17691
	},
17692
 
17693
	_isLocal: ( function() {
17694
		var rhash = /#.*$/;
17695
 
17696
		return function( anchor ) {
17697
			var anchorUrl, locationUrl;
17698
 
17699
			anchorUrl = anchor.href.replace( rhash, "" );
17700
			locationUrl = location.href.replace( rhash, "" );
17701
 
17702
			// Decoding may throw an error if the URL isn't UTF-8 (#9518)
17703
			try {
17704
				anchorUrl = decodeURIComponent( anchorUrl );
17705
			} catch ( error ) {}
17706
			try {
17707
				locationUrl = decodeURIComponent( locationUrl );
17708
			} catch ( error ) {}
17709
 
17710
			return anchor.hash.length > 1 && anchorUrl === locationUrl;
17711
		};
17712
	} )(),
17713
 
17714
	_create: function() {
17715
		var that = this,
17716
			options = this.options;
17717
 
17718
		this.running = false;
17719
 
17720
		this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
17721
		this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
17722
 
17723
		this._processTabs();
17724
		options.active = this._initialActive();
17725
 
17726
		// Take disabling tabs via class attribute from HTML
17727
		// into account and update option properly.
17728
		if ( Array.isArray( options.disabled ) ) {
17729
			options.disabled = $.uniqueSort( options.disabled.concat(
17730
				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
17731
					return that.tabs.index( li );
17732
				} )
17733
			) ).sort();
17734
		}
17735
 
17736
		// Check for length avoids error when initializing empty list
17737
		if ( this.options.active !== false && this.anchors.length ) {
17738
			this.active = this._findActive( options.active );
17739
		} else {
17740
			this.active = $();
17741
		}
17742
 
17743
		this._refresh();
17744
 
17745
		if ( this.active.length ) {
17746
			this.load( options.active );
17747
		}
17748
	},
17749
 
17750
	_initialActive: function() {
17751
		var active = this.options.active,
17752
			collapsible = this.options.collapsible,
17753
			locationHash = location.hash.substring( 1 );
17754
 
17755
		if ( active === null ) {
17756
 
17757
			// check the fragment identifier in the URL
17758
			if ( locationHash ) {
17759
				this.tabs.each( function( i, tab ) {
17760
					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
17761
						active = i;
17762
						return false;
17763
					}
17764
				} );
17765
			}
17766
 
17767
			// Check for a tab marked active via a class
17768
			if ( active === null ) {
17769
				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
17770
			}
17771
 
17772
			// No active tab, set to false
17773
			if ( active === null || active === -1 ) {
17774
				active = this.tabs.length ? 0 : false;
17775
			}
17776
		}
17777
 
17778
		// Handle numbers: negative, out of range
17779
		if ( active !== false ) {
17780
			active = this.tabs.index( this.tabs.eq( active ) );
17781
			if ( active === -1 ) {
17782
				active = collapsible ? false : 0;
17783
			}
17784
		}
17785
 
17786
		// Don't allow collapsible: false and active: false
17787
		if ( !collapsible && active === false && this.anchors.length ) {
17788
			active = 0;
17789
		}
17790
 
17791
		return active;
17792
	},
17793
 
17794
	_getCreateEventData: function() {
17795
		return {
17796
			tab: this.active,
17797
			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
17798
		};
17799
	},
17800
 
17801
	_tabKeydown: function( event ) {
17802
		var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ),
17803
			selectedIndex = this.tabs.index( focusedTab ),
17804
			goingForward = true;
17805
 
17806
		if ( this._handlePageNav( event ) ) {
17807
			return;
17808
		}
17809
 
17810
		switch ( event.keyCode ) {
17811
		case $.ui.keyCode.RIGHT:
17812
		case $.ui.keyCode.DOWN:
17813
			selectedIndex++;
17814
			break;
17815
		case $.ui.keyCode.UP:
17816
		case $.ui.keyCode.LEFT:
17817
			goingForward = false;
17818
			selectedIndex--;
17819
			break;
17820
		case $.ui.keyCode.END:
17821
			selectedIndex = this.anchors.length - 1;
17822
			break;
17823
		case $.ui.keyCode.HOME:
17824
			selectedIndex = 0;
17825
			break;
17826
		case $.ui.keyCode.SPACE:
17827
 
17828
			// Activate only, no collapsing
17829
			event.preventDefault();
17830
			clearTimeout( this.activating );
17831
			this._activate( selectedIndex );
17832
			return;
17833
		case $.ui.keyCode.ENTER:
17834
 
17835
			// Toggle (cancel delayed activation, allow collapsing)
17836
			event.preventDefault();
17837
			clearTimeout( this.activating );
17838
 
17839
			// Determine if we should collapse or activate
17840
			this._activate( selectedIndex === this.options.active ? false : selectedIndex );
17841
			return;
17842
		default:
17843
			return;
17844
		}
17845
 
17846
		// Focus the appropriate tab, based on which key was pressed
17847
		event.preventDefault();
17848
		clearTimeout( this.activating );
17849
		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
17850
 
17851
		// Navigating with control/command key will prevent automatic activation
17852
		if ( !event.ctrlKey && !event.metaKey ) {
17853
 
17854
			// Update aria-selected immediately so that AT think the tab is already selected.
17855
			// Otherwise AT may confuse the user by stating that they need to activate the tab,
17856
			// but the tab will already be activated by the time the announcement finishes.
17857
			focusedTab.attr( "aria-selected", "false" );
17858
			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
17859
 
17860
			this.activating = this._delay( function() {
17861
				this.option( "active", selectedIndex );
17862
			}, this.delay );
17863
		}
17864
	},
17865
 
17866
	_panelKeydown: function( event ) {
17867
		if ( this._handlePageNav( event ) ) {
17868
			return;
17869
		}
17870
 
17871
		// Ctrl+up moves focus to the current tab
17872
		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
17873
			event.preventDefault();
17874
			this.active.trigger( "focus" );
17875
		}
17876
	},
17877
 
17878
	// Alt+page up/down moves focus to the previous/next tab (and activates)
17879
	_handlePageNav: function( event ) {
17880
		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
17881
			this._activate( this._focusNextTab( this.options.active - 1, false ) );
17882
			return true;
17883
		}
17884
		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
17885
			this._activate( this._focusNextTab( this.options.active + 1, true ) );
17886
			return true;
17887
		}
17888
	},
17889
 
17890
	_findNextTab: function( index, goingForward ) {
17891
		var lastTabIndex = this.tabs.length - 1;
17892
 
17893
		function constrain() {
17894
			if ( index > lastTabIndex ) {
17895
				index = 0;
17896
			}
17897
			if ( index < 0 ) {
17898
				index = lastTabIndex;
17899
			}
17900
			return index;
17901
		}
17902
 
17903
		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
17904
			index = goingForward ? index + 1 : index - 1;
17905
		}
17906
 
17907
		return index;
17908
	},
17909
 
17910
	_focusNextTab: function( index, goingForward ) {
17911
		index = this._findNextTab( index, goingForward );
17912
		this.tabs.eq( index ).trigger( "focus" );
17913
		return index;
17914
	},
17915
 
17916
	_setOption: function( key, value ) {
17917
		if ( key === "active" ) {
17918
 
17919
			// _activate() will handle invalid values and update this.options
17920
			this._activate( value );
17921
			return;
17922
		}
17923
 
17924
		this._super( key, value );
17925
 
17926
		if ( key === "collapsible" ) {
17927
			this._toggleClass( "ui-tabs-collapsible", null, value );
17928
 
17929
			// Setting collapsible: false while collapsed; open first panel
17930
			if ( !value && this.options.active === false ) {
17931
				this._activate( 0 );
17932
			}
17933
		}
17934
 
17935
		if ( key === "event" ) {
17936
			this._setupEvents( value );
17937
		}
17938
 
17939
		if ( key === "heightStyle" ) {
17940
			this._setupHeightStyle( value );
17941
		}
17942
	},
17943
 
17944
	_sanitizeSelector: function( hash ) {
17945
		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
17946
	},
17947
 
17948
	refresh: function() {
17949
		var options = this.options,
17950
			lis = this.tablist.children( ":has(a[href])" );
17951
 
17952
		// Get disabled tabs from class attribute from HTML
17953
		// this will get converted to a boolean if needed in _refresh()
17954
		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
17955
			return lis.index( tab );
17956
		} );
17957
 
17958
		this._processTabs();
17959
 
17960
		// Was collapsed or no tabs
17961
		if ( options.active === false || !this.anchors.length ) {
17962
			options.active = false;
17963
			this.active = $();
17964
 
17965
		// was active, but active tab is gone
17966
		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
17967
 
17968
			// all remaining tabs are disabled
17969
			if ( this.tabs.length === options.disabled.length ) {
17970
				options.active = false;
17971
				this.active = $();
17972
 
17973
			// activate previous tab
17974
			} else {
17975
				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
17976
			}
17977
 
17978
		// was active, active tab still exists
17979
		} else {
17980
 
17981
			// make sure active index is correct
17982
			options.active = this.tabs.index( this.active );
17983
		}
17984
 
17985
		this._refresh();
17986
	},
17987
 
17988
	_refresh: function() {
17989
		this._setOptionDisabled( this.options.disabled );
17990
		this._setupEvents( this.options.event );
17991
		this._setupHeightStyle( this.options.heightStyle );
17992
 
17993
		this.tabs.not( this.active ).attr( {
17994
			"aria-selected": "false",
17995
			"aria-expanded": "false",
17996
			tabIndex: -1
17997
		} );
17998
		this.panels.not( this._getPanelForTab( this.active ) )
17999
			.hide()
18000
			.attr( {
18001
				"aria-hidden": "true"
18002
			} );
18003
 
18004
		// Make sure one tab is in the tab order
18005
		if ( !this.active.length ) {
18006
			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
18007
		} else {
18008
			this.active
18009
				.attr( {
18010
					"aria-selected": "true",
18011
					"aria-expanded": "true",
18012
					tabIndex: 0
18013
				} );
18014
			this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
18015
			this._getPanelForTab( this.active )
18016
				.show()
18017
				.attr( {
18018
					"aria-hidden": "false"
18019
				} );
18020
		}
18021
	},
18022
 
18023
	_processTabs: function() {
18024
		var that = this,
18025
			prevTabs = this.tabs,
18026
			prevAnchors = this.anchors,
18027
			prevPanels = this.panels;
18028
 
18029
		this.tablist = this._getList().attr( "role", "tablist" );
18030
		this._addClass( this.tablist, "ui-tabs-nav",
18031
			"ui-helper-reset ui-helper-clearfix ui-widget-header" );
18032
 
18033
		// Prevent users from focusing disabled tabs via click
18034
		this.tablist
18035
			.on( "mousedown" + this.eventNamespace, "> li", function( event ) {
18036
				if ( $( this ).is( ".ui-state-disabled" ) ) {
18037
					event.preventDefault();
18038
				}
18039
			} )
18040
 
18041
			// Support: IE <9
18042
			// Preventing the default action in mousedown doesn't prevent IE
18043
			// from focusing the element, so if the anchor gets focused, blur.
18044
			// We don't have to worry about focusing the previously focused
18045
			// element since clicking on a non-focusable element should focus
18046
			// the body anyway.
18047
			.on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() {
18048
				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
18049
					this.blur();
18050
				}
18051
			} );
18052
 
18053
		this.tabs = this.tablist.find( "> li:has(a[href])" )
18054
			.attr( {
18055
				role: "tab",
18056
				tabIndex: -1
18057
			} );
18058
		this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" );
18059
 
18060
		this.anchors = this.tabs.map( function() {
18061
			return $( "a", this )[ 0 ];
18062
		} )
18063
			.attr( {
18064
				tabIndex: -1
18065
			} );
18066
		this._addClass( this.anchors, "ui-tabs-anchor" );
18067
 
18068
		this.panels = $();
18069
 
18070
		this.anchors.each( function( i, anchor ) {
18071
			var selector, panel, panelId,
18072
				anchorId = $( anchor ).uniqueId().attr( "id" ),
18073
				tab = $( anchor ).closest( "li" ),
18074
				originalAriaControls = tab.attr( "aria-controls" );
18075
 
18076
			// Inline tab
18077
			if ( that._isLocal( anchor ) ) {
18078
				selector = anchor.hash;
18079
				panelId = selector.substring( 1 );
18080
				panel = that.element.find( that._sanitizeSelector( selector ) );
18081
 
18082
			// remote tab
18083
			} else {
18084
 
18085
				// If the tab doesn't already have aria-controls,
18086
				// generate an id by using a throw-away element
18087
				panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
18088
				selector = "#" + panelId;
18089
				panel = that.element.find( selector );
18090
				if ( !panel.length ) {
18091
					panel = that._createPanel( panelId );
18092
					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
18093
				}
18094
				panel.attr( "aria-live", "polite" );
18095
			}
18096
 
18097
			if ( panel.length ) {
18098
				that.panels = that.panels.add( panel );
18099
			}
18100
			if ( originalAriaControls ) {
18101
				tab.data( "ui-tabs-aria-controls", originalAriaControls );
18102
			}
18103
			tab.attr( {
18104
				"aria-controls": panelId,
18105
				"aria-labelledby": anchorId
18106
			} );
18107
			panel.attr( "aria-labelledby", anchorId );
18108
		} );
18109
 
18110
		this.panels.attr( "role", "tabpanel" );
18111
		this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
18112
 
18113
		// Avoid memory leaks (#10056)
18114
		if ( prevTabs ) {
18115
			this._off( prevTabs.not( this.tabs ) );
18116
			this._off( prevAnchors.not( this.anchors ) );
18117
			this._off( prevPanels.not( this.panels ) );
18118
		}
18119
	},
18120
 
18121
	// Allow overriding how to find the list for rare usage scenarios (#7715)
18122
	_getList: function() {
18123
		return this.tablist || this.element.find( "ol, ul" ).eq( 0 );
18124
	},
18125
 
18126
	_createPanel: function( id ) {
18127
		return $( "<div>" )
18128
			.attr( "id", id )
18129
			.data( "ui-tabs-destroy", true );
18130
	},
18131
 
18132
	_setOptionDisabled: function( disabled ) {
18133
		var currentItem, li, i;
18134
 
18135
		if ( Array.isArray( disabled ) ) {
18136
			if ( !disabled.length ) {
18137
				disabled = false;
18138
			} else if ( disabled.length === this.anchors.length ) {
18139
				disabled = true;
18140
			}
18141
		}
18142
 
18143
		// Disable tabs
18144
		for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
18145
			currentItem = $( li );
18146
			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
18147
				currentItem.attr( "aria-disabled", "true" );
18148
				this._addClass( currentItem, null, "ui-state-disabled" );
18149
			} else {
18150
				currentItem.removeAttr( "aria-disabled" );
18151
				this._removeClass( currentItem, null, "ui-state-disabled" );
18152
			}
18153
		}
18154
 
18155
		this.options.disabled = disabled;
18156
 
18157
		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null,
18158
			disabled === true );
18159
	},
18160
 
18161
	_setupEvents: function( event ) {
18162
		var events = {};
18163
		if ( event ) {
18164
			$.each( event.split( " " ), function( index, eventName ) {
18165
				events[ eventName ] = "_eventHandler";
18166
			} );
18167
		}
18168
 
18169
		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
18170
 
18171
		// Always prevent the default action, even when disabled
18172
		this._on( true, this.anchors, {
18173
			click: function( event ) {
18174
				event.preventDefault();
18175
			}
18176
		} );
18177
		this._on( this.anchors, events );
18178
		this._on( this.tabs, { keydown: "_tabKeydown" } );
18179
		this._on( this.panels, { keydown: "_panelKeydown" } );
18180
 
18181
		this._focusable( this.tabs );
18182
		this._hoverable( this.tabs );
18183
	},
18184
 
18185
	_setupHeightStyle: function( heightStyle ) {
18186
		var maxHeight,
18187
			parent = this.element.parent();
18188
 
18189
		if ( heightStyle === "fill" ) {
18190
			maxHeight = parent.height();
18191
			maxHeight -= this.element.outerHeight() - this.element.height();
18192
 
18193
			this.element.siblings( ":visible" ).each( function() {
18194
				var elem = $( this ),
18195
					position = elem.css( "position" );
18196
 
18197
				if ( position === "absolute" || position === "fixed" ) {
18198
					return;
18199
				}
18200
				maxHeight -= elem.outerHeight( true );
18201
			} );
18202
 
18203
			this.element.children().not( this.panels ).each( function() {
18204
				maxHeight -= $( this ).outerHeight( true );
18205
			} );
18206
 
18207
			this.panels.each( function() {
18208
				$( this ).height( Math.max( 0, maxHeight -
18209
					$( this ).innerHeight() + $( this ).height() ) );
18210
			} )
18211
				.css( "overflow", "auto" );
18212
		} else if ( heightStyle === "auto" ) {
18213
			maxHeight = 0;
18214
			this.panels.each( function() {
18215
				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
18216
			} ).height( maxHeight );
18217
		}
18218
	},
18219
 
18220
	_eventHandler: function( event ) {
18221
		var options = this.options,
18222
			active = this.active,
18223
			anchor = $( event.currentTarget ),
18224
			tab = anchor.closest( "li" ),
18225
			clickedIsActive = tab[ 0 ] === active[ 0 ],
18226
			collapsing = clickedIsActive && options.collapsible,
18227
			toShow = collapsing ? $() : this._getPanelForTab( tab ),
18228
			toHide = !active.length ? $() : this._getPanelForTab( active ),
18229
			eventData = {
18230
				oldTab: active,
18231
				oldPanel: toHide,
18232
				newTab: collapsing ? $() : tab,
18233
				newPanel: toShow
18234
			};
18235
 
18236
		event.preventDefault();
18237
 
18238
		if ( tab.hasClass( "ui-state-disabled" ) ||
18239
 
18240
				// tab is already loading
18241
				tab.hasClass( "ui-tabs-loading" ) ||
18242
 
18243
				// can't switch durning an animation
18244
				this.running ||
18245
 
18246
				// click on active header, but not collapsible
18247
				( clickedIsActive && !options.collapsible ) ||
18248
 
18249
				// allow canceling activation
18250
				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
18251
			return;
18252
		}
18253
 
18254
		options.active = collapsing ? false : this.tabs.index( tab );
18255
 
18256
		this.active = clickedIsActive ? $() : tab;
18257
		if ( this.xhr ) {
18258
			this.xhr.abort();
18259
		}
18260
 
18261
		if ( !toHide.length && !toShow.length ) {
18262
			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
18263
		}
18264
 
18265
		if ( toShow.length ) {
18266
			this.load( this.tabs.index( tab ), event );
18267
		}
18268
		this._toggle( event, eventData );
18269
	},
18270
 
18271
	// Handles show/hide for selecting tabs
18272
	_toggle: function( event, eventData ) {
18273
		var that = this,
18274
			toShow = eventData.newPanel,
18275
			toHide = eventData.oldPanel;
18276
 
18277
		this.running = true;
18278
 
18279
		function complete() {
18280
			that.running = false;
18281
			that._trigger( "activate", event, eventData );
18282
		}
18283
 
18284
		function show() {
18285
			that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
18286
 
18287
			if ( toShow.length && that.options.show ) {
18288
				that._show( toShow, that.options.show, complete );
18289
			} else {
18290
				toShow.show();
18291
				complete();
18292
			}
18293
		}
18294
 
18295
		// Start out by hiding, then showing, then completing
18296
		if ( toHide.length && this.options.hide ) {
18297
			this._hide( toHide, this.options.hide, function() {
18298
				that._removeClass( eventData.oldTab.closest( "li" ),
18299
					"ui-tabs-active", "ui-state-active" );
18300
				show();
18301
			} );
18302
		} else {
18303
			this._removeClass( eventData.oldTab.closest( "li" ),
18304
				"ui-tabs-active", "ui-state-active" );
18305
			toHide.hide();
18306
			show();
18307
		}
18308
 
18309
		toHide.attr( "aria-hidden", "true" );
18310
		eventData.oldTab.attr( {
18311
			"aria-selected": "false",
18312
			"aria-expanded": "false"
18313
		} );
18314
 
18315
		// If we're switching tabs, remove the old tab from the tab order.
18316
		// If we're opening from collapsed state, remove the previous tab from the tab order.
18317
		// If we're collapsing, then keep the collapsing tab in the tab order.
18318
		if ( toShow.length && toHide.length ) {
18319
			eventData.oldTab.attr( "tabIndex", -1 );
18320
		} else if ( toShow.length ) {
18321
			this.tabs.filter( function() {
18322
				return $( this ).attr( "tabIndex" ) === 0;
18323
			} )
18324
				.attr( "tabIndex", -1 );
18325
		}
18326
 
18327
		toShow.attr( "aria-hidden", "false" );
18328
		eventData.newTab.attr( {
18329
			"aria-selected": "true",
18330
			"aria-expanded": "true",
18331
			tabIndex: 0
18332
		} );
18333
	},
18334
 
18335
	_activate: function( index ) {
18336
		var anchor,
18337
			active = this._findActive( index );
18338
 
18339
		// Trying to activate the already active panel
18340
		if ( active[ 0 ] === this.active[ 0 ] ) {
18341
			return;
18342
		}
18343
 
18344
		// Trying to collapse, simulate a click on the current active header
18345
		if ( !active.length ) {
18346
			active = this.active;
18347
		}
18348
 
18349
		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
18350
		this._eventHandler( {
18351
			target: anchor,
18352
			currentTarget: anchor,
18353
			preventDefault: $.noop
18354
		} );
18355
	},
18356
 
18357
	_findActive: function( index ) {
18358
		return index === false ? $() : this.tabs.eq( index );
18359
	},
18360
 
18361
	_getIndex: function( index ) {
18362
 
18363
		// meta-function to give users option to provide a href string instead of a numerical index.
18364
		if ( typeof index === "string" ) {
18365
			index = this.anchors.index( this.anchors.filter( "[href$='" +
18366
				$.escapeSelector( index ) + "']" ) );
18367
		}
18368
 
18369
		return index;
18370
	},
18371
 
18372
	_destroy: function() {
18373
		if ( this.xhr ) {
18374
			this.xhr.abort();
18375
		}
18376
 
18377
		this.tablist
18378
			.removeAttr( "role" )
18379
			.off( this.eventNamespace );
18380
 
18381
		this.anchors
18382
			.removeAttr( "role tabIndex" )
18383
			.removeUniqueId();
18384
 
18385
		this.tabs.add( this.panels ).each( function() {
18386
			if ( $.data( this, "ui-tabs-destroy" ) ) {
18387
				$( this ).remove();
18388
			} else {
18389
				$( this ).removeAttr( "role tabIndex " +
18390
					"aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" );
18391
			}
18392
		} );
18393
 
18394
		this.tabs.each( function() {
18395
			var li = $( this ),
18396
				prev = li.data( "ui-tabs-aria-controls" );
18397
			if ( prev ) {
18398
				li
18399
					.attr( "aria-controls", prev )
18400
					.removeData( "ui-tabs-aria-controls" );
18401
			} else {
18402
				li.removeAttr( "aria-controls" );
18403
			}
18404
		} );
18405
 
18406
		this.panels.show();
18407
 
18408
		if ( this.options.heightStyle !== "content" ) {
18409
			this.panels.css( "height", "" );
18410
		}
18411
	},
18412
 
18413
	enable: function( index ) {
18414
		var disabled = this.options.disabled;
18415
		if ( disabled === false ) {
18416
			return;
18417
		}
18418
 
18419
		if ( index === undefined ) {
18420
			disabled = false;
18421
		} else {
18422
			index = this._getIndex( index );
18423
			if ( Array.isArray( disabled ) ) {
18424
				disabled = $.map( disabled, function( num ) {
18425
					return num !== index ? num : null;
18426
				} );
18427
			} else {
18428
				disabled = $.map( this.tabs, function( li, num ) {
18429
					return num !== index ? num : null;
18430
				} );
18431
			}
18432
		}
18433
		this._setOptionDisabled( disabled );
18434
	},
18435
 
18436
	disable: function( index ) {
18437
		var disabled = this.options.disabled;
18438
		if ( disabled === true ) {
18439
			return;
18440
		}
18441
 
18442
		if ( index === undefined ) {
18443
			disabled = true;
18444
		} else {
18445
			index = this._getIndex( index );
18446
			if ( $.inArray( index, disabled ) !== -1 ) {
18447
				return;
18448
			}
18449
			if ( Array.isArray( disabled ) ) {
18450
				disabled = $.merge( [ index ], disabled ).sort();
18451
			} else {
18452
				disabled = [ index ];
18453
			}
18454
		}
18455
		this._setOptionDisabled( disabled );
18456
	},
18457
 
18458
	load: function( index, event ) {
18459
		index = this._getIndex( index );
18460
		var that = this,
18461
			tab = this.tabs.eq( index ),
18462
			anchor = tab.find( ".ui-tabs-anchor" ),
18463
			panel = this._getPanelForTab( tab ),
18464
			eventData = {
18465
				tab: tab,
18466
				panel: panel
18467
			},
18468
			complete = function( jqXHR, status ) {
18469
				if ( status === "abort" ) {
18470
					that.panels.stop( false, true );
18471
				}
18472
 
18473
				that._removeClass( tab, "ui-tabs-loading" );
18474
				panel.removeAttr( "aria-busy" );
18475
 
18476
				if ( jqXHR === that.xhr ) {
18477
					delete that.xhr;
18478
				}
18479
			};
18480
 
18481
		// Not remote
18482
		if ( this._isLocal( anchor[ 0 ] ) ) {
18483
			return;
18484
		}
18485
 
18486
		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
18487
 
18488
		// Support: jQuery <1.8
18489
		// jQuery <1.8 returns false if the request is canceled in beforeSend,
18490
		// but as of 1.8, $.ajax() always returns a jqXHR object.
18491
		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
18492
			this._addClass( tab, "ui-tabs-loading" );
18493
			panel.attr( "aria-busy", "true" );
18494
 
18495
			this.xhr
18496
				.done( function( response, status, jqXHR ) {
18497
 
18498
					// support: jQuery <1.8
18499
					// http://bugs.jquery.com/ticket/11778
18500
					setTimeout( function() {
18501
						panel.html( response );
18502
						that._trigger( "load", event, eventData );
18503
 
18504
						complete( jqXHR, status );
18505
					}, 1 );
18506
				} )
18507
				.fail( function( jqXHR, status ) {
18508
 
18509
					// support: jQuery <1.8
18510
					// http://bugs.jquery.com/ticket/11778
18511
					setTimeout( function() {
18512
						complete( jqXHR, status );
18513
					}, 1 );
18514
				} );
18515
		}
18516
	},
18517
 
18518
	_ajaxSettings: function( anchor, event, eventData ) {
18519
		var that = this;
18520
		return {
18521
 
18522
			// Support: IE <11 only
18523
			// Strip any hash that exists to prevent errors with the Ajax request
18524
			url: anchor.attr( "href" ).replace( /#.*$/, "" ),
18525
			beforeSend: function( jqXHR, settings ) {
18526
				return that._trigger( "beforeLoad", event,
18527
					$.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
18528
			}
18529
		};
18530
	},
18531
 
18532
	_getPanelForTab: function( tab ) {
18533
		var id = $( tab ).attr( "aria-controls" );
18534
		return this.element.find( this._sanitizeSelector( "#" + id ) );
18535
	}
18536
} );
18537
 
18538
// DEPRECATED
18539
// TODO: Switch return back to widget declaration at top of file when this is removed
18540
if ( $.uiBackCompat !== false ) {
18541
 
18542
	// Backcompat for ui-tab class (now ui-tabs-tab)
18543
	$.widget( "ui.tabs", $.ui.tabs, {
18544
		_processTabs: function() {
18545
			this._superApply( arguments );
18546
			this._addClass( this.tabs, "ui-tab" );
18547
		}
18548
	} );
18549
}
18550
 
18551
var widgetsTabs = $.ui.tabs;
18552
 
18553
 
18554
/*!
18555
 * jQuery UI Tooltip 1.13.2
18556
 * http://jqueryui.com
18557
 *
18558
 * Copyright jQuery Foundation and other contributors
18559
 * Released under the MIT license.
18560
 * http://jquery.org/license
18561
 */
18562
 
18563
//>>label: Tooltip
18564
//>>group: Widgets
18565
//>>description: Shows additional information for any element on hover or focus.
18566
//>>docs: http://api.jqueryui.com/tooltip/
18567
//>>demos: http://jqueryui.com/tooltip/
18568
//>>css.structure: ../../themes/base/core.css
18569
//>>css.structure: ../../themes/base/tooltip.css
18570
//>>css.theme: ../../themes/base/theme.css
18571
 
18572
 
18573
$.widget( "ui.tooltip", {
18574
	version: "1.13.2",
18575
	options: {
18576
		classes: {
18577
			"ui-tooltip": "ui-corner-all ui-widget-shadow"
18578
		},
18579
		content: function() {
18580
			var title = $( this ).attr( "title" );
18581
 
18582
			// Escape title, since we're going from an attribute to raw HTML
18583
			return $( "<a>" ).text( title ).html();
18584
		},
18585
		hide: true,
18586
 
18587
		// Disabled elements have inconsistent behavior across browsers (#8661)
18588
		items: "[title]:not([disabled])",
18589
		position: {
18590
			my: "left top+15",
18591
			at: "left bottom",
18592
			collision: "flipfit flip"
18593
		},
18594
		show: true,
18595
		track: false,
18596
 
18597
		// Callbacks
18598
		close: null,
18599
		open: null
18600
	},
18601
 
18602
	_addDescribedBy: function( elem, id ) {
18603
		var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ );
18604
		describedby.push( id );
18605
		elem
18606
			.data( "ui-tooltip-id", id )
18607
			.attr( "aria-describedby", String.prototype.trim.call( describedby.join( " " ) ) );
18608
	},
18609
 
18610
	_removeDescribedBy: function( elem ) {
18611
		var id = elem.data( "ui-tooltip-id" ),
18612
			describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ),
18613
			index = $.inArray( id, describedby );
18614
 
18615
		if ( index !== -1 ) {
18616
			describedby.splice( index, 1 );
18617
		}
18618
 
18619
		elem.removeData( "ui-tooltip-id" );
18620
		describedby = String.prototype.trim.call( describedby.join( " " ) );
18621
		if ( describedby ) {
18622
			elem.attr( "aria-describedby", describedby );
18623
		} else {
18624
			elem.removeAttr( "aria-describedby" );
18625
		}
18626
	},
18627
 
18628
	_create: function() {
18629
		this._on( {
18630
			mouseover: "open",
18631
			focusin: "open"
18632
		} );
18633
 
18634
		// IDs of generated tooltips, needed for destroy
18635
		this.tooltips = {};
18636
 
18637
		// IDs of parent tooltips where we removed the title attribute
18638
		this.parents = {};
18639
 
18640
		// Append the aria-live region so tooltips announce correctly
18641
		this.liveRegion = $( "<div>" )
18642
			.attr( {
18643
				role: "log",
18644
				"aria-live": "assertive",
18645
				"aria-relevant": "additions"
18646
			} )
18647
			.appendTo( this.document[ 0 ].body );
18648
		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
18649
 
18650
		this.disabledTitles = $( [] );
18651
	},
18652
 
18653
	_setOption: function( key, value ) {
18654
		var that = this;
18655
 
18656
		this._super( key, value );
18657
 
18658
		if ( key === "content" ) {
18659
			$.each( this.tooltips, function( id, tooltipData ) {
18660
				that._updateContent( tooltipData.element );
18661
			} );
18662
		}
18663
	},
18664
 
18665
	_setOptionDisabled: function( value ) {
18666
		this[ value ? "_disable" : "_enable" ]();
18667
	},
18668
 
18669
	_disable: function() {
18670
		var that = this;
18671
 
18672
		// Close open tooltips
18673
		$.each( this.tooltips, function( id, tooltipData ) {
18674
			var event = $.Event( "blur" );
18675
			event.target = event.currentTarget = tooltipData.element[ 0 ];
18676
			that.close( event, true );
18677
		} );
18678
 
18679
		// Remove title attributes to prevent native tooltips
18680
		this.disabledTitles = this.disabledTitles.add(
18681
			this.element.find( this.options.items ).addBack()
18682
				.filter( function() {
18683
					var element = $( this );
18684
					if ( element.is( "[title]" ) ) {
18685
						return element
18686
							.data( "ui-tooltip-title", element.attr( "title" ) )
18687
							.removeAttr( "title" );
18688
					}
18689
				} )
18690
		);
18691
	},
18692
 
18693
	_enable: function() {
18694
 
18695
		// restore title attributes
18696
		this.disabledTitles.each( function() {
18697
			var element = $( this );
18698
			if ( element.data( "ui-tooltip-title" ) ) {
18699
				element.attr( "title", element.data( "ui-tooltip-title" ) );
18700
			}
18701
		} );
18702
		this.disabledTitles = $( [] );
18703
	},
18704
 
18705
	open: function( event ) {
18706
		var that = this,
18707
			target = $( event ? event.target : this.element )
18708
 
18709
				// we need closest here due to mouseover bubbling,
18710
				// but always pointing at the same event target
18711
				.closest( this.options.items );
18712
 
18713
		// No element to show a tooltip for or the tooltip is already open
18714
		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
18715
			return;
18716
		}
18717
 
18718
		if ( target.attr( "title" ) ) {
18719
			target.data( "ui-tooltip-title", target.attr( "title" ) );
18720
		}
18721
 
18722
		target.data( "ui-tooltip-open", true );
18723
 
18724
		// Kill parent tooltips, custom or native, for hover
18725
		if ( event && event.type === "mouseover" ) {
18726
			target.parents().each( function() {
18727
				var parent = $( this ),
18728
					blurEvent;
18729
				if ( parent.data( "ui-tooltip-open" ) ) {
18730
					blurEvent = $.Event( "blur" );
18731
					blurEvent.target = blurEvent.currentTarget = this;
18732
					that.close( blurEvent, true );
18733
				}
18734
				if ( parent.attr( "title" ) ) {
18735
					parent.uniqueId();
18736
					that.parents[ this.id ] = {
18737
						element: this,
18738
						title: parent.attr( "title" )
18739
					};
18740
					parent.attr( "title", "" );
18741
				}
18742
			} );
18743
		}
18744
 
18745
		this._registerCloseHandlers( event, target );
18746
		this._updateContent( target, event );
18747
	},
18748
 
18749
	_updateContent: function( target, event ) {
18750
		var content,
18751
			contentOption = this.options.content,
18752
			that = this,
18753
			eventType = event ? event.type : null;
18754
 
18755
		if ( typeof contentOption === "string" || contentOption.nodeType ||
18756
				contentOption.jquery ) {
18757
			return this._open( event, target, contentOption );
18758
		}
18759
 
18760
		content = contentOption.call( target[ 0 ], function( response ) {
18761
 
18762
			// IE may instantly serve a cached response for ajax requests
18763
			// delay this call to _open so the other call to _open runs first
18764
			that._delay( function() {
18765
 
18766
				// Ignore async response if tooltip was closed already
18767
				if ( !target.data( "ui-tooltip-open" ) ) {
18768
					return;
18769
				}
18770
 
18771
				// JQuery creates a special event for focusin when it doesn't
18772
				// exist natively. To improve performance, the native event
18773
				// object is reused and the type is changed. Therefore, we can't
18774
				// rely on the type being correct after the event finished
18775
				// bubbling, so we set it back to the previous value. (#8740)
18776
				if ( event ) {
18777
					event.type = eventType;
18778
				}
18779
				this._open( event, target, response );
18780
			} );
18781
		} );
18782
		if ( content ) {
18783
			this._open( event, target, content );
18784
		}
18785
	},
18786
 
18787
	_open: function( event, target, content ) {
18788
		var tooltipData, tooltip, delayedShow, a11yContent,
18789
			positionOption = $.extend( {}, this.options.position );
18790
 
18791
		if ( !content ) {
18792
			return;
18793
		}
18794
 
18795
		// Content can be updated multiple times. If the tooltip already
18796
		// exists, then just update the content and bail.
18797
		tooltipData = this._find( target );
18798
		if ( tooltipData ) {
18799
			tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
18800
			return;
18801
		}
18802
 
18803
		// If we have a title, clear it to prevent the native tooltip
18804
		// we have to check first to avoid defining a title if none exists
18805
		// (we don't want to cause an element to start matching [title])
18806
		//
18807
		// We use removeAttr only for key events, to allow IE to export the correct
18808
		// accessible attributes. For mouse events, set to empty string to avoid
18809
		// native tooltip showing up (happens only when removing inside mouseover).
18810
		if ( target.is( "[title]" ) ) {
18811
			if ( event && event.type === "mouseover" ) {
18812
				target.attr( "title", "" );
18813
			} else {
18814
				target.removeAttr( "title" );
18815
			}
18816
		}
18817
 
18818
		tooltipData = this._tooltip( target );
18819
		tooltip = tooltipData.tooltip;
18820
		this._addDescribedBy( target, tooltip.attr( "id" ) );
18821
		tooltip.find( ".ui-tooltip-content" ).html( content );
18822
 
18823
		// Support: Voiceover on OS X, JAWS on IE <= 9
18824
		// JAWS announces deletions even when aria-relevant="additions"
18825
		// Voiceover will sometimes re-read the entire log region's contents from the beginning
18826
		this.liveRegion.children().hide();
18827
		a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() );
18828
		a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" );
18829
		a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
18830
		a11yContent.appendTo( this.liveRegion );
18831
 
18832
		function position( event ) {
18833
			positionOption.of = event;
18834
			if ( tooltip.is( ":hidden" ) ) {
18835
				return;
18836
			}
18837
			tooltip.position( positionOption );
18838
		}
18839
		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
18840
			this._on( this.document, {
18841
				mousemove: position
18842
			} );
18843
 
18844
			// trigger once to override element-relative positioning
18845
			position( event );
18846
		} else {
18847
			tooltip.position( $.extend( {
18848
				of: target
18849
			}, this.options.position ) );
18850
		}
18851
 
18852
		tooltip.hide();
18853
 
18854
		this._show( tooltip, this.options.show );
18855
 
18856
		// Handle tracking tooltips that are shown with a delay (#8644). As soon
18857
		// as the tooltip is visible, position the tooltip using the most recent
18858
		// event.
18859
		// Adds the check to add the timers only when both delay and track options are set (#14682)
18860
		if ( this.options.track && this.options.show && this.options.show.delay ) {
18861
			delayedShow = this.delayedShow = setInterval( function() {
18862
				if ( tooltip.is( ":visible" ) ) {
18863
					position( positionOption.of );
18864
					clearInterval( delayedShow );
18865
				}
18866
			}, 13 );
18867
		}
18868
 
18869
		this._trigger( "open", event, { tooltip: tooltip } );
18870
	},
18871
 
18872
	_registerCloseHandlers: function( event, target ) {
18873
		var events = {
18874
			keyup: function( event ) {
18875
				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
18876
					var fakeEvent = $.Event( event );
18877
					fakeEvent.currentTarget = target[ 0 ];
18878
					this.close( fakeEvent, true );
18879
				}
18880
			}
18881
		};
18882
 
18883
		// Only bind remove handler for delegated targets. Non-delegated
18884
		// tooltips will handle this in destroy.
18885
		if ( target[ 0 ] !== this.element[ 0 ] ) {
18886
			events.remove = function() {
18887
				var targetElement = this._find( target );
18888
				if ( targetElement ) {
18889
					this._removeTooltip( targetElement.tooltip );
18890
				}
18891
			};
18892
		}
18893
 
18894
		if ( !event || event.type === "mouseover" ) {
18895
			events.mouseleave = "close";
18896
		}
18897
		if ( !event || event.type === "focusin" ) {
18898
			events.focusout = "close";
18899
		}
18900
		this._on( true, target, events );
18901
	},
18902
 
18903
	close: function( event ) {
18904
		var tooltip,
18905
			that = this,
18906
			target = $( event ? event.currentTarget : this.element ),
18907
			tooltipData = this._find( target );
18908
 
18909
		// The tooltip may already be closed
18910
		if ( !tooltipData ) {
18911
 
18912
			// We set ui-tooltip-open immediately upon open (in open()), but only set the
18913
			// additional data once there's actually content to show (in _open()). So even if the
18914
			// tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
18915
			// the period between open() and _open().
18916
			target.removeData( "ui-tooltip-open" );
18917
			return;
18918
		}
18919
 
18920
		tooltip = tooltipData.tooltip;
18921
 
18922
		// Disabling closes the tooltip, so we need to track when we're closing
18923
		// to avoid an infinite loop in case the tooltip becomes disabled on close
18924
		if ( tooltipData.closing ) {
18925
			return;
18926
		}
18927
 
18928
		// Clear the interval for delayed tracking tooltips
18929
		clearInterval( this.delayedShow );
18930
 
18931
		// Only set title if we had one before (see comment in _open())
18932
		// If the title attribute has changed since open(), don't restore
18933
		if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
18934
			target.attr( "title", target.data( "ui-tooltip-title" ) );
18935
		}
18936
 
18937
		this._removeDescribedBy( target );
18938
 
18939
		tooltipData.hiding = true;
18940
		tooltip.stop( true );
18941
		this._hide( tooltip, this.options.hide, function() {
18942
			that._removeTooltip( $( this ) );
18943
		} );
18944
 
18945
		target.removeData( "ui-tooltip-open" );
18946
		this._off( target, "mouseleave focusout keyup" );
18947
 
18948
		// Remove 'remove' binding only on delegated targets
18949
		if ( target[ 0 ] !== this.element[ 0 ] ) {
18950
			this._off( target, "remove" );
18951
		}
18952
		this._off( this.document, "mousemove" );
18953
 
18954
		if ( event && event.type === "mouseleave" ) {
18955
			$.each( this.parents, function( id, parent ) {
18956
				$( parent.element ).attr( "title", parent.title );
18957
				delete that.parents[ id ];
18958
			} );
18959
		}
18960
 
18961
		tooltipData.closing = true;
18962
		this._trigger( "close", event, { tooltip: tooltip } );
18963
		if ( !tooltipData.hiding ) {
18964
			tooltipData.closing = false;
18965
		}
18966
	},
18967
 
18968
	_tooltip: function( element ) {
18969
		var tooltip = $( "<div>" ).attr( "role", "tooltip" ),
18970
			content = $( "<div>" ).appendTo( tooltip ),
18971
			id = tooltip.uniqueId().attr( "id" );
18972
 
18973
		this._addClass( content, "ui-tooltip-content" );
18974
		this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" );
18975
 
18976
		tooltip.appendTo( this._appendTo( element ) );
18977
 
18978
		return this.tooltips[ id ] = {
18979
			element: element,
18980
			tooltip: tooltip
18981
		};
18982
	},
18983
 
18984
	_find: function( target ) {
18985
		var id = target.data( "ui-tooltip-id" );
18986
		return id ? this.tooltips[ id ] : null;
18987
	},
18988
 
18989
	_removeTooltip: function( tooltip ) {
18990
 
18991
		// Clear the interval for delayed tracking tooltips
18992
		clearInterval( this.delayedShow );
18993
 
18994
		tooltip.remove();
18995
		delete this.tooltips[ tooltip.attr( "id" ) ];
18996
	},
18997
 
18998
	_appendTo: function( target ) {
18999
		var element = target.closest( ".ui-front, dialog" );
19000
 
19001
		if ( !element.length ) {
19002
			element = this.document[ 0 ].body;
19003
		}
19004
 
19005
		return element;
19006
	},
19007
 
19008
	_destroy: function() {
19009
		var that = this;
19010
 
19011
		// Close open tooltips
19012
		$.each( this.tooltips, function( id, tooltipData ) {
19013
 
19014
			// Delegate to close method to handle common cleanup
19015
			var event = $.Event( "blur" ),
19016
				element = tooltipData.element;
19017
			event.target = event.currentTarget = element[ 0 ];
19018
			that.close( event, true );
19019
 
19020
			// Remove immediately; destroying an open tooltip doesn't use the
19021
			// hide animation
19022
			$( "#" + id ).remove();
19023
 
19024
			// Restore the title
19025
			if ( element.data( "ui-tooltip-title" ) ) {
19026
 
19027
				// If the title attribute has changed since open(), don't restore
19028
				if ( !element.attr( "title" ) ) {
19029
					element.attr( "title", element.data( "ui-tooltip-title" ) );
19030
				}
19031
				element.removeData( "ui-tooltip-title" );
19032
			}
19033
		} );
19034
		this.liveRegion.remove();
19035
	}
19036
} );
19037
 
19038
// DEPRECATED
19039
// TODO: Switch return back to widget declaration at top of file when this is removed
19040
if ( $.uiBackCompat !== false ) {
19041
 
19042
	// Backcompat for tooltipClass option
19043
	$.widget( "ui.tooltip", $.ui.tooltip, {
19044
		options: {
19045
			tooltipClass: null
19046
		},
19047
		_tooltip: function() {
19048
			var tooltipData = this._superApply( arguments );
19049
			if ( this.options.tooltipClass ) {
19050
				tooltipData.tooltip.addClass( this.options.tooltipClass );
19051
			}
19052
			return tooltipData;
19053
		}
19054
	} );
19055
}
19056
 
19057
var widgetsTooltip = $.ui.tooltip;
19058
 
19059
 
19060
 
19061
 
19062
} );