Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
693 steven 1
/*! jQuery UI - v1.12.1 - 2020-10-25
2
* http://jqueryui.com
3
* Includes: widget.js, position.js, data.js, disable-selection.js, focusable.js, form-reset-mixin.js, jquery-1-7.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/draggable.js, widgets/droppable.js, widgets/resizable.js, widgets/selectable.js, widgets/sortable.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/selectmenu.js, widgets/slider.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js
4
* Copyright jQuery Foundation and other contributors; Licensed MIT */
5
 
6
(function( factory ) {
7
	if ( typeof define === "function" && define.amd ) {
8
 
9
		// AMD. Register as an anonymous module.
10
		define([ "jquery" ], factory );
11
	} else {
12
 
13
		// Browser globals
14
		factory( jQuery );
15
	}
16
}(function( $ ) {
17
 
18
$.ui = $.ui || {};
19
 
20
var version = $.ui.version = "1.12.1";
21
 
22
 
23
/*!
24
 * jQuery UI Widget 1.12.1
25
 * http://jqueryui.com
26
 *
27
 * Copyright jQuery Foundation and other contributors
28
 * Released under the MIT license.
29
 * http://jquery.org/license
30
 */
31
 
32
//>>label: Widget
33
//>>group: Core
34
//>>description: Provides a factory for creating stateful widgets with a common API.
35
//>>docs: http://api.jqueryui.com/jQuery.widget/
36
//>>demos: http://jqueryui.com/widget/
37
 
38
 
39
 
40
var widgetUuid = 0;
41
var widgetSlice = Array.prototype.slice;
42
 
43
$.cleanData = ( function( orig ) {
44
	return function( elems ) {
45
		var events, elem, i;
46
		for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
47
			try {
48
 
49
				// Only trigger remove when necessary to save time
50
				events = $._data( elem, "events" );
51
				if ( events && events.remove ) {
52
					$( elem ).triggerHandler( "remove" );
53
				}
54
 
55
			// Http://bugs.jquery.com/ticket/8235
56
			} catch ( e ) {}
57
		}
58
		orig( elems );
59
	};
60
} )( $.cleanData );
61
 
62
$.widget = function( name, base, prototype ) {
63
	var existingConstructor, constructor, basePrototype;
64
 
65
	// ProxiedPrototype allows the provided prototype to remain unmodified
66
	// so that it can be used as a mixin for multiple widgets (#8876)
67
	var proxiedPrototype = {};
68
 
69
	var namespace = name.split( "." )[ 0 ];
70
	name = name.split( "." )[ 1 ];
71
	var fullName = namespace + "-" + name;
72
 
73
	if ( !prototype ) {
74
		prototype = base;
75
		base = $.Widget;
76
	}
77
 
78
	if ( $.isArray( prototype ) ) {
79
		prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
80
	}
81
 
82
	// Create selector for plugin
83
	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
84
		return !!$.data( elem, fullName );
85
	};
86
 
87
	$[ namespace ] = $[ namespace ] || {};
88
	existingConstructor = $[ namespace ][ name ];
89
	constructor = $[ namespace ][ name ] = function( options, element ) {
90
 
91
		// Allow instantiation without "new" keyword
92
		if ( !this._createWidget ) {
93
			return new constructor( options, element );
94
		}
95
 
96
		// Allow instantiation without initializing for simple inheritance
97
		// must use "new" keyword (the code above always passes args)
98
		if ( arguments.length ) {
99
			this._createWidget( options, element );
100
		}
101
	};
102
 
103
	// Extend with the existing constructor to carry over any static properties
104
	$.extend( constructor, existingConstructor, {
105
		version: prototype.version,
106
 
107
		// Copy the object used to create the prototype in case we need to
108
		// redefine the widget later
109
		_proto: $.extend( {}, prototype ),
110
 
111
		// Track widgets that inherit from this widget in case this widget is
112
		// redefined after a widget inherits from it
113
		_childConstructors: []
114
	} );
115
 
116
	basePrototype = new base();
117
 
118
	// We need to make the options hash a property directly on the new instance
119
	// otherwise we'll modify the options hash on the prototype that we're
120
	// inheriting from
121
	basePrototype.options = $.widget.extend( {}, basePrototype.options );
122
	$.each( prototype, function( prop, value ) {
123
		if ( !$.isFunction( value ) ) {
124
			proxiedPrototype[ prop ] = value;
125
			return;
126
		}
127
		proxiedPrototype[ prop ] = ( function() {
128
			function _super() {
129
				return base.prototype[ prop ].apply( this, arguments );
130
			}
131
 
132
			function _superApply( args ) {
133
				return base.prototype[ prop ].apply( this, args );
134
			}
135
 
136
			return function() {
137
				var __super = this._super;
138
				var __superApply = this._superApply;
139
				var returnValue;
140
 
141
				this._super = _super;
142
				this._superApply = _superApply;
143
 
144
				returnValue = value.apply( this, arguments );
145
 
146
				this._super = __super;
147
				this._superApply = __superApply;
148
 
149
				return returnValue;
150
			};
151
		} )();
152
	} );
153
	constructor.prototype = $.widget.extend( basePrototype, {
154
 
155
		// TODO: remove support for widgetEventPrefix
156
		// always use the name + a colon as the prefix, e.g., draggable:start
157
		// don't prefix for widgets that aren't DOM-based
158
		widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
159
	}, proxiedPrototype, {
160
		constructor: constructor,
161
		namespace: namespace,
162
		widgetName: name,
163
		widgetFullName: fullName
164
	} );
165
 
166
	// If this widget is being redefined then we need to find all widgets that
167
	// are inheriting from it and redefine all of them so that they inherit from
168
	// the new version of this widget. We're essentially trying to replace one
169
	// level in the prototype chain.
170
	if ( existingConstructor ) {
171
		$.each( existingConstructor._childConstructors, function( i, child ) {
172
			var childPrototype = child.prototype;
173
 
174
			// Redefine the child widget using the same prototype that was
175
			// originally used, but inherit from the new version of the base
176
			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
177
				child._proto );
178
		} );
179
 
180
		// Remove the list of existing child constructors from the old constructor
181
		// so the old child constructors can be garbage collected
182
		delete existingConstructor._childConstructors;
183
	} else {
184
		base._childConstructors.push( constructor );
185
	}
186
 
187
	$.widget.bridge( name, constructor );
188
 
189
	return constructor;
190
};
191
 
192
$.widget.extend = function( target ) {
193
	var input = widgetSlice.call( arguments, 1 );
194
	var inputIndex = 0;
195
	var inputLength = input.length;
196
	var key;
197
	var value;
198
 
199
	for ( ; inputIndex < inputLength; inputIndex++ ) {
200
		for ( key in input[ inputIndex ] ) {
201
			value = input[ inputIndex ][ key ];
202
			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
203
 
204
				// Clone objects
205
				if ( $.isPlainObject( value ) ) {
206
					target[ key ] = $.isPlainObject( target[ key ] ) ?
207
						$.widget.extend( {}, target[ key ], value ) :
208
 
209
						// Don't extend strings, arrays, etc. with objects
210
						$.widget.extend( {}, value );
211
 
212
				// Copy everything else by reference
213
				} else {
214
					target[ key ] = value;
215
				}
216
			}
217
		}
218
	}
219
	return target;
220
};
221
 
222
$.widget.bridge = function( name, object ) {
223
	var fullName = object.prototype.widgetFullName || name;
224
	$.fn[ name ] = function( options ) {
225
		var isMethodCall = typeof options === "string";
226
		var args = widgetSlice.call( arguments, 1 );
227
		var returnValue = this;
228
 
229
		if ( isMethodCall ) {
230
 
231
			// If this is an empty collection, we need to have the instance method
232
			// return undefined instead of the jQuery instance
233
			if ( !this.length && options === "instance" ) {
234
				returnValue = undefined;
235
			} else {
236
				this.each( function() {
237
					var methodValue;
238
					var instance = $.data( this, fullName );
239
 
240
					if ( options === "instance" ) {
241
						returnValue = instance;
242
						return false;
243
					}
244
 
245
					if ( !instance ) {
246
						return $.error( "cannot call methods on " + name +
247
							" prior to initialization; " +
248
							"attempted to call method '" + options + "'" );
249
					}
250
 
251
					if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
252
						return $.error( "no such method '" + options + "' for " + name +
253
							" widget instance" );
254
					}
255
 
256
					methodValue = instance[ options ].apply( instance, args );
257
 
258
					if ( methodValue !== instance && methodValue !== undefined ) {
259
						returnValue = methodValue && methodValue.jquery ?
260
							returnValue.pushStack( methodValue.get() ) :
261
							methodValue;
262
						return false;
263
					}
264
				} );
265
			}
266
		} else {
267
 
268
			// Allow multiple hashes to be passed on init
269
			if ( args.length ) {
270
				options = $.widget.extend.apply( null, [ options ].concat( args ) );
271
			}
272
 
273
			this.each( function() {
274
				var instance = $.data( this, fullName );
275
				if ( instance ) {
276
					instance.option( options || {} );
277
					if ( instance._init ) {
278
						instance._init();
279
					}
280
				} else {
281
					$.data( this, fullName, new object( options, this ) );
282
				}
283
			} );
284
		}
285
 
286
		return returnValue;
287
	};
288
};
289
 
290
$.Widget = function( /* options, element */ ) {};
291
$.Widget._childConstructors = [];
292
 
293
$.Widget.prototype = {
294
	widgetName: "widget",
295
	widgetEventPrefix: "",
296
	defaultElement: "<div>",
297
 
298
	options: {
299
		classes: {},
300
		disabled: false,
301
 
302
		// Callbacks
303
		create: null
304
	},
305
 
306
	_createWidget: function( options, element ) {
307
		element = $( element || this.defaultElement || this )[ 0 ];
308
		this.element = $( element );
309
		this.uuid = widgetUuid++;
310
		this.eventNamespace = "." + this.widgetName + this.uuid;
311
 
312
		this.bindings = $();
313
		this.hoverable = $();
314
		this.focusable = $();
315
		this.classesElementLookup = {};
316
 
317
		if ( element !== this ) {
318
			$.data( element, this.widgetFullName, this );
319
			this._on( true, this.element, {
320
				remove: function( event ) {
321
					if ( event.target === element ) {
322
						this.destroy();
323
					}
324
				}
325
			} );
326
			this.document = $( element.style ?
327
 
328
				// Element within the document
329
				element.ownerDocument :
330
 
331
				// Element is window or document
332
				element.document || element );
333
			this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
334
		}
335
 
336
		this.options = $.widget.extend( {},
337
			this.options,
338
			this._getCreateOptions(),
339
			options );
340
 
341
		this._create();
342
 
343
		if ( this.options.disabled ) {
344
			this._setOptionDisabled( this.options.disabled );
345
		}
346
 
347
		this._trigger( "create", null, this._getCreateEventData() );
348
		this._init();
349
	},
350
 
351
	_getCreateOptions: function() {
352
		return {};
353
	},
354
 
355
	_getCreateEventData: $.noop,
356
 
357
	_create: $.noop,
358
 
359
	_init: $.noop,
360
 
361
	destroy: function() {
362
		var that = this;
363
 
364
		this._destroy();
365
		$.each( this.classesElementLookup, function( key, value ) {
366
			that._removeClass( value, key );
367
		} );
368
 
369
		// We can probably remove the unbind calls in 2.0
370
		// all event bindings should go through this._on()
371
		this.element
372
			.off( this.eventNamespace )
373
			.removeData( this.widgetFullName );
374
		this.widget()
375
			.off( this.eventNamespace )
376
			.removeAttr( "aria-disabled" );
377
 
378
		// Clean up events and states
379
		this.bindings.off( this.eventNamespace );
380
	},
381
 
382
	_destroy: $.noop,
383
 
384
	widget: function() {
385
		return this.element;
386
	},
387
 
388
	option: function( key, value ) {
389
		var options = key;
390
		var parts;
391
		var curOption;
392
		var i;
393
 
394
		if ( arguments.length === 0 ) {
395
 
396
			// Don't return a reference to the internal hash
397
			return $.widget.extend( {}, this.options );
398
		}
399
 
400
		if ( typeof key === "string" ) {
401
 
402
			// Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
403
			options = {};
404
			parts = key.split( "." );
405
			key = parts.shift();
406
			if ( parts.length ) {
407
				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
408
				for ( i = 0; i < parts.length - 1; i++ ) {
409
					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
410
					curOption = curOption[ parts[ i ] ];
411
				}
412
				key = parts.pop();
413
				if ( arguments.length === 1 ) {
414
					return curOption[ key ] === undefined ? null : curOption[ key ];
415
				}
416
				curOption[ key ] = value;
417
			} else {
418
				if ( arguments.length === 1 ) {
419
					return this.options[ key ] === undefined ? null : this.options[ key ];
420
				}
421
				options[ key ] = value;
422
			}
423
		}
424
 
425
		this._setOptions( options );
426
 
427
		return this;
428
	},
429
 
430
	_setOptions: function( options ) {
431
		var key;
432
 
433
		for ( key in options ) {
434
			this._setOption( key, options[ key ] );
435
		}
436
 
437
		return this;
438
	},
439
 
440
	_setOption: function( key, value ) {
441
		if ( key === "classes" ) {
442
			this._setOptionClasses( value );
443
		}
444
 
445
		this.options[ key ] = value;
446
 
447
		if ( key === "disabled" ) {
448
			this._setOptionDisabled( value );
449
		}
450
 
451
		return this;
452
	},
453
 
454
	_setOptionClasses: function( value ) {
455
		var classKey, elements, currentElements;
456
 
457
		for ( classKey in value ) {
458
			currentElements = this.classesElementLookup[ classKey ];
459
			if ( value[ classKey ] === this.options.classes[ classKey ] ||
460
					!currentElements ||
461
					!currentElements.length ) {
462
				continue;
463
			}
464
 
465
			// We are doing this to create a new jQuery object because the _removeClass() call
466
			// on the next line is going to destroy the reference to the current elements being
467
			// tracked. We need to save a copy of this collection so that we can add the new classes
468
			// below.
469
			elements = $( currentElements.get() );
470
			this._removeClass( currentElements, classKey );
471
 
472
			// We don't use _addClass() here, because that uses this.options.classes
473
			// for generating the string of classes. We want to use the value passed in from
474
			// _setOption(), this is the new value of the classes option which was passed to
475
			// _setOption(). We pass this value directly to _classes().
476
			elements.addClass( this._classes( {
477
				element: elements,
478
				keys: classKey,
479
				classes: value,
480
				add: true
481
			} ) );
482
		}
483
	},
484
 
485
	_setOptionDisabled: function( value ) {
486
		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
487
 
488
		// If the widget is becoming disabled, then nothing is interactive
489
		if ( value ) {
490
			this._removeClass( this.hoverable, null, "ui-state-hover" );
491
			this._removeClass( this.focusable, null, "ui-state-focus" );
492
		}
493
	},
494
 
495
	enable: function() {
496
		return this._setOptions( { disabled: false } );
497
	},
498
 
499
	disable: function() {
500
		return this._setOptions( { disabled: true } );
501
	},
502
 
503
	_classes: function( options ) {
504
		var full = [];
505
		var that = this;
506
 
507
		options = $.extend( {
508
			element: this.element,
509
			classes: this.options.classes || {}
510
		}, options );
511
 
512
		function processClassString( classes, checkOption ) {
513
			var current, i;
514
			for ( i = 0; i < classes.length; i++ ) {
515
				current = that.classesElementLookup[ classes[ i ] ] || $();
516
				if ( options.add ) {
517
					current = $( $.unique( current.get().concat( options.element.get() ) ) );
518
				} else {
519
					current = $( current.not( options.element ).get() );
520
				}
521
				that.classesElementLookup[ classes[ i ] ] = current;
522
				full.push( classes[ i ] );
523
				if ( checkOption && options.classes[ classes[ i ] ] ) {
524
					full.push( options.classes[ classes[ i ] ] );
525
				}
526
			}
527
		}
528
 
529
		this._on( options.element, {
530
			"remove": "_untrackClassesElement"
531
		} );
532
 
533
		if ( options.keys ) {
534
			processClassString( options.keys.match( /\S+/g ) || [], true );
535
		}
536
		if ( options.extra ) {
537
			processClassString( options.extra.match( /\S+/g ) || [] );
538
		}
539
 
540
		return full.join( " " );
541
	},
542
 
543
	_untrackClassesElement: function( event ) {
544
		var that = this;
545
		$.each( that.classesElementLookup, function( key, value ) {
546
			if ( $.inArray( event.target, value ) !== -1 ) {
547
				that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
548
			}
549
		} );
550
	},
551
 
552
	_removeClass: function( element, keys, extra ) {
553
		return this._toggleClass( element, keys, extra, false );
554
	},
555
 
556
	_addClass: function( element, keys, extra ) {
557
		return this._toggleClass( element, keys, extra, true );
558
	},
559
 
560
	_toggleClass: function( element, keys, extra, add ) {
561
		add = ( typeof add === "boolean" ) ? add : extra;
562
		var shift = ( typeof element === "string" || element === null ),
563
			options = {
564
				extra: shift ? keys : extra,
565
				keys: shift ? element : keys,
566
				element: shift ? this.element : element,
567
				add: add
568
			};
569
		options.element.toggleClass( this._classes( options ), add );
570
		return this;
571
	},
572
 
573
	_on: function( suppressDisabledCheck, element, handlers ) {
574
		var delegateElement;
575
		var instance = this;
576
 
577
		// No suppressDisabledCheck flag, shuffle arguments
578
		if ( typeof suppressDisabledCheck !== "boolean" ) {
579
			handlers = element;
580
			element = suppressDisabledCheck;
581
			suppressDisabledCheck = false;
582
		}
583
 
584
		// No element argument, shuffle and use this.element
585
		if ( !handlers ) {
586
			handlers = element;
587
			element = this.element;
588
			delegateElement = this.widget();
589
		} else {
590
			element = delegateElement = $( element );
591
			this.bindings = this.bindings.add( element );
592
		}
593
 
594
		$.each( handlers, function( event, handler ) {
595
			function handlerProxy() {
596
 
597
				// Allow widgets to customize the disabled handling
598
				// - disabled as an array instead of boolean
599
				// - disabled class as method for disabling individual parts
600
				if ( !suppressDisabledCheck &&
601
						( instance.options.disabled === true ||
602
						$( this ).hasClass( "ui-state-disabled" ) ) ) {
603
					return;
604
				}
605
				return ( typeof handler === "string" ? instance[ handler ] : handler )
606
					.apply( instance, arguments );
607
			}
608
 
609
			// Copy the guid so direct unbinding works
610
			if ( typeof handler !== "string" ) {
611
				handlerProxy.guid = handler.guid =
612
					handler.guid || handlerProxy.guid || $.guid++;
613
			}
614
 
615
			var match = event.match( /^([\w:-]*)\s*(.*)$/ );
616
			var eventName = match[ 1 ] + instance.eventNamespace;
617
			var selector = match[ 2 ];
618
 
619
			if ( selector ) {
620
				delegateElement.on( eventName, selector, handlerProxy );
621
			} else {
622
				element.on( eventName, handlerProxy );
623
			}
624
		} );
625
	},
626
 
627
	_off: function( element, eventName ) {
628
		eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
629
			this.eventNamespace;
630
		element.off( eventName ).off( eventName );
631
 
632
		// Clear the stack to avoid memory leaks (#10056)
633
		this.bindings = $( this.bindings.not( element ).get() );
634
		this.focusable = $( this.focusable.not( element ).get() );
635
		this.hoverable = $( this.hoverable.not( element ).get() );
636
	},
637
 
638
	_delay: function( handler, delay ) {
639
		function handlerProxy() {
640
			return ( typeof handler === "string" ? instance[ handler ] : handler )
641
				.apply( instance, arguments );
642
		}
643
		var instance = this;
644
		return setTimeout( handlerProxy, delay || 0 );
645
	},
646
 
647
	_hoverable: function( element ) {
648
		this.hoverable = this.hoverable.add( element );
649
		this._on( element, {
650
			mouseenter: function( event ) {
651
				this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
652
			},
653
			mouseleave: function( event ) {
654
				this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
655
			}
656
		} );
657
	},
658
 
659
	_focusable: function( element ) {
660
		this.focusable = this.focusable.add( element );
661
		this._on( element, {
662
			focusin: function( event ) {
663
				this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
664
			},
665
			focusout: function( event ) {
666
				this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
667
			}
668
		} );
669
	},
670
 
671
	_trigger: function( type, event, data ) {
672
		var prop, orig;
673
		var callback = this.options[ type ];
674
 
675
		data = data || {};
676
		event = $.Event( event );
677
		event.type = ( type === this.widgetEventPrefix ?
678
			type :
679
			this.widgetEventPrefix + type ).toLowerCase();
680
 
681
		// The original event may come from any element
682
		// so we need to reset the target on the new event
683
		event.target = this.element[ 0 ];
684
 
685
		// Copy original event properties over to the new event
686
		orig = event.originalEvent;
687
		if ( orig ) {
688
			for ( prop in orig ) {
689
				if ( !( prop in event ) ) {
690
					event[ prop ] = orig[ prop ];
691
				}
692
			}
693
		}
694
 
695
		this.element.trigger( event, data );
696
		return !( $.isFunction( callback ) &&
697
			callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
698
			event.isDefaultPrevented() );
699
	}
700
};
701
 
702
$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
703
	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
704
		if ( typeof options === "string" ) {
705
			options = { effect: options };
706
		}
707
 
708
		var hasOptions;
709
		var effectName = !options ?
710
			method :
711
			options === true || typeof options === "number" ?
712
				defaultEffect :
713
				options.effect || defaultEffect;
714
 
715
		options = options || {};
716
		if ( typeof options === "number" ) {
717
			options = { duration: options };
718
		}
719
 
720
		hasOptions = !$.isEmptyObject( options );
721
		options.complete = callback;
722
 
723
		if ( options.delay ) {
724
			element.delay( options.delay );
725
		}
726
 
727
		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
728
			element[ method ]( options );
729
		} else if ( effectName !== method && element[ effectName ] ) {
730
			element[ effectName ]( options.duration, options.easing, callback );
731
		} else {
732
			element.queue( function( next ) {
733
				$( this )[ method ]();
734
				if ( callback ) {
735
					callback.call( element[ 0 ] );
736
				}
737
				next();
738
			} );
739
		}
740
	};
741
} );
742
 
743
var widget = $.widget;
744
 
745
 
746
/*!
747
 * jQuery UI Position 1.12.1
748
 * http://jqueryui.com
749
 *
750
 * Copyright jQuery Foundation and other contributors
751
 * Released under the MIT license.
752
 * http://jquery.org/license
753
 *
754
 * http://api.jqueryui.com/position/
755
 */
756
 
757
//>>label: Position
758
//>>group: Core
759
//>>description: Positions elements relative to other elements.
760
//>>docs: http://api.jqueryui.com/position/
761
//>>demos: http://jqueryui.com/position/
762
 
763
 
764
( function() {
765
var cachedScrollbarWidth,
766
	max = Math.max,
767
	abs = Math.abs,
768
	rhorizontal = /left|center|right/,
769
	rvertical = /top|center|bottom/,
770
	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
771
	rposition = /^\w+/,
772
	rpercent = /%$/,
773
	_position = $.fn.position;
774
 
775
function getOffsets( offsets, width, height ) {
776
	return [
777
		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
778
		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
779
	];
780
}
781
 
782
function parseCss( element, property ) {
783
	return parseInt( $.css( element, property ), 10 ) || 0;
784
}
785
 
786
function getDimensions( elem ) {
787
	var raw = elem[ 0 ];
788
	if ( raw.nodeType === 9 ) {
789
		return {
790
			width: elem.width(),
791
			height: elem.height(),
792
			offset: { top: 0, left: 0 }
793
		};
794
	}
795
	if ( $.isWindow( raw ) ) {
796
		return {
797
			width: elem.width(),
798
			height: elem.height(),
799
			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
800
		};
801
	}
802
	if ( raw.preventDefault ) {
803
		return {
804
			width: 0,
805
			height: 0,
806
			offset: { top: raw.pageY, left: raw.pageX }
807
		};
808
	}
809
	return {
810
		width: elem.outerWidth(),
811
		height: elem.outerHeight(),
812
		offset: elem.offset()
813
	};
814
}
815
 
816
$.position = {
817
	scrollbarWidth: function() {
818
		if ( cachedScrollbarWidth !== undefined ) {
819
			return cachedScrollbarWidth;
820
		}
821
		var w1, w2,
822
			div = $( "<div " +
823
				"style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>" +
824
				"<div style='height:100px;width:auto;'></div></div>" ),
825
			innerDiv = div.children()[ 0 ];
826
 
827
		$( "body" ).append( div );
828
		w1 = innerDiv.offsetWidth;
829
		div.css( "overflow", "scroll" );
830
 
831
		w2 = innerDiv.offsetWidth;
832
 
833
		if ( w1 === w2 ) {
834
			w2 = div[ 0 ].clientWidth;
835
		}
836
 
837
		div.remove();
838
 
839
		return ( cachedScrollbarWidth = w1 - w2 );
840
	},
841
	getScrollInfo: function( within ) {
842
		var overflowX = within.isWindow || within.isDocument ? "" :
843
				within.element.css( "overflow-x" ),
844
			overflowY = within.isWindow || within.isDocument ? "" :
845
				within.element.css( "overflow-y" ),
846
			hasOverflowX = overflowX === "scroll" ||
847
				( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ),
848
			hasOverflowY = overflowY === "scroll" ||
849
				( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight );
850
		return {
851
			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
852
			height: hasOverflowX ? $.position.scrollbarWidth() : 0
853
		};
854
	},
855
	getWithinInfo: function( element ) {
856
		var withinElement = $( element || window ),
857
			isWindow = $.isWindow( withinElement[ 0 ] ),
858
			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,
859
			hasOffset = !isWindow && !isDocument;
860
		return {
861
			element: withinElement,
862
			isWindow: isWindow,
863
			isDocument: isDocument,
864
			offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },
865
			scrollLeft: withinElement.scrollLeft(),
866
			scrollTop: withinElement.scrollTop(),
867
			width: withinElement.outerWidth(),
868
			height: withinElement.outerHeight()
869
		};
870
	}
871
};
872
 
873
$.fn.position = function( options ) {
874
	if ( !options || !options.of ) {
875
		return _position.apply( this, arguments );
876
	}
877
 
878
	// Make a copy, we don't want to modify arguments
879
	options = $.extend( {}, options );
880
 
881
	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
882
		target = $( options.of ),
883
		within = $.position.getWithinInfo( options.within ),
884
		scrollInfo = $.position.getScrollInfo( within ),
885
		collision = ( options.collision || "flip" ).split( " " ),
886
		offsets = {};
887
 
888
	dimensions = getDimensions( target );
889
	if ( target[ 0 ].preventDefault ) {
890
 
891
		// Force left top to allow flipping
892
		options.at = "left top";
893
	}
894
	targetWidth = dimensions.width;
895
	targetHeight = dimensions.height;
896
	targetOffset = dimensions.offset;
897
 
898
	// Clone to reuse original targetOffset later
899
	basePosition = $.extend( {}, targetOffset );
900
 
901
	// Force my and at to have valid horizontal and vertical positions
902
	// if a value is missing or invalid, it will be converted to center
903
	$.each( [ "my", "at" ], function() {
904
		var pos = ( options[ this ] || "" ).split( " " ),
905
			horizontalOffset,
906
			verticalOffset;
907
 
908
		if ( pos.length === 1 ) {
909
			pos = rhorizontal.test( pos[ 0 ] ) ?
910
				pos.concat( [ "center" ] ) :
911
				rvertical.test( pos[ 0 ] ) ?
912
					[ "center" ].concat( pos ) :
913
					[ "center", "center" ];
914
		}
915
		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
916
		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
917
 
918
		// Calculate offsets
919
		horizontalOffset = roffset.exec( pos[ 0 ] );
920
		verticalOffset = roffset.exec( pos[ 1 ] );
921
		offsets[ this ] = [
922
			horizontalOffset ? horizontalOffset[ 0 ] : 0,
923
			verticalOffset ? verticalOffset[ 0 ] : 0
924
		];
925
 
926
		// Reduce to just the positions without the offsets
927
		options[ this ] = [
928
			rposition.exec( pos[ 0 ] )[ 0 ],
929
			rposition.exec( pos[ 1 ] )[ 0 ]
930
		];
931
	} );
932
 
933
	// Normalize collision option
934
	if ( collision.length === 1 ) {
935
		collision[ 1 ] = collision[ 0 ];
936
	}
937
 
938
	if ( options.at[ 0 ] === "right" ) {
939
		basePosition.left += targetWidth;
940
	} else if ( options.at[ 0 ] === "center" ) {
941
		basePosition.left += targetWidth / 2;
942
	}
943
 
944
	if ( options.at[ 1 ] === "bottom" ) {
945
		basePosition.top += targetHeight;
946
	} else if ( options.at[ 1 ] === "center" ) {
947
		basePosition.top += targetHeight / 2;
948
	}
949
 
950
	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
951
	basePosition.left += atOffset[ 0 ];
952
	basePosition.top += atOffset[ 1 ];
953
 
954
	return this.each( function() {
955
		var collisionPosition, using,
956
			elem = $( this ),
957
			elemWidth = elem.outerWidth(),
958
			elemHeight = elem.outerHeight(),
959
			marginLeft = parseCss( this, "marginLeft" ),
960
			marginTop = parseCss( this, "marginTop" ),
961
			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) +
962
				scrollInfo.width,
963
			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) +
964
				scrollInfo.height,
965
			position = $.extend( {}, basePosition ),
966
			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
967
 
968
		if ( options.my[ 0 ] === "right" ) {
969
			position.left -= elemWidth;
970
		} else if ( options.my[ 0 ] === "center" ) {
971
			position.left -= elemWidth / 2;
972
		}
973
 
974
		if ( options.my[ 1 ] === "bottom" ) {
975
			position.top -= elemHeight;
976
		} else if ( options.my[ 1 ] === "center" ) {
977
			position.top -= elemHeight / 2;
978
		}
979
 
980
		position.left += myOffset[ 0 ];
981
		position.top += myOffset[ 1 ];
982
 
983
		collisionPosition = {
984
			marginLeft: marginLeft,
985
			marginTop: marginTop
986
		};
987
 
988
		$.each( [ "left", "top" ], function( i, dir ) {
989
			if ( $.ui.position[ collision[ i ] ] ) {
990
				$.ui.position[ collision[ i ] ][ dir ]( position, {
991
					targetWidth: targetWidth,
992
					targetHeight: targetHeight,
993
					elemWidth: elemWidth,
994
					elemHeight: elemHeight,
995
					collisionPosition: collisionPosition,
996
					collisionWidth: collisionWidth,
997
					collisionHeight: collisionHeight,
998
					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
999
					my: options.my,
1000
					at: options.at,
1001
					within: within,
1002
					elem: elem
1003
				} );
1004
			}
1005
		} );
1006
 
1007
		if ( options.using ) {
1008
 
1009
			// Adds feedback as second argument to using callback, if present
1010
			using = function( props ) {
1011
				var left = targetOffset.left - position.left,
1012
					right = left + targetWidth - elemWidth,
1013
					top = targetOffset.top - position.top,
1014
					bottom = top + targetHeight - elemHeight,
1015
					feedback = {
1016
						target: {
1017
							element: target,
1018
							left: targetOffset.left,
1019
							top: targetOffset.top,
1020
							width: targetWidth,
1021
							height: targetHeight
1022
						},
1023
						element: {
1024
							element: elem,
1025
							left: position.left,
1026
							top: position.top,
1027
							width: elemWidth,
1028
							height: elemHeight
1029
						},
1030
						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1031
						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1032
					};
1033
				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1034
					feedback.horizontal = "center";
1035
				}
1036
				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1037
					feedback.vertical = "middle";
1038
				}
1039
				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1040
					feedback.important = "horizontal";
1041
				} else {
1042
					feedback.important = "vertical";
1043
				}
1044
				options.using.call( this, props, feedback );
1045
			};
1046
		}
1047
 
1048
		elem.offset( $.extend( position, { using: using } ) );
1049
	} );
1050
};
1051
 
1052
$.ui.position = {
1053
	fit: {
1054
		left: function( position, data ) {
1055
			var within = data.within,
1056
				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1057
				outerWidth = within.width,
1058
				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1059
				overLeft = withinOffset - collisionPosLeft,
1060
				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1061
				newOverRight;
1062
 
1063
			// Element is wider than within
1064
			if ( data.collisionWidth > outerWidth ) {
1065
 
1066
				// Element is initially over the left side of within
1067
				if ( overLeft > 0 && overRight <= 0 ) {
1068
					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth -
1069
						withinOffset;
1070
					position.left += overLeft - newOverRight;
1071
 
1072
				// Element is initially over right side of within
1073
				} else if ( overRight > 0 && overLeft <= 0 ) {
1074
					position.left = withinOffset;
1075
 
1076
				// Element is initially over both left and right sides of within
1077
				} else {
1078
					if ( overLeft > overRight ) {
1079
						position.left = withinOffset + outerWidth - data.collisionWidth;
1080
					} else {
1081
						position.left = withinOffset;
1082
					}
1083
				}
1084
 
1085
			// Too far left -> align with left edge
1086
			} else if ( overLeft > 0 ) {
1087
				position.left += overLeft;
1088
 
1089
			// Too far right -> align with right edge
1090
			} else if ( overRight > 0 ) {
1091
				position.left -= overRight;
1092
 
1093
			// Adjust based on position and margin
1094
			} else {
1095
				position.left = max( position.left - collisionPosLeft, position.left );
1096
			}
1097
		},
1098
		top: function( position, data ) {
1099
			var within = data.within,
1100
				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1101
				outerHeight = data.within.height,
1102
				collisionPosTop = position.top - data.collisionPosition.marginTop,
1103
				overTop = withinOffset - collisionPosTop,
1104
				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1105
				newOverBottom;
1106
 
1107
			// Element is taller than within
1108
			if ( data.collisionHeight > outerHeight ) {
1109
 
1110
				// Element is initially over the top of within
1111
				if ( overTop > 0 && overBottom <= 0 ) {
1112
					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight -
1113
						withinOffset;
1114
					position.top += overTop - newOverBottom;
1115
 
1116
				// Element is initially over bottom of within
1117
				} else if ( overBottom > 0 && overTop <= 0 ) {
1118
					position.top = withinOffset;
1119
 
1120
				// Element is initially over both top and bottom of within
1121
				} else {
1122
					if ( overTop > overBottom ) {
1123
						position.top = withinOffset + outerHeight - data.collisionHeight;
1124
					} else {
1125
						position.top = withinOffset;
1126
					}
1127
				}
1128
 
1129
			// Too far up -> align with top
1130
			} else if ( overTop > 0 ) {
1131
				position.top += overTop;
1132
 
1133
			// Too far down -> align with bottom edge
1134
			} else if ( overBottom > 0 ) {
1135
				position.top -= overBottom;
1136
 
1137
			// Adjust based on position and margin
1138
			} else {
1139
				position.top = max( position.top - collisionPosTop, position.top );
1140
			}
1141
		}
1142
	},
1143
	flip: {
1144
		left: function( position, data ) {
1145
			var within = data.within,
1146
				withinOffset = within.offset.left + within.scrollLeft,
1147
				outerWidth = within.width,
1148
				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1149
				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1150
				overLeft = collisionPosLeft - offsetLeft,
1151
				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1152
				myOffset = data.my[ 0 ] === "left" ?
1153
					-data.elemWidth :
1154
					data.my[ 0 ] === "right" ?
1155
						data.elemWidth :
1156
						0,
1157
				atOffset = data.at[ 0 ] === "left" ?
1158
					data.targetWidth :
1159
					data.at[ 0 ] === "right" ?
1160
						-data.targetWidth :
1161
						0,
1162
				offset = -2 * data.offset[ 0 ],
1163
				newOverRight,
1164
				newOverLeft;
1165
 
1166
			if ( overLeft < 0 ) {
1167
				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -
1168
					outerWidth - withinOffset;
1169
				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1170
					position.left += myOffset + atOffset + offset;
1171
				}
1172
			} else if ( overRight > 0 ) {
1173
				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +
1174
					atOffset + offset - offsetLeft;
1175
				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1176
					position.left += myOffset + atOffset + offset;
1177
				}
1178
			}
1179
		},
1180
		top: function( position, data ) {
1181
			var within = data.within,
1182
				withinOffset = within.offset.top + within.scrollTop,
1183
				outerHeight = within.height,
1184
				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1185
				collisionPosTop = position.top - data.collisionPosition.marginTop,
1186
				overTop = collisionPosTop - offsetTop,
1187
				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1188
				top = data.my[ 1 ] === "top",
1189
				myOffset = top ?
1190
					-data.elemHeight :
1191
					data.my[ 1 ] === "bottom" ?
1192
						data.elemHeight :
1193
						0,
1194
				atOffset = data.at[ 1 ] === "top" ?
1195
					data.targetHeight :
1196
					data.at[ 1 ] === "bottom" ?
1197
						-data.targetHeight :
1198
						0,
1199
				offset = -2 * data.offset[ 1 ],
1200
				newOverTop,
1201
				newOverBottom;
1202
			if ( overTop < 0 ) {
1203
				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -
1204
					outerHeight - withinOffset;
1205
				if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
1206
					position.top += myOffset + atOffset + offset;
1207
				}
1208
			} else if ( overBottom > 0 ) {
1209
				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +
1210
					offset - offsetTop;
1211
				if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
1212
					position.top += myOffset + atOffset + offset;
1213
				}
1214
			}
1215
		}
1216
	},
1217
	flipfit: {
1218
		left: function() {
1219
			$.ui.position.flip.left.apply( this, arguments );
1220
			$.ui.position.fit.left.apply( this, arguments );
1221
		},
1222
		top: function() {
1223
			$.ui.position.flip.top.apply( this, arguments );
1224
			$.ui.position.fit.top.apply( this, arguments );
1225
		}
1226
	}
1227
};
1228
 
1229
} )();
1230
 
1231
var position = $.ui.position;
1232
 
1233
 
1234
/*!
1235
 * jQuery UI :data 1.12.1
1236
 * http://jqueryui.com
1237
 *
1238
 * Copyright jQuery Foundation and other contributors
1239
 * Released under the MIT license.
1240
 * http://jquery.org/license
1241
 */
1242
 
1243
//>>label: :data Selector
1244
//>>group: Core
1245
//>>description: Selects elements which have data stored under the specified key.
1246
//>>docs: http://api.jqueryui.com/data-selector/
1247
 
1248
 
1249
var data = $.extend( $.expr[ ":" ], {
1250
	data: $.expr.createPseudo ?
1251
		$.expr.createPseudo( function( dataName ) {
1252
			return function( elem ) {
1253
				return !!$.data( elem, dataName );
1254
			};
1255
		} ) :
1256
 
1257
		// Support: jQuery <1.8
1258
		function( elem, i, match ) {
1259
			return !!$.data( elem, match[ 3 ] );
1260
		}
1261
} );
1262
 
1263
/*!
1264
 * jQuery UI Disable Selection 1.12.1
1265
 * http://jqueryui.com
1266
 *
1267
 * Copyright jQuery Foundation and other contributors
1268
 * Released under the MIT license.
1269
 * http://jquery.org/license
1270
 */
1271
 
1272
//>>label: disableSelection
1273
//>>group: Core
1274
//>>description: Disable selection of text content within the set of matched elements.
1275
//>>docs: http://api.jqueryui.com/disableSelection/
1276
 
1277
// This file is deprecated
1278
 
1279
 
1280
var disableSelection = $.fn.extend( {
1281
	disableSelection: ( function() {
1282
		var eventType = "onselectstart" in document.createElement( "div" ) ?
1283
			"selectstart" :
1284
			"mousedown";
1285
 
1286
		return function() {
1287
			return this.on( eventType + ".ui-disableSelection", function( event ) {
1288
				event.preventDefault();
1289
			} );
1290
		};
1291
	} )(),
1292
 
1293
	enableSelection: function() {
1294
		return this.off( ".ui-disableSelection" );
1295
	}
1296
} );
1297
 
1298
 
1299
/*!
1300
 * jQuery UI Focusable 1.12.1
1301
 * http://jqueryui.com
1302
 *
1303
 * Copyright jQuery Foundation and other contributors
1304
 * Released under the MIT license.
1305
 * http://jquery.org/license
1306
 */
1307
 
1308
//>>label: :focusable Selector
1309
//>>group: Core
1310
//>>description: Selects elements which can be focused.
1311
//>>docs: http://api.jqueryui.com/focusable-selector/
1312
 
1313
 
1314
 
1315
// Selectors
1316
$.ui.focusable = function( element, hasTabindex ) {
1317
	var map, mapName, img, focusableIfVisible, fieldset,
1318
		nodeName = element.nodeName.toLowerCase();
1319
 
1320
	if ( "area" === nodeName ) {
1321
		map = element.parentNode;
1322
		mapName = map.name;
1323
		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
1324
			return false;
1325
		}
1326
		img = $( "img[usemap='#" + mapName + "']" );
1327
		return img.length > 0 && img.is( ":visible" );
1328
	}
1329
 
1330
	if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) {
1331
		focusableIfVisible = !element.disabled;
1332
 
1333
		if ( focusableIfVisible ) {
1334
 
1335
			// Form controls within a disabled fieldset are disabled.
1336
			// However, controls within the fieldset's legend do not get disabled.
1337
			// Since controls generally aren't placed inside legends, we skip
1338
			// this portion of the check.
1339
			fieldset = $( element ).closest( "fieldset" )[ 0 ];
1340
			if ( fieldset ) {
1341
				focusableIfVisible = !fieldset.disabled;
1342
			}
1343
		}
1344
	} else if ( "a" === nodeName ) {
1345
		focusableIfVisible = element.href || hasTabindex;
1346
	} else {
1347
		focusableIfVisible = hasTabindex;
1348
	}
1349
 
1350
	return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) );
1351
};
1352
 
1353
// Support: IE 8 only
1354
// IE 8 doesn't resolve inherit to visible/hidden for computed values
1355
function visible( element ) {
1356
	var visibility = element.css( "visibility" );
1357
	while ( visibility === "inherit" ) {
1358
		element = element.parent();
1359
		visibility = element.css( "visibility" );
1360
	}
1361
	return visibility !== "hidden";
1362
}
1363
 
1364
$.extend( $.expr[ ":" ], {
1365
	focusable: function( element ) {
1366
		return $.ui.focusable( element, $.attr( element, "tabindex" ) != null );
1367
	}
1368
} );
1369
 
1370
var focusable = $.ui.focusable;
1371
 
1372
 
1373
 
1374
 
1375
// Support: IE8 Only
1376
// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop
1377
// with a string, so we need to find the proper form.
1378
var form = $.fn.form = function() {
1379
	return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form );
1380
};
1381
 
1382
 
1383
/*!
1384
 * jQuery UI Form Reset Mixin 1.12.1
1385
 * http://jqueryui.com
1386
 *
1387
 * Copyright jQuery Foundation and other contributors
1388
 * Released under the MIT license.
1389
 * http://jquery.org/license
1390
 */
1391
 
1392
//>>label: Form Reset Mixin
1393
//>>group: Core
1394
//>>description: Refresh input widgets when their form is reset
1395
//>>docs: http://api.jqueryui.com/form-reset-mixin/
1396
 
1397
 
1398
 
1399
var formResetMixin = $.ui.formResetMixin = {
1400
	_formResetHandler: function() {
1401
		var form = $( this );
1402
 
1403
		// Wait for the form reset to actually happen before refreshing
1404
		setTimeout( function() {
1405
			var instances = form.data( "ui-form-reset-instances" );
1406
			$.each( instances, function() {
1407
				this.refresh();
1408
			} );
1409
		} );
1410
	},
1411
 
1412
	_bindFormResetHandler: function() {
1413
		this.form = this.element.form();
1414
		if ( !this.form.length ) {
1415
			return;
1416
		}
1417
 
1418
		var instances = this.form.data( "ui-form-reset-instances" ) || [];
1419
		if ( !instances.length ) {
1420
 
1421
			// We don't use _on() here because we use a single event handler per form
1422
			this.form.on( "reset.ui-form-reset", this._formResetHandler );
1423
		}
1424
		instances.push( this );
1425
		this.form.data( "ui-form-reset-instances", instances );
1426
	},
1427
 
1428
	_unbindFormResetHandler: function() {
1429
		if ( !this.form.length ) {
1430
			return;
1431
		}
1432
 
1433
		var instances = this.form.data( "ui-form-reset-instances" );
1434
		instances.splice( $.inArray( this, instances ), 1 );
1435
		if ( instances.length ) {
1436
			this.form.data( "ui-form-reset-instances", instances );
1437
		} else {
1438
			this.form
1439
				.removeData( "ui-form-reset-instances" )
1440
				.off( "reset.ui-form-reset" );
1441
		}
1442
	}
1443
};
1444
 
1445
 
1446
/*!
1447
 * jQuery UI Support for jQuery core 1.7.x 1.12.1
1448
 * http://jqueryui.com
1449
 *
1450
 * Copyright jQuery Foundation and other contributors
1451
 * Released under the MIT license.
1452
 * http://jquery.org/license
1453
 *
1454
 */
1455
 
1456
//>>label: jQuery 1.7 Support
1457
//>>group: Core
1458
//>>description: Support version 1.7.x of jQuery core
1459
 
1460
 
1461
 
1462
// Support: jQuery 1.7 only
1463
// Not a great way to check versions, but since we only support 1.7+ and only
1464
// need to detect <1.8, this is a simple check that should suffice. Checking
1465
// for "1.7." would be a bit safer, but the version string is 1.7, not 1.7.0
1466
// and we'll never reach 1.70.0 (if we do, we certainly won't be supporting
1467
// 1.7 anymore). See #11197 for why we're not using feature detection.
1468
if ( $.fn.jquery.substring( 0, 3 ) === "1.7" ) {
1469
 
1470
	// Setters for .innerWidth(), .innerHeight(), .outerWidth(), .outerHeight()
1471
	// Unlike jQuery Core 1.8+, these only support numeric values to set the
1472
	// dimensions in pixels
1473
	$.each( [ "Width", "Height" ], function( i, name ) {
1474
		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
1475
			type = name.toLowerCase(),
1476
			orig = {
1477
				innerWidth: $.fn.innerWidth,
1478
				innerHeight: $.fn.innerHeight,
1479
				outerWidth: $.fn.outerWidth,
1480
				outerHeight: $.fn.outerHeight
1481
			};
1482
 
1483
		function reduce( elem, size, border, margin ) {
1484
			$.each( side, function() {
1485
				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
1486
				if ( border ) {
1487
					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
1488
				}
1489
				if ( margin ) {
1490
					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
1491
				}
1492
			} );
1493
			return size;
1494
		}
1495
 
1496
		$.fn[ "inner" + name ] = function( size ) {
1497
			if ( size === undefined ) {
1498
				return orig[ "inner" + name ].call( this );
1499
			}
1500
 
1501
			return this.each( function() {
1502
				$( this ).css( type, reduce( this, size ) + "px" );
1503
			} );
1504
		};
1505
 
1506
		$.fn[ "outer" + name ] = function( size, margin ) {
1507
			if ( typeof size !== "number" ) {
1508
				return orig[ "outer" + name ].call( this, size );
1509
			}
1510
 
1511
			return this.each( function() {
1512
				$( this ).css( type, reduce( this, size, true, margin ) + "px" );
1513
			} );
1514
		};
1515
	} );
1516
 
1517
	$.fn.addBack = function( selector ) {
1518
		return this.add( selector == null ?
1519
			this.prevObject : this.prevObject.filter( selector )
1520
		);
1521
	};
1522
}
1523
 
1524
;
1525
/*!
1526
 * jQuery UI Keycode 1.12.1
1527
 * http://jqueryui.com
1528
 *
1529
 * Copyright jQuery Foundation and other contributors
1530
 * Released under the MIT license.
1531
 * http://jquery.org/license
1532
 */
1533
 
1534
//>>label: Keycode
1535
//>>group: Core
1536
//>>description: Provide keycodes as keynames
1537
//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/
1538
 
1539
 
1540
var keycode = $.ui.keyCode = {
1541
	BACKSPACE: 8,
1542
	COMMA: 188,
1543
	DELETE: 46,
1544
	DOWN: 40,
1545
	END: 35,
1546
	ENTER: 13,
1547
	ESCAPE: 27,
1548
	HOME: 36,
1549
	LEFT: 37,
1550
	PAGE_DOWN: 34,
1551
	PAGE_UP: 33,
1552
	PERIOD: 190,
1553
	RIGHT: 39,
1554
	SPACE: 32,
1555
	TAB: 9,
1556
	UP: 38
1557
};
1558
 
1559
 
1560
 
1561
 
1562
// Internal use only
1563
var escapeSelector = $.ui.escapeSelector = ( function() {
1564
	var selectorEscape = /([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;
1565
	return function( selector ) {
1566
		return selector.replace( selectorEscape, "\\$1" );
1567
	};
1568
} )();
1569
 
1570
 
1571
/*!
1572
 * jQuery UI Labels 1.12.1
1573
 * http://jqueryui.com
1574
 *
1575
 * Copyright jQuery Foundation and other contributors
1576
 * Released under the MIT license.
1577
 * http://jquery.org/license
1578
 */
1579
 
1580
//>>label: labels
1581
//>>group: Core
1582
//>>description: Find all the labels associated with a given input
1583
//>>docs: http://api.jqueryui.com/labels/
1584
 
1585
 
1586
 
1587
var labels = $.fn.labels = function() {
1588
	var ancestor, selector, id, labels, ancestors;
1589
 
1590
	// Check control.labels first
1591
	if ( this[ 0 ].labels && this[ 0 ].labels.length ) {
1592
		return this.pushStack( this[ 0 ].labels );
1593
	}
1594
 
1595
	// Support: IE <= 11, FF <= 37, Android <= 2.3 only
1596
	// Above browsers do not support control.labels. Everything below is to support them
1597
	// as well as document fragments. control.labels does not work on document fragments
1598
	labels = this.eq( 0 ).parents( "label" );
1599
 
1600
	// Look for the label based on the id
1601
	id = this.attr( "id" );
1602
	if ( id ) {
1603
 
1604
		// We don't search against the document in case the element
1605
		// is disconnected from the DOM
1606
		ancestor = this.eq( 0 ).parents().last();
1607
 
1608
		// Get a full set of top level ancestors
1609
		ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() );
1610
 
1611
		// Create a selector for the label based on the id
1612
		selector = "label[for='" + $.ui.escapeSelector( id ) + "']";
1613
 
1614
		labels = labels.add( ancestors.find( selector ).addBack( selector ) );
1615
 
1616
	}
1617
 
1618
	// Return whatever we have found for labels
1619
	return this.pushStack( labels );
1620
};
1621
 
1622
 
1623
/*!
1624
 * jQuery UI Scroll Parent 1.12.1
1625
 * http://jqueryui.com
1626
 *
1627
 * Copyright jQuery Foundation and other contributors
1628
 * Released under the MIT license.
1629
 * http://jquery.org/license
1630
 */
1631
 
1632
//>>label: scrollParent
1633
//>>group: Core
1634
//>>description: Get the closest ancestor element that is scrollable.
1635
//>>docs: http://api.jqueryui.com/scrollParent/
1636
 
1637
 
1638
 
1639
var scrollParent = $.fn.scrollParent = function( includeHidden ) {
1640
	var position = this.css( "position" ),
1641
		excludeStaticParent = position === "absolute",
1642
		overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
1643
		scrollParent = this.parents().filter( function() {
1644
			var parent = $( this );
1645
			if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
1646
				return false;
1647
			}
1648
			return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
1649
				parent.css( "overflow-x" ) );
1650
		} ).eq( 0 );
1651
 
1652
	return position === "fixed" || !scrollParent.length ?
1653
		$( this[ 0 ].ownerDocument || document ) :
1654
		scrollParent;
1655
};
1656
 
1657
 
1658
/*!
1659
 * jQuery UI Tabbable 1.12.1
1660
 * http://jqueryui.com
1661
 *
1662
 * Copyright jQuery Foundation and other contributors
1663
 * Released under the MIT license.
1664
 * http://jquery.org/license
1665
 */
1666
 
1667
//>>label: :tabbable Selector
1668
//>>group: Core
1669
//>>description: Selects elements which can be tabbed to.
1670
//>>docs: http://api.jqueryui.com/tabbable-selector/
1671
 
1672
 
1673
 
1674
var tabbable = $.extend( $.expr[ ":" ], {
1675
	tabbable: function( element ) {
1676
		var tabIndex = $.attr( element, "tabindex" ),
1677
			hasTabindex = tabIndex != null;
1678
		return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex );
1679
	}
1680
} );
1681
 
1682
 
1683
/*!
1684
 * jQuery UI Unique ID 1.12.1
1685
 * http://jqueryui.com
1686
 *
1687
 * Copyright jQuery Foundation and other contributors
1688
 * Released under the MIT license.
1689
 * http://jquery.org/license
1690
 */
1691
 
1692
//>>label: uniqueId
1693
//>>group: Core
1694
//>>description: Functions to generate and remove uniqueId's
1695
//>>docs: http://api.jqueryui.com/uniqueId/
1696
 
1697
 
1698
 
1699
var uniqueId = $.fn.extend( {
1700
	uniqueId: ( function() {
1701
		var uuid = 0;
1702
 
1703
		return function() {
1704
			return this.each( function() {
1705
				if ( !this.id ) {
1706
					this.id = "ui-id-" + ( ++uuid );
1707
				}
1708
			} );
1709
		};
1710
	} )(),
1711
 
1712
	removeUniqueId: function() {
1713
		return this.each( function() {
1714
			if ( /^ui-id-\d+$/.test( this.id ) ) {
1715
				$( this ).removeAttr( "id" );
1716
			}
1717
		} );
1718
	}
1719
} );
1720
 
1721
 
1722
 
1723
 
1724
// This file is deprecated
1725
var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
1726
 
1727
/*!
1728
 * jQuery UI Mouse 1.12.1
1729
 * http://jqueryui.com
1730
 *
1731
 * Copyright jQuery Foundation and other contributors
1732
 * Released under the MIT license.
1733
 * http://jquery.org/license
1734
 */
1735
 
1736
//>>label: Mouse
1737
//>>group: Widgets
1738
//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
1739
//>>docs: http://api.jqueryui.com/mouse/
1740
 
1741
 
1742
 
1743
var mouseHandled = false;
1744
$( document ).on( "mouseup", function() {
1745
	mouseHandled = false;
1746
} );
1747
 
1748
var widgetsMouse = $.widget( "ui.mouse", {
1749
	version: "1.12.1",
1750
	options: {
1751
		cancel: "input, textarea, button, select, option",
1752
		distance: 1,
1753
		delay: 0
1754
	},
1755
	_mouseInit: function() {
1756
		var that = this;
1757
 
1758
		this.element
1759
			.on( "mousedown." + this.widgetName, function( event ) {
1760
				return that._mouseDown( event );
1761
			} )
1762
			.on( "click." + this.widgetName, function( event ) {
1763
				if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
1764
					$.removeData( event.target, that.widgetName + ".preventClickEvent" );
1765
					event.stopImmediatePropagation();
1766
					return false;
1767
				}
1768
			} );
1769
 
1770
		this.started = false;
1771
	},
1772
 
1773
	// TODO: make sure destroying one instance of mouse doesn't mess with
1774
	// other instances of mouse
1775
	_mouseDestroy: function() {
1776
		this.element.off( "." + this.widgetName );
1777
		if ( this._mouseMoveDelegate ) {
1778
			this.document
1779
				.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
1780
				.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
1781
		}
1782
	},
1783
 
1784
	_mouseDown: function( event ) {
1785
 
1786
		// don't let more than one widget handle mouseStart
1787
		if ( mouseHandled ) {
1788
			return;
1789
		}
1790
 
1791
		this._mouseMoved = false;
1792
 
1793
		// We may have missed mouseup (out of window)
1794
		( this._mouseStarted && this._mouseUp( event ) );
1795
 
1796
		this._mouseDownEvent = event;
1797
 
1798
		var that = this,
1799
			btnIsLeft = ( event.which === 1 ),
1800
 
1801
			// event.target.nodeName works around a bug in IE 8 with
1802
			// disabled inputs (#7620)
1803
			elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
1804
				$( event.target ).closest( this.options.cancel ).length : false );
1805
		if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
1806
			return true;
1807
		}
1808
 
1809
		this.mouseDelayMet = !this.options.delay;
1810
		if ( !this.mouseDelayMet ) {
1811
			this._mouseDelayTimer = setTimeout( function() {
1812
				that.mouseDelayMet = true;
1813
			}, this.options.delay );
1814
		}
1815
 
1816
		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
1817
			this._mouseStarted = ( this._mouseStart( event ) !== false );
1818
			if ( !this._mouseStarted ) {
1819
				event.preventDefault();
1820
				return true;
1821
			}
1822
		}
1823
 
1824
		// Click event may never have fired (Gecko & Opera)
1825
		if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
1826
			$.removeData( event.target, this.widgetName + ".preventClickEvent" );
1827
		}
1828
 
1829
		// These delegates are required to keep context
1830
		this._mouseMoveDelegate = function( event ) {
1831
			return that._mouseMove( event );
1832
		};
1833
		this._mouseUpDelegate = function( event ) {
1834
			return that._mouseUp( event );
1835
		};
1836
 
1837
		this.document
1838
			.on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
1839
			.on( "mouseup." + this.widgetName, this._mouseUpDelegate );
1840
 
1841
		event.preventDefault();
1842
 
1843
		mouseHandled = true;
1844
		return true;
1845
	},
1846
 
1847
	_mouseMove: function( event ) {
1848
 
1849
		// Only check for mouseups outside the document if you've moved inside the document
1850
		// at least once. This prevents the firing of mouseup in the case of IE<9, which will
1851
		// fire a mousemove event if content is placed under the cursor. See #7778
1852
		// Support: IE <9
1853
		if ( this._mouseMoved ) {
1854
 
1855
			// IE mouseup check - mouseup happened when mouse was out of window
1856
			if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
1857
					!event.button ) {
1858
				return this._mouseUp( event );
1859
 
1860
			// Iframe mouseup check - mouseup occurred in another document
1861
			} else if ( !event.which ) {
1862
 
1863
				// Support: Safari <=8 - 9
1864
				// Safari sets which to 0 if you press any of the following keys
1865
				// during a drag (#14461)
1866
				if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
1867
						event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
1868
					this.ignoreMissingWhich = true;
1869
				} else if ( !this.ignoreMissingWhich ) {
1870
					return this._mouseUp( event );
1871
				}
1872
			}
1873
		}
1874
 
1875
		if ( event.which || event.button ) {
1876
			this._mouseMoved = true;
1877
		}
1878
 
1879
		if ( this._mouseStarted ) {
1880
			this._mouseDrag( event );
1881
			return event.preventDefault();
1882
		}
1883
 
1884
		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
1885
			this._mouseStarted =
1886
				( this._mouseStart( this._mouseDownEvent, event ) !== false );
1887
			( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) );
1888
		}
1889
 
1890
		return !this._mouseStarted;
1891
	},
1892
 
1893
	_mouseUp: function( event ) {
1894
		this.document
1895
			.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
1896
			.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
1897
 
1898
		if ( this._mouseStarted ) {
1899
			this._mouseStarted = false;
1900
 
1901
			if ( event.target === this._mouseDownEvent.target ) {
1902
				$.data( event.target, this.widgetName + ".preventClickEvent", true );
1903
			}
1904
 
1905
			this._mouseStop( event );
1906
		}
1907
 
1908
		if ( this._mouseDelayTimer ) {
1909
			clearTimeout( this._mouseDelayTimer );
1910
			delete this._mouseDelayTimer;
1911
		}
1912
 
1913
		this.ignoreMissingWhich = false;
1914
		mouseHandled = false;
1915
		event.preventDefault();
1916
	},
1917
 
1918
	_mouseDistanceMet: function( event ) {
1919
		return ( Math.max(
1920
				Math.abs( this._mouseDownEvent.pageX - event.pageX ),
1921
				Math.abs( this._mouseDownEvent.pageY - event.pageY )
1922
			) >= this.options.distance
1923
		);
1924
	},
1925
 
1926
	_mouseDelayMet: function( /* event */ ) {
1927
		return this.mouseDelayMet;
1928
	},
1929
 
1930
	// These are placeholder methods, to be overriden by extending plugin
1931
	_mouseStart: function( /* event */ ) {},
1932
	_mouseDrag: function( /* event */ ) {},
1933
	_mouseStop: function( /* event */ ) {},
1934
	_mouseCapture: function( /* event */ ) { return true; }
1935
} );
1936
 
1937
 
1938
 
1939
 
1940
// $.ui.plugin is deprecated. Use $.widget() extensions instead.
1941
var plugin = $.ui.plugin = {
1942
	add: function( module, option, set ) {
1943
		var i,
1944
			proto = $.ui[ module ].prototype;
1945
		for ( i in set ) {
1946
			proto.plugins[ i ] = proto.plugins[ i ] || [];
1947
			proto.plugins[ i ].push( [ option, set[ i ] ] );
1948
		}
1949
	},
1950
	call: function( instance, name, args, allowDisconnected ) {
1951
		var i,
1952
			set = instance.plugins[ name ];
1953
 
1954
		if ( !set ) {
1955
			return;
1956
		}
1957
 
1958
		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
1959
				instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
1960
			return;
1961
		}
1962
 
1963
		for ( i = 0; i < set.length; i++ ) {
1964
			if ( instance.options[ set[ i ][ 0 ] ] ) {
1965
				set[ i ][ 1 ].apply( instance.element, args );
1966
			}
1967
		}
1968
	}
1969
};
1970
 
1971
 
1972
 
1973
var safeActiveElement = $.ui.safeActiveElement = function( document ) {
1974
	var activeElement;
1975
 
1976
	// Support: IE 9 only
1977
	// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
1978
	try {
1979
		activeElement = document.activeElement;
1980
	} catch ( error ) {
1981
		activeElement = document.body;
1982
	}
1983
 
1984
	// Support: IE 9 - 11 only
1985
	// IE may return null instead of an element
1986
	// Interestingly, this only seems to occur when NOT in an iframe
1987
	if ( !activeElement ) {
1988
		activeElement = document.body;
1989
	}
1990
 
1991
	// Support: IE 11 only
1992
	// IE11 returns a seemingly empty object in some cases when accessing
1993
	// document.activeElement from an <iframe>
1994
	if ( !activeElement.nodeName ) {
1995
		activeElement = document.body;
1996
	}
1997
 
1998
	return activeElement;
1999
};
2000
 
2001
 
2002
 
2003
var safeBlur = $.ui.safeBlur = function( element ) {
2004
 
2005
	// Support: IE9 - 10 only
2006
	// If the <body> is blurred, IE will switch windows, see #9420
2007
	if ( element && element.nodeName.toLowerCase() !== "body" ) {
2008
		$( element ).trigger( "blur" );
2009
	}
2010
};
2011
 
2012
 
2013
/*!
2014
 * jQuery UI Draggable 1.12.1
2015
 * http://jqueryui.com
2016
 *
2017
 * Copyright jQuery Foundation and other contributors
2018
 * Released under the MIT license.
2019
 * http://jquery.org/license
2020
 */
2021
 
2022
//>>label: Draggable
2023
//>>group: Interactions
2024
//>>description: Enables dragging functionality for any element.
2025
//>>docs: http://api.jqueryui.com/draggable/
2026
//>>demos: http://jqueryui.com/draggable/
2027
//>>css.structure: ../../themes/base/draggable.css
2028
 
2029
 
2030
 
2031
$.widget( "ui.draggable", $.ui.mouse, {
2032
	version: "1.12.1",
2033
	widgetEventPrefix: "drag",
2034
	options: {
2035
		addClasses: true,
2036
		appendTo: "parent",
2037
		axis: false,
2038
		connectToSortable: false,
2039
		containment: false,
2040
		cursor: "auto",
2041
		cursorAt: false,
2042
		grid: false,
2043
		handle: false,
2044
		helper: "original",
2045
		iframeFix: false,
2046
		opacity: false,
2047
		refreshPositions: false,
2048
		revert: false,
2049
		revertDuration: 500,
2050
		scope: "default",
2051
		scroll: true,
2052
		scrollSensitivity: 20,
2053
		scrollSpeed: 20,
2054
		snap: false,
2055
		snapMode: "both",
2056
		snapTolerance: 20,
2057
		stack: false,
2058
		zIndex: false,
2059
 
2060
		// Callbacks
2061
		drag: null,
2062
		start: null,
2063
		stop: null
2064
	},
2065
	_create: function() {
2066
 
2067
		if ( this.options.helper === "original" ) {
2068
			this._setPositionRelative();
2069
		}
2070
		if ( this.options.addClasses ) {
2071
			this._addClass( "ui-draggable" );
2072
		}
2073
		this._setHandleClassName();
2074
 
2075
		this._mouseInit();
2076
	},
2077
 
2078
	_setOption: function( key, value ) {
2079
		this._super( key, value );
2080
		if ( key === "handle" ) {
2081
			this._removeHandleClassName();
2082
			this._setHandleClassName();
2083
		}
2084
	},
2085
 
2086
	_destroy: function() {
2087
		if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
2088
			this.destroyOnClear = true;
2089
			return;
2090
		}
2091
		this._removeHandleClassName();
2092
		this._mouseDestroy();
2093
	},
2094
 
2095
	_mouseCapture: function( event ) {
2096
		var o = this.options;
2097
 
2098
		// Among others, prevent a drag on a resizable-handle
2099
		if ( this.helper || o.disabled ||
2100
				$( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
2101
			return false;
2102
		}
2103
 
2104
		//Quit if we're not on a valid handle
2105
		this.handle = this._getHandle( event );
2106
		if ( !this.handle ) {
2107
			return false;
2108
		}
2109
 
2110
		this._blurActiveElement( event );
2111
 
2112
		this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
2113
 
2114
		return true;
2115
 
2116
	},
2117
 
2118
	_blockFrames: function( selector ) {
2119
		this.iframeBlocks = this.document.find( selector ).map( function() {
2120
			var iframe = $( this );
2121
 
2122
			return $( "<div>" )
2123
				.css( "position", "absolute" )
2124
				.appendTo( iframe.parent() )
2125
				.outerWidth( iframe.outerWidth() )
2126
				.outerHeight( iframe.outerHeight() )
2127
				.offset( iframe.offset() )[ 0 ];
2128
		} );
2129
	},
2130
 
2131
	_unblockFrames: function() {
2132
		if ( this.iframeBlocks ) {
2133
			this.iframeBlocks.remove();
2134
			delete this.iframeBlocks;
2135
		}
2136
	},
2137
 
2138
	_blurActiveElement: function( event ) {
2139
		var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
2140
			target = $( event.target );
2141
 
2142
		// Don't blur if the event occurred on an element that is within
2143
		// the currently focused element
2144
		// See #10527, #12472
2145
		if ( target.closest( activeElement ).length ) {
2146
			return;
2147
		}
2148
 
2149
		// Blur any element that currently has focus, see #4261
2150
		$.ui.safeBlur( activeElement );
2151
	},
2152
 
2153
	_mouseStart: function( event ) {
2154
 
2155
		var o = this.options;
2156
 
2157
		//Create and append the visible helper
2158
		this.helper = this._createHelper( event );
2159
 
2160
		this._addClass( this.helper, "ui-draggable-dragging" );
2161
 
2162
		//Cache the helper size
2163
		this._cacheHelperProportions();
2164
 
2165
		//If ddmanager is used for droppables, set the global draggable
2166
		if ( $.ui.ddmanager ) {
2167
			$.ui.ddmanager.current = this;
2168
		}
2169
 
2170
		/*
2171
		 * - Position generation -
2172
		 * This block generates everything position related - it's the core of draggables.
2173
		 */
2174
 
2175
		//Cache the margins of the original element
2176
		this._cacheMargins();
2177
 
2178
		//Store the helper's css position
2179
		this.cssPosition = this.helper.css( "position" );
2180
		this.scrollParent = this.helper.scrollParent( true );
2181
		this.offsetParent = this.helper.offsetParent();
2182
		this.hasFixedAncestor = this.helper.parents().filter( function() {
2183
				return $( this ).css( "position" ) === "fixed";
2184
			} ).length > 0;
2185
 
2186
		//The element's absolute position on the page minus margins
2187
		this.positionAbs = this.element.offset();
2188
		this._refreshOffsets( event );
2189
 
2190
		//Generate the original position
2191
		this.originalPosition = this.position = this._generatePosition( event, false );
2192
		this.originalPageX = event.pageX;
2193
		this.originalPageY = event.pageY;
2194
 
2195
		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
2196
		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
2197
 
2198
		//Set a containment if given in the options
2199
		this._setContainment();
2200
 
2201
		//Trigger event + callbacks
2202
		if ( this._trigger( "start", event ) === false ) {
2203
			this._clear();
2204
			return false;
2205
		}
2206
 
2207
		//Recache the helper size
2208
		this._cacheHelperProportions();
2209
 
2210
		//Prepare the droppable offsets
2211
		if ( $.ui.ddmanager && !o.dropBehaviour ) {
2212
			$.ui.ddmanager.prepareOffsets( this, event );
2213
		}
2214
 
2215
		// Execute the drag once - this causes the helper not to be visible before getting its
2216
		// correct position
2217
		this._mouseDrag( event, true );
2218
 
2219
		// If the ddmanager is used for droppables, inform the manager that dragging has started
2220
		// (see #5003)
2221
		if ( $.ui.ddmanager ) {
2222
			$.ui.ddmanager.dragStart( this, event );
2223
		}
2224
 
2225
		return true;
2226
	},
2227
 
2228
	_refreshOffsets: function( event ) {
2229
		this.offset = {
2230
			top: this.positionAbs.top - this.margins.top,
2231
			left: this.positionAbs.left - this.margins.left,
2232
			scroll: false,
2233
			parent: this._getParentOffset(),
2234
			relative: this._getRelativeOffset()
2235
		};
2236
 
2237
		this.offset.click = {
2238
			left: event.pageX - this.offset.left,
2239
			top: event.pageY - this.offset.top
2240
		};
2241
	},
2242
 
2243
	_mouseDrag: function( event, noPropagation ) {
2244
 
2245
		// reset any necessary cached properties (see #5009)
2246
		if ( this.hasFixedAncestor ) {
2247
			this.offset.parent = this._getParentOffset();
2248
		}
2249
 
2250
		//Compute the helpers position
2251
		this.position = this._generatePosition( event, true );
2252
		this.positionAbs = this._convertPositionTo( "absolute" );
2253
 
2254
		//Call plugins and callbacks and use the resulting position if something is returned
2255
		if ( !noPropagation ) {
2256
			var ui = this._uiHash();
2257
			if ( this._trigger( "drag", event, ui ) === false ) {
2258
				this._mouseUp( new $.Event( "mouseup", event ) );
2259
				return false;
2260
			}
2261
			this.position = ui.position;
2262
		}
2263
 
2264
		this.helper[ 0 ].style.left = this.position.left + "px";
2265
		this.helper[ 0 ].style.top = this.position.top + "px";
2266
 
2267
		if ( $.ui.ddmanager ) {
2268
			$.ui.ddmanager.drag( this, event );
2269
		}
2270
 
2271
		return false;
2272
	},
2273
 
2274
	_mouseStop: function( event ) {
2275
 
2276
		//If we are using droppables, inform the manager about the drop
2277
		var that = this,
2278
			dropped = false;
2279
		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
2280
			dropped = $.ui.ddmanager.drop( this, event );
2281
		}
2282
 
2283
		//if a drop comes from outside (a sortable)
2284
		if ( this.dropped ) {
2285
			dropped = this.dropped;
2286
			this.dropped = false;
2287
		}
2288
 
2289
		if ( ( this.options.revert === "invalid" && !dropped ) ||
2290
				( this.options.revert === "valid" && dropped ) ||
2291
				this.options.revert === true || ( $.isFunction( this.options.revert ) &&
2292
				this.options.revert.call( this.element, dropped ) )
2293
		) {
2294
			$( this.helper ).animate(
2295
				this.originalPosition,
2296
				parseInt( this.options.revertDuration, 10 ),
2297
				function() {
2298
					if ( that._trigger( "stop", event ) !== false ) {
2299
						that._clear();
2300
					}
2301
				}
2302
			);
2303
		} else {
2304
			if ( this._trigger( "stop", event ) !== false ) {
2305
				this._clear();
2306
			}
2307
		}
2308
 
2309
		return false;
2310
	},
2311
 
2312
	_mouseUp: function( event ) {
2313
		this._unblockFrames();
2314
 
2315
		// If the ddmanager is used for droppables, inform the manager that dragging has stopped
2316
		// (see #5003)
2317
		if ( $.ui.ddmanager ) {
2318
			$.ui.ddmanager.dragStop( this, event );
2319
		}
2320
 
2321
		// Only need to focus if the event occurred on the draggable itself, see #10527
2322
		if ( this.handleElement.is( event.target ) ) {
2323
 
2324
			// The interaction is over; whether or not the click resulted in a drag,
2325
			// focus the element
2326
			this.element.trigger( "focus" );
2327
		}
2328
 
2329
		return $.ui.mouse.prototype._mouseUp.call( this, event );
2330
	},
2331
 
2332
	cancel: function() {
2333
 
2334
		if ( this.helper.is( ".ui-draggable-dragging" ) ) {
2335
			this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
2336
		} else {
2337
			this._clear();
2338
		}
2339
 
2340
		return this;
2341
 
2342
	},
2343
 
2344
	_getHandle: function( event ) {
2345
		return this.options.handle ?
2346
			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
2347
			true;
2348
	},
2349
 
2350
	_setHandleClassName: function() {
2351
		this.handleElement = this.options.handle ?
2352
			this.element.find( this.options.handle ) : this.element;
2353
		this._addClass( this.handleElement, "ui-draggable-handle" );
2354
	},
2355
 
2356
	_removeHandleClassName: function() {
2357
		this._removeClass( this.handleElement, "ui-draggable-handle" );
2358
	},
2359
 
2360
	_createHelper: function( event ) {
2361
 
2362
		var o = this.options,
2363
			helperIsFunction = $.isFunction( o.helper ),
2364
			helper = helperIsFunction ?
2365
				$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
2366
				( o.helper === "clone" ?
2367
					this.element.clone().removeAttr( "id" ) :
2368
					this.element );
2369
 
2370
		if ( !helper.parents( "body" ).length ) {
2371
			helper.appendTo( ( o.appendTo === "parent" ?
2372
				this.element[ 0 ].parentNode :
2373
				o.appendTo ) );
2374
		}
2375
 
2376
		// Http://bugs.jqueryui.com/ticket/9446
2377
		// a helper function can return the original element
2378
		// which wouldn't have been set to relative in _create
2379
		if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
2380
			this._setPositionRelative();
2381
		}
2382
 
2383
		if ( helper[ 0 ] !== this.element[ 0 ] &&
2384
				!( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
2385
			helper.css( "position", "absolute" );
2386
		}
2387
 
2388
		return helper;
2389
 
2390
	},
2391
 
2392
	_setPositionRelative: function() {
2393
		if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
2394
			this.element[ 0 ].style.position = "relative";
2395
		}
2396
	},
2397
 
2398
	_adjustOffsetFromHelper: function( obj ) {
2399
		if ( typeof obj === "string" ) {
2400
			obj = obj.split( " " );
2401
		}
2402
		if ( $.isArray( obj ) ) {
2403
			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
2404
		}
2405
		if ( "left" in obj ) {
2406
			this.offset.click.left = obj.left + this.margins.left;
2407
		}
2408
		if ( "right" in obj ) {
2409
			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
2410
		}
2411
		if ( "top" in obj ) {
2412
			this.offset.click.top = obj.top + this.margins.top;
2413
		}
2414
		if ( "bottom" in obj ) {
2415
			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
2416
		}
2417
	},
2418
 
2419
	_isRootNode: function( element ) {
2420
		return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
2421
	},
2422
 
2423
	_getParentOffset: function() {
2424
 
2425
		//Get the offsetParent and cache its position
2426
		var po = this.offsetParent.offset(),
2427
			document = this.document[ 0 ];
2428
 
2429
		// This is a special case where we need to modify a offset calculated on start, since the
2430
		// following happened:
2431
		// 1. The position of the helper is absolute, so it's position is calculated based on the
2432
		// next positioned parent
2433
		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
2434
		// the document, which means that the scroll is included in the initial calculation of the
2435
		// offset of the parent, and never recalculated upon drag
2436
		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
2437
				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
2438
			po.left += this.scrollParent.scrollLeft();
2439
			po.top += this.scrollParent.scrollTop();
2440
		}
2441
 
2442
		if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
2443
			po = { top: 0, left: 0 };
2444
		}
2445
 
2446
		return {
2447
			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
2448
			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
2449
		};
2450
 
2451
	},
2452
 
2453
	_getRelativeOffset: function() {
2454
		if ( this.cssPosition !== "relative" ) {
2455
			return { top: 0, left: 0 };
2456
		}
2457
 
2458
		var p = this.element.position(),
2459
			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
2460
 
2461
		return {
2462
			top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
2463
				( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
2464
			left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
2465
				( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
2466
		};
2467
 
2468
	},
2469
 
2470
	_cacheMargins: function() {
2471
		this.margins = {
2472
			left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
2473
			top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
2474
			right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
2475
			bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
2476
		};
2477
	},
2478
 
2479
	_cacheHelperProportions: function() {
2480
		this.helperProportions = {
2481
			width: this.helper.outerWidth(),
2482
			height: this.helper.outerHeight()
2483
		};
2484
	},
2485
 
2486
	_setContainment: function() {
2487
 
2488
		var isUserScrollable, c, ce,
2489
			o = this.options,
2490
			document = this.document[ 0 ];
2491
 
2492
		this.relativeContainer = null;
2493
 
2494
		if ( !o.containment ) {
2495
			this.containment = null;
2496
			return;
2497
		}
2498
 
2499
		if ( o.containment === "window" ) {
2500
			this.containment = [
2501
				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
2502
				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
2503
				$( window ).scrollLeft() + $( window ).width() -
2504
					this.helperProportions.width - this.margins.left,
2505
				$( window ).scrollTop() +
2506
					( $( window ).height() || document.body.parentNode.scrollHeight ) -
2507
					this.helperProportions.height - this.margins.top
2508
			];
2509
			return;
2510
		}
2511
 
2512
		if ( o.containment === "document" ) {
2513
			this.containment = [
2514
				0,
2515
				0,
2516
				$( document ).width() - this.helperProportions.width - this.margins.left,
2517
				( $( document ).height() || document.body.parentNode.scrollHeight ) -
2518
					this.helperProportions.height - this.margins.top
2519
			];
2520
			return;
2521
		}
2522
 
2523
		if ( o.containment.constructor === Array ) {
2524
			this.containment = o.containment;
2525
			return;
2526
		}
2527
 
2528
		if ( o.containment === "parent" ) {
2529
			o.containment = this.helper[ 0 ].parentNode;
2530
		}
2531
 
2532
		c = $( o.containment );
2533
		ce = c[ 0 ];
2534
 
2535
		if ( !ce ) {
2536
			return;
2537
		}
2538
 
2539
		isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
2540
 
2541
		this.containment = [
2542
			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
2543
				( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
2544
			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
2545
				( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
2546
			( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
2547
				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
2548
				( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
2549
				this.helperProportions.width -
2550
				this.margins.left -
2551
				this.margins.right,
2552
			( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
2553
				( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
2554
				( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
2555
				this.helperProportions.height -
2556
				this.margins.top -
2557
				this.margins.bottom
2558
		];
2559
		this.relativeContainer = c;
2560
	},
2561
 
2562
	_convertPositionTo: function( d, pos ) {
2563
 
2564
		if ( !pos ) {
2565
			pos = this.position;
2566
		}
2567
 
2568
		var mod = d === "absolute" ? 1 : -1,
2569
			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
2570
 
2571
		return {
2572
			top: (
2573
 
2574
				// The absolute mouse position
2575
				pos.top	+
2576
 
2577
				// Only for relative positioned nodes: Relative offset from element to offset parent
2578
				this.offset.relative.top * mod +
2579
 
2580
				// The offsetParent's offset without borders (offset + border)
2581
				this.offset.parent.top * mod -
2582
				( ( this.cssPosition === "fixed" ?
2583
					-this.offset.scroll.top :
2584
					( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
2585
			),
2586
			left: (
2587
 
2588
				// The absolute mouse position
2589
				pos.left +
2590
 
2591
				// Only for relative positioned nodes: Relative offset from element to offset parent
2592
				this.offset.relative.left * mod +
2593
 
2594
				// The offsetParent's offset without borders (offset + border)
2595
				this.offset.parent.left * mod	-
2596
				( ( this.cssPosition === "fixed" ?
2597
					-this.offset.scroll.left :
2598
					( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
2599
			)
2600
		};
2601
 
2602
	},
2603
 
2604
	_generatePosition: function( event, constrainPosition ) {
2605
 
2606
		var containment, co, top, left,
2607
			o = this.options,
2608
			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
2609
			pageX = event.pageX,
2610
			pageY = event.pageY;
2611
 
2612
		// Cache the scroll
2613
		if ( !scrollIsRootNode || !this.offset.scroll ) {
2614
			this.offset.scroll = {
2615
				top: this.scrollParent.scrollTop(),
2616
				left: this.scrollParent.scrollLeft()
2617
			};
2618
		}
2619
 
2620
		/*
2621
		 * - Position constraining -
2622
		 * Constrain the position to a mix of grid, containment.
2623
		 */
2624
 
2625
		// If we are not dragging yet, we won't check for options
2626
		if ( constrainPosition ) {
2627
			if ( this.containment ) {
2628
				if ( this.relativeContainer ) {
2629
					co = this.relativeContainer.offset();
2630
					containment = [
2631
						this.containment[ 0 ] + co.left,
2632
						this.containment[ 1 ] + co.top,
2633
						this.containment[ 2 ] + co.left,
2634
						this.containment[ 3 ] + co.top
2635
					];
2636
				} else {
2637
					containment = this.containment;
2638
				}
2639
 
2640
				if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
2641
					pageX = containment[ 0 ] + this.offset.click.left;
2642
				}
2643
				if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
2644
					pageY = containment[ 1 ] + this.offset.click.top;
2645
				}
2646
				if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
2647
					pageX = containment[ 2 ] + this.offset.click.left;
2648
				}
2649
				if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
2650
					pageY = containment[ 3 ] + this.offset.click.top;
2651
				}
2652
			}
2653
 
2654
			if ( o.grid ) {
2655
 
2656
				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid
2657
				// argument errors in IE (see ticket #6950)
2658
				top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
2659
					this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
2660
				pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
2661
					top - this.offset.click.top > containment[ 3 ] ) ?
2662
						top :
2663
						( ( top - this.offset.click.top >= containment[ 1 ] ) ?
2664
							top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
2665
 
2666
				left = o.grid[ 0 ] ? this.originalPageX +
2667
					Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
2668
					this.originalPageX;
2669
				pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
2670
					left - this.offset.click.left > containment[ 2 ] ) ?
2671
						left :
2672
						( ( left - this.offset.click.left >= containment[ 0 ] ) ?
2673
							left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
2674
			}
2675
 
2676
			if ( o.axis === "y" ) {
2677
				pageX = this.originalPageX;
2678
			}
2679
 
2680
			if ( o.axis === "x" ) {
2681
				pageY = this.originalPageY;
2682
			}
2683
		}
2684
 
2685
		return {
2686
			top: (
2687
 
2688
				// The absolute mouse position
2689
				pageY -
2690
 
2691
				// Click offset (relative to the element)
2692
				this.offset.click.top -
2693
 
2694
				// Only for relative positioned nodes: Relative offset from element to offset parent
2695
				this.offset.relative.top -
2696
 
2697
				// The offsetParent's offset without borders (offset + border)
2698
				this.offset.parent.top +
2699
				( this.cssPosition === "fixed" ?
2700
					-this.offset.scroll.top :
2701
					( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
2702
			),
2703
			left: (
2704
 
2705
				// The absolute mouse position
2706
				pageX -
2707
 
2708
				// Click offset (relative to the element)
2709
				this.offset.click.left -
2710
 
2711
				// Only for relative positioned nodes: Relative offset from element to offset parent
2712
				this.offset.relative.left -
2713
 
2714
				// The offsetParent's offset without borders (offset + border)
2715
				this.offset.parent.left +
2716
				( this.cssPosition === "fixed" ?
2717
					-this.offset.scroll.left :
2718
					( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
2719
			)
2720
		};
2721
 
2722
	},
2723
 
2724
	_clear: function() {
2725
		this._removeClass( this.helper, "ui-draggable-dragging" );
2726
		if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
2727
			this.helper.remove();
2728
		}
2729
		this.helper = null;
2730
		this.cancelHelperRemoval = false;
2731
		if ( this.destroyOnClear ) {
2732
			this.destroy();
2733
		}
2734
	},
2735
 
2736
	// From now on bulk stuff - mainly helpers
2737
 
2738
	_trigger: function( type, event, ui ) {
2739
		ui = ui || this._uiHash();
2740
		$.ui.plugin.call( this, type, [ event, ui, this ], true );
2741
 
2742
		// Absolute position and offset (see #6884 ) have to be recalculated after plugins
2743
		if ( /^(drag|start|stop)/.test( type ) ) {
2744
			this.positionAbs = this._convertPositionTo( "absolute" );
2745
			ui.offset = this.positionAbs;
2746
		}
2747
		return $.Widget.prototype._trigger.call( this, type, event, ui );
2748
	},
2749
 
2750
	plugins: {},
2751
 
2752
	_uiHash: function() {
2753
		return {
2754
			helper: this.helper,
2755
			position: this.position,
2756
			originalPosition: this.originalPosition,
2757
			offset: this.positionAbs
2758
		};
2759
	}
2760
 
2761
} );
2762
 
2763
$.ui.plugin.add( "draggable", "connectToSortable", {
2764
	start: function( event, ui, draggable ) {
2765
		var uiSortable = $.extend( {}, ui, {
2766
			item: draggable.element
2767
		} );
2768
 
2769
		draggable.sortables = [];
2770
		$( draggable.options.connectToSortable ).each( function() {
2771
			var sortable = $( this ).sortable( "instance" );
2772
 
2773
			if ( sortable && !sortable.options.disabled ) {
2774
				draggable.sortables.push( sortable );
2775
 
2776
				// RefreshPositions is called at drag start to refresh the containerCache
2777
				// which is used in drag. This ensures it's initialized and synchronized
2778
				// with any changes that might have happened on the page since initialization.
2779
				sortable.refreshPositions();
2780
				sortable._trigger( "activate", event, uiSortable );
2781
			}
2782
		} );
2783
	},
2784
	stop: function( event, ui, draggable ) {
2785
		var uiSortable = $.extend( {}, ui, {
2786
			item: draggable.element
2787
		} );
2788
 
2789
		draggable.cancelHelperRemoval = false;
2790
 
2791
		$.each( draggable.sortables, function() {
2792
			var sortable = this;
2793
 
2794
			if ( sortable.isOver ) {
2795
				sortable.isOver = 0;
2796
 
2797
				// Allow this sortable to handle removing the helper
2798
				draggable.cancelHelperRemoval = true;
2799
				sortable.cancelHelperRemoval = false;
2800
 
2801
				// Use _storedCSS To restore properties in the sortable,
2802
				// as this also handles revert (#9675) since the draggable
2803
				// may have modified them in unexpected ways (#8809)
2804
				sortable._storedCSS = {
2805
					position: sortable.placeholder.css( "position" ),
2806
					top: sortable.placeholder.css( "top" ),
2807
					left: sortable.placeholder.css( "left" )
2808
				};
2809
 
2810
				sortable._mouseStop( event );
2811
 
2812
				// Once drag has ended, the sortable should return to using
2813
				// its original helper, not the shared helper from draggable
2814
				sortable.options.helper = sortable.options._helper;
2815
			} else {
2816
 
2817
				// Prevent this Sortable from removing the helper.
2818
				// However, don't set the draggable to remove the helper
2819
				// either as another connected Sortable may yet handle the removal.
2820
				sortable.cancelHelperRemoval = true;
2821
 
2822
				sortable._trigger( "deactivate", event, uiSortable );
2823
			}
2824
		} );
2825
	},
2826
	drag: function( event, ui, draggable ) {
2827
		$.each( draggable.sortables, function() {
2828
			var innermostIntersecting = false,
2829
				sortable = this;
2830
 
2831
			// Copy over variables that sortable's _intersectsWith uses
2832
			sortable.positionAbs = draggable.positionAbs;
2833
			sortable.helperProportions = draggable.helperProportions;
2834
			sortable.offset.click = draggable.offset.click;
2835
 
2836
			if ( sortable._intersectsWith( sortable.containerCache ) ) {
2837
				innermostIntersecting = true;
2838
 
2839
				$.each( draggable.sortables, function() {
2840
 
2841
					// Copy over variables that sortable's _intersectsWith uses
2842
					this.positionAbs = draggable.positionAbs;
2843
					this.helperProportions = draggable.helperProportions;
2844
					this.offset.click = draggable.offset.click;
2845
 
2846
					if ( this !== sortable &&
2847
							this._intersectsWith( this.containerCache ) &&
2848
							$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
2849
						innermostIntersecting = false;
2850
					}
2851
 
2852
					return innermostIntersecting;
2853
				} );
2854
			}
2855
 
2856
			if ( innermostIntersecting ) {
2857
 
2858
				// If it intersects, we use a little isOver variable and set it once,
2859
				// so that the move-in stuff gets fired only once.
2860
				if ( !sortable.isOver ) {
2861
					sortable.isOver = 1;
2862
 
2863
					// Store draggable's parent in case we need to reappend to it later.
2864
					draggable._parent = ui.helper.parent();
2865
 
2866
					sortable.currentItem = ui.helper
2867
						.appendTo( sortable.element )
2868
						.data( "ui-sortable-item", true );
2869
 
2870
					// Store helper option to later restore it
2871
					sortable.options._helper = sortable.options.helper;
2872
 
2873
					sortable.options.helper = function() {
2874
						return ui.helper[ 0 ];
2875
					};
2876
 
2877
					// Fire the start events of the sortable with our passed browser event,
2878
					// and our own helper (so it doesn't create a new one)
2879
					event.target = sortable.currentItem[ 0 ];
2880
					sortable._mouseCapture( event, true );
2881
					sortable._mouseStart( event, true, true );
2882
 
2883
					// Because the browser event is way off the new appended portlet,
2884
					// modify necessary variables to reflect the changes
2885
					sortable.offset.click.top = draggable.offset.click.top;
2886
					sortable.offset.click.left = draggable.offset.click.left;
2887
					sortable.offset.parent.left -= draggable.offset.parent.left -
2888
						sortable.offset.parent.left;
2889
					sortable.offset.parent.top -= draggable.offset.parent.top -
2890
						sortable.offset.parent.top;
2891
 
2892
					draggable._trigger( "toSortable", event );
2893
 
2894
					// Inform draggable that the helper is in a valid drop zone,
2895
					// used solely in the revert option to handle "valid/invalid".
2896
					draggable.dropped = sortable.element;
2897
 
2898
					// Need to refreshPositions of all sortables in the case that
2899
					// adding to one sortable changes the location of the other sortables (#9675)
2900
					$.each( draggable.sortables, function() {
2901
						this.refreshPositions();
2902
					} );
2903
 
2904
					// Hack so receive/update callbacks work (mostly)
2905
					draggable.currentItem = draggable.element;
2906
					sortable.fromOutside = draggable;
2907
				}
2908
 
2909
				if ( sortable.currentItem ) {
2910
					sortable._mouseDrag( event );
2911
 
2912
					// Copy the sortable's position because the draggable's can potentially reflect
2913
					// a relative position, while sortable is always absolute, which the dragged
2914
					// element has now become. (#8809)
2915
					ui.position = sortable.position;
2916
				}
2917
			} else {
2918
 
2919
				// If it doesn't intersect with the sortable, and it intersected before,
2920
				// we fake the drag stop of the sortable, but make sure it doesn't remove
2921
				// the helper by using cancelHelperRemoval.
2922
				if ( sortable.isOver ) {
2923
 
2924
					sortable.isOver = 0;
2925
					sortable.cancelHelperRemoval = true;
2926
 
2927
					// Calling sortable's mouseStop would trigger a revert,
2928
					// so revert must be temporarily false until after mouseStop is called.
2929
					sortable.options._revert = sortable.options.revert;
2930
					sortable.options.revert = false;
2931
 
2932
					sortable._trigger( "out", event, sortable._uiHash( sortable ) );
2933
					sortable._mouseStop( event, true );
2934
 
2935
					// Restore sortable behaviors that were modfied
2936
					// when the draggable entered the sortable area (#9481)
2937
					sortable.options.revert = sortable.options._revert;
2938
					sortable.options.helper = sortable.options._helper;
2939
 
2940
					if ( sortable.placeholder ) {
2941
						sortable.placeholder.remove();
2942
					}
2943
 
2944
					// Restore and recalculate the draggable's offset considering the sortable
2945
					// may have modified them in unexpected ways. (#8809, #10669)
2946
					ui.helper.appendTo( draggable._parent );
2947
					draggable._refreshOffsets( event );
2948
					ui.position = draggable._generatePosition( event, true );
2949
 
2950
					draggable._trigger( "fromSortable", event );
2951
 
2952
					// Inform draggable that the helper is no longer in a valid drop zone
2953
					draggable.dropped = false;
2954
 
2955
					// Need to refreshPositions of all sortables just in case removing
2956
					// from one sortable changes the location of other sortables (#9675)
2957
					$.each( draggable.sortables, function() {
2958
						this.refreshPositions();
2959
					} );
2960
				}
2961
			}
2962
		} );
2963
	}
2964
} );
2965
 
2966
$.ui.plugin.add( "draggable", "cursor", {
2967
	start: function( event, ui, instance ) {
2968
		var t = $( "body" ),
2969
			o = instance.options;
2970
 
2971
		if ( t.css( "cursor" ) ) {
2972
			o._cursor = t.css( "cursor" );
2973
		}
2974
		t.css( "cursor", o.cursor );
2975
	},
2976
	stop: function( event, ui, instance ) {
2977
		var o = instance.options;
2978
		if ( o._cursor ) {
2979
			$( "body" ).css( "cursor", o._cursor );
2980
		}
2981
	}
2982
} );
2983
 
2984
$.ui.plugin.add( "draggable", "opacity", {
2985
	start: function( event, ui, instance ) {
2986
		var t = $( ui.helper ),
2987
			o = instance.options;
2988
		if ( t.css( "opacity" ) ) {
2989
			o._opacity = t.css( "opacity" );
2990
		}
2991
		t.css( "opacity", o.opacity );
2992
	},
2993
	stop: function( event, ui, instance ) {
2994
		var o = instance.options;
2995
		if ( o._opacity ) {
2996
			$( ui.helper ).css( "opacity", o._opacity );
2997
		}
2998
	}
2999
} );
3000
 
3001
$.ui.plugin.add( "draggable", "scroll", {
3002
	start: function( event, ui, i ) {
3003
		if ( !i.scrollParentNotHidden ) {
3004
			i.scrollParentNotHidden = i.helper.scrollParent( false );
3005
		}
3006
 
3007
		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
3008
				i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
3009
			i.overflowOffset = i.scrollParentNotHidden.offset();
3010
		}
3011
	},
3012
	drag: function( event, ui, i  ) {
3013
 
3014
		var o = i.options,
3015
			scrolled = false,
3016
			scrollParent = i.scrollParentNotHidden[ 0 ],
3017
			document = i.document[ 0 ];
3018
 
3019
		if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
3020
			if ( !o.axis || o.axis !== "x" ) {
3021
				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
3022
						o.scrollSensitivity ) {
3023
					scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
3024
				} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
3025
					scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
3026
				}
3027
			}
3028
 
3029
			if ( !o.axis || o.axis !== "y" ) {
3030
				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
3031
						o.scrollSensitivity ) {
3032
					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
3033
				} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
3034
					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
3035
				}
3036
			}
3037
 
3038
		} else {
3039
 
3040
			if ( !o.axis || o.axis !== "x" ) {
3041
				if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
3042
					scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
3043
				} else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
3044
						o.scrollSensitivity ) {
3045
					scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
3046
				}
3047
			}
3048
 
3049
			if ( !o.axis || o.axis !== "y" ) {
3050
				if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
3051
					scrolled = $( document ).scrollLeft(
3052
						$( document ).scrollLeft() - o.scrollSpeed
3053
					);
3054
				} else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
3055
						o.scrollSensitivity ) {
3056
					scrolled = $( document ).scrollLeft(
3057
						$( document ).scrollLeft() + o.scrollSpeed
3058
					);
3059
				}
3060
			}
3061
 
3062
		}
3063
 
3064
		if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
3065
			$.ui.ddmanager.prepareOffsets( i, event );
3066
		}
3067
 
3068
	}
3069
} );
3070
 
3071
$.ui.plugin.add( "draggable", "snap", {
3072
	start: function( event, ui, i ) {
3073
 
3074
		var o = i.options;
3075
 
3076
		i.snapElements = [];
3077
 
3078
		$( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
3079
			.each( function() {
3080
				var $t = $( this ),
3081
					$o = $t.offset();
3082
				if ( this !== i.element[ 0 ] ) {
3083
					i.snapElements.push( {
3084
						item: this,
3085
						width: $t.outerWidth(), height: $t.outerHeight(),
3086
						top: $o.top, left: $o.left
3087
					} );
3088
				}
3089
			} );
3090
 
3091
	},
3092
	drag: function( event, ui, inst ) {
3093
 
3094
		var ts, bs, ls, rs, l, r, t, b, i, first,
3095
			o = inst.options,
3096
			d = o.snapTolerance,
3097
			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
3098
			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
3099
 
3100
		for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
3101
 
3102
			l = inst.snapElements[ i ].left - inst.margins.left;
3103
			r = l + inst.snapElements[ i ].width;
3104
			t = inst.snapElements[ i ].top - inst.margins.top;
3105
			b = t + inst.snapElements[ i ].height;
3106
 
3107
			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
3108
					!$.contains( inst.snapElements[ i ].item.ownerDocument,
3109
					inst.snapElements[ i ].item ) ) {
3110
				if ( inst.snapElements[ i ].snapping ) {
3111
					( inst.options.snap.release &&
3112
						inst.options.snap.release.call(
3113
							inst.element,
3114
							event,
3115
							$.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
3116
						) );
3117
				}
3118
				inst.snapElements[ i ].snapping = false;
3119
				continue;
3120
			}
3121
 
3122
			if ( o.snapMode !== "inner" ) {
3123
				ts = Math.abs( t - y2 ) <= d;
3124
				bs = Math.abs( b - y1 ) <= d;
3125
				ls = Math.abs( l - x2 ) <= d;
3126
				rs = Math.abs( r - x1 ) <= d;
3127
				if ( ts ) {
3128
					ui.position.top = inst._convertPositionTo( "relative", {
3129
						top: t - inst.helperProportions.height,
3130
						left: 0
3131
					} ).top;
3132
				}
3133
				if ( bs ) {
3134
					ui.position.top = inst._convertPositionTo( "relative", {
3135
						top: b,
3136
						left: 0
3137
					} ).top;
3138
				}
3139
				if ( ls ) {
3140
					ui.position.left = inst._convertPositionTo( "relative", {
3141
						top: 0,
3142
						left: l - inst.helperProportions.width
3143
					} ).left;
3144
				}
3145
				if ( rs ) {
3146
					ui.position.left = inst._convertPositionTo( "relative", {
3147
						top: 0,
3148
						left: r
3149
					} ).left;
3150
				}
3151
			}
3152
 
3153
			first = ( ts || bs || ls || rs );
3154
 
3155
			if ( o.snapMode !== "outer" ) {
3156
				ts = Math.abs( t - y1 ) <= d;
3157
				bs = Math.abs( b - y2 ) <= d;
3158
				ls = Math.abs( l - x1 ) <= d;
3159
				rs = Math.abs( r - x2 ) <= d;
3160
				if ( ts ) {
3161
					ui.position.top = inst._convertPositionTo( "relative", {
3162
						top: t,
3163
						left: 0
3164
					} ).top;
3165
				}
3166
				if ( bs ) {
3167
					ui.position.top = inst._convertPositionTo( "relative", {
3168
						top: b - inst.helperProportions.height,
3169
						left: 0
3170
					} ).top;
3171
				}
3172
				if ( ls ) {
3173
					ui.position.left = inst._convertPositionTo( "relative", {
3174
						top: 0,
3175
						left: l
3176
					} ).left;
3177
				}
3178
				if ( rs ) {
3179
					ui.position.left = inst._convertPositionTo( "relative", {
3180
						top: 0,
3181
						left: r - inst.helperProportions.width
3182
					} ).left;
3183
				}
3184
			}
3185
 
3186
			if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
3187
				( inst.options.snap.snap &&
3188
					inst.options.snap.snap.call(
3189
						inst.element,
3190
						event,
3191
						$.extend( inst._uiHash(), {
3192
							snapItem: inst.snapElements[ i ].item
3193
						} ) ) );
3194
			}
3195
			inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
3196
 
3197
		}
3198
 
3199
	}
3200
} );
3201
 
3202
$.ui.plugin.add( "draggable", "stack", {
3203
	start: function( event, ui, instance ) {
3204
		var min,
3205
			o = instance.options,
3206
			group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
3207
				return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
3208
					( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
3209
			} );
3210
 
3211
		if ( !group.length ) { return; }
3212
 
3213
		min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
3214
		$( group ).each( function( i ) {
3215
			$( this ).css( "zIndex", min + i );
3216
		} );
3217
		this.css( "zIndex", ( min + group.length ) );
3218
	}
3219
} );
3220
 
3221
$.ui.plugin.add( "draggable", "zIndex", {
3222
	start: function( event, ui, instance ) {
3223
		var t = $( ui.helper ),
3224
			o = instance.options;
3225
 
3226
		if ( t.css( "zIndex" ) ) {
3227
			o._zIndex = t.css( "zIndex" );
3228
		}
3229
		t.css( "zIndex", o.zIndex );
3230
	},
3231
	stop: function( event, ui, instance ) {
3232
		var o = instance.options;
3233
 
3234
		if ( o._zIndex ) {
3235
			$( ui.helper ).css( "zIndex", o._zIndex );
3236
		}
3237
	}
3238
} );
3239
 
3240
var widgetsDraggable = $.ui.draggable;
3241
 
3242
 
3243
/*!
3244
 * jQuery UI Droppable 1.12.1
3245
 * http://jqueryui.com
3246
 *
3247
 * Copyright jQuery Foundation and other contributors
3248
 * Released under the MIT license.
3249
 * http://jquery.org/license
3250
 */
3251
 
3252
//>>label: Droppable
3253
//>>group: Interactions
3254
//>>description: Enables drop targets for draggable elements.
3255
//>>docs: http://api.jqueryui.com/droppable/
3256
//>>demos: http://jqueryui.com/droppable/
3257
 
3258
 
3259
 
3260
$.widget( "ui.droppable", {
3261
	version: "1.12.1",
3262
	widgetEventPrefix: "drop",
3263
	options: {
3264
		accept: "*",
3265
		addClasses: true,
3266
		greedy: false,
3267
		scope: "default",
3268
		tolerance: "intersect",
3269
 
3270
		// Callbacks
3271
		activate: null,
3272
		deactivate: null,
3273
		drop: null,
3274
		out: null,
3275
		over: null
3276
	},
3277
	_create: function() {
3278
 
3279
		var proportions,
3280
			o = this.options,
3281
			accept = o.accept;
3282
 
3283
		this.isover = false;
3284
		this.isout = true;
3285
 
3286
		this.accept = $.isFunction( accept ) ? accept : function( d ) {
3287
			return d.is( accept );
3288
		};
3289
 
3290
		this.proportions = function( /* valueToWrite */ ) {
3291
			if ( arguments.length ) {
3292
 
3293
				// Store the droppable's proportions
3294
				proportions = arguments[ 0 ];
3295
			} else {
3296
 
3297
				// Retrieve or derive the droppable's proportions
3298
				return proportions ?
3299
					proportions :
3300
					proportions = {
3301
						width: this.element[ 0 ].offsetWidth,
3302
						height: this.element[ 0 ].offsetHeight
3303
					};
3304
			}
3305
		};
3306
 
3307
		this._addToManager( o.scope );
3308
 
3309
		o.addClasses && this._addClass( "ui-droppable" );
3310
 
3311
	},
3312
 
3313
	_addToManager: function( scope ) {
3314
 
3315
		// Add the reference and positions to the manager
3316
		$.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
3317
		$.ui.ddmanager.droppables[ scope ].push( this );
3318
	},
3319
 
3320
	_splice: function( drop ) {
3321
		var i = 0;
3322
		for ( ; i < drop.length; i++ ) {
3323
			if ( drop[ i ] === this ) {
3324
				drop.splice( i, 1 );
3325
			}
3326
		}
3327
	},
3328
 
3329
	_destroy: function() {
3330
		var drop = $.ui.ddmanager.droppables[ this.options.scope ];
3331
 
3332
		this._splice( drop );
3333
	},
3334
 
3335
	_setOption: function( key, value ) {
3336
 
3337
		if ( key === "accept" ) {
3338
			this.accept = $.isFunction( value ) ? value : function( d ) {
3339
				return d.is( value );
3340
			};
3341
		} else if ( key === "scope" ) {
3342
			var drop = $.ui.ddmanager.droppables[ this.options.scope ];
3343
 
3344
			this._splice( drop );
3345
			this._addToManager( value );
3346
		}
3347
 
3348
		this._super( key, value );
3349
	},
3350
 
3351
	_activate: function( event ) {
3352
		var draggable = $.ui.ddmanager.current;
3353
 
3354
		this._addActiveClass();
3355
		if ( draggable ) {
3356
			this._trigger( "activate", event, this.ui( draggable ) );
3357
		}
3358
	},
3359
 
3360
	_deactivate: function( event ) {
3361
		var draggable = $.ui.ddmanager.current;
3362
 
3363
		this._removeActiveClass();
3364
		if ( draggable ) {
3365
			this._trigger( "deactivate", event, this.ui( draggable ) );
3366
		}
3367
	},
3368
 
3369
	_over: function( event ) {
3370
 
3371
		var draggable = $.ui.ddmanager.current;
3372
 
3373
		// Bail if draggable and droppable are same element
3374
		if ( !draggable || ( draggable.currentItem ||
3375
				draggable.element )[ 0 ] === this.element[ 0 ] ) {
3376
			return;
3377
		}
3378
 
3379
		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
3380
				draggable.element ) ) ) {
3381
			this._addHoverClass();
3382
			this._trigger( "over", event, this.ui( draggable ) );
3383
		}
3384
 
3385
	},
3386
 
3387
	_out: function( event ) {
3388
 
3389
		var draggable = $.ui.ddmanager.current;
3390
 
3391
		// Bail if draggable and droppable are same element
3392
		if ( !draggable || ( draggable.currentItem ||
3393
				draggable.element )[ 0 ] === this.element[ 0 ] ) {
3394
			return;
3395
		}
3396
 
3397
		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
3398
				draggable.element ) ) ) {
3399
			this._removeHoverClass();
3400
			this._trigger( "out", event, this.ui( draggable ) );
3401
		}
3402
 
3403
	},
3404
 
3405
	_drop: function( event, custom ) {
3406
 
3407
		var draggable = custom || $.ui.ddmanager.current,
3408
			childrenIntersection = false;
3409
 
3410
		// Bail if draggable and droppable are same element
3411
		if ( !draggable || ( draggable.currentItem ||
3412
				draggable.element )[ 0 ] === this.element[ 0 ] ) {
3413
			return false;
3414
		}
3415
 
3416
		this.element
3417
			.find( ":data(ui-droppable)" )
3418
			.not( ".ui-draggable-dragging" )
3419
			.each( function() {
3420
				var inst = $( this ).droppable( "instance" );
3421
				if (
3422
					inst.options.greedy &&
3423
					!inst.options.disabled &&
3424
					inst.options.scope === draggable.options.scope &&
3425
					inst.accept.call(
3426
						inst.element[ 0 ], ( draggable.currentItem || draggable.element )
3427
					) &&
3428
					intersect(
3429
						draggable,
3430
						$.extend( inst, { offset: inst.element.offset() } ),
3431
						inst.options.tolerance, event
3432
					)
3433
				) {
3434
					childrenIntersection = true;
3435
					return false; }
3436
			} );
3437
		if ( childrenIntersection ) {
3438
			return false;
3439
		}
3440
 
3441
		if ( this.accept.call( this.element[ 0 ],
3442
				( draggable.currentItem || draggable.element ) ) ) {
3443
			this._removeActiveClass();
3444
			this._removeHoverClass();
3445
 
3446
			this._trigger( "drop", event, this.ui( draggable ) );
3447
			return this.element;
3448
		}
3449
 
3450
		return false;
3451
 
3452
	},
3453
 
3454
	ui: function( c ) {
3455
		return {
3456
			draggable: ( c.currentItem || c.element ),
3457
			helper: c.helper,
3458
			position: c.position,
3459
			offset: c.positionAbs
3460
		};
3461
	},
3462
 
3463
	// Extension points just to make backcompat sane and avoid duplicating logic
3464
	// TODO: Remove in 1.13 along with call to it below
3465
	_addHoverClass: function() {
3466
		this._addClass( "ui-droppable-hover" );
3467
	},
3468
 
3469
	_removeHoverClass: function() {
3470
		this._removeClass( "ui-droppable-hover" );
3471
	},
3472
 
3473
	_addActiveClass: function() {
3474
		this._addClass( "ui-droppable-active" );
3475
	},
3476
 
3477
	_removeActiveClass: function() {
3478
		this._removeClass( "ui-droppable-active" );
3479
	}
3480
} );
3481
 
3482
var intersect = $.ui.intersect = ( function() {
3483
	function isOverAxis( x, reference, size ) {
3484
		return ( x >= reference ) && ( x < ( reference + size ) );
3485
	}
3486
 
3487
	return function( draggable, droppable, toleranceMode, event ) {
3488
 
3489
		if ( !droppable.offset ) {
3490
			return false;
3491
		}
3492
 
3493
		var x1 = ( draggable.positionAbs ||
3494
				draggable.position.absolute ).left + draggable.margins.left,
3495
			y1 = ( draggable.positionAbs ||
3496
				draggable.position.absolute ).top + draggable.margins.top,
3497
			x2 = x1 + draggable.helperProportions.width,
3498
			y2 = y1 + draggable.helperProportions.height,
3499
			l = droppable.offset.left,
3500
			t = droppable.offset.top,
3501
			r = l + droppable.proportions().width,
3502
			b = t + droppable.proportions().height;
3503
 
3504
		switch ( toleranceMode ) {
3505
		case "fit":
3506
			return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
3507
		case "intersect":
3508
			return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
3509
				x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
3510
				t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
3511
				y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
3512
		case "pointer":
3513
			return isOverAxis( event.pageY, t, droppable.proportions().height ) &&
3514
				isOverAxis( event.pageX, l, droppable.proportions().width );
3515
		case "touch":
3516
			return (
3517
				( y1 >= t && y1 <= b ) || // Top edge touching
3518
				( y2 >= t && y2 <= b ) || // Bottom edge touching
3519
				( y1 < t && y2 > b ) // Surrounded vertically
3520
			) && (
3521
				( x1 >= l && x1 <= r ) || // Left edge touching
3522
				( x2 >= l && x2 <= r ) || // Right edge touching
3523
				( x1 < l && x2 > r ) // Surrounded horizontally
3524
			);
3525
		default:
3526
			return false;
3527
		}
3528
	};
3529
} )();
3530
 
3531
/*
3532
	This manager tracks offsets of draggables and droppables
3533
*/
3534
$.ui.ddmanager = {
3535
	current: null,
3536
	droppables: { "default": [] },
3537
	prepareOffsets: function( t, event ) {
3538
 
3539
		var i, j,
3540
			m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
3541
			type = event ? event.type : null, // workaround for #2317
3542
			list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
3543
 
3544
		droppablesLoop: for ( i = 0; i < m.length; i++ ) {
3545
 
3546
			// No disabled and non-accepted
3547
			if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ],
3548
					( t.currentItem || t.element ) ) ) ) {
3549
				continue;
3550
			}
3551
 
3552
			// Filter out elements in the current dragged item
3553
			for ( j = 0; j < list.length; j++ ) {
3554
				if ( list[ j ] === m[ i ].element[ 0 ] ) {
3555
					m[ i ].proportions().height = 0;
3556
					continue droppablesLoop;
3557
				}
3558
			}
3559
 
3560
			m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
3561
			if ( !m[ i ].visible ) {
3562
				continue;
3563
			}
3564
 
3565
			// Activate the droppable if used directly from draggables
3566
			if ( type === "mousedown" ) {
3567
				m[ i ]._activate.call( m[ i ], event );
3568
			}
3569
 
3570
			m[ i ].offset = m[ i ].element.offset();
3571
			m[ i ].proportions( {
3572
				width: m[ i ].element[ 0 ].offsetWidth,
3573
				height: m[ i ].element[ 0 ].offsetHeight
3574
			} );
3575
 
3576
		}
3577
 
3578
	},
3579
	drop: function( draggable, event ) {
3580
 
3581
		var dropped = false;
3582
 
3583
		// Create a copy of the droppables in case the list changes during the drop (#9116)
3584
		$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
3585
 
3586
			if ( !this.options ) {
3587
				return;
3588
			}
3589
			if ( !this.options.disabled && this.visible &&
3590
					intersect( draggable, this, this.options.tolerance, event ) ) {
3591
				dropped = this._drop.call( this, event ) || dropped;
3592
			}
3593
 
3594
			if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ],
3595
					( draggable.currentItem || draggable.element ) ) ) {
3596
				this.isout = true;
3597
				this.isover = false;
3598
				this._deactivate.call( this, event );
3599
			}
3600
 
3601
		} );
3602
		return dropped;
3603
 
3604
	},
3605
	dragStart: function( draggable, event ) {
3606
 
3607
		// Listen for scrolling so that if the dragging causes scrolling the position of the
3608
		// droppables can be recalculated (see #5003)
3609
		draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() {
3610
			if ( !draggable.options.refreshPositions ) {
3611
				$.ui.ddmanager.prepareOffsets( draggable, event );
3612
			}
3613
		} );
3614
	},
3615
	drag: function( draggable, event ) {
3616
 
3617
		// If you have a highly dynamic page, you might try this option. It renders positions
3618
		// every time you move the mouse.
3619
		if ( draggable.options.refreshPositions ) {
3620
			$.ui.ddmanager.prepareOffsets( draggable, event );
3621
		}
3622
 
3623
		// Run through all droppables and check their positions based on specific tolerance options
3624
		$.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
3625
 
3626
			if ( this.options.disabled || this.greedyChild || !this.visible ) {
3627
				return;
3628
			}
3629
 
3630
			var parentInstance, scope, parent,
3631
				intersects = intersect( draggable, this, this.options.tolerance, event ),
3632
				c = !intersects && this.isover ?
3633
					"isout" :
3634
					( intersects && !this.isover ? "isover" : null );
3635
			if ( !c ) {
3636
				return;
3637
			}
3638
 
3639
			if ( this.options.greedy ) {
3640
 
3641
				// find droppable parents with same scope
3642
				scope = this.options.scope;
3643
				parent = this.element.parents( ":data(ui-droppable)" ).filter( function() {
3644
					return $( this ).droppable( "instance" ).options.scope === scope;
3645
				} );
3646
 
3647
				if ( parent.length ) {
3648
					parentInstance = $( parent[ 0 ] ).droppable( "instance" );
3649
					parentInstance.greedyChild = ( c === "isover" );
3650
				}
3651
			}
3652
 
3653
			// We just moved into a greedy child
3654
			if ( parentInstance && c === "isover" ) {
3655
				parentInstance.isover = false;
3656
				parentInstance.isout = true;
3657
				parentInstance._out.call( parentInstance, event );
3658
			}
3659
 
3660
			this[ c ] = true;
3661
			this[ c === "isout" ? "isover" : "isout" ] = false;
3662
			this[ c === "isover" ? "_over" : "_out" ].call( this, event );
3663
 
3664
			// We just moved out of a greedy child
3665
			if ( parentInstance && c === "isout" ) {
3666
				parentInstance.isout = false;
3667
				parentInstance.isover = true;
3668
				parentInstance._over.call( parentInstance, event );
3669
			}
3670
		} );
3671
 
3672
	},
3673
	dragStop: function( draggable, event ) {
3674
		draggable.element.parentsUntil( "body" ).off( "scroll.droppable" );
3675
 
3676
		// Call prepareOffsets one final time since IE does not fire return scroll events when
3677
		// overflow was caused by drag (see #5003)
3678
		if ( !draggable.options.refreshPositions ) {
3679
			$.ui.ddmanager.prepareOffsets( draggable, event );
3680
		}
3681
	}
3682
};
3683
 
3684
// DEPRECATED
3685
// TODO: switch return back to widget declaration at top of file when this is removed
3686
if ( $.uiBackCompat !== false ) {
3687
 
3688
	// Backcompat for activeClass and hoverClass options
3689
	$.widget( "ui.droppable", $.ui.droppable, {
3690
		options: {
3691
			hoverClass: false,
3692
			activeClass: false
3693
		},
3694
		_addActiveClass: function() {
3695
			this._super();
3696
			if ( this.options.activeClass ) {
3697
				this.element.addClass( this.options.activeClass );
3698
			}
3699
		},
3700
		_removeActiveClass: function() {
3701
			this._super();
3702
			if ( this.options.activeClass ) {
3703
				this.element.removeClass( this.options.activeClass );
3704
			}
3705
		},
3706
		_addHoverClass: function() {
3707
			this._super();
3708
			if ( this.options.hoverClass ) {
3709
				this.element.addClass( this.options.hoverClass );
3710
			}
3711
		},
3712
		_removeHoverClass: function() {
3713
			this._super();
3714
			if ( this.options.hoverClass ) {
3715
				this.element.removeClass( this.options.hoverClass );
3716
			}
3717
		}
3718
	} );
3719
}
3720
 
3721
var widgetsDroppable = $.ui.droppable;
3722
 
3723
 
3724
/*!
3725
 * jQuery UI Resizable 1.12.1
3726
 * http://jqueryui.com
3727
 *
3728
 * Copyright jQuery Foundation and other contributors
3729
 * Released under the MIT license.
3730
 * http://jquery.org/license
3731
 */
3732
 
3733
//>>label: Resizable
3734
//>>group: Interactions
3735
//>>description: Enables resize functionality for any element.
3736
//>>docs: http://api.jqueryui.com/resizable/
3737
//>>demos: http://jqueryui.com/resizable/
3738
//>>css.structure: ../../themes/base/core.css
3739
//>>css.structure: ../../themes/base/resizable.css
3740
//>>css.theme: ../../themes/base/theme.css
3741
 
3742
 
3743
 
3744
$.widget( "ui.resizable", $.ui.mouse, {
3745
	version: "1.12.1",
3746
	widgetEventPrefix: "resize",
3747
	options: {
3748
		alsoResize: false,
3749
		animate: false,
3750
		animateDuration: "slow",
3751
		animateEasing: "swing",
3752
		aspectRatio: false,
3753
		autoHide: false,
3754
		classes: {
3755
			"ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se"
3756
		},
3757
		containment: false,
3758
		ghost: false,
3759
		grid: false,
3760
		handles: "e,s,se",
3761
		helper: false,
3762
		maxHeight: null,
3763
		maxWidth: null,
3764
		minHeight: 10,
3765
		minWidth: 10,
3766
 
3767
		// See #7960
3768
		zIndex: 90,
3769
 
3770
		// Callbacks
3771
		resize: null,
3772
		start: null,
3773
		stop: null
3774
	},
3775
 
3776
	_num: function( value ) {
3777
		return parseFloat( value ) || 0;
3778
	},
3779
 
3780
	_isNumber: function( value ) {
3781
		return !isNaN( parseFloat( value ) );
3782
	},
3783
 
3784
	_hasScroll: function( el, a ) {
3785
 
3786
		if ( $( el ).css( "overflow" ) === "hidden" ) {
3787
			return false;
3788
		}
3789
 
3790
		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
3791
			has = false;
3792
 
3793
		if ( el[ scroll ] > 0 ) {
3794
			return true;
3795
		}
3796
 
3797
		// TODO: determine which cases actually cause this to happen
3798
		// if the element doesn't have the scroll set, see if it's possible to
3799
		// set the scroll
3800
		el[ scroll ] = 1;
3801
		has = ( el[ scroll ] > 0 );
3802
		el[ scroll ] = 0;
3803
		return has;
3804
	},
3805
 
3806
	_create: function() {
3807
 
3808
		var margins,
3809
			o = this.options,
3810
			that = this;
3811
		this._addClass( "ui-resizable" );
3812
 
3813
		$.extend( this, {
3814
			_aspectRatio: !!( o.aspectRatio ),
3815
			aspectRatio: o.aspectRatio,
3816
			originalElement: this.element,
3817
			_proportionallyResizeElements: [],
3818
			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
3819
		} );
3820
 
3821
		// Wrap the element if it cannot hold child nodes
3822
		if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) {
3823
 
3824
			this.element.wrap(
3825
				$( "<div class='ui-wrapper' style='overflow: hidden;'></div>" ).css( {
3826
					position: this.element.css( "position" ),
3827
					width: this.element.outerWidth(),
3828
					height: this.element.outerHeight(),
3829
					top: this.element.css( "top" ),
3830
					left: this.element.css( "left" )
3831
				} )
3832
			);
3833
 
3834
			this.element = this.element.parent().data(
3835
				"ui-resizable", this.element.resizable( "instance" )
3836
			);
3837
 
3838
			this.elementIsWrapper = true;
3839
 
3840
			margins = {
3841
				marginTop: this.originalElement.css( "marginTop" ),
3842
				marginRight: this.originalElement.css( "marginRight" ),
3843
				marginBottom: this.originalElement.css( "marginBottom" ),
3844
				marginLeft: this.originalElement.css( "marginLeft" )
3845
			};
3846
 
3847
			this.element.css( margins );
3848
			this.originalElement.css( "margin", 0 );
3849
 
3850
			// support: Safari
3851
			// Prevent Safari textarea resize
3852
			this.originalResizeStyle = this.originalElement.css( "resize" );
3853
			this.originalElement.css( "resize", "none" );
3854
 
3855
			this._proportionallyResizeElements.push( this.originalElement.css( {
3856
				position: "static",
3857
				zoom: 1,
3858
				display: "block"
3859
			} ) );
3860
 
3861
			// Support: IE9
3862
			// avoid IE jump (hard set the margin)
3863
			this.originalElement.css( margins );
3864
 
3865
			this._proportionallyResize();
3866
		}
3867
 
3868
		this._setupHandles();
3869
 
3870
		if ( o.autoHide ) {
3871
			$( this.element )
3872
				.on( "mouseenter", function() {
3873
					if ( o.disabled ) {
3874
						return;
3875
					}
3876
					that._removeClass( "ui-resizable-autohide" );
3877
					that._handles.show();
3878
				} )
3879
				.on( "mouseleave", function() {
3880
					if ( o.disabled ) {
3881
						return;
3882
					}
3883
					if ( !that.resizing ) {
3884
						that._addClass( "ui-resizable-autohide" );
3885
						that._handles.hide();
3886
					}
3887
				} );
3888
		}
3889
 
3890
		this._mouseInit();
3891
	},
3892
 
3893
	_destroy: function() {
3894
 
3895
		this._mouseDestroy();
3896
 
3897
		var wrapper,
3898
			_destroy = function( exp ) {
3899
				$( exp )
3900
					.removeData( "resizable" )
3901
					.removeData( "ui-resizable" )
3902
					.off( ".resizable" )
3903
					.find( ".ui-resizable-handle" )
3904
						.remove();
3905
			};
3906
 
3907
		// TODO: Unwrap at same DOM position
3908
		if ( this.elementIsWrapper ) {
3909
			_destroy( this.element );
3910
			wrapper = this.element;
3911
			this.originalElement.css( {
3912
				position: wrapper.css( "position" ),
3913
				width: wrapper.outerWidth(),
3914
				height: wrapper.outerHeight(),
3915
				top: wrapper.css( "top" ),
3916
				left: wrapper.css( "left" )
3917
			} ).insertAfter( wrapper );
3918
			wrapper.remove();
3919
		}
3920
 
3921
		this.originalElement.css( "resize", this.originalResizeStyle );
3922
		_destroy( this.originalElement );
3923
 
3924
		return this;
3925
	},
3926
 
3927
	_setOption: function( key, value ) {
3928
		this._super( key, value );
3929
 
3930
		switch ( key ) {
3931
		case "handles":
3932
			this._removeHandles();
3933
			this._setupHandles();
3934
			break;
3935
		default:
3936
			break;
3937
		}
3938
	},
3939
 
3940
	_setupHandles: function() {
3941
		var o = this.options, handle, i, n, hname, axis, that = this;
3942
		this.handles = o.handles ||
3943
			( !$( ".ui-resizable-handle", this.element ).length ?
3944
				"e,s,se" : {
3945
					n: ".ui-resizable-n",
3946
					e: ".ui-resizable-e",
3947
					s: ".ui-resizable-s",
3948
					w: ".ui-resizable-w",
3949
					se: ".ui-resizable-se",
3950
					sw: ".ui-resizable-sw",
3951
					ne: ".ui-resizable-ne",
3952
					nw: ".ui-resizable-nw"
3953
				} );
3954
 
3955
		this._handles = $();
3956
		if ( this.handles.constructor === String ) {
3957
 
3958
			if ( this.handles === "all" ) {
3959
				this.handles = "n,e,s,w,se,sw,ne,nw";
3960
			}
3961
 
3962
			n = this.handles.split( "," );
3963
			this.handles = {};
3964
 
3965
			for ( i = 0; i < n.length; i++ ) {
3966
 
3967
				handle = $.trim( n[ i ] );
3968
				hname = "ui-resizable-" + handle;
3969
				axis = $( "<div>" );
3970
				this._addClass( axis, "ui-resizable-handle " + hname );
3971
 
3972
				axis.css( { zIndex: o.zIndex } );
3973
 
3974
				this.handles[ handle ] = ".ui-resizable-" + handle;
3975
				this.element.append( axis );
3976
			}
3977
 
3978
		}
3979
 
3980
		this._renderAxis = function( target ) {
3981
 
3982
			var i, axis, padPos, padWrapper;
3983
 
3984
			target = target || this.element;
3985
 
3986
			for ( i in this.handles ) {
3987
 
3988
				if ( this.handles[ i ].constructor === String ) {
3989
					this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show();
3990
				} else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
3991
					this.handles[ i ] = $( this.handles[ i ] );
3992
					this._on( this.handles[ i ], { "mousedown": that._mouseDown } );
3993
				}
3994
 
3995
				if ( this.elementIsWrapper &&
3996
						this.originalElement[ 0 ]
3997
							.nodeName
3998
							.match( /^(textarea|input|select|button)$/i ) ) {
3999
					axis = $( this.handles[ i ], this.element );
4000
 
4001
					padWrapper = /sw|ne|nw|se|n|s/.test( i ) ?
4002
						axis.outerHeight() :
4003
						axis.outerWidth();
4004
 
4005
					padPos = [ "padding",
4006
						/ne|nw|n/.test( i ) ? "Top" :
4007
						/se|sw|s/.test( i ) ? "Bottom" :
4008
						/^e$/.test( i ) ? "Right" : "Left" ].join( "" );
4009
 
4010
					target.css( padPos, padWrapper );
4011
 
4012
					this._proportionallyResize();
4013
				}
4014
 
4015
				this._handles = this._handles.add( this.handles[ i ] );
4016
			}
4017
		};
4018
 
4019
		// TODO: make renderAxis a prototype function
4020
		this._renderAxis( this.element );
4021
 
4022
		this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
4023
		this._handles.disableSelection();
4024
 
4025
		this._handles.on( "mouseover", function() {
4026
			if ( !that.resizing ) {
4027
				if ( this.className ) {
4028
					axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i );
4029
				}
4030
				that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se";
4031
			}
4032
		} );
4033
 
4034
		if ( o.autoHide ) {
4035
			this._handles.hide();
4036
			this._addClass( "ui-resizable-autohide" );
4037
		}
4038
	},
4039
 
4040
	_removeHandles: function() {
4041
		this._handles.remove();
4042
	},
4043
 
4044
	_mouseCapture: function( event ) {
4045
		var i, handle,
4046
			capture = false;
4047
 
4048
		for ( i in this.handles ) {
4049
			handle = $( this.handles[ i ] )[ 0 ];
4050
			if ( handle === event.target || $.contains( handle, event.target ) ) {
4051
				capture = true;
4052
			}
4053
		}
4054
 
4055
		return !this.options.disabled && capture;
4056
	},
4057
 
4058
	_mouseStart: function( event ) {
4059
 
4060
		var curleft, curtop, cursor,
4061
			o = this.options,
4062
			el = this.element;
4063
 
4064
		this.resizing = true;
4065
 
4066
		this._renderProxy();
4067
 
4068
		curleft = this._num( this.helper.css( "left" ) );
4069
		curtop = this._num( this.helper.css( "top" ) );
4070
 
4071
		if ( o.containment ) {
4072
			curleft += $( o.containment ).scrollLeft() || 0;
4073
			curtop += $( o.containment ).scrollTop() || 0;
4074
		}
4075
 
4076
		this.offset = this.helper.offset();
4077
		this.position = { left: curleft, top: curtop };
4078
 
4079
		this.size = this._helper ? {
4080
				width: this.helper.width(),
4081
				height: this.helper.height()
4082
			} : {
4083
				width: el.width(),
4084
				height: el.height()
4085
			};
4086
 
4087
		this.originalSize = this._helper ? {
4088
				width: el.outerWidth(),
4089
				height: el.outerHeight()
4090
			} : {
4091
				width: el.width(),
4092
				height: el.height()
4093
			};
4094
 
4095
		this.sizeDiff = {
4096
			width: el.outerWidth() - el.width(),
4097
			height: el.outerHeight() - el.height()
4098
		};
4099
 
4100
		this.originalPosition = { left: curleft, top: curtop };
4101
		this.originalMousePosition = { left: event.pageX, top: event.pageY };
4102
 
4103
		this.aspectRatio = ( typeof o.aspectRatio === "number" ) ?
4104
			o.aspectRatio :
4105
			( ( this.originalSize.width / this.originalSize.height ) || 1 );
4106
 
4107
		cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" );
4108
		$( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor );
4109
 
4110
		this._addClass( "ui-resizable-resizing" );
4111
		this._propagate( "start", event );
4112
		return true;
4113
	},
4114
 
4115
	_mouseDrag: function( event ) {
4116
 
4117
		var data, props,
4118
			smp = this.originalMousePosition,
4119
			a = this.axis,
4120
			dx = ( event.pageX - smp.left ) || 0,
4121
			dy = ( event.pageY - smp.top ) || 0,
4122
			trigger = this._change[ a ];
4123
 
4124
		this._updatePrevProperties();
4125
 
4126
		if ( !trigger ) {
4127
			return false;
4128
		}
4129
 
4130
		data = trigger.apply( this, [ event, dx, dy ] );
4131
 
4132
		this._updateVirtualBoundaries( event.shiftKey );
4133
		if ( this._aspectRatio || event.shiftKey ) {
4134
			data = this._updateRatio( data, event );
4135
		}
4136
 
4137
		data = this._respectSize( data, event );
4138
 
4139
		this._updateCache( data );
4140
 
4141
		this._propagate( "resize", event );
4142
 
4143
		props = this._applyChanges();
4144
 
4145
		if ( !this._helper && this._proportionallyResizeElements.length ) {
4146
			this._proportionallyResize();
4147
		}
4148
 
4149
		if ( !$.isEmptyObject( props ) ) {
4150
			this._updatePrevProperties();
4151
			this._trigger( "resize", event, this.ui() );
4152
			this._applyChanges();
4153
		}
4154
 
4155
		return false;
4156
	},
4157
 
4158
	_mouseStop: function( event ) {
4159
 
4160
		this.resizing = false;
4161
		var pr, ista, soffseth, soffsetw, s, left, top,
4162
			o = this.options, that = this;
4163
 
4164
		if ( this._helper ) {
4165
 
4166
			pr = this._proportionallyResizeElements;
4167
			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName );
4168
			soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height;
4169
			soffsetw = ista ? 0 : that.sizeDiff.width;
4170
 
4171
			s = {
4172
				width: ( that.helper.width()  - soffsetw ),
4173
				height: ( that.helper.height() - soffseth )
4174
			};
4175
			left = ( parseFloat( that.element.css( "left" ) ) +
4176
				( that.position.left - that.originalPosition.left ) ) || null;
4177
			top = ( parseFloat( that.element.css( "top" ) ) +
4178
				( that.position.top - that.originalPosition.top ) ) || null;
4179
 
4180
			if ( !o.animate ) {
4181
				this.element.css( $.extend( s, { top: top, left: left } ) );
4182
			}
4183
 
4184
			that.helper.height( that.size.height );
4185
			that.helper.width( that.size.width );
4186
 
4187
			if ( this._helper && !o.animate ) {
4188
				this._proportionallyResize();
4189
			}
4190
		}
4191
 
4192
		$( "body" ).css( "cursor", "auto" );
4193
 
4194
		this._removeClass( "ui-resizable-resizing" );
4195
 
4196
		this._propagate( "stop", event );
4197
 
4198
		if ( this._helper ) {
4199
			this.helper.remove();
4200
		}
4201
 
4202
		return false;
4203
 
4204
	},
4205
 
4206
	_updatePrevProperties: function() {
4207
		this.prevPosition = {
4208
			top: this.position.top,
4209
			left: this.position.left
4210
		};
4211
		this.prevSize = {
4212
			width: this.size.width,
4213
			height: this.size.height
4214
		};
4215
	},
4216
 
4217
	_applyChanges: function() {
4218
		var props = {};
4219
 
4220
		if ( this.position.top !== this.prevPosition.top ) {
4221
			props.top = this.position.top + "px";
4222
		}
4223
		if ( this.position.left !== this.prevPosition.left ) {
4224
			props.left = this.position.left + "px";
4225
		}
4226
		if ( this.size.width !== this.prevSize.width ) {
4227
			props.width = this.size.width + "px";
4228
		}
4229
		if ( this.size.height !== this.prevSize.height ) {
4230
			props.height = this.size.height + "px";
4231
		}
4232
 
4233
		this.helper.css( props );
4234
 
4235
		return props;
4236
	},
4237
 
4238
	_updateVirtualBoundaries: function( forceAspectRatio ) {
4239
		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
4240
			o = this.options;
4241
 
4242
		b = {
4243
			minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0,
4244
			maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity,
4245
			minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0,
4246
			maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity
4247
		};
4248
 
4249
		if ( this._aspectRatio || forceAspectRatio ) {
4250
			pMinWidth = b.minHeight * this.aspectRatio;
4251
			pMinHeight = b.minWidth / this.aspectRatio;
4252
			pMaxWidth = b.maxHeight * this.aspectRatio;
4253
			pMaxHeight = b.maxWidth / this.aspectRatio;
4254
 
4255
			if ( pMinWidth > b.minWidth ) {
4256
				b.minWidth = pMinWidth;
4257
			}
4258
			if ( pMinHeight > b.minHeight ) {
4259
				b.minHeight = pMinHeight;
4260
			}
4261
			if ( pMaxWidth < b.maxWidth ) {
4262
				b.maxWidth = pMaxWidth;
4263
			}
4264
			if ( pMaxHeight < b.maxHeight ) {
4265
				b.maxHeight = pMaxHeight;
4266
			}
4267
		}
4268
		this._vBoundaries = b;
4269
	},
4270
 
4271
	_updateCache: function( data ) {
4272
		this.offset = this.helper.offset();
4273
		if ( this._isNumber( data.left ) ) {
4274
			this.position.left = data.left;
4275
		}
4276
		if ( this._isNumber( data.top ) ) {
4277
			this.position.top = data.top;
4278
		}
4279
		if ( this._isNumber( data.height ) ) {
4280
			this.size.height = data.height;
4281
		}
4282
		if ( this._isNumber( data.width ) ) {
4283
			this.size.width = data.width;
4284
		}
4285
	},
4286
 
4287
	_updateRatio: function( data ) {
4288
 
4289
		var cpos = this.position,
4290
			csize = this.size,
4291
			a = this.axis;
4292
 
4293
		if ( this._isNumber( data.height ) ) {
4294
			data.width = ( data.height * this.aspectRatio );
4295
		} else if ( this._isNumber( data.width ) ) {
4296
			data.height = ( data.width / this.aspectRatio );
4297
		}
4298
 
4299
		if ( a === "sw" ) {
4300
			data.left = cpos.left + ( csize.width - data.width );
4301
			data.top = null;
4302
		}
4303
		if ( a === "nw" ) {
4304
			data.top = cpos.top + ( csize.height - data.height );
4305
			data.left = cpos.left + ( csize.width - data.width );
4306
		}
4307
 
4308
		return data;
4309
	},
4310
 
4311
	_respectSize: function( data ) {
4312
 
4313
		var o = this._vBoundaries,
4314
			a = this.axis,
4315
			ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ),
4316
			ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ),
4317
			isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ),
4318
			isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ),
4319
			dw = this.originalPosition.left + this.originalSize.width,
4320
			dh = this.originalPosition.top + this.originalSize.height,
4321
			cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a );
4322
		if ( isminw ) {
4323
			data.width = o.minWidth;
4324
		}
4325
		if ( isminh ) {
4326
			data.height = o.minHeight;
4327
		}
4328
		if ( ismaxw ) {
4329
			data.width = o.maxWidth;
4330
		}
4331
		if ( ismaxh ) {
4332
			data.height = o.maxHeight;
4333
		}
4334
 
4335
		if ( isminw && cw ) {
4336
			data.left = dw - o.minWidth;
4337
		}
4338
		if ( ismaxw && cw ) {
4339
			data.left = dw - o.maxWidth;
4340
		}
4341
		if ( isminh && ch ) {
4342
			data.top = dh - o.minHeight;
4343
		}
4344
		if ( ismaxh && ch ) {
4345
			data.top = dh - o.maxHeight;
4346
		}
4347
 
4348
		// Fixing jump error on top/left - bug #2330
4349
		if ( !data.width && !data.height && !data.left && data.top ) {
4350
			data.top = null;
4351
		} else if ( !data.width && !data.height && !data.top && data.left ) {
4352
			data.left = null;
4353
		}
4354
 
4355
		return data;
4356
	},
4357
 
4358
	_getPaddingPlusBorderDimensions: function( element ) {
4359
		var i = 0,
4360
			widths = [],
4361
			borders = [
4362
				element.css( "borderTopWidth" ),
4363
				element.css( "borderRightWidth" ),
4364
				element.css( "borderBottomWidth" ),
4365
				element.css( "borderLeftWidth" )
4366
			],
4367
			paddings = [
4368
				element.css( "paddingTop" ),
4369
				element.css( "paddingRight" ),
4370
				element.css( "paddingBottom" ),
4371
				element.css( "paddingLeft" )
4372
			];
4373
 
4374
		for ( ; i < 4; i++ ) {
4375
			widths[ i ] = ( parseFloat( borders[ i ] ) || 0 );
4376
			widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 );
4377
		}
4378
 
4379
		return {
4380
			height: widths[ 0 ] + widths[ 2 ],
4381
			width: widths[ 1 ] + widths[ 3 ]
4382
		};
4383
	},
4384
 
4385
	_proportionallyResize: function() {
4386
 
4387
		if ( !this._proportionallyResizeElements.length ) {
4388
			return;
4389
		}
4390
 
4391
		var prel,
4392
			i = 0,
4393
			element = this.helper || this.element;
4394
 
4395
		for ( ; i < this._proportionallyResizeElements.length; i++ ) {
4396
 
4397
			prel = this._proportionallyResizeElements[ i ];
4398
 
4399
			// TODO: Seems like a bug to cache this.outerDimensions
4400
			// considering that we are in a loop.
4401
			if ( !this.outerDimensions ) {
4402
				this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
4403
			}
4404
 
4405
			prel.css( {
4406
				height: ( element.height() - this.outerDimensions.height ) || 0,
4407
				width: ( element.width() - this.outerDimensions.width ) || 0
4408
			} );
4409
 
4410
		}
4411
 
4412
	},
4413
 
4414
	_renderProxy: function() {
4415
 
4416
		var el = this.element, o = this.options;
4417
		this.elementOffset = el.offset();
4418
 
4419
		if ( this._helper ) {
4420
 
4421
			this.helper = this.helper || $( "<div style='overflow:hidden;'></div>" );
4422
 
4423
			this._addClass( this.helper, this._helper );
4424
			this.helper.css( {
4425
				width: this.element.outerWidth(),
4426
				height: this.element.outerHeight(),
4427
				position: "absolute",
4428
				left: this.elementOffset.left + "px",
4429
				top: this.elementOffset.top + "px",
4430
				zIndex: ++o.zIndex //TODO: Don't modify option
4431
			} );
4432
 
4433
			this.helper
4434
				.appendTo( "body" )
4435
				.disableSelection();
4436
 
4437
		} else {
4438
			this.helper = this.element;
4439
		}
4440
 
4441
	},
4442
 
4443
	_change: {
4444
		e: function( event, dx ) {
4445
			return { width: this.originalSize.width + dx };
4446
		},
4447
		w: function( event, dx ) {
4448
			var cs = this.originalSize, sp = this.originalPosition;
4449
			return { left: sp.left + dx, width: cs.width - dx };
4450
		},
4451
		n: function( event, dx, dy ) {
4452
			var cs = this.originalSize, sp = this.originalPosition;
4453
			return { top: sp.top + dy, height: cs.height - dy };
4454
		},
4455
		s: function( event, dx, dy ) {
4456
			return { height: this.originalSize.height + dy };
4457
		},
4458
		se: function( event, dx, dy ) {
4459
			return $.extend( this._change.s.apply( this, arguments ),
4460
				this._change.e.apply( this, [ event, dx, dy ] ) );
4461
		},
4462
		sw: function( event, dx, dy ) {
4463
			return $.extend( this._change.s.apply( this, arguments ),
4464
				this._change.w.apply( this, [ event, dx, dy ] ) );
4465
		},
4466
		ne: function( event, dx, dy ) {
4467
			return $.extend( this._change.n.apply( this, arguments ),
4468
				this._change.e.apply( this, [ event, dx, dy ] ) );
4469
		},
4470
		nw: function( event, dx, dy ) {
4471
			return $.extend( this._change.n.apply( this, arguments ),
4472
				this._change.w.apply( this, [ event, dx, dy ] ) );
4473
		}
4474
	},
4475
 
4476
	_propagate: function( n, event ) {
4477
		$.ui.plugin.call( this, n, [ event, this.ui() ] );
4478
		( n !== "resize" && this._trigger( n, event, this.ui() ) );
4479
	},
4480
 
4481
	plugins: {},
4482
 
4483
	ui: function() {
4484
		return {
4485
			originalElement: this.originalElement,
4486
			element: this.element,
4487
			helper: this.helper,
4488
			position: this.position,
4489
			size: this.size,
4490
			originalSize: this.originalSize,
4491
			originalPosition: this.originalPosition
4492
		};
4493
	}
4494
 
4495
} );
4496
 
4497
/*
4498
 * Resizable Extensions
4499
 */
4500
 
4501
$.ui.plugin.add( "resizable", "animate", {
4502
 
4503
	stop: function( event ) {
4504
		var that = $( this ).resizable( "instance" ),
4505
			o = that.options,
4506
			pr = that._proportionallyResizeElements,
4507
			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ),
4508
			soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height,
4509
			soffsetw = ista ? 0 : that.sizeDiff.width,
4510
			style = {
4511
				width: ( that.size.width - soffsetw ),
4512
				height: ( that.size.height - soffseth )
4513
			},
4514
			left = ( parseFloat( that.element.css( "left" ) ) +
4515
				( that.position.left - that.originalPosition.left ) ) || null,
4516
			top = ( parseFloat( that.element.css( "top" ) ) +
4517
				( that.position.top - that.originalPosition.top ) ) || null;
4518
 
4519
		that.element.animate(
4520
			$.extend( style, top && left ? { top: top, left: left } : {} ), {
4521
				duration: o.animateDuration,
4522
				easing: o.animateEasing,
4523
				step: function() {
4524
 
4525
					var data = {
4526
						width: parseFloat( that.element.css( "width" ) ),
4527
						height: parseFloat( that.element.css( "height" ) ),
4528
						top: parseFloat( that.element.css( "top" ) ),
4529
						left: parseFloat( that.element.css( "left" ) )
4530
					};
4531
 
4532
					if ( pr && pr.length ) {
4533
						$( pr[ 0 ] ).css( { width: data.width, height: data.height } );
4534
					}
4535
 
4536
					// Propagating resize, and updating values for each animation step
4537
					that._updateCache( data );
4538
					that._propagate( "resize", event );
4539
 
4540
				}
4541
			}
4542
		);
4543
	}
4544
 
4545
} );
4546
 
4547
$.ui.plugin.add( "resizable", "containment", {
4548
 
4549
	start: function() {
4550
		var element, p, co, ch, cw, width, height,
4551
			that = $( this ).resizable( "instance" ),
4552
			o = that.options,
4553
			el = that.element,
4554
			oc = o.containment,
4555
			ce = ( oc instanceof $ ) ?
4556
				oc.get( 0 ) :
4557
				( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
4558
 
4559
		if ( !ce ) {
4560
			return;
4561
		}
4562
 
4563
		that.containerElement = $( ce );
4564
 
4565
		if ( /document/.test( oc ) || oc === document ) {
4566
			that.containerOffset = {
4567
				left: 0,
4568
				top: 0
4569
			};
4570
			that.containerPosition = {
4571
				left: 0,
4572
				top: 0
4573
			};
4574
 
4575
			that.parentData = {
4576
				element: $( document ),
4577
				left: 0,
4578
				top: 0,
4579
				width: $( document ).width(),
4580
				height: $( document ).height() || document.body.parentNode.scrollHeight
4581
			};
4582
		} else {
4583
			element = $( ce );
4584
			p = [];
4585
			$( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) {
4586
				p[ i ] = that._num( element.css( "padding" + name ) );
4587
			} );
4588
 
4589
			that.containerOffset = element.offset();
4590
			that.containerPosition = element.position();
4591
			that.containerSize = {
4592
				height: ( element.innerHeight() - p[ 3 ] ),
4593
				width: ( element.innerWidth() - p[ 1 ] )
4594
			};
4595
 
4596
			co = that.containerOffset;
4597
			ch = that.containerSize.height;
4598
			cw = that.containerSize.width;
4599
			width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
4600
			height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
4601
 
4602
			that.parentData = {
4603
				element: ce,
4604
				left: co.left,
4605
				top: co.top,
4606
				width: width,
4607
				height: height
4608
			};
4609
		}
4610
	},
4611
 
4612
	resize: function( event ) {
4613
		var woset, hoset, isParent, isOffsetRelative,
4614
			that = $( this ).resizable( "instance" ),
4615
			o = that.options,
4616
			co = that.containerOffset,
4617
			cp = that.position,
4618
			pRatio = that._aspectRatio || event.shiftKey,
4619
			cop = {
4620
				top: 0,
4621
				left: 0
4622
			},
4623
			ce = that.containerElement,
4624
			continueResize = true;
4625
 
4626
		if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
4627
			cop = co;
4628
		}
4629
 
4630
		if ( cp.left < ( that._helper ? co.left : 0 ) ) {
4631
			that.size.width = that.size.width +
4632
				( that._helper ?
4633
					( that.position.left - co.left ) :
4634
					( that.position.left - cop.left ) );
4635
 
4636
			if ( pRatio ) {
4637
				that.size.height = that.size.width / that.aspectRatio;
4638
				continueResize = false;
4639
			}
4640
			that.position.left = o.helper ? co.left : 0;
4641
		}
4642
 
4643
		if ( cp.top < ( that._helper ? co.top : 0 ) ) {
4644
			that.size.height = that.size.height +
4645
				( that._helper ?
4646
					( that.position.top - co.top ) :
4647
					that.position.top );
4648
 
4649
			if ( pRatio ) {
4650
				that.size.width = that.size.height * that.aspectRatio;
4651
				continueResize = false;
4652
			}
4653
			that.position.top = that._helper ? co.top : 0;
4654
		}
4655
 
4656
		isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
4657
		isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
4658
 
4659
		if ( isParent && isOffsetRelative ) {
4660
			that.offset.left = that.parentData.left + that.position.left;
4661
			that.offset.top = that.parentData.top + that.position.top;
4662
		} else {
4663
			that.offset.left = that.element.offset().left;
4664
			that.offset.top = that.element.offset().top;
4665
		}
4666
 
4667
		woset = Math.abs( that.sizeDiff.width +
4668
			( that._helper ?
4669
				that.offset.left - cop.left :
4670
				( that.offset.left - co.left ) ) );
4671
 
4672
		hoset = Math.abs( that.sizeDiff.height +
4673
			( that._helper ?
4674
				that.offset.top - cop.top :
4675
				( that.offset.top - co.top ) ) );
4676
 
4677
		if ( woset + that.size.width >= that.parentData.width ) {
4678
			that.size.width = that.parentData.width - woset;
4679
			if ( pRatio ) {
4680
				that.size.height = that.size.width / that.aspectRatio;
4681
				continueResize = false;
4682
			}
4683
		}
4684
 
4685
		if ( hoset + that.size.height >= that.parentData.height ) {
4686
			that.size.height = that.parentData.height - hoset;
4687
			if ( pRatio ) {
4688
				that.size.width = that.size.height * that.aspectRatio;
4689
				continueResize = false;
4690
			}
4691
		}
4692
 
4693
		if ( !continueResize ) {
4694
			that.position.left = that.prevPosition.left;
4695
			that.position.top = that.prevPosition.top;
4696
			that.size.width = that.prevSize.width;
4697
			that.size.height = that.prevSize.height;
4698
		}
4699
	},
4700
 
4701
	stop: function() {
4702
		var that = $( this ).resizable( "instance" ),
4703
			o = that.options,
4704
			co = that.containerOffset,
4705
			cop = that.containerPosition,
4706
			ce = that.containerElement,
4707
			helper = $( that.helper ),
4708
			ho = helper.offset(),
4709
			w = helper.outerWidth() - that.sizeDiff.width,
4710
			h = helper.outerHeight() - that.sizeDiff.height;
4711
 
4712
		if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
4713
			$( this ).css( {
4714
				left: ho.left - cop.left - co.left,
4715
				width: w,
4716
				height: h
4717
			} );
4718
		}
4719
 
4720
		if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
4721
			$( this ).css( {
4722
				left: ho.left - cop.left - co.left,
4723
				width: w,
4724
				height: h
4725
			} );
4726
		}
4727
	}
4728
} );
4729
 
4730
$.ui.plugin.add( "resizable", "alsoResize", {
4731
 
4732
	start: function() {
4733
		var that = $( this ).resizable( "instance" ),
4734
			o = that.options;
4735
 
4736
		$( o.alsoResize ).each( function() {
4737
			var el = $( this );
4738
			el.data( "ui-resizable-alsoresize", {
4739
				width: parseFloat( el.width() ), height: parseFloat( el.height() ),
4740
				left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
4741
			} );
4742
		} );
4743
	},
4744
 
4745
	resize: function( event, ui ) {
4746
		var that = $( this ).resizable( "instance" ),
4747
			o = that.options,
4748
			os = that.originalSize,
4749
			op = that.originalPosition,
4750
			delta = {
4751
				height: ( that.size.height - os.height ) || 0,
4752
				width: ( that.size.width - os.width ) || 0,
4753
				top: ( that.position.top - op.top ) || 0,
4754
				left: ( that.position.left - op.left ) || 0
4755
			};
4756
 
4757
			$( o.alsoResize ).each( function() {
4758
				var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {},
4759
					css = el.parents( ui.originalElement[ 0 ] ).length ?
4760
							[ "width", "height" ] :
4761
							[ "width", "height", "top", "left" ];
4762
 
4763
				$.each( css, function( i, prop ) {
4764
					var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 );
4765
					if ( sum && sum >= 0 ) {
4766
						style[ prop ] = sum || null;
4767
					}
4768
				} );
4769
 
4770
				el.css( style );
4771
			} );
4772
	},
4773
 
4774
	stop: function() {
4775
		$( this ).removeData( "ui-resizable-alsoresize" );
4776
	}
4777
} );
4778
 
4779
$.ui.plugin.add( "resizable", "ghost", {
4780
 
4781
	start: function() {
4782
 
4783
		var that = $( this ).resizable( "instance" ), cs = that.size;
4784
 
4785
		that.ghost = that.originalElement.clone();
4786
		that.ghost.css( {
4787
			opacity: 0.25,
4788
			display: "block",
4789
			position: "relative",
4790
			height: cs.height,
4791
			width: cs.width,
4792
			margin: 0,
4793
			left: 0,
4794
			top: 0
4795
		} );
4796
 
4797
		that._addClass( that.ghost, "ui-resizable-ghost" );
4798
 
4799
		// DEPRECATED
4800
		// TODO: remove after 1.12
4801
		if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) {
4802
 
4803
			// Ghost option
4804
			that.ghost.addClass( this.options.ghost );
4805
		}
4806
 
4807
		that.ghost.appendTo( that.helper );
4808
 
4809
	},
4810
 
4811
	resize: function() {
4812
		var that = $( this ).resizable( "instance" );
4813
		if ( that.ghost ) {
4814
			that.ghost.css( {
4815
				position: "relative",
4816
				height: that.size.height,
4817
				width: that.size.width
4818
			} );
4819
		}
4820
	},
4821
 
4822
	stop: function() {
4823
		var that = $( this ).resizable( "instance" );
4824
		if ( that.ghost && that.helper ) {
4825
			that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) );
4826
		}
4827
	}
4828
 
4829
} );
4830
 
4831
$.ui.plugin.add( "resizable", "grid", {
4832
 
4833
	resize: function() {
4834
		var outerDimensions,
4835
			that = $( this ).resizable( "instance" ),
4836
			o = that.options,
4837
			cs = that.size,
4838
			os = that.originalSize,
4839
			op = that.originalPosition,
4840
			a = that.axis,
4841
			grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
4842
			gridX = ( grid[ 0 ] || 1 ),
4843
			gridY = ( grid[ 1 ] || 1 ),
4844
			ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX,
4845
			oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY,
4846
			newWidth = os.width + ox,
4847
			newHeight = os.height + oy,
4848
			isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ),
4849
			isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ),
4850
			isMinWidth = o.minWidth && ( o.minWidth > newWidth ),
4851
			isMinHeight = o.minHeight && ( o.minHeight > newHeight );
4852
 
4853
		o.grid = grid;
4854
 
4855
		if ( isMinWidth ) {
4856
			newWidth += gridX;
4857
		}
4858
		if ( isMinHeight ) {
4859
			newHeight += gridY;
4860
		}
4861
		if ( isMaxWidth ) {
4862
			newWidth -= gridX;
4863
		}
4864
		if ( isMaxHeight ) {
4865
			newHeight -= gridY;
4866
		}
4867
 
4868
		if ( /^(se|s|e)$/.test( a ) ) {
4869
			that.size.width = newWidth;
4870
			that.size.height = newHeight;
4871
		} else if ( /^(ne)$/.test( a ) ) {
4872
			that.size.width = newWidth;
4873
			that.size.height = newHeight;
4874
			that.position.top = op.top - oy;
4875
		} else if ( /^(sw)$/.test( a ) ) {
4876
			that.size.width = newWidth;
4877
			that.size.height = newHeight;
4878
			that.position.left = op.left - ox;
4879
		} else {
4880
			if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) {
4881
				outerDimensions = that._getPaddingPlusBorderDimensions( this );
4882
			}
4883
 
4884
			if ( newHeight - gridY > 0 ) {
4885
				that.size.height = newHeight;
4886
				that.position.top = op.top - oy;
4887
			} else {
4888
				newHeight = gridY - outerDimensions.height;
4889
				that.size.height = newHeight;
4890
				that.position.top = op.top + os.height - newHeight;
4891
			}
4892
			if ( newWidth - gridX > 0 ) {
4893
				that.size.width = newWidth;
4894
				that.position.left = op.left - ox;
4895
			} else {
4896
				newWidth = gridX - outerDimensions.width;
4897
				that.size.width = newWidth;
4898
				that.position.left = op.left + os.width - newWidth;
4899
			}
4900
		}
4901
	}
4902
 
4903
} );
4904
 
4905
var widgetsResizable = $.ui.resizable;
4906
 
4907
 
4908
/*!
4909
 * jQuery UI Selectable 1.12.1
4910
 * http://jqueryui.com
4911
 *
4912
 * Copyright jQuery Foundation and other contributors
4913
 * Released under the MIT license.
4914
 * http://jquery.org/license
4915
 */
4916
 
4917
//>>label: Selectable
4918
//>>group: Interactions
4919
//>>description: Allows groups of elements to be selected with the mouse.
4920
//>>docs: http://api.jqueryui.com/selectable/
4921
//>>demos: http://jqueryui.com/selectable/
4922
//>>css.structure: ../../themes/base/selectable.css
4923
 
4924
 
4925
 
4926
var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, {
4927
	version: "1.12.1",
4928
	options: {
4929
		appendTo: "body",
4930
		autoRefresh: true,
4931
		distance: 0,
4932
		filter: "*",
4933
		tolerance: "touch",
4934
 
4935
		// Callbacks
4936
		selected: null,
4937
		selecting: null,
4938
		start: null,
4939
		stop: null,
4940
		unselected: null,
4941
		unselecting: null
4942
	},
4943
	_create: function() {
4944
		var that = this;
4945
 
4946
		this._addClass( "ui-selectable" );
4947
 
4948
		this.dragged = false;
4949
 
4950
		// Cache selectee children based on filter
4951
		this.refresh = function() {
4952
			that.elementPos = $( that.element[ 0 ] ).offset();
4953
			that.selectees = $( that.options.filter, that.element[ 0 ] );
4954
			that._addClass( that.selectees, "ui-selectee" );
4955
			that.selectees.each( function() {
4956
				var $this = $( this ),
4957
					selecteeOffset = $this.offset(),
4958
					pos = {
4959
						left: selecteeOffset.left - that.elementPos.left,
4960
						top: selecteeOffset.top - that.elementPos.top
4961
					};
4962
				$.data( this, "selectable-item", {
4963
					element: this,
4964
					$element: $this,
4965
					left: pos.left,
4966
					top: pos.top,
4967
					right: pos.left + $this.outerWidth(),
4968
					bottom: pos.top + $this.outerHeight(),
4969
					startselected: false,
4970
					selected: $this.hasClass( "ui-selected" ),
4971
					selecting: $this.hasClass( "ui-selecting" ),
4972
					unselecting: $this.hasClass( "ui-unselecting" )
4973
				} );
4974
			} );
4975
		};
4976
		this.refresh();
4977
 
4978
		this._mouseInit();
4979
 
4980
		this.helper = $( "<div>" );
4981
		this._addClass( this.helper, "ui-selectable-helper" );
4982
	},
4983
 
4984
	_destroy: function() {
4985
		this.selectees.removeData( "selectable-item" );
4986
		this._mouseDestroy();
4987
	},
4988
 
4989
	_mouseStart: function( event ) {
4990
		var that = this,
4991
			options = this.options;
4992
 
4993
		this.opos = [ event.pageX, event.pageY ];
4994
		this.elementPos = $( this.element[ 0 ] ).offset();
4995
 
4996
		if ( this.options.disabled ) {
4997
			return;
4998
		}
4999
 
5000
		this.selectees = $( options.filter, this.element[ 0 ] );
5001
 
5002
		this._trigger( "start", event );
5003
 
5004
		$( options.appendTo ).append( this.helper );
5005
 
5006
		// position helper (lasso)
5007
		this.helper.css( {
5008
			"left": event.pageX,
5009
			"top": event.pageY,
5010
			"width": 0,
5011
			"height": 0
5012
		} );
5013
 
5014
		if ( options.autoRefresh ) {
5015
			this.refresh();
5016
		}
5017
 
5018
		this.selectees.filter( ".ui-selected" ).each( function() {
5019
			var selectee = $.data( this, "selectable-item" );
5020
			selectee.startselected = true;
5021
			if ( !event.metaKey && !event.ctrlKey ) {
5022
				that._removeClass( selectee.$element, "ui-selected" );
5023
				selectee.selected = false;
5024
				that._addClass( selectee.$element, "ui-unselecting" );
5025
				selectee.unselecting = true;
5026
 
5027
				// selectable UNSELECTING callback
5028
				that._trigger( "unselecting", event, {
5029
					unselecting: selectee.element
5030
				} );
5031
			}
5032
		} );
5033
 
5034
		$( event.target ).parents().addBack().each( function() {
5035
			var doSelect,
5036
				selectee = $.data( this, "selectable-item" );
5037
			if ( selectee ) {
5038
				doSelect = ( !event.metaKey && !event.ctrlKey ) ||
5039
					!selectee.$element.hasClass( "ui-selected" );
5040
				that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
5041
					._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
5042
				selectee.unselecting = !doSelect;
5043
				selectee.selecting = doSelect;
5044
				selectee.selected = doSelect;
5045
 
5046
				// selectable (UN)SELECTING callback
5047
				if ( doSelect ) {
5048
					that._trigger( "selecting", event, {
5049
						selecting: selectee.element
5050
					} );
5051
				} else {
5052
					that._trigger( "unselecting", event, {
5053
						unselecting: selectee.element
5054
					} );
5055
				}
5056
				return false;
5057
			}
5058
		} );
5059
 
5060
	},
5061
 
5062
	_mouseDrag: function( event ) {
5063
 
5064
		this.dragged = true;
5065
 
5066
		if ( this.options.disabled ) {
5067
			return;
5068
		}
5069
 
5070
		var tmp,
5071
			that = this,
5072
			options = this.options,
5073
			x1 = this.opos[ 0 ],
5074
			y1 = this.opos[ 1 ],
5075
			x2 = event.pageX,
5076
			y2 = event.pageY;
5077
 
5078
		if ( x1 > x2 ) { tmp = x2; x2 = x1; x1 = tmp; }
5079
		if ( y1 > y2 ) { tmp = y2; y2 = y1; y1 = tmp; }
5080
		this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
5081
 
5082
		this.selectees.each( function() {
5083
			var selectee = $.data( this, "selectable-item" ),
5084
				hit = false,
5085
				offset = {};
5086
 
5087
			//prevent helper from being selected if appendTo: selectable
5088
			if ( !selectee || selectee.element === that.element[ 0 ] ) {
5089
				return;
5090
			}
5091
 
5092
			offset.left   = selectee.left   + that.elementPos.left;
5093
			offset.right  = selectee.right  + that.elementPos.left;
5094
			offset.top    = selectee.top    + that.elementPos.top;
5095
			offset.bottom = selectee.bottom + that.elementPos.top;
5096
 
5097
			if ( options.tolerance === "touch" ) {
5098
				hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
5099
                    offset.bottom < y1 ) );
5100
			} else if ( options.tolerance === "fit" ) {
5101
				hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
5102
                    offset.bottom < y2 );
5103
			}
5104
 
5105
			if ( hit ) {
5106
 
5107
				// SELECT
5108
				if ( selectee.selected ) {
5109
					that._removeClass( selectee.$element, "ui-selected" );
5110
					selectee.selected = false;
5111
				}
5112
				if ( selectee.unselecting ) {
5113
					that._removeClass( selectee.$element, "ui-unselecting" );
5114
					selectee.unselecting = false;
5115
				}
5116
				if ( !selectee.selecting ) {
5117
					that._addClass( selectee.$element, "ui-selecting" );
5118
					selectee.selecting = true;
5119
 
5120
					// selectable SELECTING callback
5121
					that._trigger( "selecting", event, {
5122
						selecting: selectee.element
5123
					} );
5124
				}
5125
			} else {
5126
 
5127
				// UNSELECT
5128
				if ( selectee.selecting ) {
5129
					if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
5130
						that._removeClass( selectee.$element, "ui-selecting" );
5131
						selectee.selecting = false;
5132
						that._addClass( selectee.$element, "ui-selected" );
5133
						selectee.selected = true;
5134
					} else {
5135
						that._removeClass( selectee.$element, "ui-selecting" );
5136
						selectee.selecting = false;
5137
						if ( selectee.startselected ) {
5138
							that._addClass( selectee.$element, "ui-unselecting" );
5139
							selectee.unselecting = true;
5140
						}
5141
 
5142
						// selectable UNSELECTING callback
5143
						that._trigger( "unselecting", event, {
5144
							unselecting: selectee.element
5145
						} );
5146
					}
5147
				}
5148
				if ( selectee.selected ) {
5149
					if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
5150
						that._removeClass( selectee.$element, "ui-selected" );
5151
						selectee.selected = false;
5152
 
5153
						that._addClass( selectee.$element, "ui-unselecting" );
5154
						selectee.unselecting = true;
5155
 
5156
						// selectable UNSELECTING callback
5157
						that._trigger( "unselecting", event, {
5158
							unselecting: selectee.element
5159
						} );
5160
					}
5161
				}
5162
			}
5163
		} );
5164
 
5165
		return false;
5166
	},
5167
 
5168
	_mouseStop: function( event ) {
5169
		var that = this;
5170
 
5171
		this.dragged = false;
5172
 
5173
		$( ".ui-unselecting", this.element[ 0 ] ).each( function() {
5174
			var selectee = $.data( this, "selectable-item" );
5175
			that._removeClass( selectee.$element, "ui-unselecting" );
5176
			selectee.unselecting = false;
5177
			selectee.startselected = false;
5178
			that._trigger( "unselected", event, {
5179
				unselected: selectee.element
5180
			} );
5181
		} );
5182
		$( ".ui-selecting", this.element[ 0 ] ).each( function() {
5183
			var selectee = $.data( this, "selectable-item" );
5184
			that._removeClass( selectee.$element, "ui-selecting" )
5185
				._addClass( selectee.$element, "ui-selected" );
5186
			selectee.selecting = false;
5187
			selectee.selected = true;
5188
			selectee.startselected = true;
5189
			that._trigger( "selected", event, {
5190
				selected: selectee.element
5191
			} );
5192
		} );
5193
		this._trigger( "stop", event );
5194
 
5195
		this.helper.remove();
5196
 
5197
		return false;
5198
	}
5199
 
5200
} );
5201
 
5202
 
5203
/*!
5204
 * jQuery UI Sortable 1.12.1
5205
 * http://jqueryui.com
5206
 *
5207
 * Copyright jQuery Foundation and other contributors
5208
 * Released under the MIT license.
5209
 * http://jquery.org/license
5210
 */
5211
 
5212
//>>label: Sortable
5213
//>>group: Interactions
5214
//>>description: Enables items in a list to be sorted using the mouse.
5215
//>>docs: http://api.jqueryui.com/sortable/
5216
//>>demos: http://jqueryui.com/sortable/
5217
//>>css.structure: ../../themes/base/sortable.css
5218
 
5219
 
5220
 
5221
var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, {
5222
	version: "1.12.1",
5223
	widgetEventPrefix: "sort",
5224
	ready: false,
5225
	options: {
5226
		appendTo: "parent",
5227
		axis: false,
5228
		connectWith: false,
5229
		containment: false,
5230
		cursor: "auto",
5231
		cursorAt: false,
5232
		dropOnEmpty: true,
5233
		forcePlaceholderSize: false,
5234
		forceHelperSize: false,
5235
		grid: false,
5236
		handle: false,
5237
		helper: "original",
5238
		items: "> *",
5239
		opacity: false,
5240
		placeholder: false,
5241
		revert: false,
5242
		scroll: true,
5243
		scrollSensitivity: 20,
5244
		scrollSpeed: 20,
5245
		scope: "default",
5246
		tolerance: "intersect",
5247
		zIndex: 1000,
5248
 
5249
		// Callbacks
5250
		activate: null,
5251
		beforeStop: null,
5252
		change: null,
5253
		deactivate: null,
5254
		out: null,
5255
		over: null,
5256
		receive: null,
5257
		remove: null,
5258
		sort: null,
5259
		start: null,
5260
		stop: null,
5261
		update: null
5262
	},
5263
 
5264
	_isOverAxis: function( x, reference, size ) {
5265
		return ( x >= reference ) && ( x < ( reference + size ) );
5266
	},
5267
 
5268
	_isFloating: function( item ) {
5269
		return ( /left|right/ ).test( item.css( "float" ) ) ||
5270
			( /inline|table-cell/ ).test( item.css( "display" ) );
5271
	},
5272
 
5273
	_create: function() {
5274
		this.containerCache = {};
5275
		this._addClass( "ui-sortable" );
5276
 
5277
		//Get the items
5278
		this.refresh();
5279
 
5280
		//Let's determine the parent's offset
5281
		this.offset = this.element.offset();
5282
 
5283
		//Initialize mouse events for interaction
5284
		this._mouseInit();
5285
 
5286
		this._setHandleClassName();
5287
 
5288
		//We're ready to go
5289
		this.ready = true;
5290
 
5291
	},
5292
 
5293
	_setOption: function( key, value ) {
5294
		this._super( key, value );
5295
 
5296
		if ( key === "handle" ) {
5297
			this._setHandleClassName();
5298
		}
5299
	},
5300
 
5301
	_setHandleClassName: function() {
5302
		var that = this;
5303
		this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" );
5304
		$.each( this.items, function() {
5305
			that._addClass(
5306
				this.instance.options.handle ?
5307
					this.item.find( this.instance.options.handle ) :
5308
					this.item,
5309
				"ui-sortable-handle"
5310
			);
5311
		} );
5312
	},
5313
 
5314
	_destroy: function() {
5315
		this._mouseDestroy();
5316
 
5317
		for ( var i = this.items.length - 1; i >= 0; i-- ) {
5318
			this.items[ i ].item.removeData( this.widgetName + "-item" );
5319
		}
5320
 
5321
		return this;
5322
	},
5323
 
5324
	_mouseCapture: function( event, overrideHandle ) {
5325
		var currentItem = null,
5326
			validHandle = false,
5327
			that = this;
5328
 
5329
		if ( this.reverting ) {
5330
			return false;
5331
		}
5332
 
5333
		if ( this.options.disabled || this.options.type === "static" ) {
5334
			return false;
5335
		}
5336
 
5337
		//We have to refresh the items data once first
5338
		this._refreshItems( event );
5339
 
5340
		//Find out if the clicked node (or one of its parents) is a actual item in this.items
5341
		$( event.target ).parents().each( function() {
5342
			if ( $.data( this, that.widgetName + "-item" ) === that ) {
5343
				currentItem = $( this );
5344
				return false;
5345
			}
5346
		} );
5347
		if ( $.data( event.target, that.widgetName + "-item" ) === that ) {
5348
			currentItem = $( event.target );
5349
		}
5350
 
5351
		if ( !currentItem ) {
5352
			return false;
5353
		}
5354
		if ( this.options.handle && !overrideHandle ) {
5355
			$( this.options.handle, currentItem ).find( "*" ).addBack().each( function() {
5356
				if ( this === event.target ) {
5357
					validHandle = true;
5358
				}
5359
			} );
5360
			if ( !validHandle ) {
5361
				return false;
5362
			}
5363
		}
5364
 
5365
		this.currentItem = currentItem;
5366
		this._removeCurrentsFromItems();
5367
		return true;
5368
 
5369
	},
5370
 
5371
	_mouseStart: function( event, overrideHandle, noActivation ) {
5372
 
5373
		var i, body,
5374
			o = this.options;
5375
 
5376
		this.currentContainer = this;
5377
 
5378
		//We only need to call refreshPositions, because the refreshItems call has been moved to
5379
		// mouseCapture
5380
		this.refreshPositions();
5381
 
5382
		//Create and append the visible helper
5383
		this.helper = this._createHelper( event );
5384
 
5385
		//Cache the helper size
5386
		this._cacheHelperProportions();
5387
 
5388
		/*
5389
		 * - Position generation -
5390
		 * This block generates everything position related - it's the core of draggables.
5391
		 */
5392
 
5393
		//Cache the margins of the original element
5394
		this._cacheMargins();
5395
 
5396
		//Get the next scrolling parent
5397
		this.scrollParent = this.helper.scrollParent();
5398
 
5399
		//The element's absolute position on the page minus margins
5400
		this.offset = this.currentItem.offset();
5401
		this.offset = {
5402
			top: this.offset.top - this.margins.top,
5403
			left: this.offset.left - this.margins.left
5404
		};
5405
 
5406
		$.extend( this.offset, {
5407
			click: { //Where the click happened, relative to the element
5408
				left: event.pageX - this.offset.left,
5409
				top: event.pageY - this.offset.top
5410
			},
5411
			parent: this._getParentOffset(),
5412
 
5413
			// This is a relative to absolute position minus the actual position calculation -
5414
			// only used for relative positioned helper
5415
			relative: this._getRelativeOffset()
5416
		} );
5417
 
5418
		// Only after we got the offset, we can change the helper's position to absolute
5419
		// TODO: Still need to figure out a way to make relative sorting possible
5420
		this.helper.css( "position", "absolute" );
5421
		this.cssPosition = this.helper.css( "position" );
5422
 
5423
		//Generate the original position
5424
		this.originalPosition = this._generatePosition( event );
5425
		this.originalPageX = event.pageX;
5426
		this.originalPageY = event.pageY;
5427
 
5428
		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
5429
		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
5430
 
5431
		//Cache the former DOM position
5432
		this.domPosition = {
5433
			prev: this.currentItem.prev()[ 0 ],
5434
			parent: this.currentItem.parent()[ 0 ]
5435
		};
5436
 
5437
		// If the helper is not the original, hide the original so it's not playing any role during
5438
		// the drag, won't cause anything bad this way
5439
		if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
5440
			this.currentItem.hide();
5441
		}
5442
 
5443
		//Create the placeholder
5444
		this._createPlaceholder();
5445
 
5446
		//Set a containment if given in the options
5447
		if ( o.containment ) {
5448
			this._setContainment();
5449
		}
5450
 
5451
		if ( o.cursor && o.cursor !== "auto" ) { // cursor option
5452
			body = this.document.find( "body" );
5453
 
5454
			// Support: IE
5455
			this.storedCursor = body.css( "cursor" );
5456
			body.css( "cursor", o.cursor );
5457
 
5458
			this.storedStylesheet =
5459
				$( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body );
5460
		}
5461
 
5462
		if ( o.opacity ) { // opacity option
5463
			if ( this.helper.css( "opacity" ) ) {
5464
				this._storedOpacity = this.helper.css( "opacity" );
5465
			}
5466
			this.helper.css( "opacity", o.opacity );
5467
		}
5468
 
5469
		if ( o.zIndex ) { // zIndex option
5470
			if ( this.helper.css( "zIndex" ) ) {
5471
				this._storedZIndex = this.helper.css( "zIndex" );
5472
			}
5473
			this.helper.css( "zIndex", o.zIndex );
5474
		}
5475
 
5476
		//Prepare scrolling
5477
		if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
5478
				this.scrollParent[ 0 ].tagName !== "HTML" ) {
5479
			this.overflowOffset = this.scrollParent.offset();
5480
		}
5481
 
5482
		//Call callbacks
5483
		this._trigger( "start", event, this._uiHash() );
5484
 
5485
		//Recache the helper size
5486
		if ( !this._preserveHelperProportions ) {
5487
			this._cacheHelperProportions();
5488
		}
5489
 
5490
		//Post "activate" events to possible containers
5491
		if ( !noActivation ) {
5492
			for ( i = this.containers.length - 1; i >= 0; i-- ) {
5493
				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
5494
			}
5495
		}
5496
 
5497
		//Prepare possible droppables
5498
		if ( $.ui.ddmanager ) {
5499
			$.ui.ddmanager.current = this;
5500
		}
5501
 
5502
		if ( $.ui.ddmanager && !o.dropBehaviour ) {
5503
			$.ui.ddmanager.prepareOffsets( this, event );
5504
		}
5505
 
5506
		this.dragging = true;
5507
 
5508
		this._addClass( this.helper, "ui-sortable-helper" );
5509
 
5510
		// Execute the drag once - this causes the helper not to be visiblebefore getting its
5511
		// correct position
5512
		this._mouseDrag( event );
5513
		return true;
5514
 
5515
	},
5516
 
5517
	_mouseDrag: function( event ) {
5518
		var i, item, itemElement, intersection,
5519
			o = this.options,
5520
			scrolled = false;
5521
 
5522
		//Compute the helpers position
5523
		this.position = this._generatePosition( event );
5524
		this.positionAbs = this._convertPositionTo( "absolute" );
5525
 
5526
		if ( !this.lastPositionAbs ) {
5527
			this.lastPositionAbs = this.positionAbs;
5528
		}
5529
 
5530
		//Do scrolling
5531
		if ( this.options.scroll ) {
5532
			if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
5533
					this.scrollParent[ 0 ].tagName !== "HTML" ) {
5534
 
5535
				if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -
5536
						event.pageY < o.scrollSensitivity ) {
5537
					this.scrollParent[ 0 ].scrollTop =
5538
						scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;
5539
				} else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {
5540
					this.scrollParent[ 0 ].scrollTop =
5541
						scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;
5542
				}
5543
 
5544
				if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -
5545
						event.pageX < o.scrollSensitivity ) {
5546
					this.scrollParent[ 0 ].scrollLeft = scrolled =
5547
						this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;
5548
				} else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {
5549
					this.scrollParent[ 0 ].scrollLeft = scrolled =
5550
						this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;
5551
				}
5552
 
5553
			} else {
5554
 
5555
				if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {
5556
					scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );
5557
				} else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <
5558
						o.scrollSensitivity ) {
5559
					scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );
5560
				}
5561
 
5562
				if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {
5563
					scrolled = this.document.scrollLeft(
5564
						this.document.scrollLeft() - o.scrollSpeed
5565
					);
5566
				} else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <
5567
						o.scrollSensitivity ) {
5568
					scrolled = this.document.scrollLeft(
5569
						this.document.scrollLeft() + o.scrollSpeed
5570
					);
5571
				}
5572
 
5573
			}
5574
 
5575
			if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
5576
				$.ui.ddmanager.prepareOffsets( this, event );
5577
			}
5578
		}
5579
 
5580
		//Regenerate the absolute position used for position checks
5581
		this.positionAbs = this._convertPositionTo( "absolute" );
5582
 
5583
		//Set the helper position
5584
		if ( !this.options.axis || this.options.axis !== "y" ) {
5585
			this.helper[ 0 ].style.left = this.position.left + "px";
5586
		}
5587
		if ( !this.options.axis || this.options.axis !== "x" ) {
5588
			this.helper[ 0 ].style.top = this.position.top + "px";
5589
		}
5590
 
5591
		//Rearrange
5592
		for ( i = this.items.length - 1; i >= 0; i-- ) {
5593
 
5594
			//Cache variables and intersection, continue if no intersection
5595
			item = this.items[ i ];
5596
			itemElement = item.item[ 0 ];
5597
			intersection = this._intersectsWithPointer( item );
5598
			if ( !intersection ) {
5599
				continue;
5600
			}
5601
 
5602
			// Only put the placeholder inside the current Container, skip all
5603
			// items from other containers. This works because when moving
5604
			// an item from one container to another the
5605
			// currentContainer is switched before the placeholder is moved.
5606
			//
5607
			// Without this, moving items in "sub-sortables" can cause
5608
			// the placeholder to jitter between the outer and inner container.
5609
			if ( item.instance !== this.currentContainer ) {
5610
				continue;
5611
			}
5612
 
5613
			// Cannot intersect with itself
5614
			// no useless actions that have been done before
5615
			// no action if the item moved is the parent of the item checked
5616
			if ( itemElement !== this.currentItem[ 0 ] &&
5617
				this.placeholder[ intersection === 1 ? "next" : "prev" ]()[ 0 ] !== itemElement &&
5618
				!$.contains( this.placeholder[ 0 ], itemElement ) &&
5619
				( this.options.type === "semi-dynamic" ?
5620
					!$.contains( this.element[ 0 ], itemElement ) :
5621
					true
5622
				)
5623
			) {
5624
 
5625
				this.direction = intersection === 1 ? "down" : "up";
5626
 
5627
				if ( this.options.tolerance === "pointer" || this._intersectsWithSides( item ) ) {
5628
					this._rearrange( event, item );
5629
				} else {
5630
					break;
5631
				}
5632
 
5633
				this._trigger( "change", event, this._uiHash() );
5634
				break;
5635
			}
5636
		}
5637
 
5638
		//Post events to containers
5639
		this._contactContainers( event );
5640
 
5641
		//Interconnect with droppables
5642
		if ( $.ui.ddmanager ) {
5643
			$.ui.ddmanager.drag( this, event );
5644
		}
5645
 
5646
		//Call callbacks
5647
		this._trigger( "sort", event, this._uiHash() );
5648
 
5649
		this.lastPositionAbs = this.positionAbs;
5650
		return false;
5651
 
5652
	},
5653
 
5654
	_mouseStop: function( event, noPropagation ) {
5655
 
5656
		if ( !event ) {
5657
			return;
5658
		}
5659
 
5660
		//If we are using droppables, inform the manager about the drop
5661
		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
5662
			$.ui.ddmanager.drop( this, event );
5663
		}
5664
 
5665
		if ( this.options.revert ) {
5666
			var that = this,
5667
				cur = this.placeholder.offset(),
5668
				axis = this.options.axis,
5669
				animation = {};
5670
 
5671
			if ( !axis || axis === "x" ) {
5672
				animation.left = cur.left - this.offset.parent.left - this.margins.left +
5673
					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
5674
 
5675
						this.offsetParent[ 0 ].scrollLeft
5676
					);
5677
			}
5678
			if ( !axis || axis === "y" ) {
5679
				animation.top = cur.top - this.offset.parent.top - this.margins.top +
5680
					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
5681
 
5682
						this.offsetParent[ 0 ].scrollTop
5683
					);
5684
			}
5685
			this.reverting = true;
5686
			$( this.helper ).animate(
5687
				animation,
5688
				parseInt( this.options.revert, 10 ) || 500,
5689
				function() {
5690
					that._clear( event );
5691
				}
5692
			);
5693
		} else {
5694
			this._clear( event, noPropagation );
5695
		}
5696
 
5697
		return false;
5698
 
5699
	},
5700
 
5701
	cancel: function() {
5702
 
5703
		if ( this.dragging ) {
5704
 
5705
			this._mouseUp( new $.Event( "mouseup", { target: null } ) );
5706
 
5707
			if ( this.options.helper === "original" ) {
5708
				this.currentItem.css( this._storedCSS );
5709
				this._removeClass( this.currentItem, "ui-sortable-helper" );
5710
			} else {
5711
				this.currentItem.show();
5712
			}
5713
 
5714
			//Post deactivating events to containers
5715
			for ( var i = this.containers.length - 1; i >= 0; i-- ) {
5716
				this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) );
5717
				if ( this.containers[ i ].containerCache.over ) {
5718
					this.containers[ i ]._trigger( "out", null, this._uiHash( this ) );
5719
					this.containers[ i ].containerCache.over = 0;
5720
				}
5721
			}
5722
 
5723
		}
5724
 
5725
		if ( this.placeholder ) {
5726
 
5727
			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
5728
			// it unbinds ALL events from the original node!
5729
			if ( this.placeholder[ 0 ].parentNode ) {
5730
				this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
5731
			}
5732
			if ( this.options.helper !== "original" && this.helper &&
5733
					this.helper[ 0 ].parentNode ) {
5734
				this.helper.remove();
5735
			}
5736
 
5737
			$.extend( this, {
5738
				helper: null,
5739
				dragging: false,
5740
				reverting: false,
5741
				_noFinalSort: null
5742
			} );
5743
 
5744
			if ( this.domPosition.prev ) {
5745
				$( this.domPosition.prev ).after( this.currentItem );
5746
			} else {
5747
				$( this.domPosition.parent ).prepend( this.currentItem );
5748
			}
5749
		}
5750
 
5751
		return this;
5752
 
5753
	},
5754
 
5755
	serialize: function( o ) {
5756
 
5757
		var items = this._getItemsAsjQuery( o && o.connected ),
5758
			str = [];
5759
		o = o || {};
5760
 
5761
		$( items ).each( function() {
5762
			var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" )
5763
				.match( o.expression || ( /(.+)[\-=_](.+)/ ) );
5764
			if ( res ) {
5765
				str.push(
5766
					( o.key || res[ 1 ] + "[]" ) +
5767
					"=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );
5768
			}
5769
		} );
5770
 
5771
		if ( !str.length && o.key ) {
5772
			str.push( o.key + "=" );
5773
		}
5774
 
5775
		return str.join( "&" );
5776
 
5777
	},
5778
 
5779
	toArray: function( o ) {
5780
 
5781
		var items = this._getItemsAsjQuery( o && o.connected ),
5782
			ret = [];
5783
 
5784
		o = o || {};
5785
 
5786
		items.each( function() {
5787
			ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" );
5788
		} );
5789
		return ret;
5790
 
5791
	},
5792
 
5793
	/* Be careful with the following core functions */
5794
	_intersectsWith: function( item ) {
5795
 
5796
		var x1 = this.positionAbs.left,
5797
			x2 = x1 + this.helperProportions.width,
5798
			y1 = this.positionAbs.top,
5799
			y2 = y1 + this.helperProportions.height,
5800
			l = item.left,
5801
			r = l + item.width,
5802
			t = item.top,
5803
			b = t + item.height,
5804
			dyClick = this.offset.click.top,
5805
			dxClick = this.offset.click.left,
5806
			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t &&
5807
				( y1 + dyClick ) < b ),
5808
			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l &&
5809
				( x1 + dxClick ) < r ),
5810
			isOverElement = isOverElementHeight && isOverElementWidth;
5811
 
5812
		if ( this.options.tolerance === "pointer" ||
5813
			this.options.forcePointerForContainers ||
5814
			( this.options.tolerance !== "pointer" &&
5815
				this.helperProportions[ this.floating ? "width" : "height" ] >
5816
				item[ this.floating ? "width" : "height" ] )
5817
		) {
5818
			return isOverElement;
5819
		} else {
5820
 
5821
			return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half
5822
				x2 - ( this.helperProportions.width / 2 ) < r && // Left Half
5823
				t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half
5824
				y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half
5825
 
5826
		}
5827
	},
5828
 
5829
	_intersectsWithPointer: function( item ) {
5830
		var verticalDirection, horizontalDirection,
5831
			isOverElementHeight = ( this.options.axis === "x" ) ||
5832
				this._isOverAxis(
5833
					this.positionAbs.top + this.offset.click.top, item.top, item.height ),
5834
			isOverElementWidth = ( this.options.axis === "y" ) ||
5835
				this._isOverAxis(
5836
					this.positionAbs.left + this.offset.click.left, item.left, item.width ),
5837
			isOverElement = isOverElementHeight && isOverElementWidth;
5838
 
5839
		if ( !isOverElement ) {
5840
			return false;
5841
		}
5842
 
5843
		verticalDirection = this._getDragVerticalDirection();
5844
		horizontalDirection = this._getDragHorizontalDirection();
5845
 
5846
		return this.floating ?
5847
			( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 )
5848
			: ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) );
5849
 
5850
	},
5851
 
5852
	_intersectsWithSides: function( item ) {
5853
 
5854
		var isOverBottomHalf = this._isOverAxis( this.positionAbs.top +
5855
				this.offset.click.top, item.top + ( item.height / 2 ), item.height ),
5856
			isOverRightHalf = this._isOverAxis( this.positionAbs.left +
5857
				this.offset.click.left, item.left + ( item.width / 2 ), item.width ),
5858
			verticalDirection = this._getDragVerticalDirection(),
5859
			horizontalDirection = this._getDragHorizontalDirection();
5860
 
5861
		if ( this.floating && horizontalDirection ) {
5862
			return ( ( horizontalDirection === "right" && isOverRightHalf ) ||
5863
				( horizontalDirection === "left" && !isOverRightHalf ) );
5864
		} else {
5865
			return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) ||
5866
				( verticalDirection === "up" && !isOverBottomHalf ) );
5867
		}
5868
 
5869
	},
5870
 
5871
	_getDragVerticalDirection: function() {
5872
		var delta = this.positionAbs.top - this.lastPositionAbs.top;
5873
		return delta !== 0 && ( delta > 0 ? "down" : "up" );
5874
	},
5875
 
5876
	_getDragHorizontalDirection: function() {
5877
		var delta = this.positionAbs.left - this.lastPositionAbs.left;
5878
		return delta !== 0 && ( delta > 0 ? "right" : "left" );
5879
	},
5880
 
5881
	refresh: function( event ) {
5882
		this._refreshItems( event );
5883
		this._setHandleClassName();
5884
		this.refreshPositions();
5885
		return this;
5886
	},
5887
 
5888
	_connectWith: function() {
5889
		var options = this.options;
5890
		return options.connectWith.constructor === String ?
5891
			[ options.connectWith ] :
5892
			options.connectWith;
5893
	},
5894
 
5895
	_getItemsAsjQuery: function( connected ) {
5896
 
5897
		var i, j, cur, inst,
5898
			items = [],
5899
			queries = [],
5900
			connectWith = this._connectWith();
5901
 
5902
		if ( connectWith && connected ) {
5903
			for ( i = connectWith.length - 1; i >= 0; i-- ) {
5904
				cur = $( connectWith[ i ], this.document[ 0 ] );
5905
				for ( j = cur.length - 1; j >= 0; j-- ) {
5906
					inst = $.data( cur[ j ], this.widgetFullName );
5907
					if ( inst && inst !== this && !inst.options.disabled ) {
5908
						queries.push( [ $.isFunction( inst.options.items ) ?
5909
							inst.options.items.call( inst.element ) :
5910
							$( inst.options.items, inst.element )
5911
								.not( ".ui-sortable-helper" )
5912
								.not( ".ui-sortable-placeholder" ), inst ] );
5913
					}
5914
				}
5915
			}
5916
		}
5917
 
5918
		queries.push( [ $.isFunction( this.options.items ) ?
5919
			this.options.items
5920
				.call( this.element, null, { options: this.options, item: this.currentItem } ) :
5921
			$( this.options.items, this.element )
5922
				.not( ".ui-sortable-helper" )
5923
				.not( ".ui-sortable-placeholder" ), this ] );
5924
 
5925
		function addItems() {
5926
			items.push( this );
5927
		}
5928
		for ( i = queries.length - 1; i >= 0; i-- ) {
5929
			queries[ i ][ 0 ].each( addItems );
5930
		}
5931
 
5932
		return $( items );
5933
 
5934
	},
5935
 
5936
	_removeCurrentsFromItems: function() {
5937
 
5938
		var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" );
5939
 
5940
		this.items = $.grep( this.items, function( item ) {
5941
			for ( var j = 0; j < list.length; j++ ) {
5942
				if ( list[ j ] === item.item[ 0 ] ) {
5943
					return false;
5944
				}
5945
			}
5946
			return true;
5947
		} );
5948
 
5949
	},
5950
 
5951
	_refreshItems: function( event ) {
5952
 
5953
		this.items = [];
5954
		this.containers = [ this ];
5955
 
5956
		var i, j, cur, inst, targetData, _queries, item, queriesLength,
5957
			items = this.items,
5958
			queries = [ [ $.isFunction( this.options.items ) ?
5959
				this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :
5960
				$( this.options.items, this.element ), this ] ],
5961
			connectWith = this._connectWith();
5962
 
5963
		//Shouldn't be run the first time through due to massive slow-down
5964
		if ( connectWith && this.ready ) {
5965
			for ( i = connectWith.length - 1; i >= 0; i-- ) {
5966
				cur = $( connectWith[ i ], this.document[ 0 ] );
5967
				for ( j = cur.length - 1; j >= 0; j-- ) {
5968
					inst = $.data( cur[ j ], this.widgetFullName );
5969
					if ( inst && inst !== this && !inst.options.disabled ) {
5970
						queries.push( [ $.isFunction( inst.options.items ) ?
5971
							inst.options.items
5972
								.call( inst.element[ 0 ], event, { item: this.currentItem } ) :
5973
							$( inst.options.items, inst.element ), inst ] );
5974
						this.containers.push( inst );
5975
					}
5976
				}
5977
			}
5978
		}
5979
 
5980
		for ( i = queries.length - 1; i >= 0; i-- ) {
5981
			targetData = queries[ i ][ 1 ];
5982
			_queries = queries[ i ][ 0 ];
5983
 
5984
			for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {
5985
				item = $( _queries[ j ] );
5986
 
5987
				// Data for target checking (mouse manager)
5988
				item.data( this.widgetName + "-item", targetData );
5989
 
5990
				items.push( {
5991
					item: item,
5992
					instance: targetData,
5993
					width: 0, height: 0,
5994
					left: 0, top: 0
5995
				} );
5996
			}
5997
		}
5998
 
5999
	},
6000
 
6001
	refreshPositions: function( fast ) {
6002
 
6003
		// Determine whether items are being displayed horizontally
6004
		this.floating = this.items.length ?
6005
			this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
6006
			false;
6007
 
6008
		//This has to be redone because due to the item being moved out/into the offsetParent,
6009
		// the offsetParent's position will change
6010
		if ( this.offsetParent && this.helper ) {
6011
			this.offset.parent = this._getParentOffset();
6012
		}
6013
 
6014
		var i, item, t, p;
6015
 
6016
		for ( i = this.items.length - 1; i >= 0; i-- ) {
6017
			item = this.items[ i ];
6018
 
6019
			//We ignore calculating positions of all connected containers when we're not over them
6020
			if ( item.instance !== this.currentContainer && this.currentContainer &&
6021
					item.item[ 0 ] !== this.currentItem[ 0 ] ) {
6022
				continue;
6023
			}
6024
 
6025
			t = this.options.toleranceElement ?
6026
				$( this.options.toleranceElement, item.item ) :
6027
				item.item;
6028
 
6029
			if ( !fast ) {
6030
				item.width = t.outerWidth();
6031
				item.height = t.outerHeight();
6032
			}
6033
 
6034
			p = t.offset();
6035
			item.left = p.left;
6036
			item.top = p.top;
6037
		}
6038
 
6039
		if ( this.options.custom && this.options.custom.refreshContainers ) {
6040
			this.options.custom.refreshContainers.call( this );
6041
		} else {
6042
			for ( i = this.containers.length - 1; i >= 0; i-- ) {
6043
				p = this.containers[ i ].element.offset();
6044
				this.containers[ i ].containerCache.left = p.left;
6045
				this.containers[ i ].containerCache.top = p.top;
6046
				this.containers[ i ].containerCache.width =
6047
					this.containers[ i ].element.outerWidth();
6048
				this.containers[ i ].containerCache.height =
6049
					this.containers[ i ].element.outerHeight();
6050
			}
6051
		}
6052
 
6053
		return this;
6054
	},
6055
 
6056
	_createPlaceholder: function( that ) {
6057
		that = that || this;
6058
		var className,
6059
			o = that.options;
6060
 
6061
		if ( !o.placeholder || o.placeholder.constructor === String ) {
6062
			className = o.placeholder;
6063
			o.placeholder = {
6064
				element: function() {
6065
 
6066
					var nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(),
6067
						element = $( "<" + nodeName + ">", that.document[ 0 ] );
6068
 
6069
						that._addClass( element, "ui-sortable-placeholder",
6070
								className || that.currentItem[ 0 ].className )
6071
							._removeClass( element, "ui-sortable-helper" );
6072
 
6073
					if ( nodeName === "tbody" ) {
6074
						that._createTrPlaceholder(
6075
							that.currentItem.find( "tr" ).eq( 0 ),
6076
							$( "<tr>", that.document[ 0 ] ).appendTo( element )
6077
						);
6078
					} else if ( nodeName === "tr" ) {
6079
						that._createTrPlaceholder( that.currentItem, element );
6080
					} else if ( nodeName === "img" ) {
6081
						element.attr( "src", that.currentItem.attr( "src" ) );
6082
					}
6083
 
6084
					if ( !className ) {
6085
						element.css( "visibility", "hidden" );
6086
					}
6087
 
6088
					return element;
6089
				},
6090
				update: function( container, p ) {
6091
 
6092
					// 1. If a className is set as 'placeholder option, we don't force sizes -
6093
					// the class is responsible for that
6094
					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a
6095
					// class name is specified
6096
					if ( className && !o.forcePlaceholderSize ) {
6097
						return;
6098
					}
6099
 
6100
					//If the element doesn't have a actual height by itself (without styles coming
6101
					// from a stylesheet), it receives the inline height from the dragged item
6102
					if ( !p.height() ) {
6103
						p.height(
6104
							that.currentItem.innerHeight() -
6105
							parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) -
6106
							parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) );
6107
					}
6108
					if ( !p.width() ) {
6109
						p.width(
6110
							that.currentItem.innerWidth() -
6111
							parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) -
6112
							parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) );
6113
					}
6114
				}
6115
			};
6116
		}
6117
 
6118
		//Create the placeholder
6119
		that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );
6120
 
6121
		//Append it after the actual current item
6122
		that.currentItem.after( that.placeholder );
6123
 
6124
		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
6125
		o.placeholder.update( that, that.placeholder );
6126
 
6127
	},
6128
 
6129
	_createTrPlaceholder: function( sourceTr, targetTr ) {
6130
		var that = this;
6131
 
6132
		sourceTr.children().each( function() {
6133
			$( "<td>&#160;</td>", that.document[ 0 ] )
6134
				.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
6135
				.appendTo( targetTr );
6136
		} );
6137
	},
6138
 
6139
	_contactContainers: function( event ) {
6140
		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
6141
			floating, axis,
6142
			innermostContainer = null,
6143
			innermostIndex = null;
6144
 
6145
		// Get innermost container that intersects with item
6146
		for ( i = this.containers.length - 1; i >= 0; i-- ) {
6147
 
6148
			// Never consider a container that's located within the item itself
6149
			if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {
6150
				continue;
6151
			}
6152
 
6153
			if ( this._intersectsWith( this.containers[ i ].containerCache ) ) {
6154
 
6155
				// If we've already found a container and it's more "inner" than this, then continue
6156
				if ( innermostContainer &&
6157
						$.contains(
6158
							this.containers[ i ].element[ 0 ],
6159
							innermostContainer.element[ 0 ] ) ) {
6160
					continue;
6161
				}
6162
 
6163
				innermostContainer = this.containers[ i ];
6164
				innermostIndex = i;
6165
 
6166
			} else {
6167
 
6168
				// container doesn't intersect. trigger "out" event if necessary
6169
				if ( this.containers[ i ].containerCache.over ) {
6170
					this.containers[ i ]._trigger( "out", event, this._uiHash( this ) );
6171
					this.containers[ i ].containerCache.over = 0;
6172
				}
6173
			}
6174
 
6175
		}
6176
 
6177
		// If no intersecting containers found, return
6178
		if ( !innermostContainer ) {
6179
			return;
6180
		}
6181
 
6182
		// Move the item into the container if it's not there already
6183
		if ( this.containers.length === 1 ) {
6184
			if ( !this.containers[ innermostIndex ].containerCache.over ) {
6185
				this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
6186
				this.containers[ innermostIndex ].containerCache.over = 1;
6187
			}
6188
		} else {
6189
 
6190
			// When entering a new container, we will find the item with the least distance and
6191
			// append our item near it
6192
			dist = 10000;
6193
			itemWithLeastDistance = null;
6194
			floating = innermostContainer.floating || this._isFloating( this.currentItem );
6195
			posProperty = floating ? "left" : "top";
6196
			sizeProperty = floating ? "width" : "height";
6197
			axis = floating ? "pageX" : "pageY";
6198
 
6199
			for ( j = this.items.length - 1; j >= 0; j-- ) {
6200
				if ( !$.contains(
6201
						this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )
6202
				) {
6203
					continue;
6204
				}
6205
				if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {
6206
					continue;
6207
				}
6208
 
6209
				cur = this.items[ j ].item.offset()[ posProperty ];
6210
				nearBottom = false;
6211
				if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
6212
					nearBottom = true;
6213
				}
6214
 
6215
				if ( Math.abs( event[ axis ] - cur ) < dist ) {
6216
					dist = Math.abs( event[ axis ] - cur );
6217
					itemWithLeastDistance = this.items[ j ];
6218
					this.direction = nearBottom ? "up" : "down";
6219
				}
6220
			}
6221
 
6222
			//Check if dropOnEmpty is enabled
6223
			if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {
6224
				return;
6225
			}
6226
 
6227
			if ( this.currentContainer === this.containers[ innermostIndex ] ) {
6228
				if ( !this.currentContainer.containerCache.over ) {
6229
					this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
6230
					this.currentContainer.containerCache.over = 1;
6231
				}
6232
				return;
6233
			}
6234
 
6235
			itemWithLeastDistance ?
6236
				this._rearrange( event, itemWithLeastDistance, null, true ) :
6237
				this._rearrange( event, null, this.containers[ innermostIndex ].element, true );
6238
			this._trigger( "change", event, this._uiHash() );
6239
			this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) );
6240
			this.currentContainer = this.containers[ innermostIndex ];
6241
 
6242
			//Update the placeholder
6243
			this.options.placeholder.update( this.currentContainer, this.placeholder );
6244
 
6245
			this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
6246
			this.containers[ innermostIndex ].containerCache.over = 1;
6247
		}
6248
 
6249
	},
6250
 
6251
	_createHelper: function( event ) {
6252
 
6253
		var o = this.options,
6254
			helper = $.isFunction( o.helper ) ?
6255
				$( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :
6256
				( o.helper === "clone" ? this.currentItem.clone() : this.currentItem );
6257
 
6258
		//Add the helper to the DOM if that didn't happen already
6259
		if ( !helper.parents( "body" ).length ) {
6260
			$( o.appendTo !== "parent" ?
6261
				o.appendTo :
6262
				this.currentItem[ 0 ].parentNode )[ 0 ].appendChild( helper[ 0 ] );
6263
		}
6264
 
6265
		if ( helper[ 0 ] === this.currentItem[ 0 ] ) {
6266
			this._storedCSS = {
6267
				width: this.currentItem[ 0 ].style.width,
6268
				height: this.currentItem[ 0 ].style.height,
6269
				position: this.currentItem.css( "position" ),
6270
				top: this.currentItem.css( "top" ),
6271
				left: this.currentItem.css( "left" )
6272
			};
6273
		}
6274
 
6275
		if ( !helper[ 0 ].style.width || o.forceHelperSize ) {
6276
			helper.width( this.currentItem.width() );
6277
		}
6278
		if ( !helper[ 0 ].style.height || o.forceHelperSize ) {
6279
			helper.height( this.currentItem.height() );
6280
		}
6281
 
6282
		return helper;
6283
 
6284
	},
6285
 
6286
	_adjustOffsetFromHelper: function( obj ) {
6287
		if ( typeof obj === "string" ) {
6288
			obj = obj.split( " " );
6289
		}
6290
		if ( $.isArray( obj ) ) {
6291
			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
6292
		}
6293
		if ( "left" in obj ) {
6294
			this.offset.click.left = obj.left + this.margins.left;
6295
		}
6296
		if ( "right" in obj ) {
6297
			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
6298
		}
6299
		if ( "top" in obj ) {
6300
			this.offset.click.top = obj.top + this.margins.top;
6301
		}
6302
		if ( "bottom" in obj ) {
6303
			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
6304
		}
6305
	},
6306
 
6307
	_getParentOffset: function() {
6308
 
6309
		//Get the offsetParent and cache its position
6310
		this.offsetParent = this.helper.offsetParent();
6311
		var po = this.offsetParent.offset();
6312
 
6313
		// This is a special case where we need to modify a offset calculated on start, since the
6314
		// following happened:
6315
		// 1. The position of the helper is absolute, so it's position is calculated based on the
6316
		// next positioned parent
6317
		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
6318
		// the document, which means that the scroll is included in the initial calculation of the
6319
		// offset of the parent, and never recalculated upon drag
6320
		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&
6321
				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
6322
			po.left += this.scrollParent.scrollLeft();
6323
			po.top += this.scrollParent.scrollTop();
6324
		}
6325
 
6326
		// This needs to be actually done for all browsers, since pageX/pageY includes this
6327
		// information with an ugly IE fix
6328
		if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ||
6329
				( this.offsetParent[ 0 ].tagName &&
6330
				this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) {
6331
			po = { top: 0, left: 0 };
6332
		}
6333
 
6334
		return {
6335
			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
6336
			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
6337
		};
6338
 
6339
	},
6340
 
6341
	_getRelativeOffset: function() {
6342
 
6343
		if ( this.cssPosition === "relative" ) {
6344
			var p = this.currentItem.position();
6345
			return {
6346
				top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
6347
					this.scrollParent.scrollTop(),
6348
				left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
6349
					this.scrollParent.scrollLeft()
6350
			};
6351
		} else {
6352
			return { top: 0, left: 0 };
6353
		}
6354
 
6355
	},
6356
 
6357
	_cacheMargins: function() {
6358
		this.margins = {
6359
			left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ),
6360
			top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 )
6361
		};
6362
	},
6363
 
6364
	_cacheHelperProportions: function() {
6365
		this.helperProportions = {
6366
			width: this.helper.outerWidth(),
6367
			height: this.helper.outerHeight()
6368
		};
6369
	},
6370
 
6371
	_setContainment: function() {
6372
 
6373
		var ce, co, over,
6374
			o = this.options;
6375
		if ( o.containment === "parent" ) {
6376
			o.containment = this.helper[ 0 ].parentNode;
6377
		}
6378
		if ( o.containment === "document" || o.containment === "window" ) {
6379
			this.containment = [
6380
 
6381
 
6382
				o.containment === "document" ?
6383
					this.document.width() :
6384
					this.window.width() - this.helperProportions.width - this.margins.left,
6385
				( o.containment === "document" ?
6386
					( this.document.height() || document.body.parentNode.scrollHeight ) :
6387
					this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight
6388
				) - this.helperProportions.height - this.margins.top
6389
			];
6390
		}
6391
 
6392
		if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {
6393
			ce = $( o.containment )[ 0 ];
6394
			co = $( o.containment ).offset();
6395
			over = ( $( ce ).css( "overflow" ) !== "hidden" );
6396
 
6397
			this.containment = [
6398
				co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) +
6399
					( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left,
6400
				co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) +
6401
					( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top,
6402
				co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
6403
					( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) -
6404
					( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) -
6405
					this.helperProportions.width - this.margins.left,
6406
				co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
6407
					( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) -
6408
					( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) -
6409
					this.helperProportions.height - this.margins.top
6410
			];
6411
		}
6412
 
6413
	},
6414
 
6415
	_convertPositionTo: function( d, pos ) {
6416
 
6417
		if ( !pos ) {
6418
			pos = this.position;
6419
		}
6420
		var mod = d === "absolute" ? 1 : -1,
6421
			scroll = this.cssPosition === "absolute" &&
6422
				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
6423
				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
6424
					this.offsetParent :
6425
					this.scrollParent,
6426
			scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
6427
 
6428
		return {
6429
			top: (
6430
 
6431
				// The absolute mouse position
6432
				pos.top	+
6433
 
6434
				// Only for relative positioned nodes: Relative offset from element to offset parent
6435
				this.offset.relative.top * mod +
6436
 
6437
				// The offsetParent's offset without borders (offset + border)
6438
				this.offset.parent.top * mod -
6439
				( ( this.cssPosition === "fixed" ?
6440
					-this.scrollParent.scrollTop() :
6441
					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )
6442
			),
6443
			left: (
6444
 
6445
				// The absolute mouse position
6446
				pos.left +
6447
 
6448
				// Only for relative positioned nodes: Relative offset from element to offset parent
6449
				this.offset.relative.left * mod +
6450
 
6451
				// The offsetParent's offset without borders (offset + border)
6452
				this.offset.parent.left * mod	-
6453
				( ( this.cssPosition === "fixed" ?
6454
					-this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
6455
					scroll.scrollLeft() ) * mod )
6456
			)
6457
		};
6458
 
6459
	},
6460
 
6461
	_generatePosition: function( event ) {
6462
 
6463
		var top, left,
6464
			o = this.options,
6465
			pageX = event.pageX,
6466
			pageY = event.pageY,
6467
			scroll = this.cssPosition === "absolute" &&
6468
				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
6469
				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
6470
					this.offsetParent :
6471
					this.scrollParent,
6472
				scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
6473
 
6474
		// This is another very weird special case that only happens for relative elements:
6475
		// 1. If the css position is relative
6476
		// 2. and the scroll parent is the document or similar to the offset parent
6477
		// we have to refresh the relative offset during the scroll so there are no jumps
6478
		if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
6479
				this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {
6480
			this.offset.relative = this._getRelativeOffset();
6481
		}
6482
 
6483
		/*
6484
		 * - Position constraining -
6485
		 * Constrain the position to a mix of grid, containment.
6486
		 */
6487
 
6488
		if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options
6489
 
6490
			if ( this.containment ) {
6491
				if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {
6492
					pageX = this.containment[ 0 ] + this.offset.click.left;
6493
				}
6494
				if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {
6495
					pageY = this.containment[ 1 ] + this.offset.click.top;
6496
				}
6497
				if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {
6498
					pageX = this.containment[ 2 ] + this.offset.click.left;
6499
				}
6500
				if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {
6501
					pageY = this.containment[ 3 ] + this.offset.click.top;
6502
				}
6503
			}
6504
 
6505
			if ( o.grid ) {
6506
				top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /
6507
					o.grid[ 1 ] ) * o.grid[ 1 ];
6508
				pageY = this.containment ?
6509
					( ( top - this.offset.click.top >= this.containment[ 1 ] &&
6510
						top - this.offset.click.top <= this.containment[ 3 ] ) ?
6511
							top :
6512
							( ( top - this.offset.click.top >= this.containment[ 1 ] ) ?
6513
								top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) :
6514
								top;
6515
 
6516
				left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /
6517
					o.grid[ 0 ] ) * o.grid[ 0 ];
6518
				pageX = this.containment ?
6519
					( ( left - this.offset.click.left >= this.containment[ 0 ] &&
6520
						left - this.offset.click.left <= this.containment[ 2 ] ) ?
6521
							left :
6522
							( ( left - this.offset.click.left >= this.containment[ 0 ] ) ?
6523
								left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) :
6524
								left;
6525
			}
6526
 
6527
		}
6528
 
6529
		return {
6530
			top: (
6531
 
6532
				// The absolute mouse position
6533
				pageY -
6534
 
6535
				// Click offset (relative to the element)
6536
				this.offset.click.top -
6537
 
6538
				// Only for relative positioned nodes: Relative offset from element to offset parent
6539
				this.offset.relative.top -
6540
 
6541
				// The offsetParent's offset without borders (offset + border)
6542
				this.offset.parent.top +
6543
				( ( this.cssPosition === "fixed" ?
6544
					-this.scrollParent.scrollTop() :
6545
					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )
6546
			),
6547
			left: (
6548
 
6549
				// The absolute mouse position
6550
				pageX -
6551
 
6552
				// Click offset (relative to the element)
6553
				this.offset.click.left -
6554
 
6555
				// Only for relative positioned nodes: Relative offset from element to offset parent
6556
				this.offset.relative.left -
6557
 
6558
				// The offsetParent's offset without borders (offset + border)
6559
				this.offset.parent.left +
6560
				( ( this.cssPosition === "fixed" ?
6561
					-this.scrollParent.scrollLeft() :
6562
					scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
6563
			)
6564
		};
6565
 
6566
	},
6567
 
6568
	_rearrange: function( event, i, a, hardRefresh ) {
6569
 
6570
		a ? a[ 0 ].appendChild( this.placeholder[ 0 ] ) :
6571
			i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ],
6572
				( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) );
6573
 
6574
		//Various things done here to improve the performance:
6575
		// 1. we create a setTimeout, that calls refreshPositions
6576
		// 2. on the instance, we have a counter variable, that get's higher after every append
6577
		// 3. on the local scope, we copy the counter variable, and check in the timeout,
6578
		// if it's still the same
6579
		// 4. this lets only the last addition to the timeout stack through
6580
		this.counter = this.counter ? ++this.counter : 1;
6581
		var counter = this.counter;
6582
 
6583
		this._delay( function() {
6584
			if ( counter === this.counter ) {
6585
 
6586
				//Precompute after each DOM insertion, NOT on mousemove
6587
				this.refreshPositions( !hardRefresh );
6588
			}
6589
		} );
6590
 
6591
	},
6592
 
6593
	_clear: function( event, noPropagation ) {
6594
 
6595
		this.reverting = false;
6596
 
6597
		// We delay all events that have to be triggered to after the point where the placeholder
6598
		// has been removed and everything else normalized again
6599
		var i,
6600
			delayedTriggers = [];
6601
 
6602
		// We first have to update the dom position of the actual currentItem
6603
		// Note: don't do it if the current item is already removed (by a user), or it gets
6604
		// reappended (see #4088)
6605
		if ( !this._noFinalSort && this.currentItem.parent().length ) {
6606
			this.placeholder.before( this.currentItem );
6607
		}
6608
		this._noFinalSort = null;
6609
 
6610
		if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {
6611
			for ( i in this._storedCSS ) {
6612
				if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) {
6613
					this._storedCSS[ i ] = "";
6614
				}
6615
			}
6616
			this.currentItem.css( this._storedCSS );
6617
			this._removeClass( this.currentItem, "ui-sortable-helper" );
6618
		} else {
6619
			this.currentItem.show();
6620
		}
6621
 
6622
		if ( this.fromOutside && !noPropagation ) {
6623
			delayedTriggers.push( function( event ) {
6624
				this._trigger( "receive", event, this._uiHash( this.fromOutside ) );
6625
			} );
6626
		}
6627
		if ( ( this.fromOutside ||
6628
				this.domPosition.prev !==
6629
				this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] ||
6630
				this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {
6631
 
6632
			// Trigger update callback if the DOM position has changed
6633
			delayedTriggers.push( function( event ) {
6634
				this._trigger( "update", event, this._uiHash() );
6635
			} );
6636
		}
6637
 
6638
		// Check if the items Container has Changed and trigger appropriate
6639
		// events.
6640
		if ( this !== this.currentContainer ) {
6641
			if ( !noPropagation ) {
6642
				delayedTriggers.push( function( event ) {
6643
					this._trigger( "remove", event, this._uiHash() );
6644
				} );
6645
				delayedTriggers.push( ( function( c ) {
6646
					return function( event ) {
6647
						c._trigger( "receive", event, this._uiHash( this ) );
6648
					};
6649
				} ).call( this, this.currentContainer ) );
6650
				delayedTriggers.push( ( function( c ) {
6651
					return function( event ) {
6652
						c._trigger( "update", event, this._uiHash( this ) );
6653
					};
6654
				} ).call( this, this.currentContainer ) );
6655
			}
6656
		}
6657
 
6658
		//Post events to containers
6659
		function delayEvent( type, instance, container ) {
6660
			return function( event ) {
6661
				container._trigger( type, event, instance._uiHash( instance ) );
6662
			};
6663
		}
6664
		for ( i = this.containers.length - 1; i >= 0; i-- ) {
6665
			if ( !noPropagation ) {
6666
				delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
6667
			}
6668
			if ( this.containers[ i ].containerCache.over ) {
6669
				delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
6670
				this.containers[ i ].containerCache.over = 0;
6671
			}
6672
		}
6673
 
6674
		//Do what was originally in plugins
6675
		if ( this.storedCursor ) {
6676
			this.document.find( "body" ).css( "cursor", this.storedCursor );
6677
			this.storedStylesheet.remove();
6678
		}
6679
		if ( this._storedOpacity ) {
6680
			this.helper.css( "opacity", this._storedOpacity );
6681
		}
6682
		if ( this._storedZIndex ) {
6683
			this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex );
6684
		}
6685
 
6686
		this.dragging = false;
6687
 
6688
		if ( !noPropagation ) {
6689
			this._trigger( "beforeStop", event, this._uiHash() );
6690
		}
6691
 
6692
		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
6693
		// it unbinds ALL events from the original node!
6694
		this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
6695
 
6696
		if ( !this.cancelHelperRemoval ) {
6697
			if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
6698
				this.helper.remove();
6699
			}
6700
			this.helper = null;
6701
		}
6702
 
6703
		if ( !noPropagation ) {
6704
			for ( i = 0; i < delayedTriggers.length; i++ ) {
6705
 
6706
				// Trigger all delayed events
6707
				delayedTriggers[ i ].call( this, event );
6708
			}
6709
			this._trigger( "stop", event, this._uiHash() );
6710
		}
6711
 
6712
		this.fromOutside = false;
6713
		return !this.cancelHelperRemoval;
6714
 
6715
	},
6716
 
6717
	_trigger: function() {
6718
		if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {
6719
			this.cancel();
6720
		}
6721
	},
6722
 
6723
	_uiHash: function( _inst ) {
6724
		var inst = _inst || this;
6725
		return {
6726
			helper: inst.helper,
6727
			placeholder: inst.placeholder || $( [] ),
6728
			position: inst.position,
6729
			originalPosition: inst.originalPosition,
6730
			offset: inst.positionAbs,
6731
			item: inst.currentItem,
6732
			sender: _inst ? _inst.element : null
6733
		};
6734
	}
6735
 
6736
} );
6737
 
6738
 
6739
/*!
6740
 * jQuery UI Accordion 1.12.1
6741
 * http://jqueryui.com
6742
 *
6743
 * Copyright jQuery Foundation and other contributors
6744
 * Released under the MIT license.
6745
 * http://jquery.org/license
6746
 */
6747
 
6748
//>>label: Accordion
6749
//>>group: Widgets
6750
// jscs:disable maximumLineLength
6751
//>>description: Displays collapsible content panels for presenting information in a limited amount of space.
6752
// jscs:enable maximumLineLength
6753
//>>docs: http://api.jqueryui.com/accordion/
6754
//>>demos: http://jqueryui.com/accordion/
6755
//>>css.structure: ../../themes/base/core.css
6756
//>>css.structure: ../../themes/base/accordion.css
6757
//>>css.theme: ../../themes/base/theme.css
6758
 
6759
 
6760
 
6761
var widgetsAccordion = $.widget( "ui.accordion", {
6762
	version: "1.12.1",
6763
	options: {
6764
		active: 0,
6765
		animate: {},
6766
		classes: {
6767
			"ui-accordion-header": "ui-corner-top",
6768
			"ui-accordion-header-collapsed": "ui-corner-all",
6769
			"ui-accordion-content": "ui-corner-bottom"
6770
		},
6771
		collapsible: false,
6772
		event: "click",
6773
		header: "> li > :first-child, > :not(li):even",
6774
		heightStyle: "auto",
6775
		icons: {
6776
			activeHeader: "ui-icon-triangle-1-s",
6777
			header: "ui-icon-triangle-1-e"
6778
		},
6779
 
6780
		// Callbacks
6781
		activate: null,
6782
		beforeActivate: null
6783
	},
6784
 
6785
	hideProps: {
6786
		borderTopWidth: "hide",
6787
		borderBottomWidth: "hide",
6788
		paddingTop: "hide",
6789
		paddingBottom: "hide",
6790
		height: "hide"
6791
	},
6792
 
6793
	showProps: {
6794
		borderTopWidth: "show",
6795
		borderBottomWidth: "show",
6796
		paddingTop: "show",
6797
		paddingBottom: "show",
6798
		height: "show"
6799
	},
6800
 
6801
	_create: function() {
6802
		var options = this.options;
6803
 
6804
		this.prevShow = this.prevHide = $();
6805
		this._addClass( "ui-accordion", "ui-widget ui-helper-reset" );
6806
		this.element.attr( "role", "tablist" );
6807
 
6808
		// Don't allow collapsible: false and active: false / null
6809
		if ( !options.collapsible && ( options.active === false || options.active == null ) ) {
6810
			options.active = 0;
6811
		}
6812
 
6813
		this._processPanels();
6814
 
6815
		// handle negative values
6816
		if ( options.active < 0 ) {
6817
			options.active += this.headers.length;
6818
		}
6819
		this._refresh();
6820
	},
6821
 
6822
	_getCreateEventData: function() {
6823
		return {
6824
			header: this.active,
6825
			panel: !this.active.length ? $() : this.active.next()
6826
		};
6827
	},
6828
 
6829
	_createIcons: function() {
6830
		var icon, children,
6831
			icons = this.options.icons;
6832
 
6833
		if ( icons ) {
6834
			icon = $( "<span>" );
6835
			this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header );
6836
			icon.prependTo( this.headers );
6837
			children = this.active.children( ".ui-accordion-header-icon" );
6838
			this._removeClass( children, icons.header )
6839
				._addClass( children, null, icons.activeHeader )
6840
				._addClass( this.headers, "ui-accordion-icons" );
6841
		}
6842
	},
6843
 
6844
	_destroyIcons: function() {
6845
		this._removeClass( this.headers, "ui-accordion-icons" );
6846
		this.headers.children( ".ui-accordion-header-icon" ).remove();
6847
	},
6848
 
6849
	_destroy: function() {
6850
		var contents;
6851
 
6852
		// Clean up main element
6853
		this.element.removeAttr( "role" );
6854
 
6855
		// Clean up headers
6856
		this.headers
6857
			.removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" )
6858
			.removeUniqueId();
6859
 
6860
		this._destroyIcons();
6861
 
6862
		// Clean up content panels
6863
		contents = this.headers.next()
6864
			.css( "display", "" )
6865
			.removeAttr( "role aria-hidden aria-labelledby" )
6866
			.removeUniqueId();
6867
 
6868
		if ( this.options.heightStyle !== "content" ) {
6869
			contents.css( "height", "" );
6870
		}
6871
	},
6872
 
6873
	_setOption: function( key, value ) {
6874
		if ( key === "active" ) {
6875
 
6876
			// _activate() will handle invalid values and update this.options
6877
			this._activate( value );
6878
			return;
6879
		}
6880
 
6881
		if ( key === "event" ) {
6882
			if ( this.options.event ) {
6883
				this._off( this.headers, this.options.event );
6884
			}
6885
			this._setupEvents( value );
6886
		}
6887
 
6888
		this._super( key, value );
6889
 
6890
		// Setting collapsible: false while collapsed; open first panel
6891
		if ( key === "collapsible" && !value && this.options.active === false ) {
6892
			this._activate( 0 );
6893
		}
6894
 
6895
		if ( key === "icons" ) {
6896
			this._destroyIcons();
6897
			if ( value ) {
6898
				this._createIcons();
6899
			}
6900
		}
6901
	},
6902
 
6903
	_setOptionDisabled: function( value ) {
6904
		this._super( value );
6905
 
6906
		this.element.attr( "aria-disabled", value );
6907
 
6908
		// Support: IE8 Only
6909
		// #5332 / #6059 - opacity doesn't cascade to positioned elements in IE
6910
		// so we need to add the disabled class to the headers and panels
6911
		this._toggleClass( null, "ui-state-disabled", !!value );
6912
		this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled",
6913
			!!value );
6914
	},
6915
 
6916
	_keydown: function( event ) {
6917
		if ( event.altKey || event.ctrlKey ) {
6918
			return;
6919
		}
6920
 
6921
		var keyCode = $.ui.keyCode,
6922
			length = this.headers.length,
6923
			currentIndex = this.headers.index( event.target ),
6924
			toFocus = false;
6925
 
6926
		switch ( event.keyCode ) {
6927
		case keyCode.RIGHT:
6928
		case keyCode.DOWN:
6929
			toFocus = this.headers[ ( currentIndex + 1 ) % length ];
6930
			break;
6931
		case keyCode.LEFT:
6932
		case keyCode.UP:
6933
			toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
6934
			break;
6935
		case keyCode.SPACE:
6936
		case keyCode.ENTER:
6937
			this._eventHandler( event );
6938
			break;
6939
		case keyCode.HOME:
6940
			toFocus = this.headers[ 0 ];
6941
			break;
6942
		case keyCode.END:
6943
			toFocus = this.headers[ length - 1 ];
6944
			break;
6945
		}
6946
 
6947
		if ( toFocus ) {
6948
			$( event.target ).attr( "tabIndex", -1 );
6949
			$( toFocus ).attr( "tabIndex", 0 );
6950
			$( toFocus ).trigger( "focus" );
6951
			event.preventDefault();
6952
		}
6953
	},
6954
 
6955
	_panelKeyDown: function( event ) {
6956
		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
6957
			$( event.currentTarget ).prev().trigger( "focus" );
6958
		}
6959
	},
6960
 
6961
	refresh: function() {
6962
		var options = this.options;
6963
		this._processPanels();
6964
 
6965
		// Was collapsed or no panel
6966
		if ( ( options.active === false && options.collapsible === true ) ||
6967
				!this.headers.length ) {
6968
			options.active = false;
6969
			this.active = $();
6970
 
6971
		// active false only when collapsible is true
6972
		} else if ( options.active === false ) {
6973
			this._activate( 0 );
6974
 
6975
		// was active, but active panel is gone
6976
		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
6977
 
6978
			// all remaining panel are disabled
6979
			if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) {
6980
				options.active = false;
6981
				this.active = $();
6982
 
6983
			// activate previous panel
6984
			} else {
6985
				this._activate( Math.max( 0, options.active - 1 ) );
6986
			}
6987
 
6988
		// was active, active panel still exists
6989
		} else {
6990
 
6991
			// make sure active index is correct
6992
			options.active = this.headers.index( this.active );
6993
		}
6994
 
6995
		this._destroyIcons();
6996
 
6997
		this._refresh();
6998
	},
6999
 
7000
	_processPanels: function() {
7001
		var prevHeaders = this.headers,
7002
			prevPanels = this.panels;
7003
 
7004
		this.headers = this.element.find( this.options.header );
7005
		this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed",
7006
			"ui-state-default" );
7007
 
7008
		this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide();
7009
		this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" );
7010
 
7011
		// Avoid memory leaks (#10056)
7012
		if ( prevPanels ) {
7013
			this._off( prevHeaders.not( this.headers ) );
7014
			this._off( prevPanels.not( this.panels ) );
7015
		}
7016
	},
7017
 
7018
	_refresh: function() {
7019
		var maxHeight,
7020
			options = this.options,
7021
			heightStyle = options.heightStyle,
7022
			parent = this.element.parent();
7023
 
7024
		this.active = this._findActive( options.active );
7025
		this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" )
7026
			._removeClass( this.active, "ui-accordion-header-collapsed" );
7027
		this._addClass( this.active.next(), "ui-accordion-content-active" );
7028
		this.active.next().show();
7029
 
7030
		this.headers
7031
			.attr( "role", "tab" )
7032
			.each( function() {
7033
				var header = $( this ),
7034
					headerId = header.uniqueId().attr( "id" ),
7035
					panel = header.next(),
7036
					panelId = panel.uniqueId().attr( "id" );
7037
				header.attr( "aria-controls", panelId );
7038
				panel.attr( "aria-labelledby", headerId );
7039
			} )
7040
			.next()
7041
				.attr( "role", "tabpanel" );
7042
 
7043
		this.headers
7044
			.not( this.active )
7045
				.attr( {
7046
					"aria-selected": "false",
7047
					"aria-expanded": "false",
7048
					tabIndex: -1
7049
				} )
7050
				.next()
7051
					.attr( {
7052
						"aria-hidden": "true"
7053
					} )
7054
					.hide();
7055
 
7056
		// Make sure at least one header is in the tab order
7057
		if ( !this.active.length ) {
7058
			this.headers.eq( 0 ).attr( "tabIndex", 0 );
7059
		} else {
7060
			this.active.attr( {
7061
				"aria-selected": "true",
7062
				"aria-expanded": "true",
7063
				tabIndex: 0
7064
			} )
7065
				.next()
7066
					.attr( {
7067
						"aria-hidden": "false"
7068
					} );
7069
		}
7070
 
7071
		this._createIcons();
7072
 
7073
		this._setupEvents( options.event );
7074
 
7075
		if ( heightStyle === "fill" ) {
7076
			maxHeight = parent.height();
7077
			this.element.siblings( ":visible" ).each( function() {
7078
				var elem = $( this ),
7079
					position = elem.css( "position" );
7080
 
7081
				if ( position === "absolute" || position === "fixed" ) {
7082
					return;
7083
				}
7084
				maxHeight -= elem.outerHeight( true );
7085
			} );
7086
 
7087
			this.headers.each( function() {
7088
				maxHeight -= $( this ).outerHeight( true );
7089
			} );
7090
 
7091
			this.headers.next()
7092
				.each( function() {
7093
					$( this ).height( Math.max( 0, maxHeight -
7094
						$( this ).innerHeight() + $( this ).height() ) );
7095
				} )
7096
				.css( "overflow", "auto" );
7097
		} else if ( heightStyle === "auto" ) {
7098
			maxHeight = 0;
7099
			this.headers.next()
7100
				.each( function() {
7101
					var isVisible = $( this ).is( ":visible" );
7102
					if ( !isVisible ) {
7103
						$( this ).show();
7104
					}
7105
					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
7106
					if ( !isVisible ) {
7107
						$( this ).hide();
7108
					}
7109
				} )
7110
				.height( maxHeight );
7111
		}
7112
	},
7113
 
7114
	_activate: function( index ) {
7115
		var active = this._findActive( index )[ 0 ];
7116
 
7117
		// Trying to activate the already active panel
7118
		if ( active === this.active[ 0 ] ) {
7119
			return;
7120
		}
7121
 
7122
		// Trying to collapse, simulate a click on the currently active header
7123
		active = active || this.active[ 0 ];
7124
 
7125
		this._eventHandler( {
7126
			target: active,
7127
			currentTarget: active,
7128
			preventDefault: $.noop
7129
		} );
7130
	},
7131
 
7132
	_findActive: function( selector ) {
7133
		return typeof selector === "number" ? this.headers.eq( selector ) : $();
7134
	},
7135
 
7136
	_setupEvents: function( event ) {
7137
		var events = {
7138
			keydown: "_keydown"
7139
		};
7140
		if ( event ) {
7141
			$.each( event.split( " " ), function( index, eventName ) {
7142
				events[ eventName ] = "_eventHandler";
7143
			} );
7144
		}
7145
 
7146
		this._off( this.headers.add( this.headers.next() ) );
7147
		this._on( this.headers, events );
7148
		this._on( this.headers.next(), { keydown: "_panelKeyDown" } );
7149
		this._hoverable( this.headers );
7150
		this._focusable( this.headers );
7151
	},
7152
 
7153
	_eventHandler: function( event ) {
7154
		var activeChildren, clickedChildren,
7155
			options = this.options,
7156
			active = this.active,
7157
			clicked = $( event.currentTarget ),
7158
			clickedIsActive = clicked[ 0 ] === active[ 0 ],
7159
			collapsing = clickedIsActive && options.collapsible,
7160
			toShow = collapsing ? $() : clicked.next(),
7161
			toHide = active.next(),
7162
			eventData = {
7163
				oldHeader: active,
7164
				oldPanel: toHide,
7165
				newHeader: collapsing ? $() : clicked,
7166
				newPanel: toShow
7167
			};
7168
 
7169
		event.preventDefault();
7170
 
7171
		if (
7172
 
7173
				// click on active header, but not collapsible
7174
				( clickedIsActive && !options.collapsible ) ||
7175
 
7176
				// allow canceling activation
7177
				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
7178
			return;
7179
		}
7180
 
7181
		options.active = collapsing ? false : this.headers.index( clicked );
7182
 
7183
		// When the call to ._toggle() comes after the class changes
7184
		// it causes a very odd bug in IE 8 (see #6720)
7185
		this.active = clickedIsActive ? $() : clicked;
7186
		this._toggle( eventData );
7187
 
7188
		// Switch classes
7189
		// corner classes on the previously active header stay after the animation
7190
		this._removeClass( active, "ui-accordion-header-active", "ui-state-active" );
7191
		if ( options.icons ) {
7192
			activeChildren = active.children( ".ui-accordion-header-icon" );
7193
			this._removeClass( activeChildren, null, options.icons.activeHeader )
7194
				._addClass( activeChildren, null, options.icons.header );
7195
		}
7196
 
7197
		if ( !clickedIsActive ) {
7198
			this._removeClass( clicked, "ui-accordion-header-collapsed" )
7199
				._addClass( clicked, "ui-accordion-header-active", "ui-state-active" );
7200
			if ( options.icons ) {
7201
				clickedChildren = clicked.children( ".ui-accordion-header-icon" );
7202
				this._removeClass( clickedChildren, null, options.icons.header )
7203
					._addClass( clickedChildren, null, options.icons.activeHeader );
7204
			}
7205
 
7206
			this._addClass( clicked.next(), "ui-accordion-content-active" );
7207
		}
7208
	},
7209
 
7210
	_toggle: function( data ) {
7211
		var toShow = data.newPanel,
7212
			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
7213
 
7214
		// Handle activating a panel during the animation for another activation
7215
		this.prevShow.add( this.prevHide ).stop( true, true );
7216
		this.prevShow = toShow;
7217
		this.prevHide = toHide;
7218
 
7219
		if ( this.options.animate ) {
7220
			this._animate( toShow, toHide, data );
7221
		} else {
7222
			toHide.hide();
7223
			toShow.show();
7224
			this._toggleComplete( data );
7225
		}
7226
 
7227
		toHide.attr( {
7228
			"aria-hidden": "true"
7229
		} );
7230
		toHide.prev().attr( {
7231
			"aria-selected": "false",
7232
			"aria-expanded": "false"
7233
		} );
7234
 
7235
		// if we're switching panels, remove the old header from the tab order
7236
		// if we're opening from collapsed state, remove the previous header from the tab order
7237
		// if we're collapsing, then keep the collapsing header in the tab order
7238
		if ( toShow.length && toHide.length ) {
7239
			toHide.prev().attr( {
7240
				"tabIndex": -1,
7241
				"aria-expanded": "false"
7242
			} );
7243
		} else if ( toShow.length ) {
7244
			this.headers.filter( function() {
7245
				return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
7246
			} )
7247
				.attr( "tabIndex", -1 );
7248
		}
7249
 
7250
		toShow
7251
			.attr( "aria-hidden", "false" )
7252
			.prev()
7253
				.attr( {
7254
					"aria-selected": "true",
7255
					"aria-expanded": "true",
7256
					tabIndex: 0
7257
				} );
7258
	},
7259
 
7260
	_animate: function( toShow, toHide, data ) {
7261
		var total, easing, duration,
7262
			that = this,
7263
			adjust = 0,
7264
			boxSizing = toShow.css( "box-sizing" ),
7265
			down = toShow.length &&
7266
				( !toHide.length || ( toShow.index() < toHide.index() ) ),
7267
			animate = this.options.animate || {},
7268
			options = down && animate.down || animate,
7269
			complete = function() {
7270
				that._toggleComplete( data );
7271
			};
7272
 
7273
		if ( typeof options === "number" ) {
7274
			duration = options;
7275
		}
7276
		if ( typeof options === "string" ) {
7277
			easing = options;
7278
		}
7279
 
7280
		// fall back from options to animation in case of partial down settings
7281
		easing = easing || options.easing || animate.easing;
7282
		duration = duration || options.duration || animate.duration;
7283
 
7284
		if ( !toHide.length ) {
7285
			return toShow.animate( this.showProps, duration, easing, complete );
7286
		}
7287
		if ( !toShow.length ) {
7288
			return toHide.animate( this.hideProps, duration, easing, complete );
7289
		}
7290
 
7291
		total = toShow.show().outerHeight();
7292
		toHide.animate( this.hideProps, {
7293
			duration: duration,
7294
			easing: easing,
7295
			step: function( now, fx ) {
7296
				fx.now = Math.round( now );
7297
			}
7298
		} );
7299
		toShow
7300
			.hide()
7301
			.animate( this.showProps, {
7302
				duration: duration,
7303
				easing: easing,
7304
				complete: complete,
7305
				step: function( now, fx ) {
7306
					fx.now = Math.round( now );
7307
					if ( fx.prop !== "height" ) {
7308
						if ( boxSizing === "content-box" ) {
7309
							adjust += fx.now;
7310
						}
7311
					} else if ( that.options.heightStyle !== "content" ) {
7312
						fx.now = Math.round( total - toHide.outerHeight() - adjust );
7313
						adjust = 0;
7314
					}
7315
				}
7316
			} );
7317
	},
7318
 
7319
	_toggleComplete: function( data ) {
7320
		var toHide = data.oldPanel,
7321
			prev = toHide.prev();
7322
 
7323
		this._removeClass( toHide, "ui-accordion-content-active" );
7324
		this._removeClass( prev, "ui-accordion-header-active" )
7325
			._addClass( prev, "ui-accordion-header-collapsed" );
7326
 
7327
		// Work around for rendering bug in IE (#5421)
7328
		if ( toHide.length ) {
7329
			toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
7330
		}
7331
		this._trigger( "activate", null, data );
7332
	}
7333
} );
7334
 
7335
 
7336
/*!
7337
 * jQuery UI Menu 1.12.1
7338
 * http://jqueryui.com
7339
 *
7340
 * Copyright jQuery Foundation and other contributors
7341
 * Released under the MIT license.
7342
 * http://jquery.org/license
7343
 */
7344
 
7345
//>>label: Menu
7346
//>>group: Widgets
7347
//>>description: Creates nestable menus.
7348
//>>docs: http://api.jqueryui.com/menu/
7349
//>>demos: http://jqueryui.com/menu/
7350
//>>css.structure: ../../themes/base/core.css
7351
//>>css.structure: ../../themes/base/menu.css
7352
//>>css.theme: ../../themes/base/theme.css
7353
 
7354
 
7355
 
7356
var widgetsMenu = $.widget( "ui.menu", {
7357
	version: "1.12.1",
7358
	defaultElement: "<ul>",
7359
	delay: 300,
7360
	options: {
7361
		icons: {
7362
			submenu: "ui-icon-caret-1-e"
7363
		},
7364
		items: "> *",
7365
		menus: "ul",
7366
		position: {
7367
			my: "left top",
7368
			at: "right top"
7369
		},
7370
		role: "menu",
7371
 
7372
		// Callbacks
7373
		blur: null,
7374
		focus: null,
7375
		select: null
7376
	},
7377
 
7378
	_create: function() {
7379
		this.activeMenu = this.element;
7380
 
7381
		// Flag used to prevent firing of the click handler
7382
		// as the event bubbles up through nested menus
7383
		this.mouseHandled = false;
7384
		this.element
7385
			.uniqueId()
7386
			.attr( {
7387
				role: this.options.role,
7388
				tabIndex: 0
7389
			} );
7390
 
7391
		this._addClass( "ui-menu", "ui-widget ui-widget-content" );
7392
		this._on( {
7393
 
7394
			// Prevent focus from sticking to links inside menu after clicking
7395
			// them (focus should always stay on UL during navigation).
7396
			"mousedown .ui-menu-item": function( event ) {
7397
				event.preventDefault();
7398
			},
7399
			"click .ui-menu-item": function( event ) {
7400
				var target = $( event.target );
7401
				var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
7402
				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
7403
					this.select( event );
7404
 
7405
					// Only set the mouseHandled flag if the event will bubble, see #9469.
7406
					if ( !event.isPropagationStopped() ) {
7407
						this.mouseHandled = true;
7408
					}
7409
 
7410
					// Open submenu on click
7411
					if ( target.has( ".ui-menu" ).length ) {
7412
						this.expand( event );
7413
					} else if ( !this.element.is( ":focus" ) &&
7414
							active.closest( ".ui-menu" ).length ) {
7415
 
7416
						// Redirect focus to the menu
7417
						this.element.trigger( "focus", [ true ] );
7418
 
7419
						// If the active item is on the top level, let it stay active.
7420
						// Otherwise, blur the active item since it is no longer visible.
7421
						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
7422
							clearTimeout( this.timer );
7423
						}
7424
					}
7425
				}
7426
			},
7427
			"mouseenter .ui-menu-item": function( event ) {
7428
 
7429
				// Ignore mouse events while typeahead is active, see #10458.
7430
				// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
7431
				// is over an item in the menu
7432
				if ( this.previousFilter ) {
7433
					return;
7434
				}
7435
 
7436
				var actualTarget = $( event.target ).closest( ".ui-menu-item" ),
7437
					target = $( event.currentTarget );
7438
 
7439
				// Ignore bubbled events on parent items, see #11641
7440
				if ( actualTarget[ 0 ] !== target[ 0 ] ) {
7441
					return;
7442
				}
7443
 
7444
				// Remove ui-state-active class from siblings of the newly focused menu item
7445
				// to avoid a jump caused by adjacent elements both having a class with a border
7446
				this._removeClass( target.siblings().children( ".ui-state-active" ),
7447
					null, "ui-state-active" );
7448
				this.focus( event, target );
7449
			},
7450
			mouseleave: "collapseAll",
7451
			"mouseleave .ui-menu": "collapseAll",
7452
			focus: function( event, keepActiveItem ) {
7453
 
7454
				// If there's already an active item, keep it active
7455
				// If not, activate the first item
7456
				var item = this.active || this.element.find( this.options.items ).eq( 0 );
7457
 
7458
				if ( !keepActiveItem ) {
7459
					this.focus( event, item );
7460
				}
7461
			},
7462
			blur: function( event ) {
7463
				this._delay( function() {
7464
					var notContained = !$.contains(
7465
						this.element[ 0 ],
7466
						$.ui.safeActiveElement( this.document[ 0 ] )
7467
					);
7468
					if ( notContained ) {
7469
						this.collapseAll( event );
7470
					}
7471
				} );
7472
			},
7473
			keydown: "_keydown"
7474
		} );
7475
 
7476
		this.refresh();
7477
 
7478
		// Clicks outside of a menu collapse any open menus
7479
		this._on( this.document, {
7480
			click: function( event ) {
7481
				if ( this._closeOnDocumentClick( event ) ) {
7482
					this.collapseAll( event );
7483
				}
7484
 
7485
				// Reset the mouseHandled flag
7486
				this.mouseHandled = false;
7487
			}
7488
		} );
7489
	},
7490
 
7491
	_destroy: function() {
7492
		var items = this.element.find( ".ui-menu-item" )
7493
				.removeAttr( "role aria-disabled" ),
7494
			submenus = items.children( ".ui-menu-item-wrapper" )
7495
				.removeUniqueId()
7496
				.removeAttr( "tabIndex role aria-haspopup" );
7497
 
7498
		// Destroy (sub)menus
7499
		this.element
7500
			.removeAttr( "aria-activedescendant" )
7501
			.find( ".ui-menu" ).addBack()
7502
				.removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " +
7503
					"tabIndex" )
7504
				.removeUniqueId()
7505
				.show();
7506
 
7507
		submenus.children().each( function() {
7508
			var elem = $( this );
7509
			if ( elem.data( "ui-menu-submenu-caret" ) ) {
7510
				elem.remove();
7511
			}
7512
		} );
7513
	},
7514
 
7515
	_keydown: function( event ) {
7516
		var match, prev, character, skip,
7517
			preventDefault = true;
7518
 
7519
		switch ( event.keyCode ) {
7520
		case $.ui.keyCode.PAGE_UP:
7521
			this.previousPage( event );
7522
			break;
7523
		case $.ui.keyCode.PAGE_DOWN:
7524
			this.nextPage( event );
7525
			break;
7526
		case $.ui.keyCode.HOME:
7527
			this._move( "first", "first", event );
7528
			break;
7529
		case $.ui.keyCode.END:
7530
			this._move( "last", "last", event );
7531
			break;
7532
		case $.ui.keyCode.UP:
7533
			this.previous( event );
7534
			break;
7535
		case $.ui.keyCode.DOWN:
7536
			this.next( event );
7537
			break;
7538
		case $.ui.keyCode.LEFT:
7539
			this.collapse( event );
7540
			break;
7541
		case $.ui.keyCode.RIGHT:
7542
			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
7543
				this.expand( event );
7544
			}
7545
			break;
7546
		case $.ui.keyCode.ENTER:
7547
		case $.ui.keyCode.SPACE:
7548
			this._activate( event );
7549
			break;
7550
		case $.ui.keyCode.ESCAPE:
7551
			this.collapse( event );
7552
			break;
7553
		default:
7554
			preventDefault = false;
7555
			prev = this.previousFilter || "";
7556
			skip = false;
7557
 
7558
			// Support number pad values
7559
			character = event.keyCode >= 96 && event.keyCode <= 105 ?
7560
				( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode );
7561
 
7562
			clearTimeout( this.filterTimer );
7563
 
7564
			if ( character === prev ) {
7565
				skip = true;
7566
			} else {
7567
				character = prev + character;
7568
			}
7569
 
7570
			match = this._filterMenuItems( character );
7571
			match = skip && match.index( this.active.next() ) !== -1 ?
7572
				this.active.nextAll( ".ui-menu-item" ) :
7573
				match;
7574
 
7575
			// If no matches on the current filter, reset to the last character pressed
7576
			// to move down the menu to the first item that starts with that character
7577
			if ( !match.length ) {
7578
				character = String.fromCharCode( event.keyCode );
7579
				match = this._filterMenuItems( character );
7580
			}
7581
 
7582
			if ( match.length ) {
7583
				this.focus( event, match );
7584
				this.previousFilter = character;
7585
				this.filterTimer = this._delay( function() {
7586
					delete this.previousFilter;
7587
				}, 1000 );
7588
			} else {
7589
				delete this.previousFilter;
7590
			}
7591
		}
7592
 
7593
		if ( preventDefault ) {
7594
			event.preventDefault();
7595
		}
7596
	},
7597
 
7598
	_activate: function( event ) {
7599
		if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
7600
			if ( this.active.children( "[aria-haspopup='true']" ).length ) {
7601
				this.expand( event );
7602
			} else {
7603
				this.select( event );
7604
			}
7605
		}
7606
	},
7607
 
7608
	refresh: function() {
7609
		var menus, items, newSubmenus, newItems, newWrappers,
7610
			that = this,
7611
			icon = this.options.icons.submenu,
7612
			submenus = this.element.find( this.options.menus );
7613
 
7614
		this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length );
7615
 
7616
		// Initialize nested menus
7617
		newSubmenus = submenus.filter( ":not(.ui-menu)" )
7618
			.hide()
7619
			.attr( {
7620
				role: this.options.role,
7621
				"aria-hidden": "true",
7622
				"aria-expanded": "false"
7623
			} )
7624
			.each( function() {
7625
				var menu = $( this ),
7626
					item = menu.prev(),
7627
					submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true );
7628
 
7629
				that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon );
7630
				item
7631
					.attr( "aria-haspopup", "true" )
7632
					.prepend( submenuCaret );
7633
				menu.attr( "aria-labelledby", item.attr( "id" ) );
7634
			} );
7635
 
7636
		this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" );
7637
 
7638
		menus = submenus.add( this.element );
7639
		items = menus.find( this.options.items );
7640
 
7641
		// Initialize menu-items containing spaces and/or dashes only as dividers
7642
		items.not( ".ui-menu-item" ).each( function() {
7643
			var item = $( this );
7644
			if ( that._isDivider( item ) ) {
7645
				that._addClass( item, "ui-menu-divider", "ui-widget-content" );
7646
			}
7647
		} );
7648
 
7649
		// Don't refresh list items that are already adapted
7650
		newItems = items.not( ".ui-menu-item, .ui-menu-divider" );
7651
		newWrappers = newItems.children()
7652
			.not( ".ui-menu" )
7653
				.uniqueId()
7654
				.attr( {
7655
					tabIndex: -1,
7656
					role: this._itemRole()
7657
				} );
7658
		this._addClass( newItems, "ui-menu-item" )
7659
			._addClass( newWrappers, "ui-menu-item-wrapper" );
7660
 
7661
		// Add aria-disabled attribute to any disabled menu item
7662
		items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
7663
 
7664
		// If the active item has been removed, blur the menu
7665
		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
7666
			this.blur();
7667
		}
7668
	},
7669
 
7670
	_itemRole: function() {
7671
		return {
7672
			menu: "menuitem",
7673
			listbox: "option"
7674
		}[ this.options.role ];
7675
	},
7676
 
7677
	_setOption: function( key, value ) {
7678
		if ( key === "icons" ) {
7679
			var icons = this.element.find( ".ui-menu-icon" );
7680
			this._removeClass( icons, null, this.options.icons.submenu )
7681
				._addClass( icons, null, value.submenu );
7682
		}
7683
		this._super( key, value );
7684
	},
7685
 
7686
	_setOptionDisabled: function( value ) {
7687
		this._super( value );
7688
 
7689
		this.element.attr( "aria-disabled", String( value ) );
7690
		this._toggleClass( null, "ui-state-disabled", !!value );
7691
	},
7692
 
7693
	focus: function( event, item ) {
7694
		var nested, focused, activeParent;
7695
		this.blur( event, event && event.type === "focus" );
7696
 
7697
		this._scrollIntoView( item );
7698
 
7699
		this.active = item.first();
7700
 
7701
		focused = this.active.children( ".ui-menu-item-wrapper" );
7702
		this._addClass( focused, null, "ui-state-active" );
7703
 
7704
		// Only update aria-activedescendant if there's a role
7705
		// otherwise we assume focus is managed elsewhere
7706
		if ( this.options.role ) {
7707
			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
7708
		}
7709
 
7710
		// Highlight active parent menu item, if any
7711
		activeParent = this.active
7712
			.parent()
7713
				.closest( ".ui-menu-item" )
7714
					.children( ".ui-menu-item-wrapper" );
7715
		this._addClass( activeParent, null, "ui-state-active" );
7716
 
7717
		if ( event && event.type === "keydown" ) {
7718
			this._close();
7719
		} else {
7720
			this.timer = this._delay( function() {
7721
				this._close();
7722
			}, this.delay );
7723
		}
7724
 
7725
		nested = item.children( ".ui-menu" );
7726
		if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
7727
			this._startOpening( nested );
7728
		}
7729
		this.activeMenu = item.parent();
7730
 
7731
		this._trigger( "focus", event, { item: item } );
7732
	},
7733
 
7734
	_scrollIntoView: function( item ) {
7735
		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
7736
		if ( this._hasScroll() ) {
7737
			borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0;
7738
			paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0;
7739
			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
7740
			scroll = this.activeMenu.scrollTop();
7741
			elementHeight = this.activeMenu.height();
7742
			itemHeight = item.outerHeight();
7743
 
7744
			if ( offset < 0 ) {
7745
				this.activeMenu.scrollTop( scroll + offset );
7746
			} else if ( offset + itemHeight > elementHeight ) {
7747
				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
7748
			}
7749
		}
7750
	},
7751
 
7752
	blur: function( event, fromFocus ) {
7753
		if ( !fromFocus ) {
7754
			clearTimeout( this.timer );
7755
		}
7756
 
7757
		if ( !this.active ) {
7758
			return;
7759
		}
7760
 
7761
		this._removeClass( this.active.children( ".ui-menu-item-wrapper" ),
7762
			null, "ui-state-active" );
7763
 
7764
		this._trigger( "blur", event, { item: this.active } );
7765
		this.active = null;
7766
	},
7767
 
7768
	_startOpening: function( submenu ) {
7769
		clearTimeout( this.timer );
7770
 
7771
		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
7772
		// shift in the submenu position when mousing over the caret icon
7773
		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
7774
			return;
7775
		}
7776
 
7777
		this.timer = this._delay( function() {
7778
			this._close();
7779
			this._open( submenu );
7780
		}, this.delay );
7781
	},
7782
 
7783
	_open: function( submenu ) {
7784
		var position = $.extend( {
7785
			of: this.active
7786
		}, this.options.position );
7787
 
7788
		clearTimeout( this.timer );
7789
		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
7790
			.hide()
7791
			.attr( "aria-hidden", "true" );
7792
 
7793
		submenu
7794
			.show()
7795
			.removeAttr( "aria-hidden" )
7796
			.attr( "aria-expanded", "true" )
7797
			.position( position );
7798
	},
7799
 
7800
	collapseAll: function( event, all ) {
7801
		clearTimeout( this.timer );
7802
		this.timer = this._delay( function() {
7803
 
7804
			// If we were passed an event, look for the submenu that contains the event
7805
			var currentMenu = all ? this.element :
7806
				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
7807
 
7808
			// If we found no valid submenu ancestor, use the main menu to close all
7809
			// sub menus anyway
7810
			if ( !currentMenu.length ) {
7811
				currentMenu = this.element;
7812
			}
7813
 
7814
			this._close( currentMenu );
7815
 
7816
			this.blur( event );
7817
 
7818
			// Work around active item staying active after menu is blurred
7819
			this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" );
7820
 
7821
			this.activeMenu = currentMenu;
7822
		}, this.delay );
7823
	},
7824
 
7825
	// With no arguments, closes the currently active menu - if nothing is active
7826
	// it closes all menus.  If passed an argument, it will search for menus BELOW
7827
	_close: function( startMenu ) {
7828
		if ( !startMenu ) {
7829
			startMenu = this.active ? this.active.parent() : this.element;
7830
		}
7831
 
7832
		startMenu.find( ".ui-menu" )
7833
			.hide()
7834
			.attr( "aria-hidden", "true" )
7835
			.attr( "aria-expanded", "false" );
7836
	},
7837
 
7838
	_closeOnDocumentClick: function( event ) {
7839
		return !$( event.target ).closest( ".ui-menu" ).length;
7840
	},
7841
 
7842
	_isDivider: function( item ) {
7843
 
7844
		// Match hyphen, em dash, en dash
7845
		return !/[^\-\u2014\u2013\s]/.test( item.text() );
7846
	},
7847
 
7848
	collapse: function( event ) {
7849
		var newItem = this.active &&
7850
			this.active.parent().closest( ".ui-menu-item", this.element );
7851
		if ( newItem && newItem.length ) {
7852
			this._close();
7853
			this.focus( event, newItem );
7854
		}
7855
	},
7856
 
7857
	expand: function( event ) {
7858
		var newItem = this.active &&
7859
			this.active
7860
				.children( ".ui-menu " )
7861
					.find( this.options.items )
7862
						.first();
7863
 
7864
		if ( newItem && newItem.length ) {
7865
			this._open( newItem.parent() );
7866
 
7867
			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
7868
			this._delay( function() {
7869
				this.focus( event, newItem );
7870
			} );
7871
		}
7872
	},
7873
 
7874
	next: function( event ) {
7875
		this._move( "next", "first", event );
7876
	},
7877
 
7878
	previous: function( event ) {
7879
		this._move( "prev", "last", event );
7880
	},
7881
 
7882
	isFirstItem: function() {
7883
		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
7884
	},
7885
 
7886
	isLastItem: function() {
7887
		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
7888
	},
7889
 
7890
	_move: function( direction, filter, event ) {
7891
		var next;
7892
		if ( this.active ) {
7893
			if ( direction === "first" || direction === "last" ) {
7894
				next = this.active
7895
					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
7896
					.eq( -1 );
7897
			} else {
7898
				next = this.active
7899
					[ direction + "All" ]( ".ui-menu-item" )
7900
					.eq( 0 );
7901
			}
7902
		}
7903
		if ( !next || !next.length || !this.active ) {
7904
			next = this.activeMenu.find( this.options.items )[ filter ]();
7905
		}
7906
 
7907
		this.focus( event, next );
7908
	},
7909
 
7910
	nextPage: function( event ) {
7911
		var item, base, height;
7912
 
7913
		if ( !this.active ) {
7914
			this.next( event );
7915
			return;
7916
		}
7917
		if ( this.isLastItem() ) {
7918
			return;
7919
		}
7920
		if ( this._hasScroll() ) {
7921
			base = this.active.offset().top;
7922
			height = this.element.height();
7923
			this.active.nextAll( ".ui-menu-item" ).each( function() {
7924
				item = $( this );
7925
				return item.offset().top - base - height < 0;
7926
			} );
7927
 
7928
			this.focus( event, item );
7929
		} else {
7930
			this.focus( event, this.activeMenu.find( this.options.items )
7931
				[ !this.active ? "first" : "last" ]() );
7932
		}
7933
	},
7934
 
7935
	previousPage: function( event ) {
7936
		var item, base, height;
7937
		if ( !this.active ) {
7938
			this.next( event );
7939
			return;
7940
		}
7941
		if ( this.isFirstItem() ) {
7942
			return;
7943
		}
7944
		if ( this._hasScroll() ) {
7945
			base = this.active.offset().top;
7946
			height = this.element.height();
7947
			this.active.prevAll( ".ui-menu-item" ).each( function() {
7948
				item = $( this );
7949
				return item.offset().top - base + height > 0;
7950
			} );
7951
 
7952
			this.focus( event, item );
7953
		} else {
7954
			this.focus( event, this.activeMenu.find( this.options.items ).first() );
7955
		}
7956
	},
7957
 
7958
	_hasScroll: function() {
7959
		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
7960
	},
7961
 
7962
	select: function( event ) {
7963
 
7964
		// TODO: It should never be possible to not have an active item at this
7965
		// point, but the tests don't trigger mouseenter before click.
7966
		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
7967
		var ui = { item: this.active };
7968
		if ( !this.active.has( ".ui-menu" ).length ) {
7969
			this.collapseAll( event, true );
7970
		}
7971
		this._trigger( "select", event, ui );
7972
	},
7973
 
7974
	_filterMenuItems: function( character ) {
7975
		var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
7976
			regex = new RegExp( "^" + escapedCharacter, "i" );
7977
 
7978
		return this.activeMenu
7979
			.find( this.options.items )
7980
 
7981
				// Only match on items, not dividers or other content (#10571)
7982
				.filter( ".ui-menu-item" )
7983
					.filter( function() {
7984
						return regex.test(
7985
							$.trim( $( this ).children( ".ui-menu-item-wrapper" ).text() ) );
7986
					} );
7987
	}
7988
} );
7989
 
7990
 
7991
/*!
7992
 * jQuery UI Autocomplete 1.12.1
7993
 * http://jqueryui.com
7994
 *
7995
 * Copyright jQuery Foundation and other contributors
7996
 * Released under the MIT license.
7997
 * http://jquery.org/license
7998
 */
7999
 
8000
//>>label: Autocomplete
8001
//>>group: Widgets
8002
//>>description: Lists suggested words as the user is typing.
8003
//>>docs: http://api.jqueryui.com/autocomplete/
8004
//>>demos: http://jqueryui.com/autocomplete/
8005
//>>css.structure: ../../themes/base/core.css
8006
//>>css.structure: ../../themes/base/autocomplete.css
8007
//>>css.theme: ../../themes/base/theme.css
8008
 
8009
 
8010
 
8011
$.widget( "ui.autocomplete", {
8012
	version: "1.12.1",
8013
	defaultElement: "<input>",
8014
	options: {
8015
		appendTo: null,
8016
		autoFocus: false,
8017
		delay: 300,
8018
		minLength: 1,
8019
		position: {
8020
			my: "left top",
8021
			at: "left bottom",
8022
			collision: "none"
8023
		},
8024
		source: null,
8025
 
8026
		// Callbacks
8027
		change: null,
8028
		close: null,
8029
		focus: null,
8030
		open: null,
8031
		response: null,
8032
		search: null,
8033
		select: null
8034
	},
8035
 
8036
	requestIndex: 0,
8037
	pending: 0,
8038
 
8039
	_create: function() {
8040
 
8041
		// Some browsers only repeat keydown events, not keypress events,
8042
		// so we use the suppressKeyPress flag to determine if we've already
8043
		// handled the keydown event. #7269
8044
		// Unfortunately the code for & in keypress is the same as the up arrow,
8045
		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
8046
		// events when we know the keydown event was used to modify the
8047
		// search term. #7799
8048
		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
8049
			nodeName = this.element[ 0 ].nodeName.toLowerCase(),
8050
			isTextarea = nodeName === "textarea",
8051
			isInput = nodeName === "input";
8052
 
8053
		// Textareas are always multi-line
8054
		// Inputs are always single-line, even if inside a contentEditable element
8055
		// IE also treats inputs as contentEditable
8056
		// All other element types are determined by whether or not they're contentEditable
8057
		this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element );
8058
 
8059
		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
8060
		this.isNewMenu = true;
8061
 
8062
		this._addClass( "ui-autocomplete-input" );
8063
		this.element.attr( "autocomplete", "off" );
8064
 
8065
		this._on( this.element, {
8066
			keydown: function( event ) {
8067
				if ( this.element.prop( "readOnly" ) ) {
8068
					suppressKeyPress = true;
8069
					suppressInput = true;
8070
					suppressKeyPressRepeat = true;
8071
					return;
8072
				}
8073
 
8074
				suppressKeyPress = false;
8075
				suppressInput = false;
8076
				suppressKeyPressRepeat = false;
8077
				var keyCode = $.ui.keyCode;
8078
				switch ( event.keyCode ) {
8079
				case keyCode.PAGE_UP:
8080
					suppressKeyPress = true;
8081
					this._move( "previousPage", event );
8082
					break;
8083
				case keyCode.PAGE_DOWN:
8084
					suppressKeyPress = true;
8085
					this._move( "nextPage", event );
8086
					break;
8087
				case keyCode.UP:
8088
					suppressKeyPress = true;
8089
					this._keyEvent( "previous", event );
8090
					break;
8091
				case keyCode.DOWN:
8092
					suppressKeyPress = true;
8093
					this._keyEvent( "next", event );
8094
					break;
8095
				case keyCode.ENTER:
8096
 
8097
					// when menu is open and has focus
8098
					if ( this.menu.active ) {
8099
 
8100
						// #6055 - Opera still allows the keypress to occur
8101
						// which causes forms to submit
8102
						suppressKeyPress = true;
8103
						event.preventDefault();
8104
						this.menu.select( event );
8105
					}
8106
					break;
8107
				case keyCode.TAB:
8108
					if ( this.menu.active ) {
8109
						this.menu.select( event );
8110
					}
8111
					break;
8112
				case keyCode.ESCAPE:
8113
					if ( this.menu.element.is( ":visible" ) ) {
8114
						if ( !this.isMultiLine ) {
8115
							this._value( this.term );
8116
						}
8117
						this.close( event );
8118
 
8119
						// Different browsers have different default behavior for escape
8120
						// Single press can mean undo or clear
8121
						// Double press in IE means clear the whole form
8122
						event.preventDefault();
8123
					}
8124
					break;
8125
				default:
8126
					suppressKeyPressRepeat = true;
8127
 
8128
					// search timeout should be triggered before the input value is changed
8129
					this._searchTimeout( event );
8130
					break;
8131
				}
8132
			},
8133
			keypress: function( event ) {
8134
				if ( suppressKeyPress ) {
8135
					suppressKeyPress = false;
8136
					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
8137
						event.preventDefault();
8138
					}
8139
					return;
8140
				}
8141
				if ( suppressKeyPressRepeat ) {
8142
					return;
8143
				}
8144
 
8145
				// Replicate some key handlers to allow them to repeat in Firefox and Opera
8146
				var keyCode = $.ui.keyCode;
8147
				switch ( event.keyCode ) {
8148
				case keyCode.PAGE_UP:
8149
					this._move( "previousPage", event );
8150
					break;
8151
				case keyCode.PAGE_DOWN:
8152
					this._move( "nextPage", event );
8153
					break;
8154
				case keyCode.UP:
8155
					this._keyEvent( "previous", event );
8156
					break;
8157
				case keyCode.DOWN:
8158
					this._keyEvent( "next", event );
8159
					break;
8160
				}
8161
			},
8162
			input: function( event ) {
8163
				if ( suppressInput ) {
8164
					suppressInput = false;
8165
					event.preventDefault();
8166
					return;
8167
				}
8168
				this._searchTimeout( event );
8169
			},
8170
			focus: function() {
8171
				this.selectedItem = null;
8172
				this.previous = this._value();
8173
			},
8174
			blur: function( event ) {
8175
				if ( this.cancelBlur ) {
8176
					delete this.cancelBlur;
8177
					return;
8178
				}
8179
 
8180
				clearTimeout( this.searching );
8181
				this.close( event );
8182
				this._change( event );
8183
			}
8184
		} );
8185
 
8186
		this._initSource();
8187
		this.menu = $( "<ul>" )
8188
			.appendTo( this._appendTo() )
8189
			.menu( {
8190
 
8191
				// disable ARIA support, the live region takes care of that
8192
				role: null
8193
			} )
8194
			.hide()
8195
			.menu( "instance" );
8196
 
8197
		this._addClass( this.menu.element, "ui-autocomplete", "ui-front" );
8198
		this._on( this.menu.element, {
8199
			mousedown: function( event ) {
8200
 
8201
				// prevent moving focus out of the text field
8202
				event.preventDefault();
8203
 
8204
				// IE doesn't prevent moving focus even with event.preventDefault()
8205
				// so we set a flag to know when we should ignore the blur event
8206
				this.cancelBlur = true;
8207
				this._delay( function() {
8208
					delete this.cancelBlur;
8209
 
8210
					// Support: IE 8 only
8211
					// Right clicking a menu item or selecting text from the menu items will
8212
					// result in focus moving out of the input. However, we've already received
8213
					// and ignored the blur event because of the cancelBlur flag set above. So
8214
					// we restore focus to ensure that the menu closes properly based on the user's
8215
					// next actions.
8216
					if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
8217
						this.element.trigger( "focus" );
8218
					}
8219
				} );
8220
			},
8221
			menufocus: function( event, ui ) {
8222
				var label, item;
8223
 
8224
				// support: Firefox
8225
				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
8226
				if ( this.isNewMenu ) {
8227
					this.isNewMenu = false;
8228
					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
8229
						this.menu.blur();
8230
 
8231
						this.document.one( "mousemove", function() {
8232
							$( event.target ).trigger( event.originalEvent );
8233
						} );
8234
 
8235
						return;
8236
					}
8237
				}
8238
 
8239
				item = ui.item.data( "ui-autocomplete-item" );
8240
				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
8241
 
8242
					// use value to match what will end up in the input, if it was a key event
8243
					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
8244
						this._value( item.value );
8245
					}
8246
				}
8247
 
8248
				// Announce the value in the liveRegion
8249
				label = ui.item.attr( "aria-label" ) || item.value;
8250
				if ( label && $.trim( label ).length ) {
8251
					this.liveRegion.children().hide();
8252
					$( "<div>" ).text( label ).appendTo( this.liveRegion );
8253
				}
8254
			},
8255
			menuselect: function( event, ui ) {
8256
				var item = ui.item.data( "ui-autocomplete-item" ),
8257
					previous = this.previous;
8258
 
8259
				// Only trigger when focus was lost (click on menu)
8260
				if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
8261
					this.element.trigger( "focus" );
8262
					this.previous = previous;
8263
 
8264
					// #6109 - IE triggers two focus events and the second
8265
					// is asynchronous, so we need to reset the previous
8266
					// term synchronously and asynchronously :-(
8267
					this._delay( function() {
8268
						this.previous = previous;
8269
						this.selectedItem = item;
8270
					} );
8271
				}
8272
 
8273
				if ( false !== this._trigger( "select", event, { item: item } ) ) {
8274
					this._value( item.value );
8275
				}
8276
 
8277
				// reset the term after the select event
8278
				// this allows custom select handling to work properly
8279
				this.term = this._value();
8280
 
8281
				this.close( event );
8282
				this.selectedItem = item;
8283
			}
8284
		} );
8285
 
8286
		this.liveRegion = $( "<div>", {
8287
			role: "status",
8288
			"aria-live": "assertive",
8289
			"aria-relevant": "additions"
8290
		} )
8291
			.appendTo( this.document[ 0 ].body );
8292
 
8293
		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
8294
 
8295
		// Turning off autocomplete prevents the browser from remembering the
8296
		// value when navigating through history, so we re-enable autocomplete
8297
		// if the page is unloaded before the widget is destroyed. #7790
8298
		this._on( this.window, {
8299
			beforeunload: function() {
8300
				this.element.removeAttr( "autocomplete" );
8301
			}
8302
		} );
8303
	},
8304
 
8305
	_destroy: function() {
8306
		clearTimeout( this.searching );
8307
		this.element.removeAttr( "autocomplete" );
8308
		this.menu.element.remove();
8309
		this.liveRegion.remove();
8310
	},
8311
 
8312
	_setOption: function( key, value ) {
8313
		this._super( key, value );
8314
		if ( key === "source" ) {
8315
			this._initSource();
8316
		}
8317
		if ( key === "appendTo" ) {
8318
			this.menu.element.appendTo( this._appendTo() );
8319
		}
8320
		if ( key === "disabled" && value && this.xhr ) {
8321
			this.xhr.abort();
8322
		}
8323
	},
8324
 
8325
	_isEventTargetInWidget: function( event ) {
8326
		var menuElement = this.menu.element[ 0 ];
8327
 
8328
		return event.target === this.element[ 0 ] ||
8329
			event.target === menuElement ||
8330
			$.contains( menuElement, event.target );
8331
	},
8332
 
8333
	_closeOnClickOutside: function( event ) {
8334
		if ( !this._isEventTargetInWidget( event ) ) {
8335
			this.close();
8336
		}
8337
	},
8338
 
8339
	_appendTo: function() {
8340
		var element = this.options.appendTo;
8341
 
8342
		if ( element ) {
8343
			element = element.jquery || element.nodeType ?
8344
				$( element ) :
8345
				this.document.find( element ).eq( 0 );
8346
		}
8347
 
8348
		if ( !element || !element[ 0 ] ) {
8349
			element = this.element.closest( ".ui-front, dialog" );
8350
		}
8351
 
8352
		if ( !element.length ) {
8353
			element = this.document[ 0 ].body;
8354
		}
8355
 
8356
		return element;
8357
	},
8358
 
8359
	_initSource: function() {
8360
		var array, url,
8361
			that = this;
8362
		if ( $.isArray( this.options.source ) ) {
8363
			array = this.options.source;
8364
			this.source = function( request, response ) {
8365
				response( $.ui.autocomplete.filter( array, request.term ) );
8366
			};
8367
		} else if ( typeof this.options.source === "string" ) {
8368
			url = this.options.source;
8369
			this.source = function( request, response ) {
8370
				if ( that.xhr ) {
8371
					that.xhr.abort();
8372
				}
8373
				that.xhr = $.ajax( {
8374
					url: url,
8375
					data: request,
8376
					dataType: "json",
8377
					success: function( data ) {
8378
						response( data );
8379
					},
8380
					error: function() {
8381
						response( [] );
8382
					}
8383
				} );
8384
			};
8385
		} else {
8386
			this.source = this.options.source;
8387
		}
8388
	},
8389
 
8390
	_searchTimeout: function( event ) {
8391
		clearTimeout( this.searching );
8392
		this.searching = this._delay( function() {
8393
 
8394
			// Search if the value has changed, or if the user retypes the same value (see #7434)
8395
			var equalValues = this.term === this._value(),
8396
				menuVisible = this.menu.element.is( ":visible" ),
8397
				modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
8398
 
8399
			if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
8400
				this.selectedItem = null;
8401
				this.search( null, event );
8402
			}
8403
		}, this.options.delay );
8404
	},
8405
 
8406
	search: function( value, event ) {
8407
		value = value != null ? value : this._value();
8408
 
8409
		// Always save the actual value, not the one passed as an argument
8410
		this.term = this._value();
8411
 
8412
		if ( value.length < this.options.minLength ) {
8413
			return this.close( event );
8414
		}
8415
 
8416
		if ( this._trigger( "search", event ) === false ) {
8417
			return;
8418
		}
8419
 
8420
		return this._search( value );
8421
	},
8422
 
8423
	_search: function( value ) {
8424
		this.pending++;
8425
		this._addClass( "ui-autocomplete-loading" );
8426
		this.cancelSearch = false;
8427
 
8428
		this.source( { term: value }, this._response() );
8429
	},
8430
 
8431
	_response: function() {
8432
		var index = ++this.requestIndex;
8433
 
8434
		return $.proxy( function( content ) {
8435
			if ( index === this.requestIndex ) {
8436
				this.__response( content );
8437
			}
8438
 
8439
			this.pending--;
8440
			if ( !this.pending ) {
8441
				this._removeClass( "ui-autocomplete-loading" );
8442
			}
8443
		}, this );
8444
	},
8445
 
8446
	__response: function( content ) {
8447
		if ( content ) {
8448
			content = this._normalize( content );
8449
		}
8450
		this._trigger( "response", null, { content: content } );
8451
		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
8452
			this._suggest( content );
8453
			this._trigger( "open" );
8454
		} else {
8455
 
8456
			// use ._close() instead of .close() so we don't cancel future searches
8457
			this._close();
8458
		}
8459
	},
8460
 
8461
	close: function( event ) {
8462
		this.cancelSearch = true;
8463
		this._close( event );
8464
	},
8465
 
8466
	_close: function( event ) {
8467
 
8468
		// Remove the handler that closes the menu on outside clicks
8469
		this._off( this.document, "mousedown" );
8470
 
8471
		if ( this.menu.element.is( ":visible" ) ) {
8472
			this.menu.element.hide();
8473
			this.menu.blur();
8474
			this.isNewMenu = true;
8475
			this._trigger( "close", event );
8476
		}
8477
	},
8478
 
8479
	_change: function( event ) {
8480
		if ( this.previous !== this._value() ) {
8481
			this._trigger( "change", event, { item: this.selectedItem } );
8482
		}
8483
	},
8484
 
8485
	_normalize: function( items ) {
8486
 
8487
		// assume all items have the right format when the first item is complete
8488
		if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
8489
			return items;
8490
		}
8491
		return $.map( items, function( item ) {
8492
			if ( typeof item === "string" ) {
8493
				return {
8494
					label: item,
8495
					value: item
8496
				};
8497
			}
8498
			return $.extend( {}, item, {
8499
				label: item.label || item.value,
8500
				value: item.value || item.label
8501
			} );
8502
		} );
8503
	},
8504
 
8505
	_suggest: function( items ) {
8506
		var ul = this.menu.element.empty();
8507
		this._renderMenu( ul, items );
8508
		this.isNewMenu = true;
8509
		this.menu.refresh();
8510
 
8511
		// Size and position menu
8512
		ul.show();
8513
		this._resizeMenu();
8514
		ul.position( $.extend( {
8515
			of: this.element
8516
		}, this.options.position ) );
8517
 
8518
		if ( this.options.autoFocus ) {
8519
			this.menu.next();
8520
		}
8521
 
8522
		// Listen for interactions outside of the widget (#6642)
8523
		this._on( this.document, {
8524
			mousedown: "_closeOnClickOutside"
8525
		} );
8526
	},
8527
 
8528
	_resizeMenu: function() {
8529
		var ul = this.menu.element;
8530
		ul.outerWidth( Math.max(
8531
 
8532
			// Firefox wraps long text (possibly a rounding bug)
8533
			// so we add 1px to avoid the wrapping (#7513)
8534
			ul.width( "" ).outerWidth() + 1,
8535
			this.element.outerWidth()
8536
		) );
8537
	},
8538
 
8539
	_renderMenu: function( ul, items ) {
8540
		var that = this;
8541
		$.each( items, function( index, item ) {
8542
			that._renderItemData( ul, item );
8543
		} );
8544
	},
8545
 
8546
	_renderItemData: function( ul, item ) {
8547
		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
8548
	},
8549
 
8550
	_renderItem: function( ul, item ) {
8551
		return $( "<li>" )
8552
			.append( $( "<div>" ).text( item.label ) )
8553
			.appendTo( ul );
8554
	},
8555
 
8556
	_move: function( direction, event ) {
8557
		if ( !this.menu.element.is( ":visible" ) ) {
8558
			this.search( null, event );
8559
			return;
8560
		}
8561
		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
8562
				this.menu.isLastItem() && /^next/.test( direction ) ) {
8563
 
8564
			if ( !this.isMultiLine ) {
8565
				this._value( this.term );
8566
			}
8567
 
8568
			this.menu.blur();
8569
			return;
8570
		}
8571
		this.menu[ direction ]( event );
8572
	},
8573
 
8574
	widget: function() {
8575
		return this.menu.element;
8576
	},
8577
 
8578
	_value: function() {
8579
		return this.valueMethod.apply( this.element, arguments );
8580
	},
8581
 
8582
	_keyEvent: function( keyEvent, event ) {
8583
		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
8584
			this._move( keyEvent, event );
8585
 
8586
			// Prevents moving cursor to beginning/end of the text field in some browsers
8587
			event.preventDefault();
8588
		}
8589
	},
8590
 
8591
	// Support: Chrome <=50
8592
	// We should be able to just use this.element.prop( "isContentEditable" )
8593
	// but hidden elements always report false in Chrome.
8594
	// https://code.google.com/p/chromium/issues/detail?id=313082
8595
	_isContentEditable: function( element ) {
8596
		if ( !element.length ) {
8597
			return false;
8598
		}
8599
 
8600
		var editable = element.prop( "contentEditable" );
8601
 
8602
		if ( editable === "inherit" ) {
8603
		  return this._isContentEditable( element.parent() );
8604
		}
8605
 
8606
		return editable === "true";
8607
	}
8608
} );
8609
 
8610
$.extend( $.ui.autocomplete, {
8611
	escapeRegex: function( value ) {
8612
		return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
8613
	},
8614
	filter: function( array, term ) {
8615
		var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
8616
		return $.grep( array, function( value ) {
8617
			return matcher.test( value.label || value.value || value );
8618
		} );
8619
	}
8620
} );
8621
 
8622
// Live region extension, adding a `messages` option
8623
// NOTE: This is an experimental API. We are still investigating
8624
// a full solution for string manipulation and internationalization.
8625
$.widget( "ui.autocomplete", $.ui.autocomplete, {
8626
	options: {
8627
		messages: {
8628
			noResults: "No search results.",
8629
			results: function( amount ) {
8630
				return amount + ( amount > 1 ? " results are" : " result is" ) +
8631
					" available, use up and down arrow keys to navigate.";
8632
			}
8633
		}
8634
	},
8635
 
8636
	__response: function( content ) {
8637
		var message;
8638
		this._superApply( arguments );
8639
		if ( this.options.disabled || this.cancelSearch ) {
8640
			return;
8641
		}
8642
		if ( content && content.length ) {
8643
			message = this.options.messages.results( content.length );
8644
		} else {
8645
			message = this.options.messages.noResults;
8646
		}
8647
		this.liveRegion.children().hide();
8648
		$( "<div>" ).text( message ).appendTo( this.liveRegion );
8649
	}
8650
} );
8651
 
8652
var widgetsAutocomplete = $.ui.autocomplete;
8653
 
8654
 
8655
/*!
8656
 * jQuery UI Controlgroup 1.12.1
8657
 * http://jqueryui.com
8658
 *
8659
 * Copyright jQuery Foundation and other contributors
8660
 * Released under the MIT license.
8661
 * http://jquery.org/license
8662
 */
8663
 
8664
//>>label: Controlgroup
8665
//>>group: Widgets
8666
//>>description: Visually groups form control widgets
8667
//>>docs: http://api.jqueryui.com/controlgroup/
8668
//>>demos: http://jqueryui.com/controlgroup/
8669
//>>css.structure: ../../themes/base/core.css
8670
//>>css.structure: ../../themes/base/controlgroup.css
8671
//>>css.theme: ../../themes/base/theme.css
8672
 
8673
 
8674
var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g;
8675
 
8676
var widgetsControlgroup = $.widget( "ui.controlgroup", {
8677
	version: "1.12.1",
8678
	defaultElement: "<div>",
8679
	options: {
8680
		direction: "horizontal",
8681
		disabled: null,
8682
		onlyVisible: true,
8683
		items: {
8684
			"button": "input[type=button], input[type=submit], input[type=reset], button, a",
8685
			"controlgroupLabel": ".ui-controlgroup-label",
8686
			"checkboxradio": "input[type='checkbox'], input[type='radio']",
8687
			"selectmenu": "select",
8688
			"spinner": ".ui-spinner-input"
8689
		}
8690
	},
8691
 
8692
	_create: function() {
8693
		this._enhance();
8694
	},
8695
 
8696
	// To support the enhanced option in jQuery Mobile, we isolate DOM manipulation
8697
	_enhance: function() {
8698
		this.element.attr( "role", "toolbar" );
8699
		this.refresh();
8700
	},
8701
 
8702
	_destroy: function() {
8703
		this._callChildMethod( "destroy" );
8704
		this.childWidgets.removeData( "ui-controlgroup-data" );
8705
		this.element.removeAttr( "role" );
8706
		if ( this.options.items.controlgroupLabel ) {
8707
			this.element
8708
				.find( this.options.items.controlgroupLabel )
8709
				.find( ".ui-controlgroup-label-contents" )
8710
				.contents().unwrap();
8711
		}
8712
	},
8713
 
8714
	_initWidgets: function() {
8715
		var that = this,
8716
			childWidgets = [];
8717
 
8718
		// First we iterate over each of the items options
8719
		$.each( this.options.items, function( widget, selector ) {
8720
			var labels;
8721
			var options = {};
8722
 
8723
			// Make sure the widget has a selector set
8724
			if ( !selector ) {
8725
				return;
8726
			}
8727
 
8728
			if ( widget === "controlgroupLabel" ) {
8729
				labels = that.element.find( selector );
8730
				labels.each( function() {
8731
					var element = $( this );
8732
 
8733
					if ( element.children( ".ui-controlgroup-label-contents" ).length ) {
8734
						return;
8735
					}
8736
					element.contents()
8737
						.wrapAll( "<span class='ui-controlgroup-label-contents'></span>" );
8738
				} );
8739
				that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" );
8740
				childWidgets = childWidgets.concat( labels.get() );
8741
				return;
8742
			}
8743
 
8744
			// Make sure the widget actually exists
8745
			if ( !$.fn[ widget ] ) {
8746
				return;
8747
			}
8748
 
8749
			// We assume everything is in the middle to start because we can't determine
8750
			// first / last elements until all enhancments are done.
8751
			if ( that[ "_" + widget + "Options" ] ) {
8752
				options = that[ "_" + widget + "Options" ]( "middle" );
8753
			} else {
8754
				options = { classes: {} };
8755
			}
8756
 
8757
			// Find instances of this widget inside controlgroup and init them
8758
			that.element
8759
				.find( selector )
8760
				.each( function() {
8761
					var element = $( this );
8762
					var instance = element[ widget ]( "instance" );
8763
 
8764
					// We need to clone the default options for this type of widget to avoid
8765
					// polluting the variable options which has a wider scope than a single widget.
8766
					var instanceOptions = $.widget.extend( {}, options );
8767
 
8768
					// If the button is the child of a spinner ignore it
8769
					// TODO: Find a more generic solution
8770
					if ( widget === "button" && element.parent( ".ui-spinner" ).length ) {
8771
						return;
8772
					}
8773
 
8774
					// Create the widget if it doesn't exist
8775
					if ( !instance ) {
8776
						instance = element[ widget ]()[ widget ]( "instance" );
8777
					}
8778
					if ( instance ) {
8779
						instanceOptions.classes =
8780
							that._resolveClassesValues( instanceOptions.classes, instance );
8781
					}
8782
					element[ widget ]( instanceOptions );
8783
 
8784
					// Store an instance of the controlgroup to be able to reference
8785
					// from the outermost element for changing options and refresh
8786
					var widgetElement = element[ widget ]( "widget" );
8787
					$.data( widgetElement[ 0 ], "ui-controlgroup-data",
8788
						instance ? instance : element[ widget ]( "instance" ) );
8789
 
8790
					childWidgets.push( widgetElement[ 0 ] );
8791
				} );
8792
		} );
8793
 
8794
		this.childWidgets = $( $.unique( childWidgets ) );
8795
		this._addClass( this.childWidgets, "ui-controlgroup-item" );
8796
	},
8797
 
8798
	_callChildMethod: function( method ) {
8799
		this.childWidgets.each( function() {
8800
			var element = $( this ),
8801
				data = element.data( "ui-controlgroup-data" );
8802
			if ( data && data[ method ] ) {
8803
				data[ method ]();
8804
			}
8805
		} );
8806
	},
8807
 
8808
	_updateCornerClass: function( element, position ) {
8809
		var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all";
8810
		var add = this._buildSimpleOptions( position, "label" ).classes.label;
8811
 
8812
		this._removeClass( element, null, remove );
8813
		this._addClass( element, null, add );
8814
	},
8815
 
8816
	_buildSimpleOptions: function( position, key ) {
8817
		var direction = this.options.direction === "vertical";
8818
		var result = {
8819
			classes: {}
8820
		};
8821
		result.classes[ key ] = {
8822
			"middle": "",
8823
			"first": "ui-corner-" + ( direction ? "top" : "left" ),
8824
			"last": "ui-corner-" + ( direction ? "bottom" : "right" ),
8825
			"only": "ui-corner-all"
8826
		}[ position ];
8827
 
8828
		return result;
8829
	},
8830
 
8831
	_spinnerOptions: function( position ) {
8832
		var options = this._buildSimpleOptions( position, "ui-spinner" );
8833
 
8834
		options.classes[ "ui-spinner-up" ] = "";
8835
		options.classes[ "ui-spinner-down" ] = "";
8836
 
8837
		return options;
8838
	},
8839
 
8840
	_buttonOptions: function( position ) {
8841
		return this._buildSimpleOptions( position, "ui-button" );
8842
	},
8843
 
8844
	_checkboxradioOptions: function( position ) {
8845
		return this._buildSimpleOptions( position, "ui-checkboxradio-label" );
8846
	},
8847
 
8848
	_selectmenuOptions: function( position ) {
8849
		var direction = this.options.direction === "vertical";
8850
		return {
8851
			width: direction ? "auto" : false,
8852
			classes: {
8853
				middle: {
8854
					"ui-selectmenu-button-open": "",
8855
					"ui-selectmenu-button-closed": ""
8856
				},
8857
				first: {
8858
					"ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ),
8859
					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" )
8860
				},
8861
				last: {
8862
					"ui-selectmenu-button-open": direction ? "" : "ui-corner-tr",
8863
					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" )
8864
				},
8865
				only: {
8866
					"ui-selectmenu-button-open": "ui-corner-top",
8867
					"ui-selectmenu-button-closed": "ui-corner-all"
8868
				}
8869
 
8870
			}[ position ]
8871
		};
8872
	},
8873
 
8874
	_resolveClassesValues: function( classes, instance ) {
8875
		var result = {};
8876
		$.each( classes, function( key ) {
8877
			var current = instance.options.classes[ key ] || "";
8878
			current = $.trim( current.replace( controlgroupCornerRegex, "" ) );
8879
			result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " );
8880
		} );
8881
		return result;
8882
	},
8883
 
8884
	_setOption: function( key, value ) {
8885
		if ( key === "direction" ) {
8886
			this._removeClass( "ui-controlgroup-" + this.options.direction );
8887
		}
8888
 
8889
		this._super( key, value );
8890
		if ( key === "disabled" ) {
8891
			this._callChildMethod( value ? "disable" : "enable" );
8892
			return;
8893
		}
8894
 
8895
		this.refresh();
8896
	},
8897
 
8898
	refresh: function() {
8899
		var children,
8900
			that = this;
8901
 
8902
		this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction );
8903
 
8904
		if ( this.options.direction === "horizontal" ) {
8905
			this._addClass( null, "ui-helper-clearfix" );
8906
		}
8907
		this._initWidgets();
8908
 
8909
		children = this.childWidgets;
8910
 
8911
		// We filter here because we need to track all childWidgets not just the visible ones
8912
		if ( this.options.onlyVisible ) {
8913
			children = children.filter( ":visible" );
8914
		}
8915
 
8916
		if ( children.length ) {
8917
 
8918
			// We do this last because we need to make sure all enhancment is done
8919
			// before determining first and last
8920
			$.each( [ "first", "last" ], function( index, value ) {
8921
				var instance = children[ value ]().data( "ui-controlgroup-data" );
8922
 
8923
				if ( instance && that[ "_" + instance.widgetName + "Options" ] ) {
8924
					var options = that[ "_" + instance.widgetName + "Options" ](
8925
						children.length === 1 ? "only" : value
8926
					);
8927
					options.classes = that._resolveClassesValues( options.classes, instance );
8928
					instance.element[ instance.widgetName ]( options );
8929
				} else {
8930
					that._updateCornerClass( children[ value ](), value );
8931
				}
8932
			} );
8933
 
8934
			// Finally call the refresh method on each of the child widgets.
8935
			this._callChildMethod( "refresh" );
8936
		}
8937
	}
8938
} );
8939
 
8940
/*!
8941
 * jQuery UI Checkboxradio 1.12.1
8942
 * http://jqueryui.com
8943
 *
8944
 * Copyright jQuery Foundation and other contributors
8945
 * Released under the MIT license.
8946
 * http://jquery.org/license
8947
 */
8948
 
8949
//>>label: Checkboxradio
8950
//>>group: Widgets
8951
//>>description: Enhances a form with multiple themeable checkboxes or radio buttons.
8952
//>>docs: http://api.jqueryui.com/checkboxradio/
8953
//>>demos: http://jqueryui.com/checkboxradio/
8954
//>>css.structure: ../../themes/base/core.css
8955
//>>css.structure: ../../themes/base/button.css
8956
//>>css.structure: ../../themes/base/checkboxradio.css
8957
//>>css.theme: ../../themes/base/theme.css
8958
 
8959
 
8960
 
8961
$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
8962
	version: "1.12.1",
8963
	options: {
8964
		disabled: null,
8965
		label: null,
8966
		icon: true,
8967
		classes: {
8968
			"ui-checkboxradio-label": "ui-corner-all",
8969
			"ui-checkboxradio-icon": "ui-corner-all"
8970
		}
8971
	},
8972
 
8973
	_getCreateOptions: function() {
8974
		var disabled, labels;
8975
		var that = this;
8976
		var options = this._super() || {};
8977
 
8978
		// We read the type here, because it makes more sense to throw a element type error first,
8979
		// rather then the error for lack of a label. Often if its the wrong type, it
8980
		// won't have a label (e.g. calling on a div, btn, etc)
8981
		this._readType();
8982
 
8983
		labels = this.element.labels();
8984
 
8985
		// If there are multiple labels, use the last one
8986
		this.label = $( labels[ labels.length - 1 ] );
8987
		if ( !this.label.length ) {
8988
			$.error( "No label found for checkboxradio widget" );
8989
		}
8990
 
8991
		this.originalLabel = "";
8992
 
8993
		// We need to get the label text but this may also need to make sure it does not contain the
8994
		// input itself.
8995
		this.label.contents().not( this.element[ 0 ] ).each( function() {
8996
 
8997
			// The label contents could be text, html, or a mix. We concat each element to get a
8998
			// string representation of the label, without the input as part of it.
8999
			that.originalLabel += this.nodeType === 3 ? $( this ).text() : this.outerHTML;
9000
		} );
9001
 
9002
		// Set the label option if we found label text
9003
		if ( this.originalLabel ) {
9004
			options.label = this.originalLabel;
9005
		}
9006
 
9007
		disabled = this.element[ 0 ].disabled;
9008
		if ( disabled != null ) {
9009
			options.disabled = disabled;
9010
		}
9011
		return options;
9012
	},
9013
 
9014
	_create: function() {
9015
		var checked = this.element[ 0 ].checked;
9016
 
9017
		this._bindFormResetHandler();
9018
 
9019
		if ( this.options.disabled == null ) {
9020
			this.options.disabled = this.element[ 0 ].disabled;
9021
		}
9022
 
9023
		this._setOption( "disabled", this.options.disabled );
9024
		this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" );
9025
		this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" );
9026
 
9027
		if ( this.type === "radio" ) {
9028
			this._addClass( this.label, "ui-checkboxradio-radio-label" );
9029
		}
9030
 
9031
		if ( this.options.label && this.options.label !== this.originalLabel ) {
9032
			this._updateLabel();
9033
		} else if ( this.originalLabel ) {
9034
			this.options.label = this.originalLabel;
9035
		}
9036
 
9037
		this._enhance();
9038
 
9039
		if ( checked ) {
9040
			this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" );
9041
			if ( this.icon ) {
9042
				this._addClass( this.icon, null, "ui-state-hover" );
9043
			}
9044
		}
9045
 
9046
		this._on( {
9047
			change: "_toggleClasses",
9048
			focus: function() {
9049
				this._addClass( this.label, null, "ui-state-focus ui-visual-focus" );
9050
			},
9051
			blur: function() {
9052
				this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" );
9053
			}
9054
		} );
9055
	},
9056
 
9057
	_readType: function() {
9058
		var nodeName = this.element[ 0 ].nodeName.toLowerCase();
9059
		this.type = this.element[ 0 ].type;
9060
		if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) {
9061
			$.error( "Can't create checkboxradio on element.nodeName=" + nodeName +
9062
				" and element.type=" + this.type );
9063
		}
9064
	},
9065
 
9066
	// Support jQuery Mobile enhanced option
9067
	_enhance: function() {
9068
		this._updateIcon( this.element[ 0 ].checked );
9069
	},
9070
 
9071
	widget: function() {
9072
		return this.label;
9073
	},
9074
 
9075
	_getRadioGroup: function() {
9076
		var group;
9077
		var name = this.element[ 0 ].name;
9078
		var nameSelector = "input[name='" + $.ui.escapeSelector( name ) + "']";
9079
 
9080
		if ( !name ) {
9081
			return $( [] );
9082
		}
9083
 
9084
		if ( this.form.length ) {
9085
			group = $( this.form[ 0 ].elements ).filter( nameSelector );
9086
		} else {
9087
 
9088
			// Not inside a form, check all inputs that also are not inside a form
9089
			group = $( nameSelector ).filter( function() {
9090
				return $( this ).form().length === 0;
9091
			} );
9092
		}
9093
 
9094
		return group.not( this.element );
9095
	},
9096
 
9097
	_toggleClasses: function() {
9098
		var checked = this.element[ 0 ].checked;
9099
		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
9100
 
9101
		if ( this.options.icon && this.type === "checkbox" ) {
9102
			this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked )
9103
				._toggleClass( this.icon, null, "ui-icon-blank", !checked );
9104
		}
9105
 
9106
		if ( this.type === "radio" ) {
9107
			this._getRadioGroup()
9108
				.each( function() {
9109
					var instance = $( this ).checkboxradio( "instance" );
9110
 
9111
					if ( instance ) {
9112
						instance._removeClass( instance.label,
9113
							"ui-checkboxradio-checked", "ui-state-active" );
9114
					}
9115
				} );
9116
		}
9117
	},
9118
 
9119
	_destroy: function() {
9120
		this._unbindFormResetHandler();
9121
 
9122
		if ( this.icon ) {
9123
			this.icon.remove();
9124
			this.iconSpace.remove();
9125
		}
9126
	},
9127
 
9128
	_setOption: function( key, value ) {
9129
 
9130
		// We don't allow the value to be set to nothing
9131
		if ( key === "label" && !value ) {
9132
			return;
9133
		}
9134
 
9135
		this._super( key, value );
9136
 
9137
		if ( key === "disabled" ) {
9138
			this._toggleClass( this.label, null, "ui-state-disabled", value );
9139
			this.element[ 0 ].disabled = value;
9140
 
9141
			// Don't refresh when setting disabled
9142
			return;
9143
		}
9144
		this.refresh();
9145
	},
9146
 
9147
	_updateIcon: function( checked ) {
9148
		var toAdd = "ui-icon ui-icon-background ";
9149
 
9150
		if ( this.options.icon ) {
9151
			if ( !this.icon ) {
9152
				this.icon = $( "<span>" );
9153
				this.iconSpace = $( "<span> </span>" );
9154
				this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" );
9155
			}
9156
 
9157
			if ( this.type === "checkbox" ) {
9158
				toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank";
9159
				this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" );
9160
			} else {
9161
				toAdd += "ui-icon-blank";
9162
			}
9163
			this._addClass( this.icon, "ui-checkboxradio-icon", toAdd );
9164
			if ( !checked ) {
9165
				this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" );
9166
			}
9167
			this.icon.prependTo( this.label ).after( this.iconSpace );
9168
		} else if ( this.icon !== undefined ) {
9169
			this.icon.remove();
9170
			this.iconSpace.remove();
9171
			delete this.icon;
9172
		}
9173
	},
9174
 
9175
	_updateLabel: function() {
9176
 
9177
		// Remove the contents of the label ( minus the icon, icon space, and input )
9178
		var contents = this.label.contents().not( this.element[ 0 ] );
9179
		if ( this.icon ) {
9180
			contents = contents.not( this.icon[ 0 ] );
9181
		}
9182
		if ( this.iconSpace ) {
9183
			contents = contents.not( this.iconSpace[ 0 ] );
9184
		}
9185
		contents.remove();
9186
 
9187
		this.label.append( this.options.label );
9188
	},
9189
 
9190
	refresh: function() {
9191
		var checked = this.element[ 0 ].checked,
9192
			isDisabled = this.element[ 0 ].disabled;
9193
 
9194
		this._updateIcon( checked );
9195
		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
9196
		if ( this.options.label !== null ) {
9197
			this._updateLabel();
9198
		}
9199
 
9200
		if ( isDisabled !== this.options.disabled ) {
9201
			this._setOptions( { "disabled": isDisabled } );
9202
		}
9203
	}
9204
 
9205
} ] );
9206
 
9207
var widgetsCheckboxradio = $.ui.checkboxradio;
9208
 
9209
 
9210
/*!
9211
 * jQuery UI Button 1.12.1
9212
 * http://jqueryui.com
9213
 *
9214
 * Copyright jQuery Foundation and other contributors
9215
 * Released under the MIT license.
9216
 * http://jquery.org/license
9217
 */
9218
 
9219
//>>label: Button
9220
//>>group: Widgets
9221
//>>description: Enhances a form with themeable buttons.
9222
//>>docs: http://api.jqueryui.com/button/
9223
//>>demos: http://jqueryui.com/button/
9224
//>>css.structure: ../../themes/base/core.css
9225
//>>css.structure: ../../themes/base/button.css
9226
//>>css.theme: ../../themes/base/theme.css
9227
 
9228
 
9229
 
9230
$.widget( "ui.button", {
9231
	version: "1.12.1",
9232
	defaultElement: "<button>",
9233
	options: {
9234
		classes: {
9235
			"ui-button": "ui-corner-all"
9236
		},
9237
		disabled: null,
9238
		icon: null,
9239
		iconPosition: "beginning",
9240
		label: null,
9241
		showLabel: true
9242
	},
9243
 
9244
	_getCreateOptions: function() {
9245
		var disabled,
9246
 
9247
			// This is to support cases like in jQuery Mobile where the base widget does have
9248
			// an implementation of _getCreateOptions
9249
			options = this._super() || {};
9250
 
9251
		this.isInput = this.element.is( "input" );
9252
 
9253
		disabled = this.element[ 0 ].disabled;
9254
		if ( disabled != null ) {
9255
			options.disabled = disabled;
9256
		}
9257
 
9258
		this.originalLabel = this.isInput ? this.element.val() : this.element.html();
9259
		if ( this.originalLabel ) {
9260
			options.label = this.originalLabel;
9261
		}
9262
 
9263
		return options;
9264
	},
9265
 
9266
	_create: function() {
9267
		if ( !this.option.showLabel & !this.options.icon ) {
9268
			this.options.showLabel = true;
9269
		}
9270
 
9271
		// We have to check the option again here even though we did in _getCreateOptions,
9272
		// because null may have been passed on init which would override what was set in
9273
		// _getCreateOptions
9274
		if ( this.options.disabled == null ) {
9275
			this.options.disabled = this.element[ 0 ].disabled || false;
9276
		}
9277
 
9278
		this.hasTitle = !!this.element.attr( "title" );
9279
 
9280
		// Check to see if the label needs to be set or if its already correct
9281
		if ( this.options.label && this.options.label !== this.originalLabel ) {
9282
			if ( this.isInput ) {
9283
				this.element.val( this.options.label );
9284
			} else {
9285
				this.element.html( this.options.label );
9286
			}
9287
		}
9288
		this._addClass( "ui-button", "ui-widget" );
9289
		this._setOption( "disabled", this.options.disabled );
9290
		this._enhance();
9291
 
9292
		if ( this.element.is( "a" ) ) {
9293
			this._on( {
9294
				"keyup": function( event ) {
9295
					if ( event.keyCode === $.ui.keyCode.SPACE ) {
9296
						event.preventDefault();
9297
 
9298
						// Support: PhantomJS <= 1.9, IE 8 Only
9299
						// If a native click is available use it so we actually cause navigation
9300
						// otherwise just trigger a click event
9301
						if ( this.element[ 0 ].click ) {
9302
							this.element[ 0 ].click();
9303
						} else {
9304
							this.element.trigger( "click" );
9305
						}
9306
					}
9307
				}
9308
			} );
9309
		}
9310
	},
9311
 
9312
	_enhance: function() {
9313
		if ( !this.element.is( "button" ) ) {
9314
			this.element.attr( "role", "button" );
9315
		}
9316
 
9317
		if ( this.options.icon ) {
9318
			this._updateIcon( "icon", this.options.icon );
9319
			this._updateTooltip();
9320
		}
9321
	},
9322
 
9323
	_updateTooltip: function() {
9324
		this.title = this.element.attr( "title" );
9325
 
9326
		if ( !this.options.showLabel && !this.title ) {
9327
			this.element.attr( "title", this.options.label );
9328
		}
9329
	},
9330
 
9331
	_updateIcon: function( option, value ) {
9332
		var icon = option !== "iconPosition",
9333
			position = icon ? this.options.iconPosition : value,
9334
			displayBlock = position === "top" || position === "bottom";
9335
 
9336
		// Create icon
9337
		if ( !this.icon ) {
9338
			this.icon = $( "<span>" );
9339
 
9340
			this._addClass( this.icon, "ui-button-icon", "ui-icon" );
9341
 
9342
			if ( !this.options.showLabel ) {
9343
				this._addClass( "ui-button-icon-only" );
9344
			}
9345
		} else if ( icon ) {
9346
 
9347
			// If we are updating the icon remove the old icon class
9348
			this._removeClass( this.icon, null, this.options.icon );
9349
		}
9350
 
9351
		// If we are updating the icon add the new icon class
9352
		if ( icon ) {
9353
			this._addClass( this.icon, null, value );
9354
		}
9355
 
9356
		this._attachIcon( position );
9357
 
9358
		// If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove
9359
		// the iconSpace if there is one.
9360
		if ( displayBlock ) {
9361
			this._addClass( this.icon, null, "ui-widget-icon-block" );
9362
			if ( this.iconSpace ) {
9363
				this.iconSpace.remove();
9364
			}
9365
		} else {
9366
 
9367
			// Position is beginning or end so remove the ui-widget-icon-block class and add the
9368
			// space if it does not exist
9369
			if ( !this.iconSpace ) {
9370
				this.iconSpace = $( "<span> </span>" );
9371
				this._addClass( this.iconSpace, "ui-button-icon-space" );
9372
			}
9373
			this._removeClass( this.icon, null, "ui-wiget-icon-block" );
9374
			this._attachIconSpace( position );
9375
		}
9376
	},
9377
 
9378
	_destroy: function() {
9379
		this.element.removeAttr( "role" );
9380
 
9381
		if ( this.icon ) {
9382
			this.icon.remove();
9383
		}
9384
		if ( this.iconSpace ) {
9385
			this.iconSpace.remove();
9386
		}
9387
		if ( !this.hasTitle ) {
9388
			this.element.removeAttr( "title" );
9389
		}
9390
	},
9391
 
9392
	_attachIconSpace: function( iconPosition ) {
9393
		this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace );
9394
	},
9395
 
9396
	_attachIcon: function( iconPosition ) {
9397
		this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon );
9398
	},
9399
 
9400
	_setOptions: function( options ) {
9401
		var newShowLabel = options.showLabel === undefined ?
9402
				this.options.showLabel :
9403
				options.showLabel,
9404
			newIcon = options.icon === undefined ? this.options.icon : options.icon;
9405
 
9406
		if ( !newShowLabel && !newIcon ) {
9407
			options.showLabel = true;
9408
		}
9409
		this._super( options );
9410
	},
9411
 
9412
	_setOption: function( key, value ) {
9413
		if ( key === "icon" ) {
9414
			if ( value ) {
9415
				this._updateIcon( key, value );
9416
			} else if ( this.icon ) {
9417
				this.icon.remove();
9418
				if ( this.iconSpace ) {
9419
					this.iconSpace.remove();
9420
				}
9421
			}
9422
		}
9423
 
9424
		if ( key === "iconPosition" ) {
9425
			this._updateIcon( key, value );
9426
		}
9427
 
9428
		// Make sure we can't end up with a button that has neither text nor icon
9429
		if ( key === "showLabel" ) {
9430
				this._toggleClass( "ui-button-icon-only", null, !value );
9431
				this._updateTooltip();
9432
		}
9433
 
9434
		if ( key === "label" ) {
9435
			if ( this.isInput ) {
9436
				this.element.val( value );
9437
			} else {
9438
 
9439
				// If there is an icon, append it, else nothing then append the value
9440
				// this avoids removal of the icon when setting label text
9441
				this.element.html( value );
9442
				if ( this.icon ) {
9443
					this._attachIcon( this.options.iconPosition );
9444
					this._attachIconSpace( this.options.iconPosition );
9445
				}
9446
			}
9447
		}
9448
 
9449
		this._super( key, value );
9450
 
9451
		if ( key === "disabled" ) {
9452
			this._toggleClass( null, "ui-state-disabled", value );
9453
			this.element[ 0 ].disabled = value;
9454
			if ( value ) {
9455
				this.element.blur();
9456
			}
9457
		}
9458
	},
9459
 
9460
	refresh: function() {
9461
 
9462
		// Make sure to only check disabled if its an element that supports this otherwise
9463
		// check for the disabled class to determine state
9464
		var isDisabled = this.element.is( "input, button" ) ?
9465
			this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" );
9466
 
9467
		if ( isDisabled !== this.options.disabled ) {
9468
			this._setOptions( { disabled: isDisabled } );
9469
		}
9470
 
9471
		this._updateTooltip();
9472
	}
9473
} );
9474
 
9475
// DEPRECATED
9476
if ( $.uiBackCompat !== false ) {
9477
 
9478
	// Text and Icons options
9479
	$.widget( "ui.button", $.ui.button, {
9480
		options: {
9481
			text: true,
9482
			icons: {
9483
				primary: null,
9484
				secondary: null
9485
			}
9486
		},
9487
 
9488
		_create: function() {
9489
			if ( this.options.showLabel && !this.options.text ) {
9490
				this.options.showLabel = this.options.text;
9491
			}
9492
			if ( !this.options.showLabel && this.options.text ) {
9493
				this.options.text = this.options.showLabel;
9494
			}
9495
			if ( !this.options.icon && ( this.options.icons.primary ||
9496
					this.options.icons.secondary ) ) {
9497
				if ( this.options.icons.primary ) {
9498
					this.options.icon = this.options.icons.primary;
9499
				} else {
9500
					this.options.icon = this.options.icons.secondary;
9501
					this.options.iconPosition = "end";
9502
				}
9503
			} else if ( this.options.icon ) {
9504
				this.options.icons.primary = this.options.icon;
9505
			}
9506
			this._super();
9507
		},
9508
 
9509
		_setOption: function( key, value ) {
9510
			if ( key === "text" ) {
9511
				this._super( "showLabel", value );
9512
				return;
9513
			}
9514
			if ( key === "showLabel" ) {
9515
				this.options.text = value;
9516
			}
9517
			if ( key === "icon" ) {
9518
				this.options.icons.primary = value;
9519
			}
9520
			if ( key === "icons" ) {
9521
				if ( value.primary ) {
9522
					this._super( "icon", value.primary );
9523
					this._super( "iconPosition", "beginning" );
9524
				} else if ( value.secondary ) {
9525
					this._super( "icon", value.secondary );
9526
					this._super( "iconPosition", "end" );
9527
				}
9528
			}
9529
			this._superApply( arguments );
9530
		}
9531
	} );
9532
 
9533
	$.fn.button = ( function( orig ) {
9534
		return function() {
9535
			if ( !this.length || ( this.length && this[ 0 ].tagName !== "INPUT" ) ||
9536
					( this.length && this[ 0 ].tagName === "INPUT" && (
9537
						this.attr( "type" ) !== "checkbox" && this.attr( "type" ) !== "radio"
9538
					) ) ) {
9539
				return orig.apply( this, arguments );
9540
			}
9541
			if ( !$.ui.checkboxradio ) {
9542
				$.error( "Checkboxradio widget missing" );
9543
			}
9544
			if ( arguments.length === 0 ) {
9545
				return this.checkboxradio( {
9546
					"icon": false
9547
				} );
9548
			}
9549
			return this.checkboxradio.apply( this, arguments );
9550
		};
9551
	} )( $.fn.button );
9552
 
9553
	$.fn.buttonset = function() {
9554
		if ( !$.ui.controlgroup ) {
9555
			$.error( "Controlgroup widget missing" );
9556
		}
9557
		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) {
9558
			return this.controlgroup.apply( this,
9559
				[ arguments[ 0 ], "items.button", arguments[ 2 ] ] );
9560
		}
9561
		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) {
9562
			return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] );
9563
		}
9564
		if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) {
9565
			arguments[ 0 ].items = {
9566
				button: arguments[ 0 ].items
9567
			};
9568
		}
9569
		return this.controlgroup.apply( this, arguments );
9570
	};
9571
}
9572
 
9573
var widgetsButton = $.ui.button;
9574
 
9575
 
9576
// jscs:disable maximumLineLength
9577
/* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
9578
/*!
9579
 * jQuery UI Datepicker 1.12.1
9580
 * http://jqueryui.com
9581
 *
9582
 * Copyright jQuery Foundation and other contributors
9583
 * Released under the MIT license.
9584
 * http://jquery.org/license
9585
 */
9586
 
9587
//>>label: Datepicker
9588
//>>group: Widgets
9589
//>>description: Displays a calendar from an input or inline for selecting dates.
9590
//>>docs: http://api.jqueryui.com/datepicker/
9591
//>>demos: http://jqueryui.com/datepicker/
9592
//>>css.structure: ../../themes/base/core.css
9593
//>>css.structure: ../../themes/base/datepicker.css
9594
//>>css.theme: ../../themes/base/theme.css
9595
 
9596
 
9597
 
9598
$.extend( $.ui, { datepicker: { version: "1.12.1" } } );
9599
 
9600
var datepicker_instActive;
9601
 
9602
function datepicker_getZindex( elem ) {
9603
	var position, value;
9604
	while ( elem.length && elem[ 0 ] !== document ) {
9605
 
9606
		// Ignore z-index if position is set to a value where z-index is ignored by the browser
9607
		// This makes behavior of this function consistent across browsers
9608
		// WebKit always returns auto if the element is positioned
9609
		position = elem.css( "position" );
9610
		if ( position === "absolute" || position === "relative" || position === "fixed" ) {
9611
 
9612
			// IE returns 0 when zIndex is not specified
9613
			// other browsers return a string
9614
			// we ignore the case of nested elements with an explicit value of 0
9615
			// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
9616
			value = parseInt( elem.css( "zIndex" ), 10 );
9617
			if ( !isNaN( value ) && value !== 0 ) {
9618
				return value;
9619
			}
9620
		}
9621
		elem = elem.parent();
9622
	}
9623
 
9624
	return 0;
9625
}
9626
/* Date picker manager.
9627
   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
9628
   Settings for (groups of) date pickers are maintained in an instance object,
9629
   allowing multiple different settings on the same page. */
9630
 
9631
function Datepicker() {
9632
	this._curInst = null; // The current instance in use
9633
	this._keyEvent = false; // If the last event was a key event
9634
	this._disabledInputs = []; // List of date picker inputs that have been disabled
9635
	this._datepickerShowing = false; // True if the popup picker is showing , false if not
9636
	this._inDialog = false; // True if showing within a "dialog", false if not
9637
	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
9638
	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
9639
	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
9640
	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
9641
	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
9642
	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
9643
	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
9644
	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
9645
	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
9646
	this.regional = []; // Available regional settings, indexed by language code
9647
	this.regional[ "" ] = { // Default regional settings
9648
		closeText: "Done", // Display text for close link
9649
		prevText: "Prev", // Display text for previous month link
9650
		nextText: "Next", // Display text for next month link
9651
		currentText: "Today", // Display text for current month link
9652
		monthNames: [ "January","February","March","April","May","June",
9653
			"July","August","September","October","November","December" ], // Names of months for drop-down and formatting
9654
		monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting
9655
		dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting
9656
		dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting
9657
		dayNamesMin: [ "Su","Mo","Tu","We","Th","Fr","Sa" ], // Column headings for days starting at Sunday
9658
		weekHeader: "Wk", // Column header for week of the year
9659
		dateFormat: "mm/dd/yy", // See format options on parseDate
9660
		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
9661
		isRTL: false, // True if right-to-left language, false if left-to-right
9662
		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
9663
		yearSuffix: "" // Additional text to append to the year in the month headers
9664
	};
9665
	this._defaults = { // Global defaults for all the date picker instances
9666
		showOn: "focus", // "focus" for popup on focus,
9667
			// "button" for trigger button, or "both" for either
9668
		showAnim: "fadeIn", // Name of jQuery animation for popup
9669
		showOptions: {}, // Options for enhanced animations
9670
		defaultDate: null, // Used when field is blank: actual date,
9671
			// +/-number for offset from today, null for today
9672
		appendText: "", // Display text following the input box, e.g. showing the format
9673
		buttonText: "...", // Text for trigger button
9674
		buttonImage: "", // URL for trigger button image
9675
		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
9676
		hideIfNoPrevNext: false, // True to hide next/previous month links
9677
			// if not applicable, false to just disable them
9678
		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
9679
		gotoCurrent: false, // True if today link goes back to current selection instead
9680
		changeMonth: false, // True if month can be selected directly, false if only prev/next
9681
		changeYear: false, // True if year can be selected directly, false if only prev/next
9682
		yearRange: "c-10:c+10", // Range of years to display in drop-down,
9683
			// either relative to today's year (-nn:+nn), relative to currently displayed year
9684
			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
9685
		showOtherMonths: false, // True to show dates in other months, false to leave blank
9686
		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
9687
		showWeek: false, // True to show week of the year, false to not show it
9688
		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
9689
			// takes a Date and returns the number of the week for it
9690
		shortYearCutoff: "+10", // Short year values < this are in the current century,
9691
			// > this are in the previous century,
9692
			// string value starting with "+" for current year + value
9693
		minDate: null, // The earliest selectable date, or null for no limit
9694
		maxDate: null, // The latest selectable date, or null for no limit
9695
		duration: "fast", // Duration of display/closure
9696
		beforeShowDay: null, // Function that takes a date and returns an array with
9697
			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
9698
			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
9699
		beforeShow: null, // Function that takes an input field and
9700
			// returns a set of custom settings for the date picker
9701
		onSelect: null, // Define a callback function when a date is selected
9702
		onChangeMonthYear: null, // Define a callback function when the month or year is changed
9703
		onClose: null, // Define a callback function when the datepicker is closed
9704
		numberOfMonths: 1, // Number of months to show at a time
9705
		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
9706
		stepMonths: 1, // Number of months to step back/forward
9707
		stepBigMonths: 12, // Number of months to step back/forward for the big links
9708
		altField: "", // Selector for an alternate field to store selected dates into
9709
		altFormat: "", // The date format to use for the alternate field
9710
		constrainInput: true, // The input is constrained by the current date format
9711
		showButtonPanel: false, // True to show button panel, false to not show it
9712
		autoSize: false, // True to size the input for the date format, false to leave as is
9713
		disabled: false // The initial disabled state
9714
	};
9715
	$.extend( this._defaults, this.regional[ "" ] );
9716
	this.regional.en = $.extend( true, {}, this.regional[ "" ] );
9717
	this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
9718
	this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) );
9719
}
9720
 
9721
$.extend( Datepicker.prototype, {
9722
	/* Class name added to elements to indicate already configured with a date picker. */
9723
	markerClassName: "hasDatepicker",
9724
 
9725
	//Keep track of the maximum number of rows displayed (see #7043)
9726
	maxRows: 4,
9727
 
9728
	// TODO rename to "widget" when switching to widget factory
9729
	_widgetDatepicker: function() {
9730
		return this.dpDiv;
9731
	},
9732
 
9733
	/* Override the default settings for all instances of the date picker.
9734
	 * @param  settings  object - the new settings to use as defaults (anonymous object)
9735
	 * @return the manager object
9736
	 */
9737
	setDefaults: function( settings ) {
9738
		datepicker_extendRemove( this._defaults, settings || {} );
9739
		return this;
9740
	},
9741
 
9742
	/* Attach the date picker to a jQuery selection.
9743
	 * @param  target	element - the target input field or division or span
9744
	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
9745
	 */
9746
	_attachDatepicker: function( target, settings ) {
9747
		var nodeName, inline, inst;
9748
		nodeName = target.nodeName.toLowerCase();
9749
		inline = ( nodeName === "div" || nodeName === "span" );
9750
		if ( !target.id ) {
9751
			this.uuid += 1;
9752
			target.id = "dp" + this.uuid;
9753
		}
9754
		inst = this._newInst( $( target ), inline );
9755
		inst.settings = $.extend( {}, settings || {} );
9756
		if ( nodeName === "input" ) {
9757
			this._connectDatepicker( target, inst );
9758
		} else if ( inline ) {
9759
			this._inlineDatepicker( target, inst );
9760
		}
9761
	},
9762
 
9763
	/* Create a new instance object. */
9764
	_newInst: function( target, inline ) {
9765
		var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars
9766
		return { id: id, input: target, // associated target
9767
			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
9768
			drawMonth: 0, drawYear: 0, // month being drawn
9769
			inline: inline, // is datepicker inline or not
9770
			dpDiv: ( !inline ? this.dpDiv : // presentation div
9771
			datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) };
9772
	},
9773
 
9774
	/* Attach the date picker to an input field. */
9775
	_connectDatepicker: function( target, inst ) {
9776
		var input = $( target );
9777
		inst.append = $( [] );
9778
		inst.trigger = $( [] );
9779
		if ( input.hasClass( this.markerClassName ) ) {
9780
			return;
9781
		}
9782
		this._attachments( input, inst );
9783
		input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ).
9784
			on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp );
9785
		this._autoSize( inst );
9786
		$.data( target, "datepicker", inst );
9787
 
9788
		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
9789
		if ( inst.settings.disabled ) {
9790
			this._disableDatepicker( target );
9791
		}
9792
	},
9793
 
9794
	/* Make attachments based on settings. */
9795
	_attachments: function( input, inst ) {
9796
		var showOn, buttonText, buttonImage,
9797
			appendText = this._get( inst, "appendText" ),
9798
			isRTL = this._get( inst, "isRTL" );
9799
 
9800
		if ( inst.append ) {
9801
			inst.append.remove();
9802
		}
9803
		if ( appendText ) {
9804
			inst.append = $( "<span class='" + this._appendClass + "'>" + appendText + "</span>" );
9805
			input[ isRTL ? "before" : "after" ]( inst.append );
9806
		}
9807
 
9808
		input.off( "focus", this._showDatepicker );
9809
 
9810
		if ( inst.trigger ) {
9811
			inst.trigger.remove();
9812
		}
9813
 
9814
		showOn = this._get( inst, "showOn" );
9815
		if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field
9816
			input.on( "focus", this._showDatepicker );
9817
		}
9818
		if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked
9819
			buttonText = this._get( inst, "buttonText" );
9820
			buttonImage = this._get( inst, "buttonImage" );
9821
			inst.trigger = $( this._get( inst, "buttonImageOnly" ) ?
9822
				$( "<img/>" ).addClass( this._triggerClass ).
9823
					attr( { src: buttonImage, alt: buttonText, title: buttonText } ) :
9824
				$( "<button type='button'></button>" ).addClass( this._triggerClass ).
9825
					html( !buttonImage ? buttonText : $( "<img/>" ).attr(
9826
					{ src:buttonImage, alt:buttonText, title:buttonText } ) ) );
9827
			input[ isRTL ? "before" : "after" ]( inst.trigger );
9828
			inst.trigger.on( "click", function() {
9829
				if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) {
9830
					$.datepicker._hideDatepicker();
9831
				} else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) {
9832
					$.datepicker._hideDatepicker();
9833
					$.datepicker._showDatepicker( input[ 0 ] );
9834
				} else {
9835
					$.datepicker._showDatepicker( input[ 0 ] );
9836
				}
9837
				return false;
9838
			} );
9839
		}
9840
	},
9841
 
9842
	/* Apply the maximum length for the date format. */
9843
	_autoSize: function( inst ) {
9844
		if ( this._get( inst, "autoSize" ) && !inst.inline ) {
9845
			var findMax, max, maxI, i,
9846
				date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits
9847
				dateFormat = this._get( inst, "dateFormat" );
9848
 
9849
			if ( dateFormat.match( /[DM]/ ) ) {
9850
				findMax = function( names ) {
9851
					max = 0;
9852
					maxI = 0;
9853
					for ( i = 0; i < names.length; i++ ) {
9854
						if ( names[ i ].length > max ) {
9855
							max = names[ i ].length;
9856
							maxI = i;
9857
						}
9858
					}
9859
					return maxI;
9860
				};
9861
				date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ?
9862
					"monthNames" : "monthNamesShort" ) ) ) );
9863
				date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ?
9864
					"dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() );
9865
			}
9866
			inst.input.attr( "size", this._formatDate( inst, date ).length );
9867
		}
9868
	},
9869
 
9870
	/* Attach an inline date picker to a div. */
9871
	_inlineDatepicker: function( target, inst ) {
9872
		var divSpan = $( target );
9873
		if ( divSpan.hasClass( this.markerClassName ) ) {
9874
			return;
9875
		}
9876
		divSpan.addClass( this.markerClassName ).append( inst.dpDiv );
9877
		$.data( target, "datepicker", inst );
9878
		this._setDate( inst, this._getDefaultDate( inst ), true );
9879
		this._updateDatepicker( inst );
9880
		this._updateAlternate( inst );
9881
 
9882
		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
9883
		if ( inst.settings.disabled ) {
9884
			this._disableDatepicker( target );
9885
		}
9886
 
9887
		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
9888
		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
9889
		inst.dpDiv.css( "display", "block" );
9890
	},
9891
 
9892
	/* Pop-up the date picker in a "dialog" box.
9893
	 * @param  input element - ignored
9894
	 * @param  date	string or Date - the initial date to display
9895
	 * @param  onSelect  function - the function to call when a date is selected
9896
	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
9897
	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
9898
	 *					event - with x/y coordinates or
9899
	 *					leave empty for default (screen centre)
9900
	 * @return the manager object
9901
	 */
9902
	_dialogDatepicker: function( input, date, onSelect, settings, pos ) {
9903
		var id, browserWidth, browserHeight, scrollX, scrollY,
9904
			inst = this._dialogInst; // internal instance
9905
 
9906
		if ( !inst ) {
9907
			this.uuid += 1;
9908
			id = "dp" + this.uuid;
9909
			this._dialogInput = $( "<input type='text' id='" + id +
9910
				"' style='position: absolute; top: -100px; width: 0px;'/>" );
9911
			this._dialogInput.on( "keydown", this._doKeyDown );
9912
			$( "body" ).append( this._dialogInput );
9913
			inst = this._dialogInst = this._newInst( this._dialogInput, false );
9914
			inst.settings = {};
9915
			$.data( this._dialogInput[ 0 ], "datepicker", inst );
9916
		}
9917
		datepicker_extendRemove( inst.settings, settings || {} );
9918
		date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date );
9919
		this._dialogInput.val( date );
9920
 
9921
		this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null );
9922
		if ( !this._pos ) {
9923
			browserWidth = document.documentElement.clientWidth;
9924
			browserHeight = document.documentElement.clientHeight;
9925
			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
9926
			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
9927
			this._pos = // should use actual width/height below
9928
				[ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ];
9929
		}
9930
 
9931
		// Move input on screen for focus, but hidden behind dialog
9932
		this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" );
9933
		inst.settings.onSelect = onSelect;
9934
		this._inDialog = true;
9935
		this.dpDiv.addClass( this._dialogClass );
9936
		this._showDatepicker( this._dialogInput[ 0 ] );
9937
		if ( $.blockUI ) {
9938
			$.blockUI( this.dpDiv );
9939
		}
9940
		$.data( this._dialogInput[ 0 ], "datepicker", inst );
9941
		return this;
9942
	},
9943
 
9944
	/* Detach a datepicker from its control.
9945
	 * @param  target	element - the target input field or division or span
9946
	 */
9947
	_destroyDatepicker: function( target ) {
9948
		var nodeName,
9949
			$target = $( target ),
9950
			inst = $.data( target, "datepicker" );
9951
 
9952
		if ( !$target.hasClass( this.markerClassName ) ) {
9953
			return;
9954
		}
9955
 
9956
		nodeName = target.nodeName.toLowerCase();
9957
		$.removeData( target, "datepicker" );
9958
		if ( nodeName === "input" ) {
9959
			inst.append.remove();
9960
			inst.trigger.remove();
9961
			$target.removeClass( this.markerClassName ).
9962
				off( "focus", this._showDatepicker ).
9963
				off( "keydown", this._doKeyDown ).
9964
				off( "keypress", this._doKeyPress ).
9965
				off( "keyup", this._doKeyUp );
9966
		} else if ( nodeName === "div" || nodeName === "span" ) {
9967
			$target.removeClass( this.markerClassName ).empty();
9968
		}
9969
 
9970
		if ( datepicker_instActive === inst ) {
9971
			datepicker_instActive = null;
9972
		}
9973
	},
9974
 
9975
	/* Enable the date picker to a jQuery selection.
9976
	 * @param  target	element - the target input field or division or span
9977
	 */
9978
	_enableDatepicker: function( target ) {
9979
		var nodeName, inline,
9980
			$target = $( target ),
9981
			inst = $.data( target, "datepicker" );
9982
 
9983
		if ( !$target.hasClass( this.markerClassName ) ) {
9984
			return;
9985
		}
9986
 
9987
		nodeName = target.nodeName.toLowerCase();
9988
		if ( nodeName === "input" ) {
9989
			target.disabled = false;
9990
			inst.trigger.filter( "button" ).
9991
				each( function() { this.disabled = false; } ).end().
9992
				filter( "img" ).css( { opacity: "1.0", cursor: "" } );
9993
		} else if ( nodeName === "div" || nodeName === "span" ) {
9994
			inline = $target.children( "." + this._inlineClass );
9995
			inline.children().removeClass( "ui-state-disabled" );
9996
			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
9997
				prop( "disabled", false );
9998
		}
9999
		this._disabledInputs = $.map( this._disabledInputs,
10000
			function( value ) { return ( value === target ? null : value ); } ); // delete entry
10001
	},
10002
 
10003
	/* Disable the date picker to a jQuery selection.
10004
	 * @param  target	element - the target input field or division or span
10005
	 */
10006
	_disableDatepicker: function( target ) {
10007
		var nodeName, inline,
10008
			$target = $( target ),
10009
			inst = $.data( target, "datepicker" );
10010
 
10011
		if ( !$target.hasClass( this.markerClassName ) ) {
10012
			return;
10013
		}
10014
 
10015
		nodeName = target.nodeName.toLowerCase();
10016
		if ( nodeName === "input" ) {
10017
			target.disabled = true;
10018
			inst.trigger.filter( "button" ).
10019
				each( function() { this.disabled = true; } ).end().
10020
				filter( "img" ).css( { opacity: "0.5", cursor: "default" } );
10021
		} else if ( nodeName === "div" || nodeName === "span" ) {
10022
			inline = $target.children( "." + this._inlineClass );
10023
			inline.children().addClass( "ui-state-disabled" );
10024
			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
10025
				prop( "disabled", true );
10026
		}
10027
		this._disabledInputs = $.map( this._disabledInputs,
10028
			function( value ) { return ( value === target ? null : value ); } ); // delete entry
10029
		this._disabledInputs[ this._disabledInputs.length ] = target;
10030
	},
10031
 
10032
	/* Is the first field in a jQuery collection disabled as a datepicker?
10033
	 * @param  target	element - the target input field or division or span
10034
	 * @return boolean - true if disabled, false if enabled
10035
	 */
10036
	_isDisabledDatepicker: function( target ) {
10037
		if ( !target ) {
10038
			return false;
10039
		}
10040
		for ( var i = 0; i < this._disabledInputs.length; i++ ) {
10041
			if ( this._disabledInputs[ i ] === target ) {
10042
				return true;
10043
			}
10044
		}
10045
		return false;
10046
	},
10047
 
10048
	/* Retrieve the instance data for the target control.
10049
	 * @param  target  element - the target input field or division or span
10050
	 * @return  object - the associated instance data
10051
	 * @throws  error if a jQuery problem getting data
10052
	 */
10053
	_getInst: function( target ) {
10054
		try {
10055
			return $.data( target, "datepicker" );
10056
		}
10057
		catch ( err ) {
10058
			throw "Missing instance data for this datepicker";
10059
		}
10060
	},
10061
 
10062
	/* Update or retrieve the settings for a date picker attached to an input field or division.
10063
	 * @param  target  element - the target input field or division or span
10064
	 * @param  name	object - the new settings to update or
10065
	 *				string - the name of the setting to change or retrieve,
10066
	 *				when retrieving also "all" for all instance settings or
10067
	 *				"defaults" for all global defaults
10068
	 * @param  value   any - the new value for the setting
10069
	 *				(omit if above is an object or to retrieve a value)
10070
	 */
10071
	_optionDatepicker: function( target, name, value ) {
10072
		var settings, date, minDate, maxDate,
10073
			inst = this._getInst( target );
10074
 
10075
		if ( arguments.length === 2 && typeof name === "string" ) {
10076
			return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) :
10077
				( inst ? ( name === "all" ? $.extend( {}, inst.settings ) :
10078
				this._get( inst, name ) ) : null ) );
10079
		}
10080
 
10081
		settings = name || {};
10082
		if ( typeof name === "string" ) {
10083
			settings = {};
10084
			settings[ name ] = value;
10085
		}
10086
 
10087
		if ( inst ) {
10088
			if ( this._curInst === inst ) {
10089
				this._hideDatepicker();
10090
			}
10091
 
10092
			date = this._getDateDatepicker( target, true );
10093
			minDate = this._getMinMaxDate( inst, "min" );
10094
			maxDate = this._getMinMaxDate( inst, "max" );
10095
			datepicker_extendRemove( inst.settings, settings );
10096
 
10097
			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
10098
			if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) {
10099
				inst.settings.minDate = this._formatDate( inst, minDate );
10100
			}
10101
			if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) {
10102
				inst.settings.maxDate = this._formatDate( inst, maxDate );
10103
			}
10104
			if ( "disabled" in settings ) {
10105
				if ( settings.disabled ) {
10106
					this._disableDatepicker( target );
10107
				} else {
10108
					this._enableDatepicker( target );
10109
				}
10110
			}
10111
			this._attachments( $( target ), inst );
10112
			this._autoSize( inst );
10113
			this._setDate( inst, date );
10114
			this._updateAlternate( inst );
10115
			this._updateDatepicker( inst );
10116
		}
10117
	},
10118
 
10119
	// Change method deprecated
10120
	_changeDatepicker: function( target, name, value ) {
10121
		this._optionDatepicker( target, name, value );
10122
	},
10123
 
10124
	/* Redraw the date picker attached to an input field or division.
10125
	 * @param  target  element - the target input field or division or span
10126
	 */
10127
	_refreshDatepicker: function( target ) {
10128
		var inst = this._getInst( target );
10129
		if ( inst ) {
10130
			this._updateDatepicker( inst );
10131
		}
10132
	},
10133
 
10134
	/* Set the dates for a jQuery selection.
10135
	 * @param  target element - the target input field or division or span
10136
	 * @param  date	Date - the new date
10137
	 */
10138
	_setDateDatepicker: function( target, date ) {
10139
		var inst = this._getInst( target );
10140
		if ( inst ) {
10141
			this._setDate( inst, date );
10142
			this._updateDatepicker( inst );
10143
			this._updateAlternate( inst );
10144
		}
10145
	},
10146
 
10147
	/* Get the date(s) for the first entry in a jQuery selection.
10148
	 * @param  target element - the target input field or division or span
10149
	 * @param  noDefault boolean - true if no default date is to be used
10150
	 * @return Date - the current date
10151
	 */
10152
	_getDateDatepicker: function( target, noDefault ) {
10153
		var inst = this._getInst( target );
10154
		if ( inst && !inst.inline ) {
10155
			this._setDateFromField( inst, noDefault );
10156
		}
10157
		return ( inst ? this._getDate( inst ) : null );
10158
	},
10159
 
10160
	/* Handle keystrokes. */
10161
	_doKeyDown: function( event ) {
10162
		var onSelect, dateStr, sel,
10163
			inst = $.datepicker._getInst( event.target ),
10164
			handled = true,
10165
			isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" );
10166
 
10167
		inst._keyEvent = true;
10168
		if ( $.datepicker._datepickerShowing ) {
10169
			switch ( event.keyCode ) {
10170
				case 9: $.datepicker._hideDatepicker();
10171
						handled = false;
10172
						break; // hide on tab out
10173
				case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." +
10174
									$.datepicker._currentClass + ")", inst.dpDiv );
10175
						if ( sel[ 0 ] ) {
10176
							$.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] );
10177
						}
10178
 
10179
						onSelect = $.datepicker._get( inst, "onSelect" );
10180
						if ( onSelect ) {
10181
							dateStr = $.datepicker._formatDate( inst );
10182
 
10183
							// Trigger custom callback
10184
							onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );
10185
						} else {
10186
							$.datepicker._hideDatepicker();
10187
						}
10188
 
10189
						return false; // don't submit the form
10190
				case 27: $.datepicker._hideDatepicker();
10191
						break; // hide on escape
10192
				case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
10193
							-$.datepicker._get( inst, "stepBigMonths" ) :
10194
							-$.datepicker._get( inst, "stepMonths" ) ), "M" );
10195
						break; // previous month/year on page up/+ ctrl
10196
				case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
10197
							+$.datepicker._get( inst, "stepBigMonths" ) :
10198
							+$.datepicker._get( inst, "stepMonths" ) ), "M" );
10199
						break; // next month/year on page down/+ ctrl
10200
				case 35: if ( event.ctrlKey || event.metaKey ) {
10201
							$.datepicker._clearDate( event.target );
10202
						}
10203
						handled = event.ctrlKey || event.metaKey;
10204
						break; // clear on ctrl or command +end
10205
				case 36: if ( event.ctrlKey || event.metaKey ) {
10206
							$.datepicker._gotoToday( event.target );
10207
						}
10208
						handled = event.ctrlKey || event.metaKey;
10209
						break; // current on ctrl or command +home
10210
				case 37: if ( event.ctrlKey || event.metaKey ) {
10211
							$.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" );
10212
						}
10213
						handled = event.ctrlKey || event.metaKey;
10214
 
10215
						// -1 day on ctrl or command +left
10216
						if ( event.originalEvent.altKey ) {
10217
							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
10218
								-$.datepicker._get( inst, "stepBigMonths" ) :
10219
								-$.datepicker._get( inst, "stepMonths" ) ), "M" );
10220
						}
10221
 
10222
						// next month/year on alt +left on Mac
10223
						break;
10224
				case 38: if ( event.ctrlKey || event.metaKey ) {
10225
							$.datepicker._adjustDate( event.target, -7, "D" );
10226
						}
10227
						handled = event.ctrlKey || event.metaKey;
10228
						break; // -1 week on ctrl or command +up
10229
				case 39: if ( event.ctrlKey || event.metaKey ) {
10230
							$.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" );
10231
						}
10232
						handled = event.ctrlKey || event.metaKey;
10233
 
10234
						// +1 day on ctrl or command +right
10235
						if ( event.originalEvent.altKey ) {
10236
							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
10237
								+$.datepicker._get( inst, "stepBigMonths" ) :
10238
								+$.datepicker._get( inst, "stepMonths" ) ), "M" );
10239
						}
10240
 
10241
						// next month/year on alt +right
10242
						break;
10243
				case 40: if ( event.ctrlKey || event.metaKey ) {
10244
							$.datepicker._adjustDate( event.target, +7, "D" );
10245
						}
10246
						handled = event.ctrlKey || event.metaKey;
10247
						break; // +1 week on ctrl or command +down
10248
				default: handled = false;
10249
			}
10250
		} else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home
10251
			$.datepicker._showDatepicker( this );
10252
		} else {
10253
			handled = false;
10254
		}
10255
 
10256
		if ( handled ) {
10257
			event.preventDefault();
10258
			event.stopPropagation();
10259
		}
10260
	},
10261
 
10262
	/* Filter entered characters - based on date format. */
10263
	_doKeyPress: function( event ) {
10264
		var chars, chr,
10265
			inst = $.datepicker._getInst( event.target );
10266
 
10267
		if ( $.datepicker._get( inst, "constrainInput" ) ) {
10268
			chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) );
10269
			chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode );
10270
			return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 );
10271
		}
10272
	},
10273
 
10274
	/* Synchronise manual entry and field/alternate field. */
10275
	_doKeyUp: function( event ) {
10276
		var date,
10277
			inst = $.datepicker._getInst( event.target );
10278
 
10279
		if ( inst.input.val() !== inst.lastVal ) {
10280
			try {
10281
				date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
10282
					( inst.input ? inst.input.val() : null ),
10283
					$.datepicker._getFormatConfig( inst ) );
10284
 
10285
				if ( date ) { // only if valid
10286
					$.datepicker._setDateFromField( inst );
10287
					$.datepicker._updateAlternate( inst );
10288
					$.datepicker._updateDatepicker( inst );
10289
				}
10290
			}
10291
			catch ( err ) {
10292
			}
10293
		}
10294
		return true;
10295
	},
10296
 
10297
	/* Pop-up the date picker for a given input field.
10298
	 * If false returned from beforeShow event handler do not show.
10299
	 * @param  input  element - the input field attached to the date picker or
10300
	 *					event - if triggered by focus
10301
	 */
10302
	_showDatepicker: function( input ) {
10303
		input = input.target || input;
10304
		if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger
10305
			input = $( "input", input.parentNode )[ 0 ];
10306
		}
10307
 
10308
		if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here
10309
			return;
10310
		}
10311
 
10312
		var inst, beforeShow, beforeShowSettings, isFixed,
10313
			offset, showAnim, duration;
10314
 
10315
		inst = $.datepicker._getInst( input );
10316
		if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) {
10317
			$.datepicker._curInst.dpDiv.stop( true, true );
10318
			if ( inst && $.datepicker._datepickerShowing ) {
10319
				$.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] );
10320
			}
10321
		}
10322
 
10323
		beforeShow = $.datepicker._get( inst, "beforeShow" );
10324
		beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {};
10325
		if ( beforeShowSettings === false ) {
10326
			return;
10327
		}
10328
		datepicker_extendRemove( inst.settings, beforeShowSettings );
10329
 
10330
		inst.lastVal = null;
10331
		$.datepicker._lastInput = input;
10332
		$.datepicker._setDateFromField( inst );
10333
 
10334
		if ( $.datepicker._inDialog ) { // hide cursor
10335
			input.value = "";
10336
		}
10337
		if ( !$.datepicker._pos ) { // position below input
10338
			$.datepicker._pos = $.datepicker._findPos( input );
10339
			$.datepicker._pos[ 1 ] += input.offsetHeight; // add the height
10340
		}
10341
 
10342
		isFixed = false;
10343
		$( input ).parents().each( function() {
10344
			isFixed |= $( this ).css( "position" ) === "fixed";
10345
			return !isFixed;
10346
		} );
10347
 
10348
		offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] };
10349
		$.datepicker._pos = null;
10350
 
10351
		//to avoid flashes on Firefox
10352
		inst.dpDiv.empty();
10353
 
10354
		// determine sizing offscreen
10355
		inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } );
10356
		$.datepicker._updateDatepicker( inst );
10357
 
10358
		// fix width for dynamic number of date pickers
10359
		// and adjust position before showing
10360
		offset = $.datepicker._checkOffset( inst, offset, isFixed );
10361
		inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ?
10362
			"static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none",
10363
			left: offset.left + "px", top: offset.top + "px" } );
10364
 
10365
		if ( !inst.inline ) {
10366
			showAnim = $.datepicker._get( inst, "showAnim" );
10367
			duration = $.datepicker._get( inst, "duration" );
10368
			inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
10369
			$.datepicker._datepickerShowing = true;
10370
 
10371
			if ( $.effects && $.effects.effect[ showAnim ] ) {
10372
				inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration );
10373
			} else {
10374
				inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null );
10375
			}
10376
 
10377
			if ( $.datepicker._shouldFocusInput( inst ) ) {
10378
				inst.input.trigger( "focus" );
10379
			}
10380
 
10381
			$.datepicker._curInst = inst;
10382
		}
10383
	},
10384
 
10385
	/* Generate the date picker content. */
10386
	_updateDatepicker: function( inst ) {
10387
		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
10388
		datepicker_instActive = inst; // for delegate hover events
10389
		inst.dpDiv.empty().append( this._generateHTML( inst ) );
10390
		this._attachHandlers( inst );
10391
 
10392
		var origyearshtml,
10393
			numMonths = this._getNumberOfMonths( inst ),
10394
			cols = numMonths[ 1 ],
10395
			width = 17,
10396
			activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
10397
 
10398
		if ( activeCell.length > 0 ) {
10399
			datepicker_handleMouseover.apply( activeCell.get( 0 ) );
10400
		}
10401
 
10402
		inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" );
10403
		if ( cols > 1 ) {
10404
			inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" );
10405
		}
10406
		inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) +
10407
			"Class" ]( "ui-datepicker-multi" );
10408
		inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) +
10409
			"Class" ]( "ui-datepicker-rtl" );
10410
 
10411
		if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
10412
			inst.input.trigger( "focus" );
10413
		}
10414
 
10415
		// Deffered render of the years select (to avoid flashes on Firefox)
10416
		if ( inst.yearshtml ) {
10417
			origyearshtml = inst.yearshtml;
10418
			setTimeout( function() {
10419
 
10420
				//assure that inst.yearshtml didn't change.
10421
				if ( origyearshtml === inst.yearshtml && inst.yearshtml ) {
10422
					inst.dpDiv.find( "select.ui-datepicker-year:first" ).replaceWith( inst.yearshtml );
10423
				}
10424
				origyearshtml = inst.yearshtml = null;
10425
			}, 0 );
10426
		}
10427
	},
10428
 
10429
	// #6694 - don't focus the input if it's already focused
10430
	// this breaks the change event in IE
10431
	// Support: IE and jQuery <1.9
10432
	_shouldFocusInput: function( inst ) {
10433
		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
10434
	},
10435
 
10436
	/* Check positioning to remain on screen. */
10437
	_checkOffset: function( inst, offset, isFixed ) {
10438
		var dpWidth = inst.dpDiv.outerWidth(),
10439
			dpHeight = inst.dpDiv.outerHeight(),
10440
			inputWidth = inst.input ? inst.input.outerWidth() : 0,
10441
			inputHeight = inst.input ? inst.input.outerHeight() : 0,
10442
			viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ),
10443
			viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() );
10444
 
10445
		offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 );
10446
		offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0;
10447
		offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0;
10448
 
10449
		// Now check if datepicker is showing outside window viewport - move to a better place if so.
10450
		offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ?
10451
			Math.abs( offset.left + dpWidth - viewWidth ) : 0 );
10452
		offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ?
10453
			Math.abs( dpHeight + inputHeight ) : 0 );
10454
 
10455
		return offset;
10456
	},
10457
 
10458
	/* Find an object's position on the screen. */
10459
	_findPos: function( obj ) {
10460
		var position,
10461
			inst = this._getInst( obj ),
10462
			isRTL = this._get( inst, "isRTL" );
10463
 
10464
		while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden( obj ) ) ) {
10465
			obj = obj[ isRTL ? "previousSibling" : "nextSibling" ];
10466
		}
10467
 
10468
		position = $( obj ).offset();
10469
		return [ position.left, position.top ];
10470
	},
10471
 
10472
	/* Hide the date picker from view.
10473
	 * @param  input  element - the input field attached to the date picker
10474
	 */
10475
	_hideDatepicker: function( input ) {
10476
		var showAnim, duration, postProcess, onClose,
10477
			inst = this._curInst;
10478
 
10479
		if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) {
10480
			return;
10481
		}
10482
 
10483
		if ( this._datepickerShowing ) {
10484
			showAnim = this._get( inst, "showAnim" );
10485
			duration = this._get( inst, "duration" );
10486
			postProcess = function() {
10487
				$.datepicker._tidyDialog( inst );
10488
			};
10489
 
10490
			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
10491
			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
10492
				inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess );
10493
			} else {
10494
				inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" :
10495
					( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess );
10496
			}
10497
 
10498
			if ( !showAnim ) {
10499
				postProcess();
10500
			}
10501
			this._datepickerShowing = false;
10502
 
10503
			onClose = this._get( inst, "onClose" );
10504
			if ( onClose ) {
10505
				onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] );
10506
			}
10507
 
10508
			this._lastInput = null;
10509
			if ( this._inDialog ) {
10510
				this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } );
10511
				if ( $.blockUI ) {
10512
					$.unblockUI();
10513
					$( "body" ).append( this.dpDiv );
10514
				}
10515
			}
10516
			this._inDialog = false;
10517
		}
10518
	},
10519
 
10520
	/* Tidy up after a dialog display. */
10521
	_tidyDialog: function( inst ) {
10522
		inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" );
10523
	},
10524
 
10525
	/* Close date picker if clicked elsewhere. */
10526
	_checkExternalClick: function( event ) {
10527
		if ( !$.datepicker._curInst ) {
10528
			return;
10529
		}
10530
 
10531
		var $target = $( event.target ),
10532
			inst = $.datepicker._getInst( $target[ 0 ] );
10533
 
10534
		if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId &&
10535
				$target.parents( "#" + $.datepicker._mainDivId ).length === 0 &&
10536
				!$target.hasClass( $.datepicker.markerClassName ) &&
10537
				!$target.closest( "." + $.datepicker._triggerClass ).length &&
10538
				$.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) ||
10539
			( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) {
10540
				$.datepicker._hideDatepicker();
10541
		}
10542
	},
10543
 
10544
	/* Adjust one of the date sub-fields. */
10545
	_adjustDate: function( id, offset, period ) {
10546
		var target = $( id ),
10547
			inst = this._getInst( target[ 0 ] );
10548
 
10549
		if ( this._isDisabledDatepicker( target[ 0 ] ) ) {
10550
			return;
10551
		}
10552
		this._adjustInstDate( inst, offset +
10553
			( period === "M" ? this._get( inst, "showCurrentAtPos" ) : 0 ), // undo positioning
10554
			period );
10555
		this._updateDatepicker( inst );
10556
	},
10557
 
10558
	/* Action for current link. */
10559
	_gotoToday: function( id ) {
10560
		var date,
10561
			target = $( id ),
10562
			inst = this._getInst( target[ 0 ] );
10563
 
10564
		if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) {
10565
			inst.selectedDay = inst.currentDay;
10566
			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
10567
			inst.drawYear = inst.selectedYear = inst.currentYear;
10568
		} else {
10569
			date = new Date();
10570
			inst.selectedDay = date.getDate();
10571
			inst.drawMonth = inst.selectedMonth = date.getMonth();
10572
			inst.drawYear = inst.selectedYear = date.getFullYear();
10573
		}
10574
		this._notifyChange( inst );
10575
		this._adjustDate( target );
10576
	},
10577
 
10578
	/* Action for selecting a new month/year. */
10579
	_selectMonthYear: function( id, select, period ) {
10580
		var target = $( id ),
10581
			inst = this._getInst( target[ 0 ] );
10582
 
10583
		inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] =
10584
		inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] =
10585
			parseInt( select.options[ select.selectedIndex ].value, 10 );
10586
 
10587
		this._notifyChange( inst );
10588
		this._adjustDate( target );
10589
	},
10590
 
10591
	/* Action for selecting a day. */
10592
	_selectDay: function( id, month, year, td ) {
10593
		var inst,
10594
			target = $( id );
10595
 
10596
		if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) {
10597
			return;
10598
		}
10599
 
10600
		inst = this._getInst( target[ 0 ] );
10601
		inst.selectedDay = inst.currentDay = $( "a", td ).html();
10602
		inst.selectedMonth = inst.currentMonth = month;
10603
		inst.selectedYear = inst.currentYear = year;
10604
		this._selectDate( id, this._formatDate( inst,
10605
			inst.currentDay, inst.currentMonth, inst.currentYear ) );
10606
	},
10607
 
10608
	/* Erase the input field and hide the date picker. */
10609
	_clearDate: function( id ) {
10610
		var target = $( id );
10611
		this._selectDate( target, "" );
10612
	},
10613
 
10614
	/* Update the input field with the selected date. */
10615
	_selectDate: function( id, dateStr ) {
10616
		var onSelect,
10617
			target = $( id ),
10618
			inst = this._getInst( target[ 0 ] );
10619
 
10620
		dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) );
10621
		if ( inst.input ) {
10622
			inst.input.val( dateStr );
10623
		}
10624
		this._updateAlternate( inst );
10625
 
10626
		onSelect = this._get( inst, "onSelect" );
10627
		if ( onSelect ) {
10628
			onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );  // trigger custom callback
10629
		} else if ( inst.input ) {
10630
			inst.input.trigger( "change" ); // fire the change event
10631
		}
10632
 
10633
		if ( inst.inline ) {
10634
			this._updateDatepicker( inst );
10635
		} else {
10636
			this._hideDatepicker();
10637
			this._lastInput = inst.input[ 0 ];
10638
			if ( typeof( inst.input[ 0 ] ) !== "object" ) {
10639
				inst.input.trigger( "focus" ); // restore focus
10640
			}
10641
			this._lastInput = null;
10642
		}
10643
	},
10644
 
10645
	/* Update any alternate field to synchronise with the main field. */
10646
	_updateAlternate: function( inst ) {
10647
		var altFormat, date, dateStr,
10648
			altField = this._get( inst, "altField" );
10649
 
10650
		if ( altField ) { // update alternate field too
10651
			altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" );
10652
			date = this._getDate( inst );
10653
			dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) );
10654
			$( altField ).val( dateStr );
10655
		}
10656
	},
10657
 
10658
	/* Set as beforeShowDay function to prevent selection of weekends.
10659
	 * @param  date  Date - the date to customise
10660
	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
10661
	 */
10662
	noWeekends: function( date ) {
10663
		var day = date.getDay();
10664
		return [ ( day > 0 && day < 6 ), "" ];
10665
	},
10666
 
10667
	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
10668
	 * @param  date  Date - the date to get the week for
10669
	 * @return  number - the number of the week within the year that contains this date
10670
	 */
10671
	iso8601Week: function( date ) {
10672
		var time,
10673
			checkDate = new Date( date.getTime() );
10674
 
10675
		// Find Thursday of this week starting on Monday
10676
		checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) );
10677
 
10678
		time = checkDate.getTime();
10679
		checkDate.setMonth( 0 ); // Compare with Jan 1
10680
		checkDate.setDate( 1 );
10681
		return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1;
10682
	},
10683
 
10684
	/* Parse a string value into a date object.
10685
	 * See formatDate below for the possible formats.
10686
	 *
10687
	 * @param  format string - the expected format of the date
10688
	 * @param  value string - the date in the above format
10689
	 * @param  settings Object - attributes include:
10690
	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
10691
	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
10692
	 *					dayNames		string[7] - names of the days from Sunday (optional)
10693
	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
10694
	 *					monthNames		string[12] - names of the months (optional)
10695
	 * @return  Date - the extracted date value or null if value is blank
10696
	 */
10697
	parseDate: function( format, value, settings ) {
10698
		if ( format == null || value == null ) {
10699
			throw "Invalid arguments";
10700
		}
10701
 
10702
		value = ( typeof value === "object" ? value.toString() : value + "" );
10703
		if ( value === "" ) {
10704
			return null;
10705
		}
10706
 
10707
		var iFormat, dim, extra,
10708
			iValue = 0,
10709
			shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff,
10710
			shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
10711
				new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ),
10712
			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
10713
			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
10714
			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
10715
			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
10716
			year = -1,
10717
			month = -1,
10718
			day = -1,
10719
			doy = -1,
10720
			literal = false,
10721
			date,
10722
 
10723
			// Check whether a format character is doubled
10724
			lookAhead = function( match ) {
10725
				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
10726
				if ( matches ) {
10727
					iFormat++;
10728
				}
10729
				return matches;
10730
			},
10731
 
10732
			// Extract a number from the string value
10733
			getNumber = function( match ) {
10734
				var isDoubled = lookAhead( match ),
10735
					size = ( match === "@" ? 14 : ( match === "!" ? 20 :
10736
					( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ),
10737
					minSize = ( match === "y" ? size : 1 ),
10738
					digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ),
10739
					num = value.substring( iValue ).match( digits );
10740
				if ( !num ) {
10741
					throw "Missing number at position " + iValue;
10742
				}
10743
				iValue += num[ 0 ].length;
10744
				return parseInt( num[ 0 ], 10 );
10745
			},
10746
 
10747
			// Extract a name from the string value and convert to an index
10748
			getName = function( match, shortNames, longNames ) {
10749
				var index = -1,
10750
					names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) {
10751
						return [ [ k, v ] ];
10752
					} ).sort( function( a, b ) {
10753
						return -( a[ 1 ].length - b[ 1 ].length );
10754
					} );
10755
 
10756
				$.each( names, function( i, pair ) {
10757
					var name = pair[ 1 ];
10758
					if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) {
10759
						index = pair[ 0 ];
10760
						iValue += name.length;
10761
						return false;
10762
					}
10763
				} );
10764
				if ( index !== -1 ) {
10765
					return index + 1;
10766
				} else {
10767
					throw "Unknown name at position " + iValue;
10768
				}
10769
			},
10770
 
10771
			// Confirm that a literal character matches the string value
10772
			checkLiteral = function() {
10773
				if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) {
10774
					throw "Unexpected literal at position " + iValue;
10775
				}
10776
				iValue++;
10777
			};
10778
 
10779
		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
10780
			if ( literal ) {
10781
				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
10782
					literal = false;
10783
				} else {
10784
					checkLiteral();
10785
				}
10786
			} else {
10787
				switch ( format.charAt( iFormat ) ) {
10788
					case "d":
10789
						day = getNumber( "d" );
10790
						break;
10791
					case "D":
10792
						getName( "D", dayNamesShort, dayNames );
10793
						break;
10794
					case "o":
10795
						doy = getNumber( "o" );
10796
						break;
10797
					case "m":
10798
						month = getNumber( "m" );
10799
						break;
10800
					case "M":
10801
						month = getName( "M", monthNamesShort, monthNames );
10802
						break;
10803
					case "y":
10804
						year = getNumber( "y" );
10805
						break;
10806
					case "@":
10807
						date = new Date( getNumber( "@" ) );
10808
						year = date.getFullYear();
10809
						month = date.getMonth() + 1;
10810
						day = date.getDate();
10811
						break;
10812
					case "!":
10813
						date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 );
10814
						year = date.getFullYear();
10815
						month = date.getMonth() + 1;
10816
						day = date.getDate();
10817
						break;
10818
					case "'":
10819
						if ( lookAhead( "'" ) ) {
10820
							checkLiteral();
10821
						} else {
10822
							literal = true;
10823
						}
10824
						break;
10825
					default:
10826
						checkLiteral();
10827
				}
10828
			}
10829
		}
10830
 
10831
		if ( iValue < value.length ) {
10832
			extra = value.substr( iValue );
10833
			if ( !/^\s+/.test( extra ) ) {
10834
				throw "Extra/unparsed characters found in date: " + extra;
10835
			}
10836
		}
10837
 
10838
		if ( year === -1 ) {
10839
			year = new Date().getFullYear();
10840
		} else if ( year < 100 ) {
10841
			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
10842
				( year <= shortYearCutoff ? 0 : -100 );
10843
		}
10844
 
10845
		if ( doy > -1 ) {
10846
			month = 1;
10847
			day = doy;
10848
			do {
10849
				dim = this._getDaysInMonth( year, month - 1 );
10850
				if ( day <= dim ) {
10851
					break;
10852
				}
10853
				month++;
10854
				day -= dim;
10855
			} while ( true );
10856
		}
10857
 
10858
		date = this._daylightSavingAdjust( new Date( year, month - 1, day ) );
10859
		if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) {
10860
			throw "Invalid date"; // E.g. 31/02/00
10861
		}
10862
		return date;
10863
	},
10864
 
10865
	/* Standard date formats. */
10866
	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
10867
	COOKIE: "D, dd M yy",
10868
	ISO_8601: "yy-mm-dd",
10869
	RFC_822: "D, d M y",
10870
	RFC_850: "DD, dd-M-y",
10871
	RFC_1036: "D, d M y",
10872
	RFC_1123: "D, d M yy",
10873
	RFC_2822: "D, d M yy",
10874
	RSS: "D, d M y", // RFC 822
10875
	TICKS: "!",
10876
	TIMESTAMP: "@",
10877
	W3C: "yy-mm-dd", // ISO 8601
10878
 
10879
	_ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) +
10880
		Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ),
10881
 
10882
	/* Format a date object into a string value.
10883
	 * The format can be combinations of the following:
10884
	 * d  - day of month (no leading zero)
10885
	 * dd - day of month (two digit)
10886
	 * o  - day of year (no leading zeros)
10887
	 * oo - day of year (three digit)
10888
	 * D  - day name short
10889
	 * DD - day name long
10890
	 * m  - month of year (no leading zero)
10891
	 * mm - month of year (two digit)
10892
	 * M  - month name short
10893
	 * MM - month name long
10894
	 * y  - year (two digit)
10895
	 * yy - year (four digit)
10896
	 * @ - Unix timestamp (ms since 01/01/1970)
10897
	 * ! - Windows ticks (100ns since 01/01/0001)
10898
	 * "..." - literal text
10899
	 * '' - single quote
10900
	 *
10901
	 * @param  format string - the desired format of the date
10902
	 * @param  date Date - the date value to format
10903
	 * @param  settings Object - attributes include:
10904
	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
10905
	 *					dayNames		string[7] - names of the days from Sunday (optional)
10906
	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
10907
	 *					monthNames		string[12] - names of the months (optional)
10908
	 * @return  string - the date in the above format
10909
	 */
10910
	formatDate: function( format, date, settings ) {
10911
		if ( !date ) {
10912
			return "";
10913
		}
10914
 
10915
		var iFormat,
10916
			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
10917
			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
10918
			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
10919
			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
10920
 
10921
			// Check whether a format character is doubled
10922
			lookAhead = function( match ) {
10923
				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
10924
				if ( matches ) {
10925
					iFormat++;
10926
				}
10927
				return matches;
10928
			},
10929
 
10930
			// Format a number, with leading zero if necessary
10931
			formatNumber = function( match, value, len ) {
10932
				var num = "" + value;
10933
				if ( lookAhead( match ) ) {
10934
					while ( num.length < len ) {
10935
						num = "0" + num;
10936
					}
10937
				}
10938
				return num;
10939
			},
10940
 
10941
			// Format a name, short or long as requested
10942
			formatName = function( match, value, shortNames, longNames ) {
10943
				return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] );
10944
			},
10945
			output = "",
10946
			literal = false;
10947
 
10948
		if ( date ) {
10949
			for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
10950
				if ( literal ) {
10951
					if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
10952
						literal = false;
10953
					} else {
10954
						output += format.charAt( iFormat );
10955
					}
10956
				} else {
10957
					switch ( format.charAt( iFormat ) ) {
10958
						case "d":
10959
							output += formatNumber( "d", date.getDate(), 2 );
10960
							break;
10961
						case "D":
10962
							output += formatName( "D", date.getDay(), dayNamesShort, dayNames );
10963
							break;
10964
						case "o":
10965
							output += formatNumber( "o",
10966
								Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 );
10967
							break;
10968
						case "m":
10969
							output += formatNumber( "m", date.getMonth() + 1, 2 );
10970
							break;
10971
						case "M":
10972
							output += formatName( "M", date.getMonth(), monthNamesShort, monthNames );
10973
							break;
10974
						case "y":
10975
							output += ( lookAhead( "y" ) ? date.getFullYear() :
10976
								( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 );
10977
							break;
10978
						case "@":
10979
							output += date.getTime();
10980
							break;
10981
						case "!":
10982
							output += date.getTime() * 10000 + this._ticksTo1970;
10983
							break;
10984
						case "'":
10985
							if ( lookAhead( "'" ) ) {
10986
								output += "'";
10987
							} else {
10988
								literal = true;
10989
							}
10990
							break;
10991
						default:
10992
							output += format.charAt( iFormat );
10993
					}
10994
				}
10995
			}
10996
		}
10997
		return output;
10998
	},
10999
 
11000
	/* Extract all possible characters from the date format. */
11001
	_possibleChars: function( format ) {
11002
		var iFormat,
11003
			chars = "",
11004
			literal = false,
11005
 
11006
			// Check whether a format character is doubled
11007
			lookAhead = function( match ) {
11008
				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
11009
				if ( matches ) {
11010
					iFormat++;
11011
				}
11012
				return matches;
11013
			};
11014
 
11015
		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
11016
			if ( literal ) {
11017
				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
11018
					literal = false;
11019
				} else {
11020
					chars += format.charAt( iFormat );
11021
				}
11022
			} else {
11023
				switch ( format.charAt( iFormat ) ) {
11024
					case "d": case "m": case "y": case "@":
11025
						chars += "0123456789";
11026
						break;
11027
					case "D": case "M":
11028
						return null; // Accept anything
11029
					case "'":
11030
						if ( lookAhead( "'" ) ) {
11031
							chars += "'";
11032
						} else {
11033
							literal = true;
11034
						}
11035
						break;
11036
					default:
11037
						chars += format.charAt( iFormat );
11038
				}
11039
			}
11040
		}
11041
		return chars;
11042
	},
11043
 
11044
	/* Get a setting value, defaulting if necessary. */
11045
	_get: function( inst, name ) {
11046
		return inst.settings[ name ] !== undefined ?
11047
			inst.settings[ name ] : this._defaults[ name ];
11048
	},
11049
 
11050
	/* Parse existing date and initialise date picker. */
11051
	_setDateFromField: function( inst, noDefault ) {
11052
		if ( inst.input.val() === inst.lastVal ) {
11053
			return;
11054
		}
11055
 
11056
		var dateFormat = this._get( inst, "dateFormat" ),
11057
			dates = inst.lastVal = inst.input ? inst.input.val() : null,
11058
			defaultDate = this._getDefaultDate( inst ),
11059
			date = defaultDate,
11060
			settings = this._getFormatConfig( inst );
11061
 
11062
		try {
11063
			date = this.parseDate( dateFormat, dates, settings ) || defaultDate;
11064
		} catch ( event ) {
11065
			dates = ( noDefault ? "" : dates );
11066
		}
11067
		inst.selectedDay = date.getDate();
11068
		inst.drawMonth = inst.selectedMonth = date.getMonth();
11069
		inst.drawYear = inst.selectedYear = date.getFullYear();
11070
		inst.currentDay = ( dates ? date.getDate() : 0 );
11071
		inst.currentMonth = ( dates ? date.getMonth() : 0 );
11072
		inst.currentYear = ( dates ? date.getFullYear() : 0 );
11073
		this._adjustInstDate( inst );
11074
	},
11075
 
11076
	/* Retrieve the default date shown on opening. */
11077
	_getDefaultDate: function( inst ) {
11078
		return this._restrictMinMax( inst,
11079
			this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) );
11080
	},
11081
 
11082
	/* A date may be specified as an exact value or a relative one. */
11083
	_determineDate: function( inst, date, defaultDate ) {
11084
		var offsetNumeric = function( offset ) {
11085
				var date = new Date();
11086
				date.setDate( date.getDate() + offset );
11087
				return date;
11088
			},
11089
			offsetString = function( offset ) {
11090
				try {
11091
					return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
11092
						offset, $.datepicker._getFormatConfig( inst ) );
11093
				}
11094
				catch ( e ) {
11095
 
11096
					// Ignore
11097
				}
11098
 
11099
				var date = ( offset.toLowerCase().match( /^c/ ) ?
11100
					$.datepicker._getDate( inst ) : null ) || new Date(),
11101
					year = date.getFullYear(),
11102
					month = date.getMonth(),
11103
					day = date.getDate(),
11104
					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
11105
					matches = pattern.exec( offset );
11106
 
11107
				while ( matches ) {
11108
					switch ( matches[ 2 ] || "d" ) {
11109
						case "d" : case "D" :
11110
							day += parseInt( matches[ 1 ], 10 ); break;
11111
						case "w" : case "W" :
11112
							day += parseInt( matches[ 1 ], 10 ) * 7; break;
11113
						case "m" : case "M" :
11114
							month += parseInt( matches[ 1 ], 10 );
11115
							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
11116
							break;
11117
						case "y": case "Y" :
11118
							year += parseInt( matches[ 1 ], 10 );
11119
							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
11120
							break;
11121
					}
11122
					matches = pattern.exec( offset );
11123
				}
11124
				return new Date( year, month, day );
11125
			},
11126
			newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) :
11127
				( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) );
11128
 
11129
		newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate );
11130
		if ( newDate ) {
11131
			newDate.setHours( 0 );
11132
			newDate.setMinutes( 0 );
11133
			newDate.setSeconds( 0 );
11134
			newDate.setMilliseconds( 0 );
11135
		}
11136
		return this._daylightSavingAdjust( newDate );
11137
	},
11138
 
11139
	/* Handle switch to/from daylight saving.
11140
	 * Hours may be non-zero on daylight saving cut-over:
11141
	 * > 12 when midnight changeover, but then cannot generate
11142
	 * midnight datetime, so jump to 1AM, otherwise reset.
11143
	 * @param  date  (Date) the date to check
11144
	 * @return  (Date) the corrected date
11145
	 */
11146
	_daylightSavingAdjust: function( date ) {
11147
		if ( !date ) {
11148
			return null;
11149
		}
11150
		date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 );
11151
		return date;
11152
	},
11153
 
11154
	/* Set the date(s) directly. */
11155
	_setDate: function( inst, date, noChange ) {
11156
		var clear = !date,
11157
			origMonth = inst.selectedMonth,
11158
			origYear = inst.selectedYear,
11159
			newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) );
11160
 
11161
		inst.selectedDay = inst.currentDay = newDate.getDate();
11162
		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
11163
		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
11164
		if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) {
11165
			this._notifyChange( inst );
11166
		}
11167
		this._adjustInstDate( inst );
11168
		if ( inst.input ) {
11169
			inst.input.val( clear ? "" : this._formatDate( inst ) );
11170
		}
11171
	},
11172
 
11173
	/* Retrieve the date(s) directly. */
11174
	_getDate: function( inst ) {
11175
		var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null :
11176
			this._daylightSavingAdjust( new Date(
11177
			inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
11178
			return startDate;
11179
	},
11180
 
11181
	/* Attach the onxxx handlers.  These are declared statically so
11182
	 * they work with static code transformers like Caja.
11183
	 */
11184
	_attachHandlers: function( inst ) {
11185
		var stepMonths = this._get( inst, "stepMonths" ),
11186
			id = "#" + inst.id.replace( /\\\\/g, "\\" );
11187
		inst.dpDiv.find( "[data-handler]" ).map( function() {
11188
			var handler = {
11189
				prev: function() {
11190
					$.datepicker._adjustDate( id, -stepMonths, "M" );
11191
				},
11192
				next: function() {
11193
					$.datepicker._adjustDate( id, +stepMonths, "M" );
11194
				},
11195
				hide: function() {
11196
					$.datepicker._hideDatepicker();
11197
				},
11198
				today: function() {
11199
					$.datepicker._gotoToday( id );
11200
				},
11201
				selectDay: function() {
11202
					$.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this );
11203
					return false;
11204
				},
11205
				selectMonth: function() {
11206
					$.datepicker._selectMonthYear( id, this, "M" );
11207
					return false;
11208
				},
11209
				selectYear: function() {
11210
					$.datepicker._selectMonthYear( id, this, "Y" );
11211
					return false;
11212
				}
11213
			};
11214
			$( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] );
11215
		} );
11216
	},
11217
 
11218
	/* Generate the HTML for the current state of the date picker. */
11219
	_generateHTML: function( inst ) {
11220
		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
11221
			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
11222
			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
11223
			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
11224
			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
11225
			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
11226
			tempDate = new Date(),
11227
			today = this._daylightSavingAdjust(
11228
				new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time
11229
			isRTL = this._get( inst, "isRTL" ),
11230
			showButtonPanel = this._get( inst, "showButtonPanel" ),
11231
			hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ),
11232
			navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ),
11233
			numMonths = this._getNumberOfMonths( inst ),
11234
			showCurrentAtPos = this._get( inst, "showCurrentAtPos" ),
11235
			stepMonths = this._get( inst, "stepMonths" ),
11236
			isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ),
11237
			currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) :
11238
				new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ),
11239
			minDate = this._getMinMaxDate( inst, "min" ),
11240
			maxDate = this._getMinMaxDate( inst, "max" ),
11241
			drawMonth = inst.drawMonth - showCurrentAtPos,
11242
			drawYear = inst.drawYear;
11243
 
11244
		if ( drawMonth < 0 ) {
11245
			drawMonth += 12;
11246
			drawYear--;
11247
		}
11248
		if ( maxDate ) {
11249
			maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(),
11250
				maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) );
11251
			maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw );
11252
			while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) {
11253
				drawMonth--;
11254
				if ( drawMonth < 0 ) {
11255
					drawMonth = 11;
11256
					drawYear--;
11257
				}
11258
			}
11259
		}
11260
		inst.drawMonth = drawMonth;
11261
		inst.drawYear = drawYear;
11262
 
11263
		prevText = this._get( inst, "prevText" );
11264
		prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText,
11265
			this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ),
11266
			this._getFormatConfig( inst ) ) );
11267
 
11268
		prev = ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ?
11269
			"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
11270
			" title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" :
11271
			( hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" ) );
11272
 
11273
		nextText = this._get( inst, "nextText" );
11274
		nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText,
11275
			this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ),
11276
			this._getFormatConfig( inst ) ) );
11277
 
11278
		next = ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ?
11279
			"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
11280
			" title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" :
11281
			( hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" ) );
11282
 
11283
		currentText = this._get( inst, "currentText" );
11284
		gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today );
11285
		currentText = ( !navigationAsDateFormat ? currentText :
11286
			this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) );
11287
 
11288
		controls = ( !inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" +
11289
			this._get( inst, "closeText" ) + "</button>" : "" );
11290
 
11291
		buttonPanel = ( showButtonPanel ) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + ( isRTL ? controls : "" ) +
11292
			( this._isInRange( inst, gotoDate ) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" +
11293
			">" + currentText + "</button>" : "" ) + ( isRTL ? "" : controls ) + "</div>" : "";
11294
 
11295
		firstDay = parseInt( this._get( inst, "firstDay" ), 10 );
11296
		firstDay = ( isNaN( firstDay ) ? 0 : firstDay );
11297
 
11298
		showWeek = this._get( inst, "showWeek" );
11299
		dayNames = this._get( inst, "dayNames" );
11300
		dayNamesMin = this._get( inst, "dayNamesMin" );
11301
		monthNames = this._get( inst, "monthNames" );
11302
		monthNamesShort = this._get( inst, "monthNamesShort" );
11303
		beforeShowDay = this._get( inst, "beforeShowDay" );
11304
		showOtherMonths = this._get( inst, "showOtherMonths" );
11305
		selectOtherMonths = this._get( inst, "selectOtherMonths" );
11306
		defaultDate = this._getDefaultDate( inst );
11307
		html = "";
11308
 
11309
		for ( row = 0; row < numMonths[ 0 ]; row++ ) {
11310
			group = "";
11311
			this.maxRows = 4;
11312
			for ( col = 0; col < numMonths[ 1 ]; col++ ) {
11313
				selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) );
11314
				cornerClass = " ui-corner-all";
11315
				calender = "";
11316
				if ( isMultiMonth ) {
11317
					calender += "<div class='ui-datepicker-group";
11318
					if ( numMonths[ 1 ] > 1 ) {
11319
						switch ( col ) {
11320
							case 0: calender += " ui-datepicker-group-first";
11321
								cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break;
11322
							case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last";
11323
								cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break;
11324
							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
11325
						}
11326
					}
11327
					calender += "'>";
11328
				}
11329
				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
11330
					( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) +
11331
					( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) +
11332
					this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate,
11333
					row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers
11334
					"</div><table class='ui-datepicker-calendar'><thead>" +
11335
					"<tr>";
11336
				thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" );
11337
				for ( dow = 0; dow < 7; dow++ ) { // days of the week
11338
					day = ( dow + firstDay ) % 7;
11339
					thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" +
11340
						"<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>";
11341
				}
11342
				calender += thead + "</tr></thead><tbody>";
11343
				daysInMonth = this._getDaysInMonth( drawYear, drawMonth );
11344
				if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) {
11345
					inst.selectedDay = Math.min( inst.selectedDay, daysInMonth );
11346
				}
11347
				leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7;
11348
				curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate
11349
				numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043)
11350
				this.maxRows = numRows;
11351
				printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) );
11352
				for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows
11353
					calender += "<tr>";
11354
					tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
11355
						this._get( inst, "calculateWeek" )( printDate ) + "</td>" );
11356
					for ( dow = 0; dow < 7; dow++ ) { // create date picker days
11357
						daySettings = ( beforeShowDay ?
11358
							beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] );
11359
						otherMonth = ( printDate.getMonth() !== drawMonth );
11360
						unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] ||
11361
							( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate );
11362
						tbody += "<td class='" +
11363
							( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends
11364
							( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months
11365
							( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key
11366
							( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ?
11367
 
11368
							// or defaultDate is current printedDate and defaultDate is selectedDate
11369
							" " + this._dayOverClass : "" ) + // highlight selected day
11370
							( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) +  // highlight unselectable days
11371
							( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates
11372
							( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day
11373
							( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different)
11374
							( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "&#39;" ) + "'" : "" ) + // cell title
11375
							( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions
11376
							( otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
11377
							( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
11378
							( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) +
11379
							( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day
11380
							( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months
11381
							"' href='#'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date
11382
						printDate.setDate( printDate.getDate() + 1 );
11383
						printDate = this._daylightSavingAdjust( printDate );
11384
					}
11385
					calender += tbody + "</tr>";
11386
				}
11387
				drawMonth++;
11388
				if ( drawMonth > 11 ) {
11389
					drawMonth = 0;
11390
					drawYear++;
11391
				}
11392
				calender += "</tbody></table>" + ( isMultiMonth ? "</div>" +
11393
							( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" );
11394
				group += calender;
11395
			}
11396
			html += group;
11397
		}
11398
		html += buttonPanel;
11399
		inst._keyEvent = false;
11400
		return html;
11401
	},
11402
 
11403
	/* Generate the month and year header. */
11404
	_generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate,
11405
			secondary, monthNames, monthNamesShort ) {
11406
 
11407
		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
11408
			changeMonth = this._get( inst, "changeMonth" ),
11409
			changeYear = this._get( inst, "changeYear" ),
11410
			showMonthAfterYear = this._get( inst, "showMonthAfterYear" ),
11411
			html = "<div class='ui-datepicker-title'>",
11412
			monthHtml = "";
11413
 
11414
		// Month selection
11415
		if ( secondary || !changeMonth ) {
11416
			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>";
11417
		} else {
11418
			inMinYear = ( minDate && minDate.getFullYear() === drawYear );
11419
			inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear );
11420
			monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
11421
			for ( month = 0; month < 12; month++ ) {
11422
				if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) {
11423
					monthHtml += "<option value='" + month + "'" +
11424
						( month === drawMonth ? " selected='selected'" : "" ) +
11425
						">" + monthNamesShort[ month ] + "</option>";
11426
				}
11427
			}
11428
			monthHtml += "</select>";
11429
		}
11430
 
11431
		if ( !showMonthAfterYear ) {
11432
			html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" );
11433
		}
11434
 
11435
		// Year selection
11436
		if ( !inst.yearshtml ) {
11437
			inst.yearshtml = "";
11438
			if ( secondary || !changeYear ) {
11439
				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
11440
			} else {
11441
 
11442
				// determine range of years to display
11443
				years = this._get( inst, "yearRange" ).split( ":" );
11444
				thisYear = new Date().getFullYear();
11445
				determineYear = function( value ) {
11446
					var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) :
11447
						( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) :
11448
						parseInt( value, 10 ) ) );
11449
					return ( isNaN( year ) ? thisYear : year );
11450
				};
11451
				year = determineYear( years[ 0 ] );
11452
				endYear = Math.max( year, determineYear( years[ 1 ] || "" ) );
11453
				year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year );
11454
				endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear );
11455
				inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
11456
				for ( ; year <= endYear; year++ ) {
11457
					inst.yearshtml += "<option value='" + year + "'" +
11458
						( year === drawYear ? " selected='selected'" : "" ) +
11459
						">" + year + "</option>";
11460
				}
11461
				inst.yearshtml += "</select>";
11462
 
11463
				html += inst.yearshtml;
11464
				inst.yearshtml = null;
11465
			}
11466
		}
11467
 
11468
		html += this._get( inst, "yearSuffix" );
11469
		if ( showMonthAfterYear ) {
11470
			html += ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" ) + monthHtml;
11471
		}
11472
		html += "</div>"; // Close datepicker_header
11473
		return html;
11474
	},
11475
 
11476
	/* Adjust one of the date sub-fields. */
11477
	_adjustInstDate: function( inst, offset, period ) {
11478
		var year = inst.selectedYear + ( period === "Y" ? offset : 0 ),
11479
			month = inst.selectedMonth + ( period === "M" ? offset : 0 ),
11480
			day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ),
11481
			date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) );
11482
 
11483
		inst.selectedDay = date.getDate();
11484
		inst.drawMonth = inst.selectedMonth = date.getMonth();
11485
		inst.drawYear = inst.selectedYear = date.getFullYear();
11486
		if ( period === "M" || period === "Y" ) {
11487
			this._notifyChange( inst );
11488
		}
11489
	},
11490
 
11491
	/* Ensure a date is within any min/max bounds. */
11492
	_restrictMinMax: function( inst, date ) {
11493
		var minDate = this._getMinMaxDate( inst, "min" ),
11494
			maxDate = this._getMinMaxDate( inst, "max" ),
11495
			newDate = ( minDate && date < minDate ? minDate : date );
11496
		return ( maxDate && newDate > maxDate ? maxDate : newDate );
11497
	},
11498
 
11499
	/* Notify change of month/year. */
11500
	_notifyChange: function( inst ) {
11501
		var onChange = this._get( inst, "onChangeMonthYear" );
11502
		if ( onChange ) {
11503
			onChange.apply( ( inst.input ? inst.input[ 0 ] : null ),
11504
				[ inst.selectedYear, inst.selectedMonth + 1, inst ] );
11505
		}
11506
	},
11507
 
11508
	/* Determine the number of months to show. */
11509
	_getNumberOfMonths: function( inst ) {
11510
		var numMonths = this._get( inst, "numberOfMonths" );
11511
		return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) );
11512
	},
11513
 
11514
	/* Determine the current maximum date - ensure no time components are set. */
11515
	_getMinMaxDate: function( inst, minMax ) {
11516
		return this._determineDate( inst, this._get( inst, minMax + "Date" ), null );
11517
	},
11518
 
11519
	/* Find the number of days in a given month. */
11520
	_getDaysInMonth: function( year, month ) {
11521
		return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate();
11522
	},
11523
 
11524
	/* Find the day of the week of the first of a month. */
11525
	_getFirstDayOfMonth: function( year, month ) {
11526
		return new Date( year, month, 1 ).getDay();
11527
	},
11528
 
11529
	/* Determines if we should allow a "next/prev" month display change. */
11530
	_canAdjustMonth: function( inst, offset, curYear, curMonth ) {
11531
		var numMonths = this._getNumberOfMonths( inst ),
11532
			date = this._daylightSavingAdjust( new Date( curYear,
11533
			curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) );
11534
 
11535
		if ( offset < 0 ) {
11536
			date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) );
11537
		}
11538
		return this._isInRange( inst, date );
11539
	},
11540
 
11541
	/* Is the given date in the accepted range? */
11542
	_isInRange: function( inst, date ) {
11543
		var yearSplit, currentYear,
11544
			minDate = this._getMinMaxDate( inst, "min" ),
11545
			maxDate = this._getMinMaxDate( inst, "max" ),
11546
			minYear = null,
11547
			maxYear = null,
11548
			years = this._get( inst, "yearRange" );
11549
			if ( years ) {
11550
				yearSplit = years.split( ":" );
11551
				currentYear = new Date().getFullYear();
11552
				minYear = parseInt( yearSplit[ 0 ], 10 );
11553
				maxYear = parseInt( yearSplit[ 1 ], 10 );
11554
				if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) {
11555
					minYear += currentYear;
11556
				}
11557
				if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) {
11558
					maxYear += currentYear;
11559
				}
11560
			}
11561
 
11562
		return ( ( !minDate || date.getTime() >= minDate.getTime() ) &&
11563
			( !maxDate || date.getTime() <= maxDate.getTime() ) &&
11564
			( !minYear || date.getFullYear() >= minYear ) &&
11565
			( !maxYear || date.getFullYear() <= maxYear ) );
11566
	},
11567
 
11568
	/* Provide the configuration settings for formatting/parsing. */
11569
	_getFormatConfig: function( inst ) {
11570
		var shortYearCutoff = this._get( inst, "shortYearCutoff" );
11571
		shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff :
11572
			new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) );
11573
		return { shortYearCutoff: shortYearCutoff,
11574
			dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ),
11575
			monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) };
11576
	},
11577
 
11578
	/* Format the given date for display. */
11579
	_formatDate: function( inst, day, month, year ) {
11580
		if ( !day ) {
11581
			inst.currentDay = inst.selectedDay;
11582
			inst.currentMonth = inst.selectedMonth;
11583
			inst.currentYear = inst.selectedYear;
11584
		}
11585
		var date = ( day ? ( typeof day === "object" ? day :
11586
			this._daylightSavingAdjust( new Date( year, month, day ) ) ) :
11587
			this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
11588
		return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) );
11589
	}
11590
} );
11591
 
11592
/*
11593
 * Bind hover events for datepicker elements.
11594
 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
11595
 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
11596
 */
11597
function datepicker_bindHover( dpDiv ) {
11598
	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
11599
	return dpDiv.on( "mouseout", selector, function() {
11600
			$( this ).removeClass( "ui-state-hover" );
11601
			if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
11602
				$( this ).removeClass( "ui-datepicker-prev-hover" );
11603
			}
11604
			if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
11605
				$( this ).removeClass( "ui-datepicker-next-hover" );
11606
			}
11607
		} )
11608
		.on( "mouseover", selector, datepicker_handleMouseover );
11609
}
11610
 
11611
function datepicker_handleMouseover() {
11612
	if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) {
11613
		$( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" );
11614
		$( this ).addClass( "ui-state-hover" );
11615
		if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
11616
			$( this ).addClass( "ui-datepicker-prev-hover" );
11617
		}
11618
		if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
11619
			$( this ).addClass( "ui-datepicker-next-hover" );
11620
		}
11621
	}
11622
}
11623
 
11624
/* jQuery extend now ignores nulls! */
11625
function datepicker_extendRemove( target, props ) {
11626
	$.extend( target, props );
11627
	for ( var name in props ) {
11628
		if ( props[ name ] == null ) {
11629
			target[ name ] = props[ name ];
11630
		}
11631
	}
11632
	return target;
11633
}
11634
 
11635
/* Invoke the datepicker functionality.
11636
   @param  options  string - a command, optionally followed by additional parameters or
11637
					Object - settings for attaching new datepicker functionality
11638
   @return  jQuery object */
11639
$.fn.datepicker = function( options ) {
11640
 
11641
	/* Verify an empty collection wasn't passed - Fixes #6976 */
11642
	if ( !this.length ) {
11643
		return this;
11644
	}
11645
 
11646
	/* Initialise the date picker. */
11647
	if ( !$.datepicker.initialized ) {
11648
		$( document ).on( "mousedown", $.datepicker._checkExternalClick );
11649
		$.datepicker.initialized = true;
11650
	}
11651
 
11652
	/* Append datepicker main container to body if not exist. */
11653
	if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) {
11654
		$( "body" ).append( $.datepicker.dpDiv );
11655
	}
11656
 
11657
	var otherArgs = Array.prototype.slice.call( arguments, 1 );
11658
	if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) {
11659
		return $.datepicker[ "_" + options + "Datepicker" ].
11660
			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
11661
	}
11662
	if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) {
11663
		return $.datepicker[ "_" + options + "Datepicker" ].
11664
			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
11665
	}
11666
	return this.each( function() {
11667
		typeof options === "string" ?
11668
			$.datepicker[ "_" + options + "Datepicker" ].
11669
				apply( $.datepicker, [ this ].concat( otherArgs ) ) :
11670
			$.datepicker._attachDatepicker( this, options );
11671
	} );
11672
};
11673
 
11674
$.datepicker = new Datepicker(); // singleton instance
11675
$.datepicker.initialized = false;
11676
$.datepicker.uuid = new Date().getTime();
11677
$.datepicker.version = "1.12.1";
11678
 
11679
var widgetsDatepicker = $.datepicker;
11680
 
11681
 
11682
/*!
11683
 * jQuery UI Dialog 1.12.1
11684
 * http://jqueryui.com
11685
 *
11686
 * Copyright jQuery Foundation and other contributors
11687
 * Released under the MIT license.
11688
 * http://jquery.org/license
11689
 */
11690
 
11691
//>>label: Dialog
11692
//>>group: Widgets
11693
//>>description: Displays customizable dialog windows.
11694
//>>docs: http://api.jqueryui.com/dialog/
11695
//>>demos: http://jqueryui.com/dialog/
11696
//>>css.structure: ../../themes/base/core.css
11697
//>>css.structure: ../../themes/base/dialog.css
11698
//>>css.theme: ../../themes/base/theme.css
11699
 
11700
 
11701
 
11702
$.widget( "ui.dialog", {
11703
	version: "1.12.1",
11704
	options: {
11705
		appendTo: "body",
11706
		autoOpen: true,
11707
		buttons: [],
11708
		classes: {
11709
			"ui-dialog": "ui-corner-all",
11710
			"ui-dialog-titlebar": "ui-corner-all"
11711
		},
11712
		closeOnEscape: true,
11713
		closeText: "Close",
11714
		draggable: true,
11715
		hide: null,
11716
		height: "auto",
11717
		maxHeight: null,
11718
		maxWidth: null,
11719
		minHeight: 150,
11720
		minWidth: 150,
11721
		modal: false,
11722
		position: {
11723
			my: "center",
11724
			at: "center",
11725
			of: window,
11726
			collision: "fit",
11727
 
11728
			// Ensure the titlebar is always visible
11729
			using: function( pos ) {
11730
				var topOffset = $( this ).css( pos ).offset().top;
11731
				if ( topOffset < 0 ) {
11732
					$( this ).css( "top", pos.top - topOffset );
11733
				}
11734
			}
11735
		},
11736
		resizable: true,
11737
		show: null,
11738
		title: null,
11739
		width: 300,
11740
 
11741
		// Callbacks
11742
		beforeClose: null,
11743
		close: null,
11744
		drag: null,
11745
		dragStart: null,
11746
		dragStop: null,
11747
		focus: null,
11748
		open: null,
11749
		resize: null,
11750
		resizeStart: null,
11751
		resizeStop: null
11752
	},
11753
 
11754
	sizeRelatedOptions: {
11755
		buttons: true,
11756
		height: true,
11757
		maxHeight: true,
11758
		maxWidth: true,
11759
		minHeight: true,
11760
		minWidth: true,
11761
		width: true
11762
	},
11763
 
11764
	resizableRelatedOptions: {
11765
		maxHeight: true,
11766
		maxWidth: true,
11767
		minHeight: true,
11768
		minWidth: true
11769
	},
11770
 
11771
	_create: function() {
11772
		this.originalCss = {
11773
			display: this.element[ 0 ].style.display,
11774
			width: this.element[ 0 ].style.width,
11775
			minHeight: this.element[ 0 ].style.minHeight,
11776
			maxHeight: this.element[ 0 ].style.maxHeight,
11777
			height: this.element[ 0 ].style.height
11778
		};
11779
		this.originalPosition = {
11780
			parent: this.element.parent(),
11781
			index: this.element.parent().children().index( this.element )
11782
		};
11783
		this.originalTitle = this.element.attr( "title" );
11784
		if ( this.options.title == null && this.originalTitle != null ) {
11785
			this.options.title = this.originalTitle;
11786
		}
11787
 
11788
		// Dialogs can't be disabled
11789
		if ( this.options.disabled ) {
11790
			this.options.disabled = false;
11791
		}
11792
 
11793
		this._createWrapper();
11794
 
11795
		this.element
11796
			.show()
11797
			.removeAttr( "title" )
11798
			.appendTo( this.uiDialog );
11799
 
11800
		this._addClass( "ui-dialog-content", "ui-widget-content" );
11801
 
11802
		this._createTitlebar();
11803
		this._createButtonPane();
11804
 
11805
		if ( this.options.draggable && $.fn.draggable ) {
11806
			this._makeDraggable();
11807
		}
11808
		if ( this.options.resizable && $.fn.resizable ) {
11809
			this._makeResizable();
11810
		}
11811
 
11812
		this._isOpen = false;
11813
 
11814
		this._trackFocus();
11815
	},
11816
 
11817
	_init: function() {
11818
		if ( this.options.autoOpen ) {
11819
			this.open();
11820
		}
11821
	},
11822
 
11823
	_appendTo: function() {
11824
		var element = this.options.appendTo;
11825
		if ( element && ( element.jquery || element.nodeType ) ) {
11826
			return $( element );
11827
		}
11828
		return this.document.find( element || "body" ).eq( 0 );
11829
	},
11830
 
11831
	_destroy: function() {
11832
		var next,
11833
			originalPosition = this.originalPosition;
11834
 
11835
		this._untrackInstance();
11836
		this._destroyOverlay();
11837
 
11838
		this.element
11839
			.removeUniqueId()
11840
			.css( this.originalCss )
11841
 
11842
			// Without detaching first, the following becomes really slow
11843
			.detach();
11844
 
11845
		this.uiDialog.remove();
11846
 
11847
		if ( this.originalTitle ) {
11848
			this.element.attr( "title", this.originalTitle );
11849
		}
11850
 
11851
		next = originalPosition.parent.children().eq( originalPosition.index );
11852
 
11853
		// Don't try to place the dialog next to itself (#8613)
11854
		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
11855
			next.before( this.element );
11856
		} else {
11857
			originalPosition.parent.append( this.element );
11858
		}
11859
	},
11860
 
11861
	widget: function() {
11862
		return this.uiDialog;
11863
	},
11864
 
11865
	disable: $.noop,
11866
	enable: $.noop,
11867
 
11868
	close: function( event ) {
11869
		var that = this;
11870
 
11871
		if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
11872
			return;
11873
		}
11874
 
11875
		this._isOpen = false;
11876
		this._focusedElement = null;
11877
		this._destroyOverlay();
11878
		this._untrackInstance();
11879
 
11880
		if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) {
11881
 
11882
			// Hiding a focused element doesn't trigger blur in WebKit
11883
			// so in case we have nothing to focus on, explicitly blur the active element
11884
			// https://bugs.webkit.org/show_bug.cgi?id=47182
11885
			$.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) );
11886
		}
11887
 
11888
		this._hide( this.uiDialog, this.options.hide, function() {
11889
			that._trigger( "close", event );
11890
		} );
11891
	},
11892
 
11893
	isOpen: function() {
11894
		return this._isOpen;
11895
	},
11896
 
11897
	moveToTop: function() {
11898
		this._moveToTop();
11899
	},
11900
 
11901
	_moveToTop: function( event, silent ) {
11902
		var moved = false,
11903
			zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() {
11904
				return +$( this ).css( "z-index" );
11905
			} ).get(),
11906
			zIndexMax = Math.max.apply( null, zIndices );
11907
 
11908
		if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
11909
			this.uiDialog.css( "z-index", zIndexMax + 1 );
11910
			moved = true;
11911
		}
11912
 
11913
		if ( moved && !silent ) {
11914
			this._trigger( "focus", event );
11915
		}
11916
		return moved;
11917
	},
11918
 
11919
	open: function() {
11920
		var that = this;
11921
		if ( this._isOpen ) {
11922
			if ( this._moveToTop() ) {
11923
				this._focusTabbable();
11924
			}
11925
			return;
11926
		}
11927
 
11928
		this._isOpen = true;
11929
		this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
11930
 
11931
		this._size();
11932
		this._position();
11933
		this._createOverlay();
11934
		this._moveToTop( null, true );
11935
 
11936
		// Ensure the overlay is moved to the top with the dialog, but only when
11937
		// opening. The overlay shouldn't move after the dialog is open so that
11938
		// modeless dialogs opened after the modal dialog stack properly.
11939
		if ( this.overlay ) {
11940
			this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
11941
		}
11942
 
11943
		this._show( this.uiDialog, this.options.show, function() {
11944
			that._focusTabbable();
11945
			that._trigger( "focus" );
11946
		} );
11947
 
11948
		// Track the dialog immediately upon openening in case a focus event
11949
		// somehow occurs outside of the dialog before an element inside the
11950
		// dialog is focused (#10152)
11951
		this._makeFocusTarget();
11952
 
11953
		this._trigger( "open" );
11954
	},
11955
 
11956
	_focusTabbable: function() {
11957
 
11958
		// Set focus to the first match:
11959
		// 1. An element that was focused previously
11960
		// 2. First element inside the dialog matching [autofocus]
11961
		// 3. Tabbable element inside the content element
11962
		// 4. Tabbable element inside the buttonpane
11963
		// 5. The close button
11964
		// 6. The dialog itself
11965
		var hasFocus = this._focusedElement;
11966
		if ( !hasFocus ) {
11967
			hasFocus = this.element.find( "[autofocus]" );
11968
		}
11969
		if ( !hasFocus.length ) {
11970
			hasFocus = this.element.find( ":tabbable" );
11971
		}
11972
		if ( !hasFocus.length ) {
11973
			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
11974
		}
11975
		if ( !hasFocus.length ) {
11976
			hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
11977
		}
11978
		if ( !hasFocus.length ) {
11979
			hasFocus = this.uiDialog;
11980
		}
11981
		hasFocus.eq( 0 ).trigger( "focus" );
11982
	},
11983
 
11984
	_keepFocus: function( event ) {
11985
		function checkFocus() {
11986
			var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
11987
				isActive = this.uiDialog[ 0 ] === activeElement ||
11988
					$.contains( this.uiDialog[ 0 ], activeElement );
11989
			if ( !isActive ) {
11990
				this._focusTabbable();
11991
			}
11992
		}
11993
		event.preventDefault();
11994
		checkFocus.call( this );
11995
 
11996
		// support: IE
11997
		// IE <= 8 doesn't prevent moving focus even with event.preventDefault()
11998
		// so we check again later
11999
		this._delay( checkFocus );
12000
	},
12001
 
12002
	_createWrapper: function() {
12003
		this.uiDialog = $( "<div>" )
12004
			.hide()
12005
			.attr( {
12006
 
12007
				// Setting tabIndex makes the div focusable
12008
				tabIndex: -1,
12009
				role: "dialog"
12010
			} )
12011
			.appendTo( this._appendTo() );
12012
 
12013
		this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" );
12014
		this._on( this.uiDialog, {
12015
			keydown: function( event ) {
12016
				if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
12017
						event.keyCode === $.ui.keyCode.ESCAPE ) {
12018
					event.preventDefault();
12019
					this.close( event );
12020
					return;
12021
				}
12022
 
12023
				// Prevent tabbing out of dialogs
12024
				if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
12025
					return;
12026
				}
12027
				var tabbables = this.uiDialog.find( ":tabbable" ),
12028
					first = tabbables.filter( ":first" ),
12029
					last = tabbables.filter( ":last" );
12030
 
12031
				if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) &&
12032
						!event.shiftKey ) {
12033
					this._delay( function() {
12034
						first.trigger( "focus" );
12035
					} );
12036
					event.preventDefault();
12037
				} else if ( ( event.target === first[ 0 ] ||
12038
						event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) {
12039
					this._delay( function() {
12040
						last.trigger( "focus" );
12041
					} );
12042
					event.preventDefault();
12043
				}
12044
			},
12045
			mousedown: function( event ) {
12046
				if ( this._moveToTop( event ) ) {
12047
					this._focusTabbable();
12048
				}
12049
			}
12050
		} );
12051
 
12052
		// We assume that any existing aria-describedby attribute means
12053
		// that the dialog content is marked up properly
12054
		// otherwise we brute force the content as the description
12055
		if ( !this.element.find( "[aria-describedby]" ).length ) {
12056
			this.uiDialog.attr( {
12057
				"aria-describedby": this.element.uniqueId().attr( "id" )
12058
			} );
12059
		}
12060
	},
12061
 
12062
	_createTitlebar: function() {
12063
		var uiDialogTitle;
12064
 
12065
		this.uiDialogTitlebar = $( "<div>" );
12066
		this._addClass( this.uiDialogTitlebar,
12067
			"ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" );
12068
		this._on( this.uiDialogTitlebar, {
12069
			mousedown: function( event ) {
12070
 
12071
				// Don't prevent click on close button (#8838)
12072
				// Focusing a dialog that is partially scrolled out of view
12073
				// causes the browser to scroll it into view, preventing the click event
12074
				if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
12075
 
12076
					// Dialog isn't getting focus when dragging (#8063)
12077
					this.uiDialog.trigger( "focus" );
12078
				}
12079
			}
12080
		} );
12081
 
12082
		// Support: IE
12083
		// Use type="button" to prevent enter keypresses in textboxes from closing the
12084
		// dialog in IE (#9312)
12085
		this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
12086
			.button( {
12087
				label: $( "<a>" ).text( this.options.closeText ).html(),
12088
				icon: "ui-icon-closethick",
12089
				showLabel: false
12090
			} )
12091
			.appendTo( this.uiDialogTitlebar );
12092
 
12093
		this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" );
12094
		this._on( this.uiDialogTitlebarClose, {
12095
			click: function( event ) {
12096
				event.preventDefault();
12097
				this.close( event );
12098
			}
12099
		} );
12100
 
12101
		uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar );
12102
		this._addClass( uiDialogTitle, "ui-dialog-title" );
12103
		this._title( uiDialogTitle );
12104
 
12105
		this.uiDialogTitlebar.prependTo( this.uiDialog );
12106
 
12107
		this.uiDialog.attr( {
12108
			"aria-labelledby": uiDialogTitle.attr( "id" )
12109
		} );
12110
	},
12111
 
12112
	_title: function( title ) {
12113
		if ( this.options.title ) {
12114
			title.text( this.options.title );
12115
		} else {
12116
			title.html( "&#160;" );
12117
		}
12118
	},
12119
 
12120
	_createButtonPane: function() {
12121
		this.uiDialogButtonPane = $( "<div>" );
12122
		this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane",
12123
			"ui-widget-content ui-helper-clearfix" );
12124
 
12125
		this.uiButtonSet = $( "<div>" )
12126
			.appendTo( this.uiDialogButtonPane );
12127
		this._addClass( this.uiButtonSet, "ui-dialog-buttonset" );
12128
 
12129
		this._createButtons();
12130
	},
12131
 
12132
	_createButtons: function() {
12133
		var that = this,
12134
			buttons = this.options.buttons;
12135
 
12136
		// If we already have a button pane, remove it
12137
		this.uiDialogButtonPane.remove();
12138
		this.uiButtonSet.empty();
12139
 
12140
		if ( $.isEmptyObject( buttons ) || ( $.isArray( buttons ) && !buttons.length ) ) {
12141
			this._removeClass( this.uiDialog, "ui-dialog-buttons" );
12142
			return;
12143
		}
12144
 
12145
		$.each( buttons, function( name, props ) {
12146
			var click, buttonOptions;
12147
			props = $.isFunction( props ) ?
12148
				{ click: props, text: name } :
12149
				props;
12150
 
12151
			// Default to a non-submitting button
12152
			props = $.extend( { type: "button" }, props );
12153
 
12154
			// Change the context for the click callback to be the main element
12155
			click = props.click;
12156
			buttonOptions = {
12157
				icon: props.icon,
12158
				iconPosition: props.iconPosition,
12159
				showLabel: props.showLabel,
12160
 
12161
				// Deprecated options
12162
				icons: props.icons,
12163
				text: props.text
12164
			};
12165
 
12166
			delete props.click;
12167
			delete props.icon;
12168
			delete props.iconPosition;
12169
			delete props.showLabel;
12170
 
12171
			// Deprecated options
12172
			delete props.icons;
12173
			if ( typeof props.text === "boolean" ) {
12174
				delete props.text;
12175
			}
12176
 
12177
			$( "<button></button>", props )
12178
				.button( buttonOptions )
12179
				.appendTo( that.uiButtonSet )
12180
				.on( "click", function() {
12181
					click.apply( that.element[ 0 ], arguments );
12182
				} );
12183
		} );
12184
		this._addClass( this.uiDialog, "ui-dialog-buttons" );
12185
		this.uiDialogButtonPane.appendTo( this.uiDialog );
12186
	},
12187
 
12188
	_makeDraggable: function() {
12189
		var that = this,
12190
			options = this.options;
12191
 
12192
		function filteredUi( ui ) {
12193
			return {
12194
				position: ui.position,
12195
				offset: ui.offset
12196
			};
12197
		}
12198
 
12199
		this.uiDialog.draggable( {
12200
			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
12201
			handle: ".ui-dialog-titlebar",
12202
			containment: "document",
12203
			start: function( event, ui ) {
12204
				that._addClass( $( this ), "ui-dialog-dragging" );
12205
				that._blockFrames();
12206
				that._trigger( "dragStart", event, filteredUi( ui ) );
12207
			},
12208
			drag: function( event, ui ) {
12209
				that._trigger( "drag", event, filteredUi( ui ) );
12210
			},
12211
			stop: function( event, ui ) {
12212
				var left = ui.offset.left - that.document.scrollLeft(),
12213
					top = ui.offset.top - that.document.scrollTop();
12214
 
12215
				options.position = {
12216
					my: "left top",
12217
					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12218
						"top" + ( top >= 0 ? "+" : "" ) + top,
12219
					of: that.window
12220
				};
12221
				that._removeClass( $( this ), "ui-dialog-dragging" );
12222
				that._unblockFrames();
12223
				that._trigger( "dragStop", event, filteredUi( ui ) );
12224
			}
12225
		} );
12226
	},
12227
 
12228
	_makeResizable: function() {
12229
		var that = this,
12230
			options = this.options,
12231
			handles = options.resizable,
12232
 
12233
			// .ui-resizable has position: relative defined in the stylesheet
12234
			// but dialogs have to use absolute or fixed positioning
12235
			position = this.uiDialog.css( "position" ),
12236
			resizeHandles = typeof handles === "string" ?
12237
				handles :
12238
				"n,e,s,w,se,sw,ne,nw";
12239
 
12240
		function filteredUi( ui ) {
12241
			return {
12242
				originalPosition: ui.originalPosition,
12243
				originalSize: ui.originalSize,
12244
				position: ui.position,
12245
				size: ui.size
12246
			};
12247
		}
12248
 
12249
		this.uiDialog.resizable( {
12250
			cancel: ".ui-dialog-content",
12251
			containment: "document",
12252
			alsoResize: this.element,
12253
			maxWidth: options.maxWidth,
12254
			maxHeight: options.maxHeight,
12255
			minWidth: options.minWidth,
12256
			minHeight: this._minHeight(),
12257
			handles: resizeHandles,
12258
			start: function( event, ui ) {
12259
				that._addClass( $( this ), "ui-dialog-resizing" );
12260
				that._blockFrames();
12261
				that._trigger( "resizeStart", event, filteredUi( ui ) );
12262
			},
12263
			resize: function( event, ui ) {
12264
				that._trigger( "resize", event, filteredUi( ui ) );
12265
			},
12266
			stop: function( event, ui ) {
12267
				var offset = that.uiDialog.offset(),
12268
					left = offset.left - that.document.scrollLeft(),
12269
					top = offset.top - that.document.scrollTop();
12270
 
12271
				options.height = that.uiDialog.height();
12272
				options.width = that.uiDialog.width();
12273
				options.position = {
12274
					my: "left top",
12275
					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12276
						"top" + ( top >= 0 ? "+" : "" ) + top,
12277
					of: that.window
12278
				};
12279
				that._removeClass( $( this ), "ui-dialog-resizing" );
12280
				that._unblockFrames();
12281
				that._trigger( "resizeStop", event, filteredUi( ui ) );
12282
			}
12283
		} )
12284
			.css( "position", position );
12285
	},
12286
 
12287
	_trackFocus: function() {
12288
		this._on( this.widget(), {
12289
			focusin: function( event ) {
12290
				this._makeFocusTarget();
12291
				this._focusedElement = $( event.target );
12292
			}
12293
		} );
12294
	},
12295
 
12296
	_makeFocusTarget: function() {
12297
		this._untrackInstance();
12298
		this._trackingInstances().unshift( this );
12299
	},
12300
 
12301
	_untrackInstance: function() {
12302
		var instances = this._trackingInstances(),
12303
			exists = $.inArray( this, instances );
12304
		if ( exists !== -1 ) {
12305
			instances.splice( exists, 1 );
12306
		}
12307
	},
12308
 
12309
	_trackingInstances: function() {
12310
		var instances = this.document.data( "ui-dialog-instances" );
12311
		if ( !instances ) {
12312
			instances = [];
12313
			this.document.data( "ui-dialog-instances", instances );
12314
		}
12315
		return instances;
12316
	},
12317
 
12318
	_minHeight: function() {
12319
		var options = this.options;
12320
 
12321
		return options.height === "auto" ?
12322
			options.minHeight :
12323
			Math.min( options.minHeight, options.height );
12324
	},
12325
 
12326
	_position: function() {
12327
 
12328
		// Need to show the dialog to get the actual offset in the position plugin
12329
		var isVisible = this.uiDialog.is( ":visible" );
12330
		if ( !isVisible ) {
12331
			this.uiDialog.show();
12332
		}
12333
		this.uiDialog.position( this.options.position );
12334
		if ( !isVisible ) {
12335
			this.uiDialog.hide();
12336
		}
12337
	},
12338
 
12339
	_setOptions: function( options ) {
12340
		var that = this,
12341
			resize = false,
12342
			resizableOptions = {};
12343
 
12344
		$.each( options, function( key, value ) {
12345
			that._setOption( key, value );
12346
 
12347
			if ( key in that.sizeRelatedOptions ) {
12348
				resize = true;
12349
			}
12350
			if ( key in that.resizableRelatedOptions ) {
12351
				resizableOptions[ key ] = value;
12352
			}
12353
		} );
12354
 
12355
		if ( resize ) {
12356
			this._size();
12357
			this._position();
12358
		}
12359
		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12360
			this.uiDialog.resizable( "option", resizableOptions );
12361
		}
12362
	},
12363
 
12364
	_setOption: function( key, value ) {
12365
		var isDraggable, isResizable,
12366
			uiDialog = this.uiDialog;
12367
 
12368
		if ( key === "disabled" ) {
12369
			return;
12370
		}
12371
 
12372
		this._super( key, value );
12373
 
12374
		if ( key === "appendTo" ) {
12375
			this.uiDialog.appendTo( this._appendTo() );
12376
		}
12377
 
12378
		if ( key === "buttons" ) {
12379
			this._createButtons();
12380
		}
12381
 
12382
		if ( key === "closeText" ) {
12383
			this.uiDialogTitlebarClose.button( {
12384
 
12385
				// Ensure that we always pass a string
12386
				label: $( "<a>" ).text( "" + this.options.closeText ).html()
12387
			} );
12388
		}
12389
 
12390
		if ( key === "draggable" ) {
12391
			isDraggable = uiDialog.is( ":data(ui-draggable)" );
12392
			if ( isDraggable && !value ) {
12393
				uiDialog.draggable( "destroy" );
12394
			}
12395
 
12396
			if ( !isDraggable && value ) {
12397
				this._makeDraggable();
12398
			}
12399
		}
12400
 
12401
		if ( key === "position" ) {
12402
			this._position();
12403
		}
12404
 
12405
		if ( key === "resizable" ) {
12406
 
12407
			// currently resizable, becoming non-resizable
12408
			isResizable = uiDialog.is( ":data(ui-resizable)" );
12409
			if ( isResizable && !value ) {
12410
				uiDialog.resizable( "destroy" );
12411
			}
12412
 
12413
			// Currently resizable, changing handles
12414
			if ( isResizable && typeof value === "string" ) {
12415
				uiDialog.resizable( "option", "handles", value );
12416
			}
12417
 
12418
			// Currently non-resizable, becoming resizable
12419
			if ( !isResizable && value !== false ) {
12420
				this._makeResizable();
12421
			}
12422
		}
12423
 
12424
		if ( key === "title" ) {
12425
			this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
12426
		}
12427
	},
12428
 
12429
	_size: function() {
12430
 
12431
		// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
12432
		// divs will both have width and height set, so we need to reset them
12433
		var nonContentHeight, minContentHeight, maxContentHeight,
12434
			options = this.options;
12435
 
12436
		// Reset content sizing
12437
		this.element.show().css( {
12438
			width: "auto",
12439
			minHeight: 0,
12440
			maxHeight: "none",
12441
			height: 0
12442
		} );
12443
 
12444
		if ( options.minWidth > options.width ) {
12445
			options.width = options.minWidth;
12446
		}
12447
 
12448
		// Reset wrapper sizing
12449
		// determine the height of all the non-content elements
12450
		nonContentHeight = this.uiDialog.css( {
12451
			height: "auto",
12452
			width: options.width
12453
		} )
12454
			.outerHeight();
12455
		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
12456
		maxContentHeight = typeof options.maxHeight === "number" ?
12457
			Math.max( 0, options.maxHeight - nonContentHeight ) :
12458
			"none";
12459
 
12460
		if ( options.height === "auto" ) {
12461
			this.element.css( {
12462
				minHeight: minContentHeight,
12463
				maxHeight: maxContentHeight,
12464
				height: "auto"
12465
			} );
12466
		} else {
12467
			this.element.height( Math.max( 0, options.height - nonContentHeight ) );
12468
		}
12469
 
12470
		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12471
			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
12472
		}
12473
	},
12474
 
12475
	_blockFrames: function() {
12476
		this.iframeBlocks = this.document.find( "iframe" ).map( function() {
12477
			var iframe = $( this );
12478
 
12479
			return $( "<div>" )
12480
				.css( {
12481
					position: "absolute",
12482
					width: iframe.outerWidth(),
12483
					height: iframe.outerHeight()
12484
				} )
12485
				.appendTo( iframe.parent() )
12486
				.offset( iframe.offset() )[ 0 ];
12487
		} );
12488
	},
12489
 
12490
	_unblockFrames: function() {
12491
		if ( this.iframeBlocks ) {
12492
			this.iframeBlocks.remove();
12493
			delete this.iframeBlocks;
12494
		}
12495
	},
12496
 
12497
	_allowInteraction: function( event ) {
12498
		if ( $( event.target ).closest( ".ui-dialog" ).length ) {
12499
			return true;
12500
		}
12501
 
12502
		// TODO: Remove hack when datepicker implements
12503
		// the .ui-front logic (#8989)
12504
		return !!$( event.target ).closest( ".ui-datepicker" ).length;
12505
	},
12506
 
12507
	_createOverlay: function() {
12508
		if ( !this.options.modal ) {
12509
			return;
12510
		}
12511
 
12512
		// We use a delay in case the overlay is created from an
12513
		// event that we're going to be cancelling (#2804)
12514
		var isOpening = true;
12515
		this._delay( function() {
12516
			isOpening = false;
12517
		} );
12518
 
12519
		if ( !this.document.data( "ui-dialog-overlays" ) ) {
12520
 
12521
			// Prevent use of anchors and inputs
12522
			// Using _on() for an event handler shared across many instances is
12523
			// safe because the dialogs stack and must be closed in reverse order
12524
			this._on( this.document, {
12525
				focusin: function( event ) {
12526
					if ( isOpening ) {
12527
						return;
12528
					}
12529
 
12530
					if ( !this._allowInteraction( event ) ) {
12531
						event.preventDefault();
12532
						this._trackingInstances()[ 0 ]._focusTabbable();
12533
					}
12534
				}
12535
			} );
12536
		}
12537
 
12538
		this.overlay = $( "<div>" )
12539
			.appendTo( this._appendTo() );
12540
 
12541
		this._addClass( this.overlay, null, "ui-widget-overlay ui-front" );
12542
		this._on( this.overlay, {
12543
			mousedown: "_keepFocus"
12544
		} );
12545
		this.document.data( "ui-dialog-overlays",
12546
			( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 );
12547
	},
12548
 
12549
	_destroyOverlay: function() {
12550
		if ( !this.options.modal ) {
12551
			return;
12552
		}
12553
 
12554
		if ( this.overlay ) {
12555
			var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
12556
 
12557
			if ( !overlays ) {
12558
				this._off( this.document, "focusin" );
12559
				this.document.removeData( "ui-dialog-overlays" );
12560
			} else {
12561
				this.document.data( "ui-dialog-overlays", overlays );
12562
			}
12563
 
12564
			this.overlay.remove();
12565
			this.overlay = null;
12566
		}
12567
	}
12568
} );
12569
 
12570
// DEPRECATED
12571
// TODO: switch return back to widget declaration at top of file when this is removed
12572
if ( $.uiBackCompat !== false ) {
12573
 
12574
	// Backcompat for dialogClass option
12575
	$.widget( "ui.dialog", $.ui.dialog, {
12576
		options: {
12577
			dialogClass: ""
12578
		},
12579
		_createWrapper: function() {
12580
			this._super();
12581
			this.uiDialog.addClass( this.options.dialogClass );
12582
		},
12583
		_setOption: function( key, value ) {
12584
			if ( key === "dialogClass" ) {
12585
				this.uiDialog
12586
					.removeClass( this.options.dialogClass )
12587
					.addClass( value );
12588
			}
12589
			this._superApply( arguments );
12590
		}
12591
	} );
12592
}
12593
 
12594
var widgetsDialog = $.ui.dialog;
12595
 
12596
 
12597
/*!
12598
 * jQuery UI Progressbar 1.12.1
12599
 * http://jqueryui.com
12600
 *
12601
 * Copyright jQuery Foundation and other contributors
12602
 * Released under the MIT license.
12603
 * http://jquery.org/license
12604
 */
12605
 
12606
//>>label: Progressbar
12607
//>>group: Widgets
12608
// jscs:disable maximumLineLength
12609
//>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators.
12610
// jscs:enable maximumLineLength
12611
//>>docs: http://api.jqueryui.com/progressbar/
12612
//>>demos: http://jqueryui.com/progressbar/
12613
//>>css.structure: ../../themes/base/core.css
12614
//>>css.structure: ../../themes/base/progressbar.css
12615
//>>css.theme: ../../themes/base/theme.css
12616
 
12617
 
12618
 
12619
var widgetsProgressbar = $.widget( "ui.progressbar", {
12620
	version: "1.12.1",
12621
	options: {
12622
		classes: {
12623
			"ui-progressbar": "ui-corner-all",
12624
			"ui-progressbar-value": "ui-corner-left",
12625
			"ui-progressbar-complete": "ui-corner-right"
12626
		},
12627
		max: 100,
12628
		value: 0,
12629
 
12630
		change: null,
12631
		complete: null
12632
	},
12633
 
12634
	min: 0,
12635
 
12636
	_create: function() {
12637
 
12638
		// Constrain initial value
12639
		this.oldValue = this.options.value = this._constrainedValue();
12640
 
12641
		this.element.attr( {
12642
 
12643
			// Only set static values; aria-valuenow and aria-valuemax are
12644
			// set inside _refreshValue()
12645
			role: "progressbar",
12646
			"aria-valuemin": this.min
12647
		} );
12648
		this._addClass( "ui-progressbar", "ui-widget ui-widget-content" );
12649
 
12650
		this.valueDiv = $( "<div>" ).appendTo( this.element );
12651
		this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" );
12652
		this._refreshValue();
12653
	},
12654
 
12655
	_destroy: function() {
12656
		this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" );
12657
 
12658
		this.valueDiv.remove();
12659
	},
12660
 
12661
	value: function( newValue ) {
12662
		if ( newValue === undefined ) {
12663
			return this.options.value;
12664
		}
12665
 
12666
		this.options.value = this._constrainedValue( newValue );
12667
		this._refreshValue();
12668
	},
12669
 
12670
	_constrainedValue: function( newValue ) {
12671
		if ( newValue === undefined ) {
12672
			newValue = this.options.value;
12673
		}
12674
 
12675
		this.indeterminate = newValue === false;
12676
 
12677
		// Sanitize value
12678
		if ( typeof newValue !== "number" ) {
12679
			newValue = 0;
12680
		}
12681
 
12682
		return this.indeterminate ? false :
12683
			Math.min( this.options.max, Math.max( this.min, newValue ) );
12684
	},
12685
 
12686
	_setOptions: function( options ) {
12687
 
12688
		// Ensure "value" option is set after other values (like max)
12689
		var value = options.value;
12690
		delete options.value;
12691
 
12692
		this._super( options );
12693
 
12694
		this.options.value = this._constrainedValue( value );
12695
		this._refreshValue();
12696
	},
12697
 
12698
	_setOption: function( key, value ) {
12699
		if ( key === "max" ) {
12700
 
12701
			// Don't allow a max less than min
12702
			value = Math.max( this.min, value );
12703
		}
12704
		this._super( key, value );
12705
	},
12706
 
12707
	_setOptionDisabled: function( value ) {
12708
		this._super( value );
12709
 
12710
		this.element.attr( "aria-disabled", value );
12711
		this._toggleClass( null, "ui-state-disabled", !!value );
12712
	},
12713
 
12714
	_percentage: function() {
12715
		return this.indeterminate ?
12716
			100 :
12717
			100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
12718
	},
12719
 
12720
	_refreshValue: function() {
12721
		var value = this.options.value,
12722
			percentage = this._percentage();
12723
 
12724
		this.valueDiv
12725
			.toggle( this.indeterminate || value > this.min )
12726
			.width( percentage.toFixed( 0 ) + "%" );
12727
 
12728
		this
12729
			._toggleClass( this.valueDiv, "ui-progressbar-complete", null,
12730
				value === this.options.max )
12731
			._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate );
12732
 
12733
		if ( this.indeterminate ) {
12734
			this.element.removeAttr( "aria-valuenow" );
12735
			if ( !this.overlayDiv ) {
12736
				this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv );
12737
				this._addClass( this.overlayDiv, "ui-progressbar-overlay" );
12738
			}
12739
		} else {
12740
			this.element.attr( {
12741
				"aria-valuemax": this.options.max,
12742
				"aria-valuenow": value
12743
			} );
12744
			if ( this.overlayDiv ) {
12745
				this.overlayDiv.remove();
12746
				this.overlayDiv = null;
12747
			}
12748
		}
12749
 
12750
		if ( this.oldValue !== value ) {
12751
			this.oldValue = value;
12752
			this._trigger( "change" );
12753
		}
12754
		if ( value === this.options.max ) {
12755
			this._trigger( "complete" );
12756
		}
12757
	}
12758
} );
12759
 
12760
 
12761
/*!
12762
 * jQuery UI Selectmenu 1.12.1
12763
 * http://jqueryui.com
12764
 *
12765
 * Copyright jQuery Foundation and other contributors
12766
 * Released under the MIT license.
12767
 * http://jquery.org/license
12768
 */
12769
 
12770
//>>label: Selectmenu
12771
//>>group: Widgets
12772
// jscs:disable maximumLineLength
12773
//>>description: Duplicates and extends the functionality of a native HTML select element, allowing it to be customizable in behavior and appearance far beyond the limitations of a native select.
12774
// jscs:enable maximumLineLength
12775
//>>docs: http://api.jqueryui.com/selectmenu/
12776
//>>demos: http://jqueryui.com/selectmenu/
12777
//>>css.structure: ../../themes/base/core.css
12778
//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css
12779
//>>css.theme: ../../themes/base/theme.css
12780
 
12781
 
12782
 
12783
var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
12784
	version: "1.12.1",
12785
	defaultElement: "<select>",
12786
	options: {
12787
		appendTo: null,
12788
		classes: {
12789
			"ui-selectmenu-button-open": "ui-corner-top",
12790
			"ui-selectmenu-button-closed": "ui-corner-all"
12791
		},
12792
		disabled: null,
12793
		icons: {
12794
			button: "ui-icon-triangle-1-s"
12795
		},
12796
		position: {
12797
			my: "left top",
12798
			at: "left bottom",
12799
			collision: "none"
12800
		},
12801
		width: false,
12802
 
12803
		// Callbacks
12804
		change: null,
12805
		close: null,
12806
		focus: null,
12807
		open: null,
12808
		select: null
12809
	},
12810
 
12811
	_create: function() {
12812
		var selectmenuId = this.element.uniqueId().attr( "id" );
12813
		this.ids = {
12814
			element: selectmenuId,
12815
			button: selectmenuId + "-button",
12816
			menu: selectmenuId + "-menu"
12817
		};
12818
 
12819
		this._drawButton();
12820
		this._drawMenu();
12821
		this._bindFormResetHandler();
12822
 
12823
		this._rendered = false;
12824
		this.menuItems = $();
12825
	},
12826
 
12827
	_drawButton: function() {
12828
		var icon,
12829
			that = this,
12830
			item = this._parseOption(
12831
				this.element.find( "option:selected" ),
12832
				this.element[ 0 ].selectedIndex
12833
			);
12834
 
12835
		// Associate existing label with the new button
12836
		this.labels = this.element.labels().attr( "for", this.ids.button );
12837
		this._on( this.labels, {
12838
			click: function( event ) {
12839
				this.button.focus();
12840
				event.preventDefault();
12841
			}
12842
		} );
12843
 
12844
		// Hide original select element
12845
		this.element.hide();
12846
 
12847
		// Create button
12848
		this.button = $( "<span>", {
12849
			tabindex: this.options.disabled ? -1 : 0,
12850
			id: this.ids.button,
12851
			role: "combobox",
12852
			"aria-expanded": "false",
12853
			"aria-autocomplete": "list",
12854
			"aria-owns": this.ids.menu,
12855
			"aria-haspopup": "true",
12856
			title: this.element.attr( "title" )
12857
		} )
12858
			.insertAfter( this.element );
12859
 
12860
		this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed",
12861
			"ui-button ui-widget" );
12862
 
12863
		icon = $( "<span>" ).appendTo( this.button );
12864
		this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button );
12865
		this.buttonItem = this._renderButtonItem( item )
12866
			.appendTo( this.button );
12867
 
12868
		if ( this.options.width !== false ) {
12869
			this._resizeButton();
12870
		}
12871
 
12872
		this._on( this.button, this._buttonEvents );
12873
		this.button.one( "focusin", function() {
12874
 
12875
			// Delay rendering the menu items until the button receives focus.
12876
			// The menu may have already been rendered via a programmatic open.
12877
			if ( !that._rendered ) {
12878
				that._refreshMenu();
12879
			}
12880
		} );
12881
	},
12882
 
12883
	_drawMenu: function() {
12884
		var that = this;
12885
 
12886
		// Create menu
12887
		this.menu = $( "<ul>", {
12888
			"aria-hidden": "true",
12889
			"aria-labelledby": this.ids.button,
12890
			id: this.ids.menu
12891
		} );
12892
 
12893
		// Wrap menu
12894
		this.menuWrap = $( "<div>" ).append( this.menu );
12895
		this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" );
12896
		this.menuWrap.appendTo( this._appendTo() );
12897
 
12898
		// Initialize menu widget
12899
		this.menuInstance = this.menu
12900
			.menu( {
12901
				classes: {
12902
					"ui-menu": "ui-corner-bottom"
12903
				},
12904
				role: "listbox",
12905
				select: function( event, ui ) {
12906
					event.preventDefault();
12907
 
12908
					// Support: IE8
12909
					// If the item was selected via a click, the text selection
12910
					// will be destroyed in IE
12911
					that._setSelection();
12912
 
12913
					that._select( ui.item.data( "ui-selectmenu-item" ), event );
12914
				},
12915
				focus: function( event, ui ) {
12916
					var item = ui.item.data( "ui-selectmenu-item" );
12917
 
12918
					// Prevent inital focus from firing and check if its a newly focused item
12919
					if ( that.focusIndex != null && item.index !== that.focusIndex ) {
12920
						that._trigger( "focus", event, { item: item } );
12921
						if ( !that.isOpen ) {
12922
							that._select( item, event );
12923
						}
12924
					}
12925
					that.focusIndex = item.index;
12926
 
12927
					that.button.attr( "aria-activedescendant",
12928
						that.menuItems.eq( item.index ).attr( "id" ) );
12929
				}
12930
			} )
12931
			.menu( "instance" );
12932
 
12933
		// Don't close the menu on mouseleave
12934
		this.menuInstance._off( this.menu, "mouseleave" );
12935
 
12936
		// Cancel the menu's collapseAll on document click
12937
		this.menuInstance._closeOnDocumentClick = function() {
12938
			return false;
12939
		};
12940
 
12941
		// Selects often contain empty items, but never contain dividers
12942
		this.menuInstance._isDivider = function() {
12943
			return false;
12944
		};
12945
	},
12946
 
12947
	refresh: function() {
12948
		this._refreshMenu();
12949
		this.buttonItem.replaceWith(
12950
			this.buttonItem = this._renderButtonItem(
12951
 
12952
				// Fall back to an empty object in case there are no options
12953
				this._getSelectedItem().data( "ui-selectmenu-item" ) || {}
12954
			)
12955
		);
12956
		if ( this.options.width === null ) {
12957
			this._resizeButton();
12958
		}
12959
	},
12960
 
12961
	_refreshMenu: function() {
12962
		var item,
12963
			options = this.element.find( "option" );
12964
 
12965
		this.menu.empty();
12966
 
12967
		this._parseOptions( options );
12968
		this._renderMenu( this.menu, this.items );
12969
 
12970
		this.menuInstance.refresh();
12971
		this.menuItems = this.menu.find( "li" )
12972
			.not( ".ui-selectmenu-optgroup" )
12973
				.find( ".ui-menu-item-wrapper" );
12974
 
12975
		this._rendered = true;
12976
 
12977
		if ( !options.length ) {
12978
			return;
12979
		}
12980
 
12981
		item = this._getSelectedItem();
12982
 
12983
		// Update the menu to have the correct item focused
12984
		this.menuInstance.focus( null, item );
12985
		this._setAria( item.data( "ui-selectmenu-item" ) );
12986
 
12987
		// Set disabled state
12988
		this._setOption( "disabled", this.element.prop( "disabled" ) );
12989
	},
12990
 
12991
	open: function( event ) {
12992
		if ( this.options.disabled ) {
12993
			return;
12994
		}
12995
 
12996
		// If this is the first time the menu is being opened, render the items
12997
		if ( !this._rendered ) {
12998
			this._refreshMenu();
12999
		} else {
13000
 
13001
			// Menu clears focus on close, reset focus to selected item
13002
			this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" );
13003
			this.menuInstance.focus( null, this._getSelectedItem() );
13004
		}
13005
 
13006
		// If there are no options, don't open the menu
13007
		if ( !this.menuItems.length ) {
13008
			return;
13009
		}
13010
 
13011
		this.isOpen = true;
13012
		this._toggleAttr();
13013
		this._resizeMenu();
13014
		this._position();
13015
 
13016
		this._on( this.document, this._documentClick );
13017
 
13018
		this._trigger( "open", event );
13019
	},
13020
 
13021
	_position: function() {
13022
		this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
13023
	},
13024
 
13025
	close: function( event ) {
13026
		if ( !this.isOpen ) {
13027
			return;
13028
		}
13029
 
13030
		this.isOpen = false;
13031
		this._toggleAttr();
13032
 
13033
		this.range = null;
13034
		this._off( this.document );
13035
 
13036
		this._trigger( "close", event );
13037
	},
13038
 
13039
	widget: function() {
13040
		return this.button;
13041
	},
13042
 
13043
	menuWidget: function() {
13044
		return this.menu;
13045
	},
13046
 
13047
	_renderButtonItem: function( item ) {
13048
		var buttonItem = $( "<span>" );
13049
 
13050
		this._setText( buttonItem, item.label );
13051
		this._addClass( buttonItem, "ui-selectmenu-text" );
13052
 
13053
		return buttonItem;
13054
	},
13055
 
13056
	_renderMenu: function( ul, items ) {
13057
		var that = this,
13058
			currentOptgroup = "";
13059
 
13060
		$.each( items, function( index, item ) {
13061
			var li;
13062
 
13063
			if ( item.optgroup !== currentOptgroup ) {
13064
				li = $( "<li>", {
13065
					text: item.optgroup
13066
				} );
13067
				that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" +
13068
					( item.element.parent( "optgroup" ).prop( "disabled" ) ?
13069
						" ui-state-disabled" :
13070
						"" ) );
13071
 
13072
				li.appendTo( ul );
13073
 
13074
				currentOptgroup = item.optgroup;
13075
			}
13076
 
13077
			that._renderItemData( ul, item );
13078
		} );
13079
	},
13080
 
13081
	_renderItemData: function( ul, item ) {
13082
		return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
13083
	},
13084
 
13085
	_renderItem: function( ul, item ) {
13086
		var li = $( "<li>" ),
13087
			wrapper = $( "<div>", {
13088
				title: item.element.attr( "title" )
13089
			} );
13090
 
13091
		if ( item.disabled ) {
13092
			this._addClass( li, null, "ui-state-disabled" );
13093
		}
13094
		this._setText( wrapper, item.label );
13095
 
13096
		return li.append( wrapper ).appendTo( ul );
13097
	},
13098
 
13099
	_setText: function( element, value ) {
13100
		if ( value ) {
13101
			element.text( value );
13102
		} else {
13103
			element.html( "&#160;" );
13104
		}
13105
	},
13106
 
13107
	_move: function( direction, event ) {
13108
		var item, next,
13109
			filter = ".ui-menu-item";
13110
 
13111
		if ( this.isOpen ) {
13112
			item = this.menuItems.eq( this.focusIndex ).parent( "li" );
13113
		} else {
13114
			item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
13115
			filter += ":not(.ui-state-disabled)";
13116
		}
13117
 
13118
		if ( direction === "first" || direction === "last" ) {
13119
			next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
13120
		} else {
13121
			next = item[ direction + "All" ]( filter ).eq( 0 );
13122
		}
13123
 
13124
		if ( next.length ) {
13125
			this.menuInstance.focus( event, next );
13126
		}
13127
	},
13128
 
13129
	_getSelectedItem: function() {
13130
		return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
13131
	},
13132
 
13133
	_toggle: function( event ) {
13134
		this[ this.isOpen ? "close" : "open" ]( event );
13135
	},
13136
 
13137
	_setSelection: function() {
13138
		var selection;
13139
 
13140
		if ( !this.range ) {
13141
			return;
13142
		}
13143
 
13144
		if ( window.getSelection ) {
13145
			selection = window.getSelection();
13146
			selection.removeAllRanges();
13147
			selection.addRange( this.range );
13148
 
13149
		// Support: IE8
13150
		} else {
13151
			this.range.select();
13152
		}
13153
 
13154
		// Support: IE
13155
		// Setting the text selection kills the button focus in IE, but
13156
		// restoring the focus doesn't kill the selection.
13157
		this.button.focus();
13158
	},
13159
 
13160
	_documentClick: {
13161
		mousedown: function( event ) {
13162
			if ( !this.isOpen ) {
13163
				return;
13164
			}
13165
 
13166
			if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" +
13167
					$.ui.escapeSelector( this.ids.button ) ).length ) {
13168
				this.close( event );
13169
			}
13170
		}
13171
	},
13172
 
13173
	_buttonEvents: {
13174
 
13175
		// Prevent text selection from being reset when interacting with the selectmenu (#10144)
13176
		mousedown: function() {
13177
			var selection;
13178
 
13179
			if ( window.getSelection ) {
13180
				selection = window.getSelection();
13181
				if ( selection.rangeCount ) {
13182
					this.range = selection.getRangeAt( 0 );
13183
				}
13184
 
13185
			// Support: IE8
13186
			} else {
13187
				this.range = document.selection.createRange();
13188
			}
13189
		},
13190
 
13191
		click: function( event ) {
13192
			this._setSelection();
13193
			this._toggle( event );
13194
		},
13195
 
13196
		keydown: function( event ) {
13197
			var preventDefault = true;
13198
			switch ( event.keyCode ) {
13199
			case $.ui.keyCode.TAB:
13200
			case $.ui.keyCode.ESCAPE:
13201
				this.close( event );
13202
				preventDefault = false;
13203
				break;
13204
			case $.ui.keyCode.ENTER:
13205
				if ( this.isOpen ) {
13206
					this._selectFocusedItem( event );
13207
				}
13208
				break;
13209
			case $.ui.keyCode.UP:
13210
				if ( event.altKey ) {
13211
					this._toggle( event );
13212
				} else {
13213
					this._move( "prev", event );
13214
				}
13215
				break;
13216
			case $.ui.keyCode.DOWN:
13217
				if ( event.altKey ) {
13218
					this._toggle( event );
13219
				} else {
13220
					this._move( "next", event );
13221
				}
13222
				break;
13223
			case $.ui.keyCode.SPACE:
13224
				if ( this.isOpen ) {
13225
					this._selectFocusedItem( event );
13226
				} else {
13227
					this._toggle( event );
13228
				}
13229
				break;
13230
			case $.ui.keyCode.LEFT:
13231
				this._move( "prev", event );
13232
				break;
13233
			case $.ui.keyCode.RIGHT:
13234
				this._move( "next", event );
13235
				break;
13236
			case $.ui.keyCode.HOME:
13237
			case $.ui.keyCode.PAGE_UP:
13238
				this._move( "first", event );
13239
				break;
13240
			case $.ui.keyCode.END:
13241
			case $.ui.keyCode.PAGE_DOWN:
13242
				this._move( "last", event );
13243
				break;
13244
			default:
13245
				this.menu.trigger( event );
13246
				preventDefault = false;
13247
			}
13248
 
13249
			if ( preventDefault ) {
13250
				event.preventDefault();
13251
			}
13252
		}
13253
	},
13254
 
13255
	_selectFocusedItem: function( event ) {
13256
		var item = this.menuItems.eq( this.focusIndex ).parent( "li" );
13257
		if ( !item.hasClass( "ui-state-disabled" ) ) {
13258
			this._select( item.data( "ui-selectmenu-item" ), event );
13259
		}
13260
	},
13261
 
13262
	_select: function( item, event ) {
13263
		var oldIndex = this.element[ 0 ].selectedIndex;
13264
 
13265
		// Change native select element
13266
		this.element[ 0 ].selectedIndex = item.index;
13267
		this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) );
13268
		this._setAria( item );
13269
		this._trigger( "select", event, { item: item } );
13270
 
13271
		if ( item.index !== oldIndex ) {
13272
			this._trigger( "change", event, { item: item } );
13273
		}
13274
 
13275
		this.close( event );
13276
	},
13277
 
13278
	_setAria: function( item ) {
13279
		var id = this.menuItems.eq( item.index ).attr( "id" );
13280
 
13281
		this.button.attr( {
13282
			"aria-labelledby": id,
13283
			"aria-activedescendant": id
13284
		} );
13285
		this.menu.attr( "aria-activedescendant", id );
13286
	},
13287
 
13288
	_setOption: function( key, value ) {
13289
		if ( key === "icons" ) {
13290
			var icon = this.button.find( "span.ui-icon" );
13291
			this._removeClass( icon, null, this.options.icons.button )
13292
				._addClass( icon, null, value.button );
13293
		}
13294
 
13295
		this._super( key, value );
13296
 
13297
		if ( key === "appendTo" ) {
13298
			this.menuWrap.appendTo( this._appendTo() );
13299
		}
13300
 
13301
		if ( key === "width" ) {
13302
			this._resizeButton();
13303
		}
13304
	},
13305
 
13306
	_setOptionDisabled: function( value ) {
13307
		this._super( value );
13308
 
13309
		this.menuInstance.option( "disabled", value );
13310
		this.button.attr( "aria-disabled", value );
13311
		this._toggleClass( this.button, null, "ui-state-disabled", value );
13312
 
13313
		this.element.prop( "disabled", value );
13314
		if ( value ) {
13315
			this.button.attr( "tabindex", -1 );
13316
			this.close();
13317
		} else {
13318
			this.button.attr( "tabindex", 0 );
13319
		}
13320
	},
13321
 
13322
	_appendTo: function() {
13323
		var element = this.options.appendTo;
13324
 
13325
		if ( element ) {
13326
			element = element.jquery || element.nodeType ?
13327
				$( element ) :
13328
				this.document.find( element ).eq( 0 );
13329
		}
13330
 
13331
		if ( !element || !element[ 0 ] ) {
13332
			element = this.element.closest( ".ui-front, dialog" );
13333
		}
13334
 
13335
		if ( !element.length ) {
13336
			element = this.document[ 0 ].body;
13337
		}
13338
 
13339
		return element;
13340
	},
13341
 
13342
	_toggleAttr: function() {
13343
		this.button.attr( "aria-expanded", this.isOpen );
13344
 
13345
		// We can't use two _toggleClass() calls here, because we need to make sure
13346
		// we always remove classes first and add them second, otherwise if both classes have the
13347
		// same theme class, it will be removed after we add it.
13348
		this._removeClass( this.button, "ui-selectmenu-button-" +
13349
			( this.isOpen ? "closed" : "open" ) )
13350
			._addClass( this.button, "ui-selectmenu-button-" +
13351
				( this.isOpen ? "open" : "closed" ) )
13352
			._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen );
13353
 
13354
		this.menu.attr( "aria-hidden", !this.isOpen );
13355
	},
13356
 
13357
	_resizeButton: function() {
13358
		var width = this.options.width;
13359
 
13360
		// For `width: false`, just remove inline style and stop
13361
		if ( width === false ) {
13362
			this.button.css( "width", "" );
13363
			return;
13364
		}
13365
 
13366
		// For `width: null`, match the width of the original element
13367
		if ( width === null ) {
13368
			width = this.element.show().outerWidth();
13369
			this.element.hide();
13370
		}
13371
 
13372
		this.button.outerWidth( width );
13373
	},
13374
 
13375
	_resizeMenu: function() {
13376
		this.menu.outerWidth( Math.max(
13377
			this.button.outerWidth(),
13378
 
13379
			// Support: IE10
13380
			// IE10 wraps long text (possibly a rounding bug)
13381
			// so we add 1px to avoid the wrapping
13382
			this.menu.width( "" ).outerWidth() + 1
13383
		) );
13384
	},
13385
 
13386
	_getCreateOptions: function() {
13387
		var options = this._super();
13388
 
13389
		options.disabled = this.element.prop( "disabled" );
13390
 
13391
		return options;
13392
	},
13393
 
13394
	_parseOptions: function( options ) {
13395
		var that = this,
13396
			data = [];
13397
		options.each( function( index, item ) {
13398
			data.push( that._parseOption( $( item ), index ) );
13399
		} );
13400
		this.items = data;
13401
	},
13402
 
13403
	_parseOption: function( option, index ) {
13404
		var optgroup = option.parent( "optgroup" );
13405
 
13406
		return {
13407
			element: option,
13408
			index: index,
13409
			value: option.val(),
13410
			label: option.text(),
13411
			optgroup: optgroup.attr( "label" ) || "",
13412
			disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
13413
		};
13414
	},
13415
 
13416
	_destroy: function() {
13417
		this._unbindFormResetHandler();
13418
		this.menuWrap.remove();
13419
		this.button.remove();
13420
		this.element.show();
13421
		this.element.removeUniqueId();
13422
		this.labels.attr( "for", this.ids.element );
13423
	}
13424
} ] );
13425
 
13426
 
13427
/*!
13428
 * jQuery UI Slider 1.12.1
13429
 * http://jqueryui.com
13430
 *
13431
 * Copyright jQuery Foundation and other contributors
13432
 * Released under the MIT license.
13433
 * http://jquery.org/license
13434
 */
13435
 
13436
//>>label: Slider
13437
//>>group: Widgets
13438
//>>description: Displays a flexible slider with ranges and accessibility via keyboard.
13439
//>>docs: http://api.jqueryui.com/slider/
13440
//>>demos: http://jqueryui.com/slider/
13441
//>>css.structure: ../../themes/base/core.css
13442
//>>css.structure: ../../themes/base/slider.css
13443
//>>css.theme: ../../themes/base/theme.css
13444
 
13445
 
13446
 
13447
var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, {
13448
	version: "1.12.1",
13449
	widgetEventPrefix: "slide",
13450
 
13451
	options: {
13452
		animate: false,
13453
		classes: {
13454
			"ui-slider": "ui-corner-all",
13455
			"ui-slider-handle": "ui-corner-all",
13456
 
13457
			// Note: ui-widget-header isn't the most fittingly semantic framework class for this
13458
			// element, but worked best visually with a variety of themes
13459
			"ui-slider-range": "ui-corner-all ui-widget-header"
13460
		},
13461
		distance: 0,
13462
		max: 100,
13463
		min: 0,
13464
		orientation: "horizontal",
13465
		range: false,
13466
		step: 1,
13467
		value: 0,
13468
		values: null,
13469
 
13470
		// Callbacks
13471
		change: null,
13472
		slide: null,
13473
		start: null,
13474
		stop: null
13475
	},
13476
 
13477
	// Number of pages in a slider
13478
	// (how many times can you page up/down to go through the whole range)
13479
	numPages: 5,
13480
 
13481
	_create: function() {
13482
		this._keySliding = false;
13483
		this._mouseSliding = false;
13484
		this._animateOff = true;
13485
		this._handleIndex = null;
13486
		this._detectOrientation();
13487
		this._mouseInit();
13488
		this._calculateNewMax();
13489
 
13490
		this._addClass( "ui-slider ui-slider-" + this.orientation,
13491
			"ui-widget ui-widget-content" );
13492
 
13493
		this._refresh();
13494
 
13495
		this._animateOff = false;
13496
	},
13497
 
13498
	_refresh: function() {
13499
		this._createRange();
13500
		this._createHandles();
13501
		this._setupEvents();
13502
		this._refreshValue();
13503
	},
13504
 
13505
	_createHandles: function() {
13506
		var i, handleCount,
13507
			options = this.options,
13508
			existingHandles = this.element.find( ".ui-slider-handle" ),
13509
			handle = "<span tabindex='0'></span>",
13510
			handles = [];
13511
 
13512
		handleCount = ( options.values && options.values.length ) || 1;
13513
 
13514
		if ( existingHandles.length > handleCount ) {
13515
			existingHandles.slice( handleCount ).remove();
13516
			existingHandles = existingHandles.slice( 0, handleCount );
13517
		}
13518
 
13519
		for ( i = existingHandles.length; i < handleCount; i++ ) {
13520
			handles.push( handle );
13521
		}
13522
 
13523
		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
13524
 
13525
		this._addClass( this.handles, "ui-slider-handle", "ui-state-default" );
13526
 
13527
		this.handle = this.handles.eq( 0 );
13528
 
13529
		this.handles.each( function( i ) {
13530
			$( this )
13531
				.data( "ui-slider-handle-index", i )
13532
				.attr( "tabIndex", 0 );
13533
		} );
13534
	},
13535
 
13536
	_createRange: function() {
13537
		var options = this.options;
13538
 
13539
		if ( options.range ) {
13540
			if ( options.range === true ) {
13541
				if ( !options.values ) {
13542
					options.values = [ this._valueMin(), this._valueMin() ];
13543
				} else if ( options.values.length && options.values.length !== 2 ) {
13544
					options.values = [ options.values[ 0 ], options.values[ 0 ] ];
13545
				} else if ( $.isArray( options.values ) ) {
13546
					options.values = options.values.slice( 0 );
13547
				}
13548
			}
13549
 
13550
			if ( !this.range || !this.range.length ) {
13551
				this.range = $( "<div>" )
13552
					.appendTo( this.element );
13553
 
13554
				this._addClass( this.range, "ui-slider-range" );
13555
			} else {
13556
				this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" );
13557
 
13558
				// Handle range switching from true to min/max
13559
				this.range.css( {
13560
					"left": "",
13561
					"bottom": ""
13562
				} );
13563
			}
13564
			if ( options.range === "min" || options.range === "max" ) {
13565
				this._addClass( this.range, "ui-slider-range-" + options.range );
13566
			}
13567
		} else {
13568
			if ( this.range ) {
13569
				this.range.remove();
13570
			}
13571
			this.range = null;
13572
		}
13573
	},
13574
 
13575
	_setupEvents: function() {
13576
		this._off( this.handles );
13577
		this._on( this.handles, this._handleEvents );
13578
		this._hoverable( this.handles );
13579
		this._focusable( this.handles );
13580
	},
13581
 
13582
	_destroy: function() {
13583
		this.handles.remove();
13584
		if ( this.range ) {
13585
			this.range.remove();
13586
		}
13587
 
13588
		this._mouseDestroy();
13589
	},
13590
 
13591
	_mouseCapture: function( event ) {
13592
		var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
13593
			that = this,
13594
			o = this.options;
13595
 
13596
		if ( o.disabled ) {
13597
			return false;
13598
		}
13599
 
13600
		this.elementSize = {
13601
			width: this.element.outerWidth(),
13602
			height: this.element.outerHeight()
13603
		};
13604
		this.elementOffset = this.element.offset();
13605
 
13606
		position = { x: event.pageX, y: event.pageY };
13607
		normValue = this._normValueFromMouse( position );
13608
		distance = this._valueMax() - this._valueMin() + 1;
13609
		this.handles.each( function( i ) {
13610
			var thisDistance = Math.abs( normValue - that.values( i ) );
13611
			if ( ( distance > thisDistance ) ||
13612
				( distance === thisDistance &&
13613
					( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) {
13614
				distance = thisDistance;
13615
				closestHandle = $( this );
13616
				index = i;
13617
			}
13618
		} );
13619
 
13620
		allowed = this._start( event, index );
13621
		if ( allowed === false ) {
13622
			return false;
13623
		}
13624
		this._mouseSliding = true;
13625
 
13626
		this._handleIndex = index;
13627
 
13628
		this._addClass( closestHandle, null, "ui-state-active" );
13629
		closestHandle.trigger( "focus" );
13630
 
13631
		offset = closestHandle.offset();
13632
		mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
13633
		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
13634
			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
13635
			top: event.pageY - offset.top -
13636
				( closestHandle.height() / 2 ) -
13637
				( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) -
13638
				( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) +
13639
				( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 )
13640
		};
13641
 
13642
		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
13643
			this._slide( event, index, normValue );
13644
		}
13645
		this._animateOff = true;
13646
		return true;
13647
	},
13648
 
13649
	_mouseStart: function() {
13650
		return true;
13651
	},
13652
 
13653
	_mouseDrag: function( event ) {
13654
		var position = { x: event.pageX, y: event.pageY },
13655
			normValue = this._normValueFromMouse( position );
13656
 
13657
		this._slide( event, this._handleIndex, normValue );
13658
 
13659
		return false;
13660
	},
13661
 
13662
	_mouseStop: function( event ) {
13663
		this._removeClass( this.handles, null, "ui-state-active" );
13664
		this._mouseSliding = false;
13665
 
13666
		this._stop( event, this._handleIndex );
13667
		this._change( event, this._handleIndex );
13668
 
13669
		this._handleIndex = null;
13670
		this._clickOffset = null;
13671
		this._animateOff = false;
13672
 
13673
		return false;
13674
	},
13675
 
13676
	_detectOrientation: function() {
13677
		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
13678
	},
13679
 
13680
	_normValueFromMouse: function( position ) {
13681
		var pixelTotal,
13682
			pixelMouse,
13683
			percentMouse,
13684
			valueTotal,
13685
			valueMouse;
13686
 
13687
		if ( this.orientation === "horizontal" ) {
13688
			pixelTotal = this.elementSize.width;
13689
			pixelMouse = position.x - this.elementOffset.left -
13690
				( this._clickOffset ? this._clickOffset.left : 0 );
13691
		} else {
13692
			pixelTotal = this.elementSize.height;
13693
			pixelMouse = position.y - this.elementOffset.top -
13694
				( this._clickOffset ? this._clickOffset.top : 0 );
13695
		}
13696
 
13697
		percentMouse = ( pixelMouse / pixelTotal );
13698
		if ( percentMouse > 1 ) {
13699
			percentMouse = 1;
13700
		}
13701
		if ( percentMouse < 0 ) {
13702
			percentMouse = 0;
13703
		}
13704
		if ( this.orientation === "vertical" ) {
13705
			percentMouse = 1 - percentMouse;
13706
		}
13707
 
13708
		valueTotal = this._valueMax() - this._valueMin();
13709
		valueMouse = this._valueMin() + percentMouse * valueTotal;
13710
 
13711
		return this._trimAlignValue( valueMouse );
13712
	},
13713
 
13714
	_uiHash: function( index, value, values ) {
13715
		var uiHash = {
13716
			handle: this.handles[ index ],
13717
			handleIndex: index,
13718
			value: value !== undefined ? value : this.value()
13719
		};
13720
 
13721
		if ( this._hasMultipleValues() ) {
13722
			uiHash.value = value !== undefined ? value : this.values( index );
13723
			uiHash.values = values || this.values();
13724
		}
13725
 
13726
		return uiHash;
13727
	},
13728
 
13729
	_hasMultipleValues: function() {
13730
		return this.options.values && this.options.values.length;
13731
	},
13732
 
13733
	_start: function( event, index ) {
13734
		return this._trigger( "start", event, this._uiHash( index ) );
13735
	},
13736
 
13737
	_slide: function( event, index, newVal ) {
13738
		var allowed, otherVal,
13739
			currentValue = this.value(),
13740
			newValues = this.values();
13741
 
13742
		if ( this._hasMultipleValues() ) {
13743
			otherVal = this.values( index ? 0 : 1 );
13744
			currentValue = this.values( index );
13745
 
13746
			if ( this.options.values.length === 2 && this.options.range === true ) {
13747
				newVal =  index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal );
13748
			}
13749
 
13750
			newValues[ index ] = newVal;
13751
		}
13752
 
13753
		if ( newVal === currentValue ) {
13754
			return;
13755
		}
13756
 
13757
		allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) );
13758
 
13759
		// A slide can be canceled by returning false from the slide callback
13760
		if ( allowed === false ) {
13761
			return;
13762
		}
13763
 
13764
		if ( this._hasMultipleValues() ) {
13765
			this.values( index, newVal );
13766
		} else {
13767
			this.value( newVal );
13768
		}
13769
	},
13770
 
13771
	_stop: function( event, index ) {
13772
		this._trigger( "stop", event, this._uiHash( index ) );
13773
	},
13774
 
13775
	_change: function( event, index ) {
13776
		if ( !this._keySliding && !this._mouseSliding ) {
13777
 
13778
			//store the last changed value index for reference when handles overlap
13779
			this._lastChangedValue = index;
13780
			this._trigger( "change", event, this._uiHash( index ) );
13781
		}
13782
	},
13783
 
13784
	value: function( newValue ) {
13785
		if ( arguments.length ) {
13786
			this.options.value = this._trimAlignValue( newValue );
13787
			this._refreshValue();
13788
			this._change( null, 0 );
13789
			return;
13790
		}
13791
 
13792
		return this._value();
13793
	},
13794
 
13795
	values: function( index, newValue ) {
13796
		var vals,
13797
			newValues,
13798
			i;
13799
 
13800
		if ( arguments.length > 1 ) {
13801
			this.options.values[ index ] = this._trimAlignValue( newValue );
13802
			this._refreshValue();
13803
			this._change( null, index );
13804
			return;
13805
		}
13806
 
13807
		if ( arguments.length ) {
13808
			if ( $.isArray( arguments[ 0 ] ) ) {
13809
				vals = this.options.values;
13810
				newValues = arguments[ 0 ];
13811
				for ( i = 0; i < vals.length; i += 1 ) {
13812
					vals[ i ] = this._trimAlignValue( newValues[ i ] );
13813
					this._change( null, i );
13814
				}
13815
				this._refreshValue();
13816
			} else {
13817
				if ( this._hasMultipleValues() ) {
13818
					return this._values( index );
13819
				} else {
13820
					return this.value();
13821
				}
13822
			}
13823
		} else {
13824
			return this._values();
13825
		}
13826
	},
13827
 
13828
	_setOption: function( key, value ) {
13829
		var i,
13830
			valsLength = 0;
13831
 
13832
		if ( key === "range" && this.options.range === true ) {
13833
			if ( value === "min" ) {
13834
				this.options.value = this._values( 0 );
13835
				this.options.values = null;
13836
			} else if ( value === "max" ) {
13837
				this.options.value = this._values( this.options.values.length - 1 );
13838
				this.options.values = null;
13839
			}
13840
		}
13841
 
13842
		if ( $.isArray( this.options.values ) ) {
13843
			valsLength = this.options.values.length;
13844
		}
13845
 
13846
		this._super( key, value );
13847
 
13848
		switch ( key ) {
13849
			case "orientation":
13850
				this._detectOrientation();
13851
				this._removeClass( "ui-slider-horizontal ui-slider-vertical" )
13852
					._addClass( "ui-slider-" + this.orientation );
13853
				this._refreshValue();
13854
				if ( this.options.range ) {
13855
					this._refreshRange( value );
13856
				}
13857
 
13858
				// Reset positioning from previous orientation
13859
				this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
13860
				break;
13861
			case "value":
13862
				this._animateOff = true;
13863
				this._refreshValue();
13864
				this._change( null, 0 );
13865
				this._animateOff = false;
13866
				break;
13867
			case "values":
13868
				this._animateOff = true;
13869
				this._refreshValue();
13870
 
13871
				// Start from the last handle to prevent unreachable handles (#9046)
13872
				for ( i = valsLength - 1; i >= 0; i-- ) {
13873
					this._change( null, i );
13874
				}
13875
				this._animateOff = false;
13876
				break;
13877
			case "step":
13878
			case "min":
13879
			case "max":
13880
				this._animateOff = true;
13881
				this._calculateNewMax();
13882
				this._refreshValue();
13883
				this._animateOff = false;
13884
				break;
13885
			case "range":
13886
				this._animateOff = true;
13887
				this._refresh();
13888
				this._animateOff = false;
13889
				break;
13890
		}
13891
	},
13892
 
13893
	_setOptionDisabled: function( value ) {
13894
		this._super( value );
13895
 
13896
		this._toggleClass( null, "ui-state-disabled", !!value );
13897
	},
13898
 
13899
	//internal value getter
13900
	// _value() returns value trimmed by min and max, aligned by step
13901
	_value: function() {
13902
		var val = this.options.value;
13903
		val = this._trimAlignValue( val );
13904
 
13905
		return val;
13906
	},
13907
 
13908
	//internal values getter
13909
	// _values() returns array of values trimmed by min and max, aligned by step
13910
	// _values( index ) returns single value trimmed by min and max, aligned by step
13911
	_values: function( index ) {
13912
		var val,
13913
			vals,
13914
			i;
13915
 
13916
		if ( arguments.length ) {
13917
			val = this.options.values[ index ];
13918
			val = this._trimAlignValue( val );
13919
 
13920
			return val;
13921
		} else if ( this._hasMultipleValues() ) {
13922
 
13923
			// .slice() creates a copy of the array
13924
			// this copy gets trimmed by min and max and then returned
13925
			vals = this.options.values.slice();
13926
			for ( i = 0; i < vals.length; i += 1 ) {
13927
				vals[ i ] = this._trimAlignValue( vals[ i ] );
13928
			}
13929
 
13930
			return vals;
13931
		} else {
13932
			return [];
13933
		}
13934
	},
13935
 
13936
	// Returns the step-aligned value that val is closest to, between (inclusive) min and max
13937
	_trimAlignValue: function( val ) {
13938
		if ( val <= this._valueMin() ) {
13939
			return this._valueMin();
13940
		}
13941
		if ( val >= this._valueMax() ) {
13942
			return this._valueMax();
13943
		}
13944
		var step = ( this.options.step > 0 ) ? this.options.step : 1,
13945
			valModStep = ( val - this._valueMin() ) % step,
13946
			alignValue = val - valModStep;
13947
 
13948
		if ( Math.abs( valModStep ) * 2 >= step ) {
13949
			alignValue += ( valModStep > 0 ) ? step : ( -step );
13950
		}
13951
 
13952
		// Since JavaScript has problems with large floats, round
13953
		// the final value to 5 digits after the decimal point (see #4124)
13954
		return parseFloat( alignValue.toFixed( 5 ) );
13955
	},
13956
 
13957
	_calculateNewMax: function() {
13958
		var max = this.options.max,
13959
			min = this._valueMin(),
13960
			step = this.options.step,
13961
			aboveMin = Math.round( ( max - min ) / step ) * step;
13962
		max = aboveMin + min;
13963
		if ( max > this.options.max ) {
13964
 
13965
			//If max is not divisible by step, rounding off may increase its value
13966
			max -= step;
13967
		}
13968
		this.max = parseFloat( max.toFixed( this._precision() ) );
13969
	},
13970
 
13971
	_precision: function() {
13972
		var precision = this._precisionOf( this.options.step );
13973
		if ( this.options.min !== null ) {
13974
			precision = Math.max( precision, this._precisionOf( this.options.min ) );
13975
		}
13976
		return precision;
13977
	},
13978
 
13979
	_precisionOf: function( num ) {
13980
		var str = num.toString(),
13981
			decimal = str.indexOf( "." );
13982
		return decimal === -1 ? 0 : str.length - decimal - 1;
13983
	},
13984
 
13985
	_valueMin: function() {
13986
		return this.options.min;
13987
	},
13988
 
13989
	_valueMax: function() {
13990
		return this.max;
13991
	},
13992
 
13993
	_refreshRange: function( orientation ) {
13994
		if ( orientation === "vertical" ) {
13995
			this.range.css( { "width": "", "left": "" } );
13996
		}
13997
		if ( orientation === "horizontal" ) {
13998
			this.range.css( { "height": "", "bottom": "" } );
13999
		}
14000
	},
14001
 
14002
	_refreshValue: function() {
14003
		var lastValPercent, valPercent, value, valueMin, valueMax,
14004
			oRange = this.options.range,
14005
			o = this.options,
14006
			that = this,
14007
			animate = ( !this._animateOff ) ? o.animate : false,
14008
			_set = {};
14009
 
14010
		if ( this._hasMultipleValues() ) {
14011
			this.handles.each( function( i ) {
14012
				valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() -
14013
					that._valueMin() ) * 100;
14014
				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
14015
				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
14016
				if ( that.options.range === true ) {
14017
					if ( that.orientation === "horizontal" ) {
14018
						if ( i === 0 ) {
14019
							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
14020
								left: valPercent + "%"
14021
							}, o.animate );
14022
						}
14023
						if ( i === 1 ) {
14024
							that.range[ animate ? "animate" : "css" ]( {
14025
								width: ( valPercent - lastValPercent ) + "%"
14026
							}, {
14027
								queue: false,
14028
								duration: o.animate
14029
							} );
14030
						}
14031
					} else {
14032
						if ( i === 0 ) {
14033
							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
14034
								bottom: ( valPercent ) + "%"
14035
							}, o.animate );
14036
						}
14037
						if ( i === 1 ) {
14038
							that.range[ animate ? "animate" : "css" ]( {
14039
								height: ( valPercent - lastValPercent ) + "%"
14040
							}, {
14041
								queue: false,
14042
								duration: o.animate
14043
							} );
14044
						}
14045
					}
14046
				}
14047
				lastValPercent = valPercent;
14048
			} );
14049
		} else {
14050
			value = this.value();
14051
			valueMin = this._valueMin();
14052
			valueMax = this._valueMax();
14053
			valPercent = ( valueMax !== valueMin ) ?
14054
					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
14055
					0;
14056
			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
14057
			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
14058
 
14059
			if ( oRange === "min" && this.orientation === "horizontal" ) {
14060
				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
14061
					width: valPercent + "%"
14062
				}, o.animate );
14063
			}
14064
			if ( oRange === "max" && this.orientation === "horizontal" ) {
14065
				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
14066
					width: ( 100 - valPercent ) + "%"
14067
				}, o.animate );
14068
			}
14069
			if ( oRange === "min" && this.orientation === "vertical" ) {
14070
				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
14071
					height: valPercent + "%"
14072
				}, o.animate );
14073
			}
14074
			if ( oRange === "max" && this.orientation === "vertical" ) {
14075
				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
14076
					height: ( 100 - valPercent ) + "%"
14077
				}, o.animate );
14078
			}
14079
		}
14080
	},
14081
 
14082
	_handleEvents: {
14083
		keydown: function( event ) {
14084
			var allowed, curVal, newVal, step,
14085
				index = $( event.target ).data( "ui-slider-handle-index" );
14086
 
14087
			switch ( event.keyCode ) {
14088
				case $.ui.keyCode.HOME:
14089
				case $.ui.keyCode.END:
14090
				case $.ui.keyCode.PAGE_UP:
14091
				case $.ui.keyCode.PAGE_DOWN:
14092
				case $.ui.keyCode.UP:
14093
				case $.ui.keyCode.RIGHT:
14094
				case $.ui.keyCode.DOWN:
14095
				case $.ui.keyCode.LEFT:
14096
					event.preventDefault();
14097
					if ( !this._keySliding ) {
14098
						this._keySliding = true;
14099
						this._addClass( $( event.target ), null, "ui-state-active" );
14100
						allowed = this._start( event, index );
14101
						if ( allowed === false ) {
14102
							return;
14103
						}
14104
					}
14105
					break;
14106
			}
14107
 
14108
			step = this.options.step;
14109
			if ( this._hasMultipleValues() ) {
14110
				curVal = newVal = this.values( index );
14111
			} else {
14112
				curVal = newVal = this.value();
14113
			}
14114
 
14115
			switch ( event.keyCode ) {
14116
				case $.ui.keyCode.HOME:
14117
					newVal = this._valueMin();
14118
					break;
14119
				case $.ui.keyCode.END:
14120
					newVal = this._valueMax();
14121
					break;
14122
				case $.ui.keyCode.PAGE_UP:
14123
					newVal = this._trimAlignValue(
14124
						curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
14125
					);
14126
					break;
14127
				case $.ui.keyCode.PAGE_DOWN:
14128
					newVal = this._trimAlignValue(
14129
						curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) );
14130
					break;
14131
				case $.ui.keyCode.UP:
14132
				case $.ui.keyCode.RIGHT:
14133
					if ( curVal === this._valueMax() ) {
14134
						return;
14135
					}
14136
					newVal = this._trimAlignValue( curVal + step );
14137
					break;
14138
				case $.ui.keyCode.DOWN:
14139
				case $.ui.keyCode.LEFT:
14140
					if ( curVal === this._valueMin() ) {
14141
						return;
14142
					}
14143
					newVal = this._trimAlignValue( curVal - step );
14144
					break;
14145
			}
14146
 
14147
			this._slide( event, index, newVal );
14148
		},
14149
		keyup: function( event ) {
14150
			var index = $( event.target ).data( "ui-slider-handle-index" );
14151
 
14152
			if ( this._keySliding ) {
14153
				this._keySliding = false;
14154
				this._stop( event, index );
14155
				this._change( event, index );
14156
				this._removeClass( $( event.target ), null, "ui-state-active" );
14157
			}
14158
		}
14159
	}
14160
} );
14161
 
14162
 
14163
/*!
14164
 * jQuery UI Spinner 1.12.1
14165
 * http://jqueryui.com
14166
 *
14167
 * Copyright jQuery Foundation and other contributors
14168
 * Released under the MIT license.
14169
 * http://jquery.org/license
14170
 */
14171
 
14172
//>>label: Spinner
14173
//>>group: Widgets
14174
//>>description: Displays buttons to easily input numbers via the keyboard or mouse.
14175
//>>docs: http://api.jqueryui.com/spinner/
14176
//>>demos: http://jqueryui.com/spinner/
14177
//>>css.structure: ../../themes/base/core.css
14178
//>>css.structure: ../../themes/base/spinner.css
14179
//>>css.theme: ../../themes/base/theme.css
14180
 
14181
 
14182
 
14183
function spinnerModifer( fn ) {
14184
	return function() {
14185
		var previous = this.element.val();
14186
		fn.apply( this, arguments );
14187
		this._refresh();
14188
		if ( previous !== this.element.val() ) {
14189
			this._trigger( "change" );
14190
		}
14191
	};
14192
}
14193
 
14194
$.widget( "ui.spinner", {
14195
	version: "1.12.1",
14196
	defaultElement: "<input>",
14197
	widgetEventPrefix: "spin",
14198
	options: {
14199
		classes: {
14200
			"ui-spinner": "ui-corner-all",
14201
			"ui-spinner-down": "ui-corner-br",
14202
			"ui-spinner-up": "ui-corner-tr"
14203
		},
14204
		culture: null,
14205
		icons: {
14206
			down: "ui-icon-triangle-1-s",
14207
			up: "ui-icon-triangle-1-n"
14208
		},
14209
		incremental: true,
14210
		max: null,
14211
		min: null,
14212
		numberFormat: null,
14213
		page: 10,
14214
		step: 1,
14215
 
14216
		change: null,
14217
		spin: null,
14218
		start: null,
14219
		stop: null
14220
	},
14221
 
14222
	_create: function() {
14223
 
14224
		// handle string values that need to be parsed
14225
		this._setOption( "max", this.options.max );
14226
		this._setOption( "min", this.options.min );
14227
		this._setOption( "step", this.options.step );
14228
 
14229
		// Only format if there is a value, prevents the field from being marked
14230
		// as invalid in Firefox, see #9573.
14231
		if ( this.value() !== "" ) {
14232
 
14233
			// Format the value, but don't constrain.
14234
			this._value( this.element.val(), true );
14235
		}
14236
 
14237
		this._draw();
14238
		this._on( this._events );
14239
		this._refresh();
14240
 
14241
		// Turning off autocomplete prevents the browser from remembering the
14242
		// value when navigating through history, so we re-enable autocomplete
14243
		// if the page is unloaded before the widget is destroyed. #7790
14244
		this._on( this.window, {
14245
			beforeunload: function() {
14246
				this.element.removeAttr( "autocomplete" );
14247
			}
14248
		} );
14249
	},
14250
 
14251
	_getCreateOptions: function() {
14252
		var options = this._super();
14253
		var element = this.element;
14254
 
14255
		$.each( [ "min", "max", "step" ], function( i, option ) {
14256
			var value = element.attr( option );
14257
			if ( value != null && value.length ) {
14258
				options[ option ] = value;
14259
			}
14260
		} );
14261
 
14262
		return options;
14263
	},
14264
 
14265
	_events: {
14266
		keydown: function( event ) {
14267
			if ( this._start( event ) && this._keydown( event ) ) {
14268
				event.preventDefault();
14269
			}
14270
		},
14271
		keyup: "_stop",
14272
		focus: function() {
14273
			this.previous = this.element.val();
14274
		},
14275
		blur: function( event ) {
14276
			if ( this.cancelBlur ) {
14277
				delete this.cancelBlur;
14278
				return;
14279
			}
14280
 
14281
			this._stop();
14282
			this._refresh();
14283
			if ( this.previous !== this.element.val() ) {
14284
				this._trigger( "change", event );
14285
			}
14286
		},
14287
		mousewheel: function( event, delta ) {
14288
			if ( !delta ) {
14289
				return;
14290
			}
14291
			if ( !this.spinning && !this._start( event ) ) {
14292
				return false;
14293
			}
14294
 
14295
			this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event );
14296
			clearTimeout( this.mousewheelTimer );
14297
			this.mousewheelTimer = this._delay( function() {
14298
				if ( this.spinning ) {
14299
					this._stop( event );
14300
				}
14301
			}, 100 );
14302
			event.preventDefault();
14303
		},
14304
		"mousedown .ui-spinner-button": function( event ) {
14305
			var previous;
14306
 
14307
			// We never want the buttons to have focus; whenever the user is
14308
			// interacting with the spinner, the focus should be on the input.
14309
			// If the input is focused then this.previous is properly set from
14310
			// when the input first received focus. If the input is not focused
14311
			// then we need to set this.previous based on the value before spinning.
14312
			previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ?
14313
				this.previous : this.element.val();
14314
			function checkFocus() {
14315
				var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] );
14316
				if ( !isActive ) {
14317
					this.element.trigger( "focus" );
14318
					this.previous = previous;
14319
 
14320
					// support: IE
14321
					// IE sets focus asynchronously, so we need to check if focus
14322
					// moved off of the input because the user clicked on the button.
14323
					this._delay( function() {
14324
						this.previous = previous;
14325
					} );
14326
				}
14327
			}
14328
 
14329
			// Ensure focus is on (or stays on) the text field
14330
			event.preventDefault();
14331
			checkFocus.call( this );
14332
 
14333
			// Support: IE
14334
			// IE doesn't prevent moving focus even with event.preventDefault()
14335
			// so we set a flag to know when we should ignore the blur event
14336
			// and check (again) if focus moved off of the input.
14337
			this.cancelBlur = true;
14338
			this._delay( function() {
14339
				delete this.cancelBlur;
14340
				checkFocus.call( this );
14341
			} );
14342
 
14343
			if ( this._start( event ) === false ) {
14344
				return;
14345
			}
14346
 
14347
			this._repeat( null, $( event.currentTarget )
14348
				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
14349
		},
14350
		"mouseup .ui-spinner-button": "_stop",
14351
		"mouseenter .ui-spinner-button": function( event ) {
14352
 
14353
			// button will add ui-state-active if mouse was down while mouseleave and kept down
14354
			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
14355
				return;
14356
			}
14357
 
14358
			if ( this._start( event ) === false ) {
14359
				return false;
14360
			}
14361
			this._repeat( null, $( event.currentTarget )
14362
				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
14363
		},
14364
 
14365
		// TODO: do we really want to consider this a stop?
14366
		// shouldn't we just stop the repeater and wait until mouseup before
14367
		// we trigger the stop event?
14368
		"mouseleave .ui-spinner-button": "_stop"
14369
	},
14370
 
14371
	// Support mobile enhanced option and make backcompat more sane
14372
	_enhance: function() {
14373
		this.uiSpinner = this.element
14374
			.attr( "autocomplete", "off" )
14375
			.wrap( "<span>" )
14376
			.parent()
14377
 
14378
				// Add buttons
14379
				.append(
14380
					"<a></a><a></a>"
14381
				);
14382
	},
14383
 
14384
	_draw: function() {
14385
		this._enhance();
14386
 
14387
		this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" );
14388
		this._addClass( "ui-spinner-input" );
14389
 
14390
		this.element.attr( "role", "spinbutton" );
14391
 
14392
		// Button bindings
14393
		this.buttons = this.uiSpinner.children( "a" )
14394
			.attr( "tabIndex", -1 )
14395
			.attr( "aria-hidden", true )
14396
			.button( {
14397
				classes: {
14398
					"ui-button": ""
14399
				}
14400
			} );
14401
 
14402
		// TODO: Right now button does not support classes this is already updated in button PR
14403
		this._removeClass( this.buttons, "ui-corner-all" );
14404
 
14405
		this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" );
14406
		this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" );
14407
		this.buttons.first().button( {
14408
			"icon": this.options.icons.up,
14409
			"showLabel": false
14410
		} );
14411
		this.buttons.last().button( {
14412
			"icon": this.options.icons.down,
14413
			"showLabel": false
14414
		} );
14415
 
14416
		// IE 6 doesn't understand height: 50% for the buttons
14417
		// unless the wrapper has an explicit height
14418
		if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) &&
14419
				this.uiSpinner.height() > 0 ) {
14420
			this.uiSpinner.height( this.uiSpinner.height() );
14421
		}
14422
	},
14423
 
14424
	_keydown: function( event ) {
14425
		var options = this.options,
14426
			keyCode = $.ui.keyCode;
14427
 
14428
		switch ( event.keyCode ) {
14429
		case keyCode.UP:
14430
			this._repeat( null, 1, event );
14431
			return true;
14432
		case keyCode.DOWN:
14433
			this._repeat( null, -1, event );
14434
			return true;
14435
		case keyCode.PAGE_UP:
14436
			this._repeat( null, options.page, event );
14437
			return true;
14438
		case keyCode.PAGE_DOWN:
14439
			this._repeat( null, -options.page, event );
14440
			return true;
14441
		}
14442
 
14443
		return false;
14444
	},
14445
 
14446
	_start: function( event ) {
14447
		if ( !this.spinning && this._trigger( "start", event ) === false ) {
14448
			return false;
14449
		}
14450
 
14451
		if ( !this.counter ) {
14452
			this.counter = 1;
14453
		}
14454
		this.spinning = true;
14455
		return true;
14456
	},
14457
 
14458
	_repeat: function( i, steps, event ) {
14459
		i = i || 500;
14460
 
14461
		clearTimeout( this.timer );
14462
		this.timer = this._delay( function() {
14463
			this._repeat( 40, steps, event );
14464
		}, i );
14465
 
14466
		this._spin( steps * this.options.step, event );
14467
	},
14468
 
14469
	_spin: function( step, event ) {
14470
		var value = this.value() || 0;
14471
 
14472
		if ( !this.counter ) {
14473
			this.counter = 1;
14474
		}
14475
 
14476
		value = this._adjustValue( value + step * this._increment( this.counter ) );
14477
 
14478
		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) {
14479
			this._value( value );
14480
			this.counter++;
14481
		}
14482
	},
14483
 
14484
	_increment: function( i ) {
14485
		var incremental = this.options.incremental;
14486
 
14487
		if ( incremental ) {
14488
			return $.isFunction( incremental ) ?
14489
				incremental( i ) :
14490
				Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
14491
		}
14492
 
14493
		return 1;
14494
	},
14495
 
14496
	_precision: function() {
14497
		var precision = this._precisionOf( this.options.step );
14498
		if ( this.options.min !== null ) {
14499
			precision = Math.max( precision, this._precisionOf( this.options.min ) );
14500
		}
14501
		return precision;
14502
	},
14503
 
14504
	_precisionOf: function( num ) {
14505
		var str = num.toString(),
14506
			decimal = str.indexOf( "." );
14507
		return decimal === -1 ? 0 : str.length - decimal - 1;
14508
	},
14509
 
14510
	_adjustValue: function( value ) {
14511
		var base, aboveMin,
14512
			options = this.options;
14513
 
14514
		// Make sure we're at a valid step
14515
		// - find out where we are relative to the base (min or 0)
14516
		base = options.min !== null ? options.min : 0;
14517
		aboveMin = value - base;
14518
 
14519
		// - round to the nearest step
14520
		aboveMin = Math.round( aboveMin / options.step ) * options.step;
14521
 
14522
		// - rounding is based on 0, so adjust back to our base
14523
		value = base + aboveMin;
14524
 
14525
		// Fix precision from bad JS floating point math
14526
		value = parseFloat( value.toFixed( this._precision() ) );
14527
 
14528
		// Clamp the value
14529
		if ( options.max !== null && value > options.max ) {
14530
			return options.max;
14531
		}
14532
		if ( options.min !== null && value < options.min ) {
14533
			return options.min;
14534
		}
14535
 
14536
		return value;
14537
	},
14538
 
14539
	_stop: function( event ) {
14540
		if ( !this.spinning ) {
14541
			return;
14542
		}
14543
 
14544
		clearTimeout( this.timer );
14545
		clearTimeout( this.mousewheelTimer );
14546
		this.counter = 0;
14547
		this.spinning = false;
14548
		this._trigger( "stop", event );
14549
	},
14550
 
14551
	_setOption: function( key, value ) {
14552
		var prevValue, first, last;
14553
 
14554
		if ( key === "culture" || key === "numberFormat" ) {
14555
			prevValue = this._parse( this.element.val() );
14556
			this.options[ key ] = value;
14557
			this.element.val( this._format( prevValue ) );
14558
			return;
14559
		}
14560
 
14561
		if ( key === "max" || key === "min" || key === "step" ) {
14562
			if ( typeof value === "string" ) {
14563
				value = this._parse( value );
14564
			}
14565
		}
14566
		if ( key === "icons" ) {
14567
			first = this.buttons.first().find( ".ui-icon" );
14568
			this._removeClass( first, null, this.options.icons.up );
14569
			this._addClass( first, null, value.up );
14570
			last = this.buttons.last().find( ".ui-icon" );
14571
			this._removeClass( last, null, this.options.icons.down );
14572
			this._addClass( last, null, value.down );
14573
		}
14574
 
14575
		this._super( key, value );
14576
	},
14577
 
14578
	_setOptionDisabled: function( value ) {
14579
		this._super( value );
14580
 
14581
		this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value );
14582
		this.element.prop( "disabled", !!value );
14583
		this.buttons.button( value ? "disable" : "enable" );
14584
	},
14585
 
14586
	_setOptions: spinnerModifer( function( options ) {
14587
		this._super( options );
14588
	} ),
14589
 
14590
	_parse: function( val ) {
14591
		if ( typeof val === "string" && val !== "" ) {
14592
			val = window.Globalize && this.options.numberFormat ?
14593
				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
14594
		}
14595
		return val === "" || isNaN( val ) ? null : val;
14596
	},
14597
 
14598
	_format: function( value ) {
14599
		if ( value === "" ) {
14600
			return "";
14601
		}
14602
		return window.Globalize && this.options.numberFormat ?
14603
			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
14604
			value;
14605
	},
14606
 
14607
	_refresh: function() {
14608
		this.element.attr( {
14609
			"aria-valuemin": this.options.min,
14610
			"aria-valuemax": this.options.max,
14611
 
14612
			// TODO: what should we do with values that can't be parsed?
14613
			"aria-valuenow": this._parse( this.element.val() )
14614
		} );
14615
	},
14616
 
14617
	isValid: function() {
14618
		var value = this.value();
14619
 
14620
		// Null is invalid
14621
		if ( value === null ) {
14622
			return false;
14623
		}
14624
 
14625
		// If value gets adjusted, it's invalid
14626
		return value === this._adjustValue( value );
14627
	},
14628
 
14629
	// Update the value without triggering change
14630
	_value: function( value, allowAny ) {
14631
		var parsed;
14632
		if ( value !== "" ) {
14633
			parsed = this._parse( value );
14634
			if ( parsed !== null ) {
14635
				if ( !allowAny ) {
14636
					parsed = this._adjustValue( parsed );
14637
				}
14638
				value = this._format( parsed );
14639
			}
14640
		}
14641
		this.element.val( value );
14642
		this._refresh();
14643
	},
14644
 
14645
	_destroy: function() {
14646
		this.element
14647
			.prop( "disabled", false )
14648
			.removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" );
14649
 
14650
		this.uiSpinner.replaceWith( this.element );
14651
	},
14652
 
14653
	stepUp: spinnerModifer( function( steps ) {
14654
		this._stepUp( steps );
14655
	} ),
14656
	_stepUp: function( steps ) {
14657
		if ( this._start() ) {
14658
			this._spin( ( steps || 1 ) * this.options.step );
14659
			this._stop();
14660
		}
14661
	},
14662
 
14663
	stepDown: spinnerModifer( function( steps ) {
14664
		this._stepDown( steps );
14665
	} ),
14666
	_stepDown: function( steps ) {
14667
		if ( this._start() ) {
14668
			this._spin( ( steps || 1 ) * -this.options.step );
14669
			this._stop();
14670
		}
14671
	},
14672
 
14673
	pageUp: spinnerModifer( function( pages ) {
14674
		this._stepUp( ( pages || 1 ) * this.options.page );
14675
	} ),
14676
 
14677
	pageDown: spinnerModifer( function( pages ) {
14678
		this._stepDown( ( pages || 1 ) * this.options.page );
14679
	} ),
14680
 
14681
	value: function( newVal ) {
14682
		if ( !arguments.length ) {
14683
			return this._parse( this.element.val() );
14684
		}
14685
		spinnerModifer( this._value ).call( this, newVal );
14686
	},
14687
 
14688
	widget: function() {
14689
		return this.uiSpinner;
14690
	}
14691
} );
14692
 
14693
// DEPRECATED
14694
// TODO: switch return back to widget declaration at top of file when this is removed
14695
if ( $.uiBackCompat !== false ) {
14696
 
14697
	// Backcompat for spinner html extension points
14698
	$.widget( "ui.spinner", $.ui.spinner, {
14699
		_enhance: function() {
14700
			this.uiSpinner = this.element
14701
				.attr( "autocomplete", "off" )
14702
				.wrap( this._uiSpinnerHtml() )
14703
				.parent()
14704
 
14705
					// Add buttons
14706
					.append( this._buttonHtml() );
14707
		},
14708
		_uiSpinnerHtml: function() {
14709
			return "<span>";
14710
		},
14711
 
14712
		_buttonHtml: function() {
14713
			return "<a></a><a></a>";
14714
		}
14715
	} );
14716
}
14717
 
14718
var widgetsSpinner = $.ui.spinner;
14719
 
14720
 
14721
/*!
14722
 * jQuery UI Tabs 1.12.1
14723
 * http://jqueryui.com
14724
 *
14725
 * Copyright jQuery Foundation and other contributors
14726
 * Released under the MIT license.
14727
 * http://jquery.org/license
14728
 */
14729
 
14730
//>>label: Tabs
14731
//>>group: Widgets
14732
//>>description: Transforms a set of container elements into a tab structure.
14733
//>>docs: http://api.jqueryui.com/tabs/
14734
//>>demos: http://jqueryui.com/tabs/
14735
//>>css.structure: ../../themes/base/core.css
14736
//>>css.structure: ../../themes/base/tabs.css
14737
//>>css.theme: ../../themes/base/theme.css
14738
 
14739
 
14740
 
14741
$.widget( "ui.tabs", {
14742
	version: "1.12.1",
14743
	delay: 300,
14744
	options: {
14745
		active: null,
14746
		classes: {
14747
			"ui-tabs": "ui-corner-all",
14748
			"ui-tabs-nav": "ui-corner-all",
14749
			"ui-tabs-panel": "ui-corner-bottom",
14750
			"ui-tabs-tab": "ui-corner-top"
14751
		},
14752
		collapsible: false,
14753
		event: "click",
14754
		heightStyle: "content",
14755
		hide: null,
14756
		show: null,
14757
 
14758
		// Callbacks
14759
		activate: null,
14760
		beforeActivate: null,
14761
		beforeLoad: null,
14762
		load: null
14763
	},
14764
 
14765
	_isLocal: ( function() {
14766
		var rhash = /#.*$/;
14767
 
14768
		return function( anchor ) {
14769
			var anchorUrl, locationUrl;
14770
 
14771
			anchorUrl = anchor.href.replace( rhash, "" );
14772
			locationUrl = location.href.replace( rhash, "" );
14773
 
14774
			// Decoding may throw an error if the URL isn't UTF-8 (#9518)
14775
			try {
14776
				anchorUrl = decodeURIComponent( anchorUrl );
14777
			} catch ( error ) {}
14778
			try {
14779
				locationUrl = decodeURIComponent( locationUrl );
14780
			} catch ( error ) {}
14781
 
14782
			return anchor.hash.length > 1 && anchorUrl === locationUrl;
14783
		};
14784
	} )(),
14785
 
14786
	_create: function() {
14787
		var that = this,
14788
			options = this.options;
14789
 
14790
		this.running = false;
14791
 
14792
		this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
14793
		this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
14794
 
14795
		this._processTabs();
14796
		options.active = this._initialActive();
14797
 
14798
		// Take disabling tabs via class attribute from HTML
14799
		// into account and update option properly.
14800
		if ( $.isArray( options.disabled ) ) {
14801
			options.disabled = $.unique( options.disabled.concat(
14802
				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
14803
					return that.tabs.index( li );
14804
				} )
14805
			) ).sort();
14806
		}
14807
 
14808
		// Check for length avoids error when initializing empty list
14809
		if ( this.options.active !== false && this.anchors.length ) {
14810
			this.active = this._findActive( options.active );
14811
		} else {
14812
			this.active = $();
14813
		}
14814
 
14815
		this._refresh();
14816
 
14817
		if ( this.active.length ) {
14818
			this.load( options.active );
14819
		}
14820
	},
14821
 
14822
	_initialActive: function() {
14823
		var active = this.options.active,
14824
			collapsible = this.options.collapsible,
14825
			locationHash = location.hash.substring( 1 );
14826
 
14827
		if ( active === null ) {
14828
 
14829
			// check the fragment identifier in the URL
14830
			if ( locationHash ) {
14831
				this.tabs.each( function( i, tab ) {
14832
					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
14833
						active = i;
14834
						return false;
14835
					}
14836
				} );
14837
			}
14838
 
14839
			// Check for a tab marked active via a class
14840
			if ( active === null ) {
14841
				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
14842
			}
14843
 
14844
			// No active tab, set to false
14845
			if ( active === null || active === -1 ) {
14846
				active = this.tabs.length ? 0 : false;
14847
			}
14848
		}
14849
 
14850
		// Handle numbers: negative, out of range
14851
		if ( active !== false ) {
14852
			active = this.tabs.index( this.tabs.eq( active ) );
14853
			if ( active === -1 ) {
14854
				active = collapsible ? false : 0;
14855
			}
14856
		}
14857
 
14858
		// Don't allow collapsible: false and active: false
14859
		if ( !collapsible && active === false && this.anchors.length ) {
14860
			active = 0;
14861
		}
14862
 
14863
		return active;
14864
	},
14865
 
14866
	_getCreateEventData: function() {
14867
		return {
14868
			tab: this.active,
14869
			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
14870
		};
14871
	},
14872
 
14873
	_tabKeydown: function( event ) {
14874
		var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ),
14875
			selectedIndex = this.tabs.index( focusedTab ),
14876
			goingForward = true;
14877
 
14878
		if ( this._handlePageNav( event ) ) {
14879
			return;
14880
		}
14881
 
14882
		switch ( event.keyCode ) {
14883
		case $.ui.keyCode.RIGHT:
14884
		case $.ui.keyCode.DOWN:
14885
			selectedIndex++;
14886
			break;
14887
		case $.ui.keyCode.UP:
14888
		case $.ui.keyCode.LEFT:
14889
			goingForward = false;
14890
			selectedIndex--;
14891
			break;
14892
		case $.ui.keyCode.END:
14893
			selectedIndex = this.anchors.length - 1;
14894
			break;
14895
		case $.ui.keyCode.HOME:
14896
			selectedIndex = 0;
14897
			break;
14898
		case $.ui.keyCode.SPACE:
14899
 
14900
			// Activate only, no collapsing
14901
			event.preventDefault();
14902
			clearTimeout( this.activating );
14903
			this._activate( selectedIndex );
14904
			return;
14905
		case $.ui.keyCode.ENTER:
14906
 
14907
			// Toggle (cancel delayed activation, allow collapsing)
14908
			event.preventDefault();
14909
			clearTimeout( this.activating );
14910
 
14911
			// Determine if we should collapse or activate
14912
			this._activate( selectedIndex === this.options.active ? false : selectedIndex );
14913
			return;
14914
		default:
14915
			return;
14916
		}
14917
 
14918
		// Focus the appropriate tab, based on which key was pressed
14919
		event.preventDefault();
14920
		clearTimeout( this.activating );
14921
		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
14922
 
14923
		// Navigating with control/command key will prevent automatic activation
14924
		if ( !event.ctrlKey && !event.metaKey ) {
14925
 
14926
			// Update aria-selected immediately so that AT think the tab is already selected.
14927
			// Otherwise AT may confuse the user by stating that they need to activate the tab,
14928
			// but the tab will already be activated by the time the announcement finishes.
14929
			focusedTab.attr( "aria-selected", "false" );
14930
			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
14931
 
14932
			this.activating = this._delay( function() {
14933
				this.option( "active", selectedIndex );
14934
			}, this.delay );
14935
		}
14936
	},
14937
 
14938
	_panelKeydown: function( event ) {
14939
		if ( this._handlePageNav( event ) ) {
14940
			return;
14941
		}
14942
 
14943
		// Ctrl+up moves focus to the current tab
14944
		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
14945
			event.preventDefault();
14946
			this.active.trigger( "focus" );
14947
		}
14948
	},
14949
 
14950
	// Alt+page up/down moves focus to the previous/next tab (and activates)
14951
	_handlePageNav: function( event ) {
14952
		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
14953
			this._activate( this._focusNextTab( this.options.active - 1, false ) );
14954
			return true;
14955
		}
14956
		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
14957
			this._activate( this._focusNextTab( this.options.active + 1, true ) );
14958
			return true;
14959
		}
14960
	},
14961
 
14962
	_findNextTab: function( index, goingForward ) {
14963
		var lastTabIndex = this.tabs.length - 1;
14964
 
14965
		function constrain() {
14966
			if ( index > lastTabIndex ) {
14967
				index = 0;
14968
			}
14969
			if ( index < 0 ) {
14970
				index = lastTabIndex;
14971
			}
14972
			return index;
14973
		}
14974
 
14975
		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
14976
			index = goingForward ? index + 1 : index - 1;
14977
		}
14978
 
14979
		return index;
14980
	},
14981
 
14982
	_focusNextTab: function( index, goingForward ) {
14983
		index = this._findNextTab( index, goingForward );
14984
		this.tabs.eq( index ).trigger( "focus" );
14985
		return index;
14986
	},
14987
 
14988
	_setOption: function( key, value ) {
14989
		if ( key === "active" ) {
14990
 
14991
			// _activate() will handle invalid values and update this.options
14992
			this._activate( value );
14993
			return;
14994
		}
14995
 
14996
		this._super( key, value );
14997
 
14998
		if ( key === "collapsible" ) {
14999
			this._toggleClass( "ui-tabs-collapsible", null, value );
15000
 
15001
			// Setting collapsible: false while collapsed; open first panel
15002
			if ( !value && this.options.active === false ) {
15003
				this._activate( 0 );
15004
			}
15005
		}
15006
 
15007
		if ( key === "event" ) {
15008
			this._setupEvents( value );
15009
		}
15010
 
15011
		if ( key === "heightStyle" ) {
15012
			this._setupHeightStyle( value );
15013
		}
15014
	},
15015
 
15016
	_sanitizeSelector: function( hash ) {
15017
		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
15018
	},
15019
 
15020
	refresh: function() {
15021
		var options = this.options,
15022
			lis = this.tablist.children( ":has(a[href])" );
15023
 
15024
		// Get disabled tabs from class attribute from HTML
15025
		// this will get converted to a boolean if needed in _refresh()
15026
		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
15027
			return lis.index( tab );
15028
		} );
15029
 
15030
		this._processTabs();
15031
 
15032
		// Was collapsed or no tabs
15033
		if ( options.active === false || !this.anchors.length ) {
15034
			options.active = false;
15035
			this.active = $();
15036
 
15037
		// was active, but active tab is gone
15038
		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
15039
 
15040
			// all remaining tabs are disabled
15041
			if ( this.tabs.length === options.disabled.length ) {
15042
				options.active = false;
15043
				this.active = $();
15044
 
15045
			// activate previous tab
15046
			} else {
15047
				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
15048
			}
15049
 
15050
		// was active, active tab still exists
15051
		} else {
15052
 
15053
			// make sure active index is correct
15054
			options.active = this.tabs.index( this.active );
15055
		}
15056
 
15057
		this._refresh();
15058
	},
15059
 
15060
	_refresh: function() {
15061
		this._setOptionDisabled( this.options.disabled );
15062
		this._setupEvents( this.options.event );
15063
		this._setupHeightStyle( this.options.heightStyle );
15064
 
15065
		this.tabs.not( this.active ).attr( {
15066
			"aria-selected": "false",
15067
			"aria-expanded": "false",
15068
			tabIndex: -1
15069
		} );
15070
		this.panels.not( this._getPanelForTab( this.active ) )
15071
			.hide()
15072
			.attr( {
15073
				"aria-hidden": "true"
15074
			} );
15075
 
15076
		// Make sure one tab is in the tab order
15077
		if ( !this.active.length ) {
15078
			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
15079
		} else {
15080
			this.active
15081
				.attr( {
15082
					"aria-selected": "true",
15083
					"aria-expanded": "true",
15084
					tabIndex: 0
15085
				} );
15086
			this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
15087
			this._getPanelForTab( this.active )
15088
				.show()
15089
				.attr( {
15090
					"aria-hidden": "false"
15091
				} );
15092
		}
15093
	},
15094
 
15095
	_processTabs: function() {
15096
		var that = this,
15097
			prevTabs = this.tabs,
15098
			prevAnchors = this.anchors,
15099
			prevPanels = this.panels;
15100
 
15101
		this.tablist = this._getList().attr( "role", "tablist" );
15102
		this._addClass( this.tablist, "ui-tabs-nav",
15103
			"ui-helper-reset ui-helper-clearfix ui-widget-header" );
15104
 
15105
		// Prevent users from focusing disabled tabs via click
15106
		this.tablist
15107
			.on( "mousedown" + this.eventNamespace, "> li", function( event ) {
15108
				if ( $( this ).is( ".ui-state-disabled" ) ) {
15109
					event.preventDefault();
15110
				}
15111
			} )
15112
 
15113
			// Support: IE <9
15114
			// Preventing the default action in mousedown doesn't prevent IE
15115
			// from focusing the element, so if the anchor gets focused, blur.
15116
			// We don't have to worry about focusing the previously focused
15117
			// element since clicking on a non-focusable element should focus
15118
			// the body anyway.
15119
			.on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() {
15120
				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
15121
					this.blur();
15122
				}
15123
			} );
15124
 
15125
		this.tabs = this.tablist.find( "> li:has(a[href])" )
15126
			.attr( {
15127
				role: "tab",
15128
				tabIndex: -1
15129
			} );
15130
		this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" );
15131
 
15132
		this.anchors = this.tabs.map( function() {
15133
			return $( "a", this )[ 0 ];
15134
		} )
15135
			.attr( {
15136
				role: "presentation",
15137
				tabIndex: -1
15138
			} );
15139
		this._addClass( this.anchors, "ui-tabs-anchor" );
15140
 
15141
		this.panels = $();
15142
 
15143
		this.anchors.each( function( i, anchor ) {
15144
			var selector, panel, panelId,
15145
				anchorId = $( anchor ).uniqueId().attr( "id" ),
15146
				tab = $( anchor ).closest( "li" ),
15147
				originalAriaControls = tab.attr( "aria-controls" );
15148
 
15149
			// Inline tab
15150
			if ( that._isLocal( anchor ) ) {
15151
				selector = anchor.hash;
15152
				panelId = selector.substring( 1 );
15153
				panel = that.element.find( that._sanitizeSelector( selector ) );
15154
 
15155
			// remote tab
15156
			} else {
15157
 
15158
				// If the tab doesn't already have aria-controls,
15159
				// generate an id by using a throw-away element
15160
				panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
15161
				selector = "#" + panelId;
15162
				panel = that.element.find( selector );
15163
				if ( !panel.length ) {
15164
					panel = that._createPanel( panelId );
15165
					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
15166
				}
15167
				panel.attr( "aria-live", "polite" );
15168
			}
15169
 
15170
			if ( panel.length ) {
15171
				that.panels = that.panels.add( panel );
15172
			}
15173
			if ( originalAriaControls ) {
15174
				tab.data( "ui-tabs-aria-controls", originalAriaControls );
15175
			}
15176
			tab.attr( {
15177
				"aria-controls": panelId,
15178
				"aria-labelledby": anchorId
15179
			} );
15180
			panel.attr( "aria-labelledby", anchorId );
15181
		} );
15182
 
15183
		this.panels.attr( "role", "tabpanel" );
15184
		this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
15185
 
15186
		// Avoid memory leaks (#10056)
15187
		if ( prevTabs ) {
15188
			this._off( prevTabs.not( this.tabs ) );
15189
			this._off( prevAnchors.not( this.anchors ) );
15190
			this._off( prevPanels.not( this.panels ) );
15191
		}
15192
	},
15193
 
15194
	// Allow overriding how to find the list for rare usage scenarios (#7715)
15195
	_getList: function() {
15196
		return this.tablist || this.element.find( "ol, ul" ).eq( 0 );
15197
	},
15198
 
15199
	_createPanel: function( id ) {
15200
		return $( "<div>" )
15201
			.attr( "id", id )
15202
			.data( "ui-tabs-destroy", true );
15203
	},
15204
 
15205
	_setOptionDisabled: function( disabled ) {
15206
		var currentItem, li, i;
15207
 
15208
		if ( $.isArray( disabled ) ) {
15209
			if ( !disabled.length ) {
15210
				disabled = false;
15211
			} else if ( disabled.length === this.anchors.length ) {
15212
				disabled = true;
15213
			}
15214
		}
15215
 
15216
		// Disable tabs
15217
		for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
15218
			currentItem = $( li );
15219
			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
15220
				currentItem.attr( "aria-disabled", "true" );
15221
				this._addClass( currentItem, null, "ui-state-disabled" );
15222
			} else {
15223
				currentItem.removeAttr( "aria-disabled" );
15224
				this._removeClass( currentItem, null, "ui-state-disabled" );
15225
			}
15226
		}
15227
 
15228
		this.options.disabled = disabled;
15229
 
15230
		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null,
15231
			disabled === true );
15232
	},
15233
 
15234
	_setupEvents: function( event ) {
15235
		var events = {};
15236
		if ( event ) {
15237
			$.each( event.split( " " ), function( index, eventName ) {
15238
				events[ eventName ] = "_eventHandler";
15239
			} );
15240
		}
15241
 
15242
		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
15243
 
15244
		// Always prevent the default action, even when disabled
15245
		this._on( true, this.anchors, {
15246
			click: function( event ) {
15247
				event.preventDefault();
15248
			}
15249
		} );
15250
		this._on( this.anchors, events );
15251
		this._on( this.tabs, { keydown: "_tabKeydown" } );
15252
		this._on( this.panels, { keydown: "_panelKeydown" } );
15253
 
15254
		this._focusable( this.tabs );
15255
		this._hoverable( this.tabs );
15256
	},
15257
 
15258
	_setupHeightStyle: function( heightStyle ) {
15259
		var maxHeight,
15260
			parent = this.element.parent();
15261
 
15262
		if ( heightStyle === "fill" ) {
15263
			maxHeight = parent.height();
15264
			maxHeight -= this.element.outerHeight() - this.element.height();
15265
 
15266
			this.element.siblings( ":visible" ).each( function() {
15267
				var elem = $( this ),
15268
					position = elem.css( "position" );
15269
 
15270
				if ( position === "absolute" || position === "fixed" ) {
15271
					return;
15272
				}
15273
				maxHeight -= elem.outerHeight( true );
15274
			} );
15275
 
15276
			this.element.children().not( this.panels ).each( function() {
15277
				maxHeight -= $( this ).outerHeight( true );
15278
			} );
15279
 
15280
			this.panels.each( function() {
15281
				$( this ).height( Math.max( 0, maxHeight -
15282
					$( this ).innerHeight() + $( this ).height() ) );
15283
			} )
15284
				.css( "overflow", "auto" );
15285
		} else if ( heightStyle === "auto" ) {
15286
			maxHeight = 0;
15287
			this.panels.each( function() {
15288
				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
15289
			} ).height( maxHeight );
15290
		}
15291
	},
15292
 
15293
	_eventHandler: function( event ) {
15294
		var options = this.options,
15295
			active = this.active,
15296
			anchor = $( event.currentTarget ),
15297
			tab = anchor.closest( "li" ),
15298
			clickedIsActive = tab[ 0 ] === active[ 0 ],
15299
			collapsing = clickedIsActive && options.collapsible,
15300
			toShow = collapsing ? $() : this._getPanelForTab( tab ),
15301
			toHide = !active.length ? $() : this._getPanelForTab( active ),
15302
			eventData = {
15303
				oldTab: active,
15304
				oldPanel: toHide,
15305
				newTab: collapsing ? $() : tab,
15306
				newPanel: toShow
15307
			};
15308
 
15309
		event.preventDefault();
15310
 
15311
		if ( tab.hasClass( "ui-state-disabled" ) ||
15312
 
15313
				// tab is already loading
15314
				tab.hasClass( "ui-tabs-loading" ) ||
15315
 
15316
				// can't switch durning an animation
15317
				this.running ||
15318
 
15319
				// click on active header, but not collapsible
15320
				( clickedIsActive && !options.collapsible ) ||
15321
 
15322
				// allow canceling activation
15323
				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
15324
			return;
15325
		}
15326
 
15327
		options.active = collapsing ? false : this.tabs.index( tab );
15328
 
15329
		this.active = clickedIsActive ? $() : tab;
15330
		if ( this.xhr ) {
15331
			this.xhr.abort();
15332
		}
15333
 
15334
		if ( !toHide.length && !toShow.length ) {
15335
			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
15336
		}
15337
 
15338
		if ( toShow.length ) {
15339
			this.load( this.tabs.index( tab ), event );
15340
		}
15341
		this._toggle( event, eventData );
15342
	},
15343
 
15344
	// Handles show/hide for selecting tabs
15345
	_toggle: function( event, eventData ) {
15346
		var that = this,
15347
			toShow = eventData.newPanel,
15348
			toHide = eventData.oldPanel;
15349
 
15350
		this.running = true;
15351
 
15352
		function complete() {
15353
			that.running = false;
15354
			that._trigger( "activate", event, eventData );
15355
		}
15356
 
15357
		function show() {
15358
			that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
15359
 
15360
			if ( toShow.length && that.options.show ) {
15361
				that._show( toShow, that.options.show, complete );
15362
			} else {
15363
				toShow.show();
15364
				complete();
15365
			}
15366
		}
15367
 
15368
		// Start out by hiding, then showing, then completing
15369
		if ( toHide.length && this.options.hide ) {
15370
			this._hide( toHide, this.options.hide, function() {
15371
				that._removeClass( eventData.oldTab.closest( "li" ),
15372
					"ui-tabs-active", "ui-state-active" );
15373
				show();
15374
			} );
15375
		} else {
15376
			this._removeClass( eventData.oldTab.closest( "li" ),
15377
				"ui-tabs-active", "ui-state-active" );
15378
			toHide.hide();
15379
			show();
15380
		}
15381
 
15382
		toHide.attr( "aria-hidden", "true" );
15383
		eventData.oldTab.attr( {
15384
			"aria-selected": "false",
15385
			"aria-expanded": "false"
15386
		} );
15387
 
15388
		// If we're switching tabs, remove the old tab from the tab order.
15389
		// If we're opening from collapsed state, remove the previous tab from the tab order.
15390
		// If we're collapsing, then keep the collapsing tab in the tab order.
15391
		if ( toShow.length && toHide.length ) {
15392
			eventData.oldTab.attr( "tabIndex", -1 );
15393
		} else if ( toShow.length ) {
15394
			this.tabs.filter( function() {
15395
				return $( this ).attr( "tabIndex" ) === 0;
15396
			} )
15397
				.attr( "tabIndex", -1 );
15398
		}
15399
 
15400
		toShow.attr( "aria-hidden", "false" );
15401
		eventData.newTab.attr( {
15402
			"aria-selected": "true",
15403
			"aria-expanded": "true",
15404
			tabIndex: 0
15405
		} );
15406
	},
15407
 
15408
	_activate: function( index ) {
15409
		var anchor,
15410
			active = this._findActive( index );
15411
 
15412
		// Trying to activate the already active panel
15413
		if ( active[ 0 ] === this.active[ 0 ] ) {
15414
			return;
15415
		}
15416
 
15417
		// Trying to collapse, simulate a click on the current active header
15418
		if ( !active.length ) {
15419
			active = this.active;
15420
		}
15421
 
15422
		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
15423
		this._eventHandler( {
15424
			target: anchor,
15425
			currentTarget: anchor,
15426
			preventDefault: $.noop
15427
		} );
15428
	},
15429
 
15430
	_findActive: function( index ) {
15431
		return index === false ? $() : this.tabs.eq( index );
15432
	},
15433
 
15434
	_getIndex: function( index ) {
15435
 
15436
		// meta-function to give users option to provide a href string instead of a numerical index.
15437
		if ( typeof index === "string" ) {
15438
			index = this.anchors.index( this.anchors.filter( "[href$='" +
15439
				$.ui.escapeSelector( index ) + "']" ) );
15440
		}
15441
 
15442
		return index;
15443
	},
15444
 
15445
	_destroy: function() {
15446
		if ( this.xhr ) {
15447
			this.xhr.abort();
15448
		}
15449
 
15450
		this.tablist
15451
			.removeAttr( "role" )
15452
			.off( this.eventNamespace );
15453
 
15454
		this.anchors
15455
			.removeAttr( "role tabIndex" )
15456
			.removeUniqueId();
15457
 
15458
		this.tabs.add( this.panels ).each( function() {
15459
			if ( $.data( this, "ui-tabs-destroy" ) ) {
15460
				$( this ).remove();
15461
			} else {
15462
				$( this ).removeAttr( "role tabIndex " +
15463
					"aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" );
15464
			}
15465
		} );
15466
 
15467
		this.tabs.each( function() {
15468
			var li = $( this ),
15469
				prev = li.data( "ui-tabs-aria-controls" );
15470
			if ( prev ) {
15471
				li
15472
					.attr( "aria-controls", prev )
15473
					.removeData( "ui-tabs-aria-controls" );
15474
			} else {
15475
				li.removeAttr( "aria-controls" );
15476
			}
15477
		} );
15478
 
15479
		this.panels.show();
15480
 
15481
		if ( this.options.heightStyle !== "content" ) {
15482
			this.panels.css( "height", "" );
15483
		}
15484
	},
15485
 
15486
	enable: function( index ) {
15487
		var disabled = this.options.disabled;
15488
		if ( disabled === false ) {
15489
			return;
15490
		}
15491
 
15492
		if ( index === undefined ) {
15493
			disabled = false;
15494
		} else {
15495
			index = this._getIndex( index );
15496
			if ( $.isArray( disabled ) ) {
15497
				disabled = $.map( disabled, function( num ) {
15498
					return num !== index ? num : null;
15499
				} );
15500
			} else {
15501
				disabled = $.map( this.tabs, function( li, num ) {
15502
					return num !== index ? num : null;
15503
				} );
15504
			}
15505
		}
15506
		this._setOptionDisabled( disabled );
15507
	},
15508
 
15509
	disable: function( index ) {
15510
		var disabled = this.options.disabled;
15511
		if ( disabled === true ) {
15512
			return;
15513
		}
15514
 
15515
		if ( index === undefined ) {
15516
			disabled = true;
15517
		} else {
15518
			index = this._getIndex( index );
15519
			if ( $.inArray( index, disabled ) !== -1 ) {
15520
				return;
15521
			}
15522
			if ( $.isArray( disabled ) ) {
15523
				disabled = $.merge( [ index ], disabled ).sort();
15524
			} else {
15525
				disabled = [ index ];
15526
			}
15527
		}
15528
		this._setOptionDisabled( disabled );
15529
	},
15530
 
15531
	load: function( index, event ) {
15532
		index = this._getIndex( index );
15533
		var that = this,
15534
			tab = this.tabs.eq( index ),
15535
			anchor = tab.find( ".ui-tabs-anchor" ),
15536
			panel = this._getPanelForTab( tab ),
15537
			eventData = {
15538
				tab: tab,
15539
				panel: panel
15540
			},
15541
			complete = function( jqXHR, status ) {
15542
				if ( status === "abort" ) {
15543
					that.panels.stop( false, true );
15544
				}
15545
 
15546
				that._removeClass( tab, "ui-tabs-loading" );
15547
				panel.removeAttr( "aria-busy" );
15548
 
15549
				if ( jqXHR === that.xhr ) {
15550
					delete that.xhr;
15551
				}
15552
			};
15553
 
15554
		// Not remote
15555
		if ( this._isLocal( anchor[ 0 ] ) ) {
15556
			return;
15557
		}
15558
 
15559
		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
15560
 
15561
		// Support: jQuery <1.8
15562
		// jQuery <1.8 returns false if the request is canceled in beforeSend,
15563
		// but as of 1.8, $.ajax() always returns a jqXHR object.
15564
		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
15565
			this._addClass( tab, "ui-tabs-loading" );
15566
			panel.attr( "aria-busy", "true" );
15567
 
15568
			this.xhr
15569
				.done( function( response, status, jqXHR ) {
15570
 
15571
					// support: jQuery <1.8
15572
					// http://bugs.jquery.com/ticket/11778
15573
					setTimeout( function() {
15574
						panel.html( response );
15575
						that._trigger( "load", event, eventData );
15576
 
15577
						complete( jqXHR, status );
15578
					}, 1 );
15579
				} )
15580
				.fail( function( jqXHR, status ) {
15581
 
15582
					// support: jQuery <1.8
15583
					// http://bugs.jquery.com/ticket/11778
15584
					setTimeout( function() {
15585
						complete( jqXHR, status );
15586
					}, 1 );
15587
				} );
15588
		}
15589
	},
15590
 
15591
	_ajaxSettings: function( anchor, event, eventData ) {
15592
		var that = this;
15593
		return {
15594
 
15595
			// Support: IE <11 only
15596
			// Strip any hash that exists to prevent errors with the Ajax request
15597
			url: anchor.attr( "href" ).replace( /#.*$/, "" ),
15598
			beforeSend: function( jqXHR, settings ) {
15599
				return that._trigger( "beforeLoad", event,
15600
					$.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
15601
			}
15602
		};
15603
	},
15604
 
15605
	_getPanelForTab: function( tab ) {
15606
		var id = $( tab ).attr( "aria-controls" );
15607
		return this.element.find( this._sanitizeSelector( "#" + id ) );
15608
	}
15609
} );
15610
 
15611
// DEPRECATED
15612
// TODO: Switch return back to widget declaration at top of file when this is removed
15613
if ( $.uiBackCompat !== false ) {
15614
 
15615
	// Backcompat for ui-tab class (now ui-tabs-tab)
15616
	$.widget( "ui.tabs", $.ui.tabs, {
15617
		_processTabs: function() {
15618
			this._superApply( arguments );
15619
			this._addClass( this.tabs, "ui-tab" );
15620
		}
15621
	} );
15622
}
15623
 
15624
var widgetsTabs = $.ui.tabs;
15625
 
15626
 
15627
/*!
15628
 * jQuery UI Tooltip 1.12.1
15629
 * http://jqueryui.com
15630
 *
15631
 * Copyright jQuery Foundation and other contributors
15632
 * Released under the MIT license.
15633
 * http://jquery.org/license
15634
 */
15635
 
15636
//>>label: Tooltip
15637
//>>group: Widgets
15638
//>>description: Shows additional information for any element on hover or focus.
15639
//>>docs: http://api.jqueryui.com/tooltip/
15640
//>>demos: http://jqueryui.com/tooltip/
15641
//>>css.structure: ../../themes/base/core.css
15642
//>>css.structure: ../../themes/base/tooltip.css
15643
//>>css.theme: ../../themes/base/theme.css
15644
 
15645
 
15646
 
15647
$.widget( "ui.tooltip", {
15648
	version: "1.12.1",
15649
	options: {
15650
		classes: {
15651
			"ui-tooltip": "ui-corner-all ui-widget-shadow"
15652
		},
15653
		content: function() {
15654
 
15655
			// support: IE<9, Opera in jQuery <1.7
15656
			// .text() can't accept undefined, so coerce to a string
15657
			var title = $( this ).attr( "title" ) || "";
15658
 
15659
			// Escape title, since we're going from an attribute to raw HTML
15660
			return $( "<a>" ).text( title ).html();
15661
		},
15662
		hide: true,
15663
 
15664
		// Disabled elements have inconsistent behavior across browsers (#8661)
15665
		items: "[title]:not([disabled])",
15666
		position: {
15667
			my: "left top+15",
15668
			at: "left bottom",
15669
			collision: "flipfit flip"
15670
		},
15671
		show: true,
15672
		track: false,
15673
 
15674
		// Callbacks
15675
		close: null,
15676
		open: null
15677
	},
15678
 
15679
	_addDescribedBy: function( elem, id ) {
15680
		var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ );
15681
		describedby.push( id );
15682
		elem
15683
			.data( "ui-tooltip-id", id )
15684
			.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
15685
	},
15686
 
15687
	_removeDescribedBy: function( elem ) {
15688
		var id = elem.data( "ui-tooltip-id" ),
15689
			describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ),
15690
			index = $.inArray( id, describedby );
15691
 
15692
		if ( index !== -1 ) {
15693
			describedby.splice( index, 1 );
15694
		}
15695
 
15696
		elem.removeData( "ui-tooltip-id" );
15697
		describedby = $.trim( describedby.join( " " ) );
15698
		if ( describedby ) {
15699
			elem.attr( "aria-describedby", describedby );
15700
		} else {
15701
			elem.removeAttr( "aria-describedby" );
15702
		}
15703
	},
15704
 
15705
	_create: function() {
15706
		this._on( {
15707
			mouseover: "open",
15708
			focusin: "open"
15709
		} );
15710
 
15711
		// IDs of generated tooltips, needed for destroy
15712
		this.tooltips = {};
15713
 
15714
		// IDs of parent tooltips where we removed the title attribute
15715
		this.parents = {};
15716
 
15717
		// Append the aria-live region so tooltips announce correctly
15718
		this.liveRegion = $( "<div>" )
15719
			.attr( {
15720
				role: "log",
15721
				"aria-live": "assertive",
15722
				"aria-relevant": "additions"
15723
			} )
15724
			.appendTo( this.document[ 0 ].body );
15725
		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
15726
 
15727
		this.disabledTitles = $( [] );
15728
	},
15729
 
15730
	_setOption: function( key, value ) {
15731
		var that = this;
15732
 
15733
		this._super( key, value );
15734
 
15735
		if ( key === "content" ) {
15736
			$.each( this.tooltips, function( id, tooltipData ) {
15737
				that._updateContent( tooltipData.element );
15738
			} );
15739
		}
15740
	},
15741
 
15742
	_setOptionDisabled: function( value ) {
15743
		this[ value ? "_disable" : "_enable" ]();
15744
	},
15745
 
15746
	_disable: function() {
15747
		var that = this;
15748
 
15749
		// Close open tooltips
15750
		$.each( this.tooltips, function( id, tooltipData ) {
15751
			var event = $.Event( "blur" );
15752
			event.target = event.currentTarget = tooltipData.element[ 0 ];
15753
			that.close( event, true );
15754
		} );
15755
 
15756
		// Remove title attributes to prevent native tooltips
15757
		this.disabledTitles = this.disabledTitles.add(
15758
			this.element.find( this.options.items ).addBack()
15759
				.filter( function() {
15760
					var element = $( this );
15761
					if ( element.is( "[title]" ) ) {
15762
						return element
15763
							.data( "ui-tooltip-title", element.attr( "title" ) )
15764
							.removeAttr( "title" );
15765
					}
15766
				} )
15767
		);
15768
	},
15769
 
15770
	_enable: function() {
15771
 
15772
		// restore title attributes
15773
		this.disabledTitles.each( function() {
15774
			var element = $( this );
15775
			if ( element.data( "ui-tooltip-title" ) ) {
15776
				element.attr( "title", element.data( "ui-tooltip-title" ) );
15777
			}
15778
		} );
15779
		this.disabledTitles = $( [] );
15780
	},
15781
 
15782
	open: function( event ) {
15783
		var that = this,
15784
			target = $( event ? event.target : this.element )
15785
 
15786
				// we need closest here due to mouseover bubbling,
15787
				// but always pointing at the same event target
15788
				.closest( this.options.items );
15789
 
15790
		// No element to show a tooltip for or the tooltip is already open
15791
		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
15792
			return;
15793
		}
15794
 
15795
		if ( target.attr( "title" ) ) {
15796
			target.data( "ui-tooltip-title", target.attr( "title" ) );
15797
		}
15798
 
15799
		target.data( "ui-tooltip-open", true );
15800
 
15801
		// Kill parent tooltips, custom or native, for hover
15802
		if ( event && event.type === "mouseover" ) {
15803
			target.parents().each( function() {
15804
				var parent = $( this ),
15805
					blurEvent;
15806
				if ( parent.data( "ui-tooltip-open" ) ) {
15807
					blurEvent = $.Event( "blur" );
15808
					blurEvent.target = blurEvent.currentTarget = this;
15809
					that.close( blurEvent, true );
15810
				}
15811
				if ( parent.attr( "title" ) ) {
15812
					parent.uniqueId();
15813
					that.parents[ this.id ] = {
15814
						element: this,
15815
						title: parent.attr( "title" )
15816
					};
15817
					parent.attr( "title", "" );
15818
				}
15819
			} );
15820
		}
15821
 
15822
		this._registerCloseHandlers( event, target );
15823
		this._updateContent( target, event );
15824
	},
15825
 
15826
	_updateContent: function( target, event ) {
15827
		var content,
15828
			contentOption = this.options.content,
15829
			that = this,
15830
			eventType = event ? event.type : null;
15831
 
15832
		if ( typeof contentOption === "string" || contentOption.nodeType ||
15833
				contentOption.jquery ) {
15834
			return this._open( event, target, contentOption );
15835
		}
15836
 
15837
		content = contentOption.call( target[ 0 ], function( response ) {
15838
 
15839
			// IE may instantly serve a cached response for ajax requests
15840
			// delay this call to _open so the other call to _open runs first
15841
			that._delay( function() {
15842
 
15843
				// Ignore async response if tooltip was closed already
15844
				if ( !target.data( "ui-tooltip-open" ) ) {
15845
					return;
15846
				}
15847
 
15848
				// JQuery creates a special event for focusin when it doesn't
15849
				// exist natively. To improve performance, the native event
15850
				// object is reused and the type is changed. Therefore, we can't
15851
				// rely on the type being correct after the event finished
15852
				// bubbling, so we set it back to the previous value. (#8740)
15853
				if ( event ) {
15854
					event.type = eventType;
15855
				}
15856
				this._open( event, target, response );
15857
			} );
15858
		} );
15859
		if ( content ) {
15860
			this._open( event, target, content );
15861
		}
15862
	},
15863
 
15864
	_open: function( event, target, content ) {
15865
		var tooltipData, tooltip, delayedShow, a11yContent,
15866
			positionOption = $.extend( {}, this.options.position );
15867
 
15868
		if ( !content ) {
15869
			return;
15870
		}
15871
 
15872
		// Content can be updated multiple times. If the tooltip already
15873
		// exists, then just update the content and bail.
15874
		tooltipData = this._find( target );
15875
		if ( tooltipData ) {
15876
			tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
15877
			return;
15878
		}
15879
 
15880
		// If we have a title, clear it to prevent the native tooltip
15881
		// we have to check first to avoid defining a title if none exists
15882
		// (we don't want to cause an element to start matching [title])
15883
		//
15884
		// We use removeAttr only for key events, to allow IE to export the correct
15885
		// accessible attributes. For mouse events, set to empty string to avoid
15886
		// native tooltip showing up (happens only when removing inside mouseover).
15887
		if ( target.is( "[title]" ) ) {
15888
			if ( event && event.type === "mouseover" ) {
15889
				target.attr( "title", "" );
15890
			} else {
15891
				target.removeAttr( "title" );
15892
			}
15893
		}
15894
 
15895
		tooltipData = this._tooltip( target );
15896
		tooltip = tooltipData.tooltip;
15897
		this._addDescribedBy( target, tooltip.attr( "id" ) );
15898
		tooltip.find( ".ui-tooltip-content" ).html( content );
15899
 
15900
		// Support: Voiceover on OS X, JAWS on IE <= 9
15901
		// JAWS announces deletions even when aria-relevant="additions"
15902
		// Voiceover will sometimes re-read the entire log region's contents from the beginning
15903
		this.liveRegion.children().hide();
15904
		a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() );
15905
		a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" );
15906
		a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
15907
		a11yContent.appendTo( this.liveRegion );
15908
 
15909
		function position( event ) {
15910
			positionOption.of = event;
15911
			if ( tooltip.is( ":hidden" ) ) {
15912
				return;
15913
			}
15914
			tooltip.position( positionOption );
15915
		}
15916
		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
15917
			this._on( this.document, {
15918
				mousemove: position
15919
			} );
15920
 
15921
			// trigger once to override element-relative positioning
15922
			position( event );
15923
		} else {
15924
			tooltip.position( $.extend( {
15925
				of: target
15926
			}, this.options.position ) );
15927
		}
15928
 
15929
		tooltip.hide();
15930
 
15931
		this._show( tooltip, this.options.show );
15932
 
15933
		// Handle tracking tooltips that are shown with a delay (#8644). As soon
15934
		// as the tooltip is visible, position the tooltip using the most recent
15935
		// event.
15936
		// Adds the check to add the timers only when both delay and track options are set (#14682)
15937
		if ( this.options.track && this.options.show && this.options.show.delay ) {
15938
			delayedShow = this.delayedShow = setInterval( function() {
15939
				if ( tooltip.is( ":visible" ) ) {
15940
					position( positionOption.of );
15941
					clearInterval( delayedShow );
15942
				}
15943
			}, $.fx.interval );
15944
		}
15945
 
15946
		this._trigger( "open", event, { tooltip: tooltip } );
15947
	},
15948
 
15949
	_registerCloseHandlers: function( event, target ) {
15950
		var events = {
15951
			keyup: function( event ) {
15952
				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
15953
					var fakeEvent = $.Event( event );
15954
					fakeEvent.currentTarget = target[ 0 ];
15955
					this.close( fakeEvent, true );
15956
				}
15957
			}
15958
		};
15959
 
15960
		// Only bind remove handler for delegated targets. Non-delegated
15961
		// tooltips will handle this in destroy.
15962
		if ( target[ 0 ] !== this.element[ 0 ] ) {
15963
			events.remove = function() {
15964
				this._removeTooltip( this._find( target ).tooltip );
15965
			};
15966
		}
15967
 
15968
		if ( !event || event.type === "mouseover" ) {
15969
			events.mouseleave = "close";
15970
		}
15971
		if ( !event || event.type === "focusin" ) {
15972
			events.focusout = "close";
15973
		}
15974
		this._on( true, target, events );
15975
	},
15976
 
15977
	close: function( event ) {
15978
		var tooltip,
15979
			that = this,
15980
			target = $( event ? event.currentTarget : this.element ),
15981
			tooltipData = this._find( target );
15982
 
15983
		// The tooltip may already be closed
15984
		if ( !tooltipData ) {
15985
 
15986
			// We set ui-tooltip-open immediately upon open (in open()), but only set the
15987
			// additional data once there's actually content to show (in _open()). So even if the
15988
			// tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
15989
			// the period between open() and _open().
15990
			target.removeData( "ui-tooltip-open" );
15991
			return;
15992
		}
15993
 
15994
		tooltip = tooltipData.tooltip;
15995
 
15996
		// Disabling closes the tooltip, so we need to track when we're closing
15997
		// to avoid an infinite loop in case the tooltip becomes disabled on close
15998
		if ( tooltipData.closing ) {
15999
			return;
16000
		}
16001
 
16002
		// Clear the interval for delayed tracking tooltips
16003
		clearInterval( this.delayedShow );
16004
 
16005
		// Only set title if we had one before (see comment in _open())
16006
		// If the title attribute has changed since open(), don't restore
16007
		if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
16008
			target.attr( "title", target.data( "ui-tooltip-title" ) );
16009
		}
16010
 
16011
		this._removeDescribedBy( target );
16012
 
16013
		tooltipData.hiding = true;
16014
		tooltip.stop( true );
16015
		this._hide( tooltip, this.options.hide, function() {
16016
			that._removeTooltip( $( this ) );
16017
		} );
16018
 
16019
		target.removeData( "ui-tooltip-open" );
16020
		this._off( target, "mouseleave focusout keyup" );
16021
 
16022
		// Remove 'remove' binding only on delegated targets
16023
		if ( target[ 0 ] !== this.element[ 0 ] ) {
16024
			this._off( target, "remove" );
16025
		}
16026
		this._off( this.document, "mousemove" );
16027
 
16028
		if ( event && event.type === "mouseleave" ) {
16029
			$.each( this.parents, function( id, parent ) {
16030
				$( parent.element ).attr( "title", parent.title );
16031
				delete that.parents[ id ];
16032
			} );
16033
		}
16034
 
16035
		tooltipData.closing = true;
16036
		this._trigger( "close", event, { tooltip: tooltip } );
16037
		if ( !tooltipData.hiding ) {
16038
			tooltipData.closing = false;
16039
		}
16040
	},
16041
 
16042
	_tooltip: function( element ) {
16043
		var tooltip = $( "<div>" ).attr( "role", "tooltip" ),
16044
			content = $( "<div>" ).appendTo( tooltip ),
16045
			id = tooltip.uniqueId().attr( "id" );
16046
 
16047
		this._addClass( content, "ui-tooltip-content" );
16048
		this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" );
16049
 
16050
		tooltip.appendTo( this._appendTo( element ) );
16051
 
16052
		return this.tooltips[ id ] = {
16053
			element: element,
16054
			tooltip: tooltip
16055
		};
16056
	},
16057
 
16058
	_find: function( target ) {
16059
		var id = target.data( "ui-tooltip-id" );
16060
		return id ? this.tooltips[ id ] : null;
16061
	},
16062
 
16063
	_removeTooltip: function( tooltip ) {
16064
		tooltip.remove();
16065
		delete this.tooltips[ tooltip.attr( "id" ) ];
16066
	},
16067
 
16068
	_appendTo: function( target ) {
16069
		var element = target.closest( ".ui-front, dialog" );
16070
 
16071
		if ( !element.length ) {
16072
			element = this.document[ 0 ].body;
16073
		}
16074
 
16075
		return element;
16076
	},
16077
 
16078
	_destroy: function() {
16079
		var that = this;
16080
 
16081
		// Close open tooltips
16082
		$.each( this.tooltips, function( id, tooltipData ) {
16083
 
16084
			// Delegate to close method to handle common cleanup
16085
			var event = $.Event( "blur" ),
16086
				element = tooltipData.element;
16087
			event.target = event.currentTarget = element[ 0 ];
16088
			that.close( event, true );
16089
 
16090
			// Remove immediately; destroying an open tooltip doesn't use the
16091
			// hide animation
16092
			$( "#" + id ).remove();
16093
 
16094
			// Restore the title
16095
			if ( element.data( "ui-tooltip-title" ) ) {
16096
 
16097
				// If the title attribute has changed since open(), don't restore
16098
				if ( !element.attr( "title" ) ) {
16099
					element.attr( "title", element.data( "ui-tooltip-title" ) );
16100
				}
16101
				element.removeData( "ui-tooltip-title" );
16102
			}
16103
		} );
16104
		this.liveRegion.remove();
16105
	}
16106
} );
16107
 
16108
// DEPRECATED
16109
// TODO: Switch return back to widget declaration at top of file when this is removed
16110
if ( $.uiBackCompat !== false ) {
16111
 
16112
	// Backcompat for tooltipClass option
16113
	$.widget( "ui.tooltip", $.ui.tooltip, {
16114
		options: {
16115
			tooltipClass: null
16116
		},
16117
		_tooltip: function() {
16118
			var tooltipData = this._superApply( arguments );
16119
			if ( this.options.tooltipClass ) {
16120
				tooltipData.tooltip.addClass( this.options.tooltipClass );
16121
			}
16122
			return tooltipData;
16123
		}
16124
	} );
16125
}
16126
 
16127
var widgetsTooltip = $.ui.tooltip;
16128
 
16129
 
16130
/*!
16131
 * jQuery UI Effects 1.12.1
16132
 * http://jqueryui.com
16133
 *
16134
 * Copyright jQuery Foundation and other contributors
16135
 * Released under the MIT license.
16136
 * http://jquery.org/license
16137
 */
16138
 
16139
//>>label: Effects Core
16140
//>>group: Effects
16141
// jscs:disable maximumLineLength
16142
//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects.
16143
// jscs:enable maximumLineLength
16144
//>>docs: http://api.jqueryui.com/category/effects-core/
16145
//>>demos: http://jqueryui.com/effect/
16146
 
16147
 
16148
 
16149
var dataSpace = "ui-effects-",
16150
	dataSpaceStyle = "ui-effects-style",
16151
	dataSpaceAnimated = "ui-effects-animated",
16152
 
16153
	// Create a local jQuery because jQuery Color relies on it and the
16154
	// global may not exist with AMD and a custom build (#10199)
16155
	jQuery = $;
16156
 
16157
$.effects = {
16158
	effect: {}
16159
};
16160
 
16161
/*!
16162
 * jQuery Color Animations v2.1.2
16163
 * https://github.com/jquery/jquery-color
16164
 *
16165
 * Copyright 2014 jQuery Foundation and other contributors
16166
 * Released under the MIT license.
16167
 * http://jquery.org/license
16168
 *
16169
 * Date: Wed Jan 16 08:47:09 2013 -0600
16170
 */
16171
( function( jQuery, undefined ) {
16172
 
16173
	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " +
16174
		"borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
16175
 
16176
	// Plusequals test for += 100 -= 100
16177
	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
16178
 
16179
	// A set of RE's that can match strings and generate color tuples.
16180
	stringParsers = [ {
16181
			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
16182
			parse: function( execResult ) {
16183
				return [
16184
					execResult[ 1 ],
16185
					execResult[ 2 ],
16186
					execResult[ 3 ],
16187
					execResult[ 4 ]
16188
				];
16189
			}
16190
		}, {
16191
			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
16192
			parse: function( execResult ) {
16193
				return [
16194
					execResult[ 1 ] * 2.55,
16195
					execResult[ 2 ] * 2.55,
16196
					execResult[ 3 ] * 2.55,
16197
					execResult[ 4 ]
16198
				];
16199
			}
16200
		}, {
16201
 
16202
			// This regex ignores A-F because it's compared against an already lowercased string
16203
			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
16204
			parse: function( execResult ) {
16205
				return [
16206
					parseInt( execResult[ 1 ], 16 ),
16207
					parseInt( execResult[ 2 ], 16 ),
16208
					parseInt( execResult[ 3 ], 16 )
16209
				];
16210
			}
16211
		}, {
16212
 
16213
			// This regex ignores A-F because it's compared against an already lowercased string
16214
			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
16215
			parse: function( execResult ) {
16216
				return [
16217
					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
16218
					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
16219
					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
16220
				];
16221
			}
16222
		}, {
16223
			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
16224
			space: "hsla",
16225
			parse: function( execResult ) {
16226
				return [
16227
					execResult[ 1 ],
16228
					execResult[ 2 ] / 100,
16229
					execResult[ 3 ] / 100,
16230
					execResult[ 4 ]
16231
				];
16232
			}
16233
		} ],
16234
 
16235
	// JQuery.Color( )
16236
	color = jQuery.Color = function( color, green, blue, alpha ) {
16237
		return new jQuery.Color.fn.parse( color, green, blue, alpha );
16238
	},
16239
	spaces = {
16240
		rgba: {
16241
			props: {
16242
				red: {
16243
					idx: 0,
16244
					type: "byte"
16245
				},
16246
				green: {
16247
					idx: 1,
16248
					type: "byte"
16249
				},
16250
				blue: {
16251
					idx: 2,
16252
					type: "byte"
16253
				}
16254
			}
16255
		},
16256
 
16257
		hsla: {
16258
			props: {
16259
				hue: {
16260
					idx: 0,
16261
					type: "degrees"
16262
				},
16263
				saturation: {
16264
					idx: 1,
16265
					type: "percent"
16266
				},
16267
				lightness: {
16268
					idx: 2,
16269
					type: "percent"
16270
				}
16271
			}
16272
		}
16273
	},
16274
	propTypes = {
16275
		"byte": {
16276
			floor: true,
16277
			max: 255
16278
		},
16279
		"percent": {
16280
			max: 1
16281
		},
16282
		"degrees": {
16283
			mod: 360,
16284
			floor: true
16285
		}
16286
	},
16287
	support = color.support = {},
16288
 
16289
	// Element for support tests
16290
	supportElem = jQuery( "<p>" )[ 0 ],
16291
 
16292
	// Colors = jQuery.Color.names
16293
	colors,
16294
 
16295
	// Local aliases of functions called often
16296
	each = jQuery.each;
16297
 
16298
// Determine rgba support immediately
16299
supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
16300
support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
16301
 
16302
// Define cache name and alpha properties
16303
// for rgba and hsla spaces
16304
each( spaces, function( spaceName, space ) {
16305
	space.cache = "_" + spaceName;
16306
	space.props.alpha = {
16307
		idx: 3,
16308
		type: "percent",
16309
		def: 1
16310
	};
16311
} );
16312
 
16313
function clamp( value, prop, allowEmpty ) {
16314
	var type = propTypes[ prop.type ] || {};
16315
 
16316
	if ( value == null ) {
16317
		return ( allowEmpty || !prop.def ) ? null : prop.def;
16318
	}
16319
 
16320
	// ~~ is an short way of doing floor for positive numbers
16321
	value = type.floor ? ~~value : parseFloat( value );
16322
 
16323
	// IE will pass in empty strings as value for alpha,
16324
	// which will hit this case
16325
	if ( isNaN( value ) ) {
16326
		return prop.def;
16327
	}
16328
 
16329
	if ( type.mod ) {
16330
 
16331
		// We add mod before modding to make sure that negatives values
16332
		// get converted properly: -10 -> 350
16333
		return ( value + type.mod ) % type.mod;
16334
	}
16335
 
16336
	// For now all property types without mod have min and max
16337
	return 0 > value ? 0 : type.max < value ? type.max : value;
16338
}
16339
 
16340
function stringParse( string ) {
16341
	var inst = color(),
16342
		rgba = inst._rgba = [];
16343
 
16344
	string = string.toLowerCase();
16345
 
16346
	each( stringParsers, function( i, parser ) {
16347
		var parsed,
16348
			match = parser.re.exec( string ),
16349
			values = match && parser.parse( match ),
16350
			spaceName = parser.space || "rgba";
16351
 
16352
		if ( values ) {
16353
			parsed = inst[ spaceName ]( values );
16354
 
16355
			// If this was an rgba parse the assignment might happen twice
16356
			// oh well....
16357
			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
16358
			rgba = inst._rgba = parsed._rgba;
16359
 
16360
			// Exit each( stringParsers ) here because we matched
16361
			return false;
16362
		}
16363
	} );
16364
 
16365
	// Found a stringParser that handled it
16366
	if ( rgba.length ) {
16367
 
16368
		// If this came from a parsed string, force "transparent" when alpha is 0
16369
		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
16370
		if ( rgba.join() === "0,0,0,0" ) {
16371
			jQuery.extend( rgba, colors.transparent );
16372
		}
16373
		return inst;
16374
	}
16375
 
16376
	// Named colors
16377
	return colors[ string ];
16378
}
16379
 
16380
color.fn = jQuery.extend( color.prototype, {
16381
	parse: function( red, green, blue, alpha ) {
16382
		if ( red === undefined ) {
16383
			this._rgba = [ null, null, null, null ];
16384
			return this;
16385
		}
16386
		if ( red.jquery || red.nodeType ) {
16387
			red = jQuery( red ).css( green );
16388
			green = undefined;
16389
		}
16390
 
16391
		var inst = this,
16392
			type = jQuery.type( red ),
16393
			rgba = this._rgba = [];
16394
 
16395
		// More than 1 argument specified - assume ( red, green, blue, alpha )
16396
		if ( green !== undefined ) {
16397
			red = [ red, green, blue, alpha ];
16398
			type = "array";
16399
		}
16400
 
16401
		if ( type === "string" ) {
16402
			return this.parse( stringParse( red ) || colors._default );
16403
		}
16404
 
16405
		if ( type === "array" ) {
16406
			each( spaces.rgba.props, function( key, prop ) {
16407
				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
16408
			} );
16409
			return this;
16410
		}
16411
 
16412
		if ( type === "object" ) {
16413
			if ( red instanceof color ) {
16414
				each( spaces, function( spaceName, space ) {
16415
					if ( red[ space.cache ] ) {
16416
						inst[ space.cache ] = red[ space.cache ].slice();
16417
					}
16418
				} );
16419
			} else {
16420
				each( spaces, function( spaceName, space ) {
16421
					var cache = space.cache;
16422
					each( space.props, function( key, prop ) {
16423
 
16424
						// If the cache doesn't exist, and we know how to convert
16425
						if ( !inst[ cache ] && space.to ) {
16426
 
16427
							// If the value was null, we don't need to copy it
16428
							// if the key was alpha, we don't need to copy it either
16429
							if ( key === "alpha" || red[ key ] == null ) {
16430
								return;
16431
							}
16432
							inst[ cache ] = space.to( inst._rgba );
16433
						}
16434
 
16435
						// This is the only case where we allow nulls for ALL properties.
16436
						// call clamp with alwaysAllowEmpty
16437
						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
16438
					} );
16439
 
16440
					// Everything defined but alpha?
16441
					if ( inst[ cache ] &&
16442
							jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
16443
 
16444
						// Use the default of 1
16445
						inst[ cache ][ 3 ] = 1;
16446
						if ( space.from ) {
16447
							inst._rgba = space.from( inst[ cache ] );
16448
						}
16449
					}
16450
				} );
16451
			}
16452
			return this;
16453
		}
16454
	},
16455
	is: function( compare ) {
16456
		var is = color( compare ),
16457
			same = true,
16458
			inst = this;
16459
 
16460
		each( spaces, function( _, space ) {
16461
			var localCache,
16462
				isCache = is[ space.cache ];
16463
			if ( isCache ) {
16464
				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
16465
				each( space.props, function( _, prop ) {
16466
					if ( isCache[ prop.idx ] != null ) {
16467
						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
16468
						return same;
16469
					}
16470
				} );
16471
			}
16472
			return same;
16473
		} );
16474
		return same;
16475
	},
16476
	_space: function() {
16477
		var used = [],
16478
			inst = this;
16479
		each( spaces, function( spaceName, space ) {
16480
			if ( inst[ space.cache ] ) {
16481
				used.push( spaceName );
16482
			}
16483
		} );
16484
		return used.pop();
16485
	},
16486
	transition: function( other, distance ) {
16487
		var end = color( other ),
16488
			spaceName = end._space(),
16489
			space = spaces[ spaceName ],
16490
			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
16491
			start = startColor[ space.cache ] || space.to( startColor._rgba ),
16492
			result = start.slice();
16493
 
16494
		end = end[ space.cache ];
16495
		each( space.props, function( key, prop ) {
16496
			var index = prop.idx,
16497
				startValue = start[ index ],
16498
				endValue = end[ index ],
16499
				type = propTypes[ prop.type ] || {};
16500
 
16501
			// If null, don't override start value
16502
			if ( endValue === null ) {
16503
				return;
16504
			}
16505
 
16506
			// If null - use end
16507
			if ( startValue === null ) {
16508
				result[ index ] = endValue;
16509
			} else {
16510
				if ( type.mod ) {
16511
					if ( endValue - startValue > type.mod / 2 ) {
16512
						startValue += type.mod;
16513
					} else if ( startValue - endValue > type.mod / 2 ) {
16514
						startValue -= type.mod;
16515
					}
16516
				}
16517
				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
16518
			}
16519
		} );
16520
		return this[ spaceName ]( result );
16521
	},
16522
	blend: function( opaque ) {
16523
 
16524
		// If we are already opaque - return ourself
16525
		if ( this._rgba[ 3 ] === 1 ) {
16526
			return this;
16527
		}
16528
 
16529
		var rgb = this._rgba.slice(),
16530
			a = rgb.pop(),
16531
			blend = color( opaque )._rgba;
16532
 
16533
		return color( jQuery.map( rgb, function( v, i ) {
16534
			return ( 1 - a ) * blend[ i ] + a * v;
16535
		} ) );
16536
	},
16537
	toRgbaString: function() {
16538
		var prefix = "rgba(",
16539
			rgba = jQuery.map( this._rgba, function( v, i ) {
16540
				return v == null ? ( i > 2 ? 1 : 0 ) : v;
16541
			} );
16542
 
16543
		if ( rgba[ 3 ] === 1 ) {
16544
			rgba.pop();
16545
			prefix = "rgb(";
16546
		}
16547
 
16548
		return prefix + rgba.join() + ")";
16549
	},
16550
	toHslaString: function() {
16551
		var prefix = "hsla(",
16552
			hsla = jQuery.map( this.hsla(), function( v, i ) {
16553
				if ( v == null ) {
16554
					v = i > 2 ? 1 : 0;
16555
				}
16556
 
16557
				// Catch 1 and 2
16558
				if ( i && i < 3 ) {
16559
					v = Math.round( v * 100 ) + "%";
16560
				}
16561
				return v;
16562
			} );
16563
 
16564
		if ( hsla[ 3 ] === 1 ) {
16565
			hsla.pop();
16566
			prefix = "hsl(";
16567
		}
16568
		return prefix + hsla.join() + ")";
16569
	},
16570
	toHexString: function( includeAlpha ) {
16571
		var rgba = this._rgba.slice(),
16572
			alpha = rgba.pop();
16573
 
16574
		if ( includeAlpha ) {
16575
			rgba.push( ~~( alpha * 255 ) );
16576
		}
16577
 
16578
		return "#" + jQuery.map( rgba, function( v ) {
16579
 
16580
			// Default to 0 when nulls exist
16581
			v = ( v || 0 ).toString( 16 );
16582
			return v.length === 1 ? "0" + v : v;
16583
		} ).join( "" );
16584
	},
16585
	toString: function() {
16586
		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
16587
	}
16588
} );
16589
color.fn.parse.prototype = color.fn;
16590
 
16591
// Hsla conversions adapted from:
16592
// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
16593
 
16594
function hue2rgb( p, q, h ) {
16595
	h = ( h + 1 ) % 1;
16596
	if ( h * 6 < 1 ) {
16597
		return p + ( q - p ) * h * 6;
16598
	}
16599
	if ( h * 2 < 1 ) {
16600
		return q;
16601
	}
16602
	if ( h * 3 < 2 ) {
16603
		return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
16604
	}
16605
	return p;
16606
}
16607
 
16608
spaces.hsla.to = function( rgba ) {
16609
	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
16610
		return [ null, null, null, rgba[ 3 ] ];
16611
	}
16612
	var r = rgba[ 0 ] / 255,
16613
		g = rgba[ 1 ] / 255,
16614
		b = rgba[ 2 ] / 255,
16615
		a = rgba[ 3 ],
16616
		max = Math.max( r, g, b ),
16617
		min = Math.min( r, g, b ),
16618
		diff = max - min,
16619
		add = max + min,
16620
		l = add * 0.5,
16621
		h, s;
16622
 
16623
	if ( min === max ) {
16624
		h = 0;
16625
	} else if ( r === max ) {
16626
		h = ( 60 * ( g - b ) / diff ) + 360;
16627
	} else if ( g === max ) {
16628
		h = ( 60 * ( b - r ) / diff ) + 120;
16629
	} else {
16630
		h = ( 60 * ( r - g ) / diff ) + 240;
16631
	}
16632
 
16633
	// Chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
16634
	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
16635
	if ( diff === 0 ) {
16636
		s = 0;
16637
	} else if ( l <= 0.5 ) {
16638
		s = diff / add;
16639
	} else {
16640
		s = diff / ( 2 - add );
16641
	}
16642
	return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ];
16643
};
16644
 
16645
spaces.hsla.from = function( hsla ) {
16646
	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
16647
		return [ null, null, null, hsla[ 3 ] ];
16648
	}
16649
	var h = hsla[ 0 ] / 360,
16650
		s = hsla[ 1 ],
16651
		l = hsla[ 2 ],
16652
		a = hsla[ 3 ],
16653
		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
16654
		p = 2 * l - q;
16655
 
16656
	return [
16657
		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
16658
		Math.round( hue2rgb( p, q, h ) * 255 ),
16659
		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
16660
		a
16661
	];
16662
};
16663
 
16664
each( spaces, function( spaceName, space ) {
16665
	var props = space.props,
16666
		cache = space.cache,
16667
		to = space.to,
16668
		from = space.from;
16669
 
16670
	// Makes rgba() and hsla()
16671
	color.fn[ spaceName ] = function( value ) {
16672
 
16673
		// Generate a cache for this space if it doesn't exist
16674
		if ( to && !this[ cache ] ) {
16675
			this[ cache ] = to( this._rgba );
16676
		}
16677
		if ( value === undefined ) {
16678
			return this[ cache ].slice();
16679
		}
16680
 
16681
		var ret,
16682
			type = jQuery.type( value ),
16683
			arr = ( type === "array" || type === "object" ) ? value : arguments,
16684
			local = this[ cache ].slice();
16685
 
16686
		each( props, function( key, prop ) {
16687
			var val = arr[ type === "object" ? key : prop.idx ];
16688
			if ( val == null ) {
16689
				val = local[ prop.idx ];
16690
			}
16691
			local[ prop.idx ] = clamp( val, prop );
16692
		} );
16693
 
16694
		if ( from ) {
16695
			ret = color( from( local ) );
16696
			ret[ cache ] = local;
16697
			return ret;
16698
		} else {
16699
			return color( local );
16700
		}
16701
	};
16702
 
16703
	// Makes red() green() blue() alpha() hue() saturation() lightness()
16704
	each( props, function( key, prop ) {
16705
 
16706
		// Alpha is included in more than one space
16707
		if ( color.fn[ key ] ) {
16708
			return;
16709
		}
16710
		color.fn[ key ] = function( value ) {
16711
			var vtype = jQuery.type( value ),
16712
				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
16713
				local = this[ fn ](),
16714
				cur = local[ prop.idx ],
16715
				match;
16716
 
16717
			if ( vtype === "undefined" ) {
16718
				return cur;
16719
			}
16720
 
16721
			if ( vtype === "function" ) {
16722
				value = value.call( this, cur );
16723
				vtype = jQuery.type( value );
16724
			}
16725
			if ( value == null && prop.empty ) {
16726
				return this;
16727
			}
16728
			if ( vtype === "string" ) {
16729
				match = rplusequals.exec( value );
16730
				if ( match ) {
16731
					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
16732
				}
16733
			}
16734
			local[ prop.idx ] = value;
16735
			return this[ fn ]( local );
16736
		};
16737
	} );
16738
} );
16739
 
16740
// Add cssHook and .fx.step function for each named hook.
16741
// accept a space separated string of properties
16742
color.hook = function( hook ) {
16743
	var hooks = hook.split( " " );
16744
	each( hooks, function( i, hook ) {
16745
		jQuery.cssHooks[ hook ] = {
16746
			set: function( elem, value ) {
16747
				var parsed, curElem,
16748
					backgroundColor = "";
16749
 
16750
				if ( value !== "transparent" && ( jQuery.type( value ) !== "string" ||
16751
						( parsed = stringParse( value ) ) ) ) {
16752
					value = color( parsed || value );
16753
					if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
16754
						curElem = hook === "backgroundColor" ? elem.parentNode : elem;
16755
						while (
16756
							( backgroundColor === "" || backgroundColor === "transparent" ) &&
16757
							curElem && curElem.style
16758
						) {
16759
							try {
16760
								backgroundColor = jQuery.css( curElem, "backgroundColor" );
16761
								curElem = curElem.parentNode;
16762
							} catch ( e ) {
16763
							}
16764
						}
16765
 
16766
						value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
16767
							backgroundColor :
16768
							"_default" );
16769
					}
16770
 
16771
					value = value.toRgbaString();
16772
				}
16773
				try {
16774
					elem.style[ hook ] = value;
16775
				} catch ( e ) {
16776
 
16777
					// Wrapped to prevent IE from throwing errors on "invalid" values like
16778
					// 'auto' or 'inherit'
16779
				}
16780
			}
16781
		};
16782
		jQuery.fx.step[ hook ] = function( fx ) {
16783
			if ( !fx.colorInit ) {
16784
				fx.start = color( fx.elem, hook );
16785
				fx.end = color( fx.end );
16786
				fx.colorInit = true;
16787
			}
16788
			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
16789
		};
16790
	} );
16791
 
16792
};
16793
 
16794
color.hook( stepHooks );
16795
 
16796
jQuery.cssHooks.borderColor = {
16797
	expand: function( value ) {
16798
		var expanded = {};
16799
 
16800
		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
16801
			expanded[ "border" + part + "Color" ] = value;
16802
		} );
16803
		return expanded;
16804
	}
16805
};
16806
 
16807
// Basic color names only.
16808
// Usage of any of the other color names requires adding yourself or including
16809
// jquery.color.svg-names.js.
16810
colors = jQuery.Color.names = {
16811
 
16812
	// 4.1. Basic color keywords
16813
	aqua: "#00ffff",
16814
	black: "#000000",
16815
	blue: "#0000ff",
16816
	fuchsia: "#ff00ff",
16817
	gray: "#808080",
16818
	green: "#008000",
16819
	lime: "#00ff00",
16820
	maroon: "#800000",
16821
	navy: "#000080",
16822
	olive: "#808000",
16823
	purple: "#800080",
16824
	red: "#ff0000",
16825
	silver: "#c0c0c0",
16826
	teal: "#008080",
16827
	white: "#ffffff",
16828
	yellow: "#ffff00",
16829
 
16830
	// 4.2.3. "transparent" color keyword
16831
	transparent: [ null, null, null, 0 ],
16832
 
16833
	_default: "#ffffff"
16834
};
16835
 
16836
} )( jQuery );
16837
 
16838
/******************************************************************************/
16839
/****************************** CLASS ANIMATIONS ******************************/
16840
/******************************************************************************/
16841
( function() {
16842
 
16843
var classAnimationActions = [ "add", "remove", "toggle" ],
16844
	shorthandStyles = {
16845
		border: 1,
16846
		borderBottom: 1,
16847
		borderColor: 1,
16848
		borderLeft: 1,
16849
		borderRight: 1,
16850
		borderTop: 1,
16851
		borderWidth: 1,
16852
		margin: 1,
16853
		padding: 1
16854
	};
16855
 
16856
$.each(
16857
	[ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ],
16858
	function( _, prop ) {
16859
		$.fx.step[ prop ] = function( fx ) {
16860
			if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
16861
				jQuery.style( fx.elem, prop, fx.end );
16862
				fx.setAttr = true;
16863
			}
16864
		};
16865
	}
16866
);
16867
 
16868
function getElementStyles( elem ) {
16869
	var key, len,
16870
		style = elem.ownerDocument.defaultView ?
16871
			elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
16872
			elem.currentStyle,
16873
		styles = {};
16874
 
16875
	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
16876
		len = style.length;
16877
		while ( len-- ) {
16878
			key = style[ len ];
16879
			if ( typeof style[ key ] === "string" ) {
16880
				styles[ $.camelCase( key ) ] = style[ key ];
16881
			}
16882
		}
16883
 
16884
	// Support: Opera, IE <9
16885
	} else {
16886
		for ( key in style ) {
16887
			if ( typeof style[ key ] === "string" ) {
16888
				styles[ key ] = style[ key ];
16889
			}
16890
		}
16891
	}
16892
 
16893
	return styles;
16894
}
16895
 
16896
function styleDifference( oldStyle, newStyle ) {
16897
	var diff = {},
16898
		name, value;
16899
 
16900
	for ( name in newStyle ) {
16901
		value = newStyle[ name ];
16902
		if ( oldStyle[ name ] !== value ) {
16903
			if ( !shorthandStyles[ name ] ) {
16904
				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
16905
					diff[ name ] = value;
16906
				}
16907
			}
16908
		}
16909
	}
16910
 
16911
	return diff;
16912
}
16913
 
16914
// Support: jQuery <1.8
16915
if ( !$.fn.addBack ) {
16916
	$.fn.addBack = function( selector ) {
16917
		return this.add( selector == null ?
16918
			this.prevObject : this.prevObject.filter( selector )
16919
		);
16920
	};
16921
}
16922
 
16923
$.effects.animateClass = function( value, duration, easing, callback ) {
16924
	var o = $.speed( duration, easing, callback );
16925
 
16926
	return this.queue( function() {
16927
		var animated = $( this ),
16928
			baseClass = animated.attr( "class" ) || "",
16929
			applyClassChange,
16930
			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
16931
 
16932
		// Map the animated objects to store the original styles.
16933
		allAnimations = allAnimations.map( function() {
16934
			var el = $( this );
16935
			return {
16936
				el: el,
16937
				start: getElementStyles( this )
16938
			};
16939
		} );
16940
 
16941
		// Apply class change
16942
		applyClassChange = function() {
16943
			$.each( classAnimationActions, function( i, action ) {
16944
				if ( value[ action ] ) {
16945
					animated[ action + "Class" ]( value[ action ] );
16946
				}
16947
			} );
16948
		};
16949
		applyClassChange();
16950
 
16951
		// Map all animated objects again - calculate new styles and diff
16952
		allAnimations = allAnimations.map( function() {
16953
			this.end = getElementStyles( this.el[ 0 ] );
16954
			this.diff = styleDifference( this.start, this.end );
16955
			return this;
16956
		} );
16957
 
16958
		// Apply original class
16959
		animated.attr( "class", baseClass );
16960
 
16961
		// Map all animated objects again - this time collecting a promise
16962
		allAnimations = allAnimations.map( function() {
16963
			var styleInfo = this,
16964
				dfd = $.Deferred(),
16965
				opts = $.extend( {}, o, {
16966
					queue: false,
16967
					complete: function() {
16968
						dfd.resolve( styleInfo );
16969
					}
16970
				} );
16971
 
16972
			this.el.animate( this.diff, opts );
16973
			return dfd.promise();
16974
		} );
16975
 
16976
		// Once all animations have completed:
16977
		$.when.apply( $, allAnimations.get() ).done( function() {
16978
 
16979
			// Set the final class
16980
			applyClassChange();
16981
 
16982
			// For each animated element,
16983
			// clear all css properties that were animated
16984
			$.each( arguments, function() {
16985
				var el = this.el;
16986
				$.each( this.diff, function( key ) {
16987
					el.css( key, "" );
16988
				} );
16989
			} );
16990
 
16991
			// This is guarnteed to be there if you use jQuery.speed()
16992
			// it also handles dequeuing the next anim...
16993
			o.complete.call( animated[ 0 ] );
16994
		} );
16995
	} );
16996
};
16997
 
16998
$.fn.extend( {
16999
	addClass: ( function( orig ) {
17000
		return function( classNames, speed, easing, callback ) {
17001
			return speed ?
17002
				$.effects.animateClass.call( this,
17003
					{ add: classNames }, speed, easing, callback ) :
17004
				orig.apply( this, arguments );
17005
		};
17006
	} )( $.fn.addClass ),
17007
 
17008
	removeClass: ( function( orig ) {
17009
		return function( classNames, speed, easing, callback ) {
17010
			return arguments.length > 1 ?
17011
				$.effects.animateClass.call( this,
17012
					{ remove: classNames }, speed, easing, callback ) :
17013
				orig.apply( this, arguments );
17014
		};
17015
	} )( $.fn.removeClass ),
17016
 
17017
	toggleClass: ( function( orig ) {
17018
		return function( classNames, force, speed, easing, callback ) {
17019
			if ( typeof force === "boolean" || force === undefined ) {
17020
				if ( !speed ) {
17021
 
17022
					// Without speed parameter
17023
					return orig.apply( this, arguments );
17024
				} else {
17025
					return $.effects.animateClass.call( this,
17026
						( force ? { add: classNames } : { remove: classNames } ),
17027
						speed, easing, callback );
17028
				}
17029
			} else {
17030
 
17031
				// Without force parameter
17032
				return $.effects.animateClass.call( this,
17033
					{ toggle: classNames }, force, speed, easing );
17034
			}
17035
		};
17036
	} )( $.fn.toggleClass ),
17037
 
17038
	switchClass: function( remove, add, speed, easing, callback ) {
17039
		return $.effects.animateClass.call( this, {
17040
			add: add,
17041
			remove: remove
17042
		}, speed, easing, callback );
17043
	}
17044
} );
17045
 
17046
} )();
17047
 
17048
/******************************************************************************/
17049
/*********************************** EFFECTS **********************************/
17050
/******************************************************************************/
17051
 
17052
( function() {
17053
 
17054
if ( $.expr && $.expr.filters && $.expr.filters.animated ) {
17055
	$.expr.filters.animated = ( function( orig ) {
17056
		return function( elem ) {
17057
			return !!$( elem ).data( dataSpaceAnimated ) || orig( elem );
17058
		};
17059
	} )( $.expr.filters.animated );
17060
}
17061
 
17062
if ( $.uiBackCompat !== false ) {
17063
	$.extend( $.effects, {
17064
 
17065
		// Saves a set of properties in a data storage
17066
		save: function( element, set ) {
17067
			var i = 0, length = set.length;
17068
			for ( ; i < length; i++ ) {
17069
				if ( set[ i ] !== null ) {
17070
					element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
17071
				}
17072
			}
17073
		},
17074
 
17075
		// Restores a set of previously saved properties from a data storage
17076
		restore: function( element, set ) {
17077
			var val, i = 0, length = set.length;
17078
			for ( ; i < length; i++ ) {
17079
				if ( set[ i ] !== null ) {
17080
					val = element.data( dataSpace + set[ i ] );
17081
					element.css( set[ i ], val );
17082
				}
17083
			}
17084
		},
17085
 
17086
		setMode: function( el, mode ) {
17087
			if ( mode === "toggle" ) {
17088
				mode = el.is( ":hidden" ) ? "show" : "hide";
17089
			}
17090
			return mode;
17091
		},
17092
 
17093
		// Wraps the element around a wrapper that copies position properties
17094
		createWrapper: function( element ) {
17095
 
17096
			// If the element is already wrapped, return it
17097
			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
17098
				return element.parent();
17099
			}
17100
 
17101
			// Wrap the element
17102
			var props = {
17103
					width: element.outerWidth( true ),
17104
					height: element.outerHeight( true ),
17105
					"float": element.css( "float" )
17106
				},
17107
				wrapper = $( "<div></div>" )
17108
					.addClass( "ui-effects-wrapper" )
17109
					.css( {
17110
						fontSize: "100%",
17111
						background: "transparent",
17112
						border: "none",
17113
						margin: 0,
17114
						padding: 0
17115
					} ),
17116
 
17117
				// Store the size in case width/height are defined in % - Fixes #5245
17118
				size = {
17119
					width: element.width(),
17120
					height: element.height()
17121
				},
17122
				active = document.activeElement;
17123
 
17124
			// Support: Firefox
17125
			// Firefox incorrectly exposes anonymous content
17126
			// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
17127
			try {
17128
				active.id;
17129
			} catch ( e ) {
17130
				active = document.body;
17131
			}
17132
 
17133
			element.wrap( wrapper );
17134
 
17135
			// Fixes #7595 - Elements lose focus when wrapped.
17136
			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
17137
				$( active ).trigger( "focus" );
17138
			}
17139
 
17140
			// Hotfix for jQuery 1.4 since some change in wrap() seems to actually
17141
			// lose the reference to the wrapped element
17142
			wrapper = element.parent();
17143
 
17144
			// Transfer positioning properties to the wrapper
17145
			if ( element.css( "position" ) === "static" ) {
17146
				wrapper.css( { position: "relative" } );
17147
				element.css( { position: "relative" } );
17148
			} else {
17149
				$.extend( props, {
17150
					position: element.css( "position" ),
17151
					zIndex: element.css( "z-index" )
17152
				} );
17153
				$.each( [ "top", "left", "bottom", "right" ], function( i, pos ) {
17154
					props[ pos ] = element.css( pos );
17155
					if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
17156
						props[ pos ] = "auto";
17157
					}
17158
				} );
17159
				element.css( {
17160
					position: "relative",
17161
					top: 0,
17162
					left: 0,
17163
					right: "auto",
17164
					bottom: "auto"
17165
				} );
17166
			}
17167
			element.css( size );
17168
 
17169
			return wrapper.css( props ).show();
17170
		},
17171
 
17172
		removeWrapper: function( element ) {
17173
			var active = document.activeElement;
17174
 
17175
			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
17176
				element.parent().replaceWith( element );
17177
 
17178
				// Fixes #7595 - Elements lose focus when wrapped.
17179
				if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
17180
					$( active ).trigger( "focus" );
17181
				}
17182
			}
17183
 
17184
			return element;
17185
		}
17186
	} );
17187
}
17188
 
17189
$.extend( $.effects, {
17190
	version: "1.12.1",
17191
 
17192
	define: function( name, mode, effect ) {
17193
		if ( !effect ) {
17194
			effect = mode;
17195
			mode = "effect";
17196
		}
17197
 
17198
		$.effects.effect[ name ] = effect;
17199
		$.effects.effect[ name ].mode = mode;
17200
 
17201
		return effect;
17202
	},
17203
 
17204
	scaledDimensions: function( element, percent, direction ) {
17205
		if ( percent === 0 ) {
17206
			return {
17207
				height: 0,
17208
				width: 0,
17209
				outerHeight: 0,
17210
				outerWidth: 0
17211
			};
17212
		}
17213
 
17214
		var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1,
17215
			y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1;
17216
 
17217
		return {
17218
			height: element.height() * y,
17219
			width: element.width() * x,
17220
			outerHeight: element.outerHeight() * y,
17221
			outerWidth: element.outerWidth() * x
17222
		};
17223
 
17224
	},
17225
 
17226
	clipToBox: function( animation ) {
17227
		return {
17228
			width: animation.clip.right - animation.clip.left,
17229
			height: animation.clip.bottom - animation.clip.top,
17230
			left: animation.clip.left,
17231
			top: animation.clip.top
17232
		};
17233
	},
17234
 
17235
	// Injects recently queued functions to be first in line (after "inprogress")
17236
	unshift: function( element, queueLength, count ) {
17237
		var queue = element.queue();
17238
 
17239
		if ( queueLength > 1 ) {
17240
			queue.splice.apply( queue,
17241
				[ 1, 0 ].concat( queue.splice( queueLength, count ) ) );
17242
		}
17243
		element.dequeue();
17244
	},
17245
 
17246
	saveStyle: function( element ) {
17247
		element.data( dataSpaceStyle, element[ 0 ].style.cssText );
17248
	},
17249
 
17250
	restoreStyle: function( element ) {
17251
		element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || "";
17252
		element.removeData( dataSpaceStyle );
17253
	},
17254
 
17255
	mode: function( element, mode ) {
17256
		var hidden = element.is( ":hidden" );
17257
 
17258
		if ( mode === "toggle" ) {
17259
			mode = hidden ? "show" : "hide";
17260
		}
17261
		if ( hidden ? mode === "hide" : mode === "show" ) {
17262
			mode = "none";
17263
		}
17264
		return mode;
17265
	},
17266
 
17267
	// Translates a [top,left] array into a baseline value
17268
	getBaseline: function( origin, original ) {
17269
		var y, x;
17270
 
17271
		switch ( origin[ 0 ] ) {
17272
		case "top":
17273
			y = 0;
17274
			break;
17275
		case "middle":
17276
			y = 0.5;
17277
			break;
17278
		case "bottom":
17279
			y = 1;
17280
			break;
17281
		default:
17282
			y = origin[ 0 ] / original.height;
17283
		}
17284
 
17285
		switch ( origin[ 1 ] ) {
17286
		case "left":
17287
			x = 0;
17288
			break;
17289
		case "center":
17290
			x = 0.5;
17291
			break;
17292
		case "right":
17293
			x = 1;
17294
			break;
17295
		default:
17296
			x = origin[ 1 ] / original.width;
17297
		}
17298
 
17299
		return {
17300
			x: x,
17301
			y: y
17302
		};
17303
	},
17304
 
17305
	// Creates a placeholder element so that the original element can be made absolute
17306
	createPlaceholder: function( element ) {
17307
		var placeholder,
17308
			cssPosition = element.css( "position" ),
17309
			position = element.position();
17310
 
17311
		// Lock in margins first to account for form elements, which
17312
		// will change margin if you explicitly set height
17313
		// see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380
17314
		// Support: Safari
17315
		element.css( {
17316
			marginTop: element.css( "marginTop" ),
17317
			marginBottom: element.css( "marginBottom" ),
17318
			marginLeft: element.css( "marginLeft" ),
17319
			marginRight: element.css( "marginRight" )
17320
		} )
17321
		.outerWidth( element.outerWidth() )
17322
		.outerHeight( element.outerHeight() );
17323
 
17324
		if ( /^(static|relative)/.test( cssPosition ) ) {
17325
			cssPosition = "absolute";
17326
 
17327
			placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( {
17328
 
17329
				// Convert inline to inline block to account for inline elements
17330
				// that turn to inline block based on content (like img)
17331
				display: /^(inline|ruby)/.test( element.css( "display" ) ) ?
17332
					"inline-block" :
17333
					"block",
17334
				visibility: "hidden",
17335
 
17336
				// Margins need to be set to account for margin collapse
17337
				marginTop: element.css( "marginTop" ),
17338
				marginBottom: element.css( "marginBottom" ),
17339
				marginLeft: element.css( "marginLeft" ),
17340
				marginRight: element.css( "marginRight" ),
17341
				"float": element.css( "float" )
17342
			} )
17343
			.outerWidth( element.outerWidth() )
17344
			.outerHeight( element.outerHeight() )
17345
			.addClass( "ui-effects-placeholder" );
17346
 
17347
			element.data( dataSpace + "placeholder", placeholder );
17348
		}
17349
 
17350
		element.css( {
17351
			position: cssPosition,
17352
			left: position.left,
17353
			top: position.top
17354
		} );
17355
 
17356
		return placeholder;
17357
	},
17358
 
17359
	removePlaceholder: function( element ) {
17360
		var dataKey = dataSpace + "placeholder",
17361
				placeholder = element.data( dataKey );
17362
 
17363
		if ( placeholder ) {
17364
			placeholder.remove();
17365
			element.removeData( dataKey );
17366
		}
17367
	},
17368
 
17369
	// Removes a placeholder if it exists and restores
17370
	// properties that were modified during placeholder creation
17371
	cleanUp: function( element ) {
17372
		$.effects.restoreStyle( element );
17373
		$.effects.removePlaceholder( element );
17374
	},
17375
 
17376
	setTransition: function( element, list, factor, value ) {
17377
		value = value || {};
17378
		$.each( list, function( i, x ) {
17379
			var unit = element.cssUnit( x );
17380
			if ( unit[ 0 ] > 0 ) {
17381
				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
17382
			}
17383
		} );
17384
		return value;
17385
	}
17386
} );
17387
 
17388
// Return an effect options object for the given parameters:
17389
function _normalizeArguments( effect, options, speed, callback ) {
17390
 
17391
	// Allow passing all options as the first parameter
17392
	if ( $.isPlainObject( effect ) ) {
17393
		options = effect;
17394
		effect = effect.effect;
17395
	}
17396
 
17397
	// Convert to an object
17398
	effect = { effect: effect };
17399
 
17400
	// Catch (effect, null, ...)
17401
	if ( options == null ) {
17402
		options = {};
17403
	}
17404
 
17405
	// Catch (effect, callback)
17406
	if ( $.isFunction( options ) ) {
17407
		callback = options;
17408
		speed = null;
17409
		options = {};
17410
	}
17411
 
17412
	// Catch (effect, speed, ?)
17413
	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
17414
		callback = speed;
17415
		speed = options;
17416
		options = {};
17417
	}
17418
 
17419
	// Catch (effect, options, callback)
17420
	if ( $.isFunction( speed ) ) {
17421
		callback = speed;
17422
		speed = null;
17423
	}
17424
 
17425
	// Add options to effect
17426
	if ( options ) {
17427
		$.extend( effect, options );
17428
	}
17429
 
17430
	speed = speed || options.duration;
17431
	effect.duration = $.fx.off ? 0 :
17432
		typeof speed === "number" ? speed :
17433
		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
17434
		$.fx.speeds._default;
17435
 
17436
	effect.complete = callback || options.complete;
17437
 
17438
	return effect;
17439
}
17440
 
17441
function standardAnimationOption( option ) {
17442
 
17443
	// Valid standard speeds (nothing, number, named speed)
17444
	if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
17445
		return true;
17446
	}
17447
 
17448
	// Invalid strings - treat as "normal" speed
17449
	if ( typeof option === "string" && !$.effects.effect[ option ] ) {
17450
		return true;
17451
	}
17452
 
17453
	// Complete callback
17454
	if ( $.isFunction( option ) ) {
17455
		return true;
17456
	}
17457
 
17458
	// Options hash (but not naming an effect)
17459
	if ( typeof option === "object" && !option.effect ) {
17460
		return true;
17461
	}
17462
 
17463
	// Didn't match any standard API
17464
	return false;
17465
}
17466
 
17467
$.fn.extend( {
17468
	effect: function( /* effect, options, speed, callback */ ) {
17469
		var args = _normalizeArguments.apply( this, arguments ),
17470
			effectMethod = $.effects.effect[ args.effect ],
17471
			defaultMode = effectMethod.mode,
17472
			queue = args.queue,
17473
			queueName = queue || "fx",
17474
			complete = args.complete,
17475
			mode = args.mode,
17476
			modes = [],
17477
			prefilter = function( next ) {
17478
				var el = $( this ),
17479
					normalizedMode = $.effects.mode( el, mode ) || defaultMode;
17480
 
17481
				// Sentinel for duck-punching the :animated psuedo-selector
17482
				el.data( dataSpaceAnimated, true );
17483
 
17484
				// Save effect mode for later use,
17485
				// we can't just call $.effects.mode again later,
17486
				// as the .show() below destroys the initial state
17487
				modes.push( normalizedMode );
17488
 
17489
				// See $.uiBackCompat inside of run() for removal of defaultMode in 1.13
17490
				if ( defaultMode && ( normalizedMode === "show" ||
17491
						( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) {
17492
					el.show();
17493
				}
17494
 
17495
				if ( !defaultMode || normalizedMode !== "none" ) {
17496
					$.effects.saveStyle( el );
17497
				}
17498
 
17499
				if ( $.isFunction( next ) ) {
17500
					next();
17501
				}
17502
			};
17503
 
17504
		if ( $.fx.off || !effectMethod ) {
17505
 
17506
			// Delegate to the original method (e.g., .show()) if possible
17507
			if ( mode ) {
17508
				return this[ mode ]( args.duration, complete );
17509
			} else {
17510
				return this.each( function() {
17511
					if ( complete ) {
17512
						complete.call( this );
17513
					}
17514
				} );
17515
			}
17516
		}
17517
 
17518
		function run( next ) {
17519
			var elem = $( this );
17520
 
17521
			function cleanup() {
17522
				elem.removeData( dataSpaceAnimated );
17523
 
17524
				$.effects.cleanUp( elem );
17525
 
17526
				if ( args.mode === "hide" ) {
17527
					elem.hide();
17528
				}
17529
 
17530
				done();
17531
			}
17532
 
17533
			function done() {
17534
				if ( $.isFunction( complete ) ) {
17535
					complete.call( elem[ 0 ] );
17536
				}
17537
 
17538
				if ( $.isFunction( next ) ) {
17539
					next();
17540
				}
17541
			}
17542
 
17543
			// Override mode option on a per element basis,
17544
			// as toggle can be either show or hide depending on element state
17545
			args.mode = modes.shift();
17546
 
17547
			if ( $.uiBackCompat !== false && !defaultMode ) {
17548
				if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
17549
 
17550
					// Call the core method to track "olddisplay" properly
17551
					elem[ mode ]();
17552
					done();
17553
				} else {
17554
					effectMethod.call( elem[ 0 ], args, done );
17555
				}
17556
			} else {
17557
				if ( args.mode === "none" ) {
17558
 
17559
					// Call the core method to track "olddisplay" properly
17560
					elem[ mode ]();
17561
					done();
17562
				} else {
17563
					effectMethod.call( elem[ 0 ], args, cleanup );
17564
				}
17565
			}
17566
		}
17567
 
17568
		// Run prefilter on all elements first to ensure that
17569
		// any showing or hiding happens before placeholder creation,
17570
		// which ensures that any layout changes are correctly captured.
17571
		return queue === false ?
17572
			this.each( prefilter ).each( run ) :
17573
			this.queue( queueName, prefilter ).queue( queueName, run );
17574
	},
17575
 
17576
	show: ( function( orig ) {
17577
		return function( option ) {
17578
			if ( standardAnimationOption( option ) ) {
17579
				return orig.apply( this, arguments );
17580
			} else {
17581
				var args = _normalizeArguments.apply( this, arguments );
17582
				args.mode = "show";
17583
				return this.effect.call( this, args );
17584
			}
17585
		};
17586
	} )( $.fn.show ),
17587
 
17588
	hide: ( function( orig ) {
17589
		return function( option ) {
17590
			if ( standardAnimationOption( option ) ) {
17591
				return orig.apply( this, arguments );
17592
			} else {
17593
				var args = _normalizeArguments.apply( this, arguments );
17594
				args.mode = "hide";
17595
				return this.effect.call( this, args );
17596
			}
17597
		};
17598
	} )( $.fn.hide ),
17599
 
17600
	toggle: ( function( orig ) {
17601
		return function( option ) {
17602
			if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
17603
				return orig.apply( this, arguments );
17604
			} else {
17605
				var args = _normalizeArguments.apply( this, arguments );
17606
				args.mode = "toggle";
17607
				return this.effect.call( this, args );
17608
			}
17609
		};
17610
	} )( $.fn.toggle ),
17611
 
17612
	cssUnit: function( key ) {
17613
		var style = this.css( key ),
17614
			val = [];
17615
 
17616
		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
17617
			if ( style.indexOf( unit ) > 0 ) {
17618
				val = [ parseFloat( style ), unit ];
17619
			}
17620
		} );
17621
		return val;
17622
	},
17623
 
17624
	cssClip: function( clipObj ) {
17625
		if ( clipObj ) {
17626
			return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " +
17627
				clipObj.bottom + "px " + clipObj.left + "px)" );
17628
		}
17629
		return parseClip( this.css( "clip" ), this );
17630
	},
17631
 
17632
	transfer: function( options, done ) {
17633
		var element = $( this ),
17634
			target = $( options.to ),
17635
			targetFixed = target.css( "position" ) === "fixed",
17636
			body = $( "body" ),
17637
			fixTop = targetFixed ? body.scrollTop() : 0,
17638
			fixLeft = targetFixed ? body.scrollLeft() : 0,
17639
			endPosition = target.offset(),
17640
			animation = {
17641
				top: endPosition.top - fixTop,
17642
				left: endPosition.left - fixLeft,
17643
				height: target.innerHeight(),
17644
				width: target.innerWidth()
17645
			},
17646
			startPosition = element.offset(),
17647
			transfer = $( "<div class='ui-effects-transfer'></div>" )
17648
				.appendTo( "body" )
17649
				.addClass( options.className )
17650
				.css( {
17651
					top: startPosition.top - fixTop,
17652
					left: startPosition.left - fixLeft,
17653
					height: element.innerHeight(),
17654
					width: element.innerWidth(),
17655
					position: targetFixed ? "fixed" : "absolute"
17656
				} )
17657
				.animate( animation, options.duration, options.easing, function() {
17658
					transfer.remove();
17659
					if ( $.isFunction( done ) ) {
17660
						done();
17661
					}
17662
				} );
17663
	}
17664
} );
17665
 
17666
function parseClip( str, element ) {
17667
		var outerWidth = element.outerWidth(),
17668
			outerHeight = element.outerHeight(),
17669
			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)\)$/,
17670
			values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ];
17671
 
17672
		return {
17673
			top: parseFloat( values[ 1 ] ) || 0,
17674
			right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ),
17675
			bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ),
17676
			left: parseFloat( values[ 4 ] ) || 0
17677
		};
17678
}
17679
 
17680
$.fx.step.clip = function( fx ) {
17681
	if ( !fx.clipInit ) {
17682
		fx.start = $( fx.elem ).cssClip();
17683
		if ( typeof fx.end === "string" ) {
17684
			fx.end = parseClip( fx.end, fx.elem );
17685
		}
17686
		fx.clipInit = true;
17687
	}
17688
 
17689
	$( fx.elem ).cssClip( {
17690
		top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top,
17691
		right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right,
17692
		bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom,
17693
		left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left
17694
	} );
17695
};
17696
 
17697
} )();
17698
 
17699
/******************************************************************************/
17700
/*********************************** EASING ***********************************/
17701
/******************************************************************************/
17702
 
17703
( function() {
17704
 
17705
// Based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
17706
 
17707
var baseEasings = {};
17708
 
17709
$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
17710
	baseEasings[ name ] = function( p ) {
17711
		return Math.pow( p, i + 2 );
17712
	};
17713
} );
17714
 
17715
$.extend( baseEasings, {
17716
	Sine: function( p ) {
17717
		return 1 - Math.cos( p * Math.PI / 2 );
17718
	},
17719
	Circ: function( p ) {
17720
		return 1 - Math.sqrt( 1 - p * p );
17721
	},
17722
	Elastic: function( p ) {
17723
		return p === 0 || p === 1 ? p :
17724
			-Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );
17725
	},
17726
	Back: function( p ) {
17727
		return p * p * ( 3 * p - 2 );
17728
	},
17729
	Bounce: function( p ) {
17730
		var pow2,
17731
			bounce = 4;
17732
 
17733
		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
17734
		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
17735
	}
17736
} );
17737
 
17738
$.each( baseEasings, function( name, easeIn ) {
17739
	$.easing[ "easeIn" + name ] = easeIn;
17740
	$.easing[ "easeOut" + name ] = function( p ) {
17741
		return 1 - easeIn( 1 - p );
17742
	};
17743
	$.easing[ "easeInOut" + name ] = function( p ) {
17744
		return p < 0.5 ?
17745
			easeIn( p * 2 ) / 2 :
17746
			1 - easeIn( p * -2 + 2 ) / 2;
17747
	};
17748
} );
17749
 
17750
} )();
17751
 
17752
var effect = $.effects;
17753
 
17754
 
17755
/*!
17756
 * jQuery UI Effects Blind 1.12.1
17757
 * http://jqueryui.com
17758
 *
17759
 * Copyright jQuery Foundation and other contributors
17760
 * Released under the MIT license.
17761
 * http://jquery.org/license
17762
 */
17763
 
17764
//>>label: Blind Effect
17765
//>>group: Effects
17766
//>>description: Blinds the element.
17767
//>>docs: http://api.jqueryui.com/blind-effect/
17768
//>>demos: http://jqueryui.com/effect/
17769
 
17770
 
17771
 
17772
var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) {
17773
	var map = {
17774
			up: [ "bottom", "top" ],
17775
			vertical: [ "bottom", "top" ],
17776
			down: [ "top", "bottom" ],
17777
			left: [ "right", "left" ],
17778
			horizontal: [ "right", "left" ],
17779
			right: [ "left", "right" ]
17780
		},
17781
		element = $( this ),
17782
		direction = options.direction || "up",
17783
		start = element.cssClip(),
17784
		animate = { clip: $.extend( {}, start ) },
17785
		placeholder = $.effects.createPlaceholder( element );
17786
 
17787
	animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ];
17788
 
17789
	if ( options.mode === "show" ) {
17790
		element.cssClip( animate.clip );
17791
		if ( placeholder ) {
17792
			placeholder.css( $.effects.clipToBox( animate ) );
17793
		}
17794
 
17795
		animate.clip = start;
17796
	}
17797
 
17798
	if ( placeholder ) {
17799
		placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing );
17800
	}
17801
 
17802
	element.animate( animate, {
17803
		queue: false,
17804
		duration: options.duration,
17805
		easing: options.easing,
17806
		complete: done
17807
	} );
17808
} );
17809
 
17810
 
17811
/*!
17812
 * jQuery UI Effects Bounce 1.12.1
17813
 * http://jqueryui.com
17814
 *
17815
 * Copyright jQuery Foundation and other contributors
17816
 * Released under the MIT license.
17817
 * http://jquery.org/license
17818
 */
17819
 
17820
//>>label: Bounce Effect
17821
//>>group: Effects
17822
//>>description: Bounces an element horizontally or vertically n times.
17823
//>>docs: http://api.jqueryui.com/bounce-effect/
17824
//>>demos: http://jqueryui.com/effect/
17825
 
17826
 
17827
 
17828
var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) {
17829
	var upAnim, downAnim, refValue,
17830
		element = $( this ),
17831
 
17832
		// Defaults:
17833
		mode = options.mode,
17834
		hide = mode === "hide",
17835
		show = mode === "show",
17836
		direction = options.direction || "up",
17837
		distance = options.distance,
17838
		times = options.times || 5,
17839
 
17840
		// Number of internal animations
17841
		anims = times * 2 + ( show || hide ? 1 : 0 ),
17842
		speed = options.duration / anims,
17843
		easing = options.easing,
17844
 
17845
		// Utility:
17846
		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
17847
		motion = ( direction === "up" || direction === "left" ),
17848
		i = 0,
17849
 
17850
		queuelen = element.queue().length;
17851
 
17852
	$.effects.createPlaceholder( element );
17853
 
17854
	refValue = element.css( ref );
17855
 
17856
	// Default distance for the BIGGEST bounce is the outer Distance / 3
17857
	if ( !distance ) {
17858
		distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
17859
	}
17860
 
17861
	if ( show ) {
17862
		downAnim = { opacity: 1 };
17863
		downAnim[ ref ] = refValue;
17864
 
17865
		// If we are showing, force opacity 0 and set the initial position
17866
		// then do the "first" animation
17867
		element
17868
			.css( "opacity", 0 )
17869
			.css( ref, motion ? -distance * 2 : distance * 2 )
17870
			.animate( downAnim, speed, easing );
17871
	}
17872
 
17873
	// Start at the smallest distance if we are hiding
17874
	if ( hide ) {
17875
		distance = distance / Math.pow( 2, times - 1 );
17876
	}
17877
 
17878
	downAnim = {};
17879
	downAnim[ ref ] = refValue;
17880
 
17881
	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
17882
	for ( ; i < times; i++ ) {
17883
		upAnim = {};
17884
		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
17885
 
17886
		element
17887
			.animate( upAnim, speed, easing )
17888
			.animate( downAnim, speed, easing );
17889
 
17890
		distance = hide ? distance * 2 : distance / 2;
17891
	}
17892
 
17893
	// Last Bounce when Hiding
17894
	if ( hide ) {
17895
		upAnim = { opacity: 0 };
17896
		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
17897
 
17898
		element.animate( upAnim, speed, easing );
17899
	}
17900
 
17901
	element.queue( done );
17902
 
17903
	$.effects.unshift( element, queuelen, anims + 1 );
17904
} );
17905
 
17906
 
17907
/*!
17908
 * jQuery UI Effects Clip 1.12.1
17909
 * http://jqueryui.com
17910
 *
17911
 * Copyright jQuery Foundation and other contributors
17912
 * Released under the MIT license.
17913
 * http://jquery.org/license
17914
 */
17915
 
17916
//>>label: Clip Effect
17917
//>>group: Effects
17918
//>>description: Clips the element on and off like an old TV.
17919
//>>docs: http://api.jqueryui.com/clip-effect/
17920
//>>demos: http://jqueryui.com/effect/
17921
 
17922
 
17923
 
17924
var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) {
17925
	var start,
17926
		animate = {},
17927
		element = $( this ),
17928
		direction = options.direction || "vertical",
17929
		both = direction === "both",
17930
		horizontal = both || direction === "horizontal",
17931
		vertical = both || direction === "vertical";
17932
 
17933
	start = element.cssClip();
17934
	animate.clip = {
17935
		top: vertical ? ( start.bottom - start.top ) / 2 : start.top,
17936
		right: horizontal ? ( start.right - start.left ) / 2 : start.right,
17937
		bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom,
17938
		left: horizontal ? ( start.right - start.left ) / 2 : start.left
17939
	};
17940
 
17941
	$.effects.createPlaceholder( element );
17942
 
17943
	if ( options.mode === "show" ) {
17944
		element.cssClip( animate.clip );
17945
		animate.clip = start;
17946
	}
17947
 
17948
	element.animate( animate, {
17949
		queue: false,
17950
		duration: options.duration,
17951
		easing: options.easing,
17952
		complete: done
17953
	} );
17954
 
17955
} );
17956
 
17957
 
17958
/*!
17959
 * jQuery UI Effects Drop 1.12.1
17960
 * http://jqueryui.com
17961
 *
17962
 * Copyright jQuery Foundation and other contributors
17963
 * Released under the MIT license.
17964
 * http://jquery.org/license
17965
 */
17966
 
17967
//>>label: Drop Effect
17968
//>>group: Effects
17969
//>>description: Moves an element in one direction and hides it at the same time.
17970
//>>docs: http://api.jqueryui.com/drop-effect/
17971
//>>demos: http://jqueryui.com/effect/
17972
 
17973
 
17974
 
17975
var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) {
17976
 
17977
	var distance,
17978
		element = $( this ),
17979
		mode = options.mode,
17980
		show = mode === "show",
17981
		direction = options.direction || "left",
17982
		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
17983
		motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=",
17984
		oppositeMotion = ( motion === "+=" ) ? "-=" : "+=",
17985
		animation = {
17986
			opacity: 0
17987
		};
17988
 
17989
	$.effects.createPlaceholder( element );
17990
 
17991
	distance = options.distance ||
17992
		element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
17993
 
17994
	animation[ ref ] = motion + distance;
17995
 
17996
	if ( show ) {
17997
		element.css( animation );
17998
 
17999
		animation[ ref ] = oppositeMotion + distance;
18000
		animation.opacity = 1;
18001
	}
18002
 
18003
	// Animate
18004
	element.animate( animation, {
18005
		queue: false,
18006
		duration: options.duration,
18007
		easing: options.easing,
18008
		complete: done
18009
	} );
18010
} );
18011
 
18012
 
18013
/*!
18014
 * jQuery UI Effects Explode 1.12.1
18015
 * http://jqueryui.com
18016
 *
18017
 * Copyright jQuery Foundation and other contributors
18018
 * Released under the MIT license.
18019
 * http://jquery.org/license
18020
 */
18021
 
18022
//>>label: Explode Effect
18023
//>>group: Effects
18024
// jscs:disable maximumLineLength
18025
//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness.
18026
// jscs:enable maximumLineLength
18027
//>>docs: http://api.jqueryui.com/explode-effect/
18028
//>>demos: http://jqueryui.com/effect/
18029
 
18030
 
18031
 
18032
var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) {
18033
 
18034
	var i, j, left, top, mx, my,
18035
		rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3,
18036
		cells = rows,
18037
		element = $( this ),
18038
		mode = options.mode,
18039
		show = mode === "show",
18040
 
18041
		// Show and then visibility:hidden the element before calculating offset
18042
		offset = element.show().css( "visibility", "hidden" ).offset(),
18043
 
18044
		// Width and height of a piece
18045
		width = Math.ceil( element.outerWidth() / cells ),
18046
		height = Math.ceil( element.outerHeight() / rows ),
18047
		pieces = [];
18048
 
18049
	// Children animate complete:
18050
	function childComplete() {
18051
		pieces.push( this );
18052
		if ( pieces.length === rows * cells ) {
18053
			animComplete();
18054
		}
18055
	}
18056
 
18057
	// Clone the element for each row and cell.
18058
	for ( i = 0; i < rows; i++ ) { // ===>
18059
		top = offset.top + i * height;
18060
		my = i - ( rows - 1 ) / 2;
18061
 
18062
		for ( j = 0; j < cells; j++ ) { // |||
18063
			left = offset.left + j * width;
18064
			mx = j - ( cells - 1 ) / 2;
18065
 
18066
			// Create a clone of the now hidden main element that will be absolute positioned
18067
			// within a wrapper div off the -left and -top equal to size of our pieces
18068
			element
18069
				.clone()
18070
				.appendTo( "body" )
18071
				.wrap( "<div></div>" )
18072
				.css( {
18073
					position: "absolute",
18074
					visibility: "visible",
18075
					left: -j * width,
18076
					top: -i * height
18077
				} )
18078
 
18079
				// Select the wrapper - make it overflow: hidden and absolute positioned based on
18080
				// where the original was located +left and +top equal to the size of pieces
18081
				.parent()
18082
					.addClass( "ui-effects-explode" )
18083
					.css( {
18084
						position: "absolute",
18085
						overflow: "hidden",
18086
						width: width,
18087
						height: height,
18088
						left: left + ( show ? mx * width : 0 ),
18089
						top: top + ( show ? my * height : 0 ),
18090
						opacity: show ? 0 : 1
18091
					} )
18092
					.animate( {
18093
						left: left + ( show ? 0 : mx * width ),
18094
						top: top + ( show ? 0 : my * height ),
18095
						opacity: show ? 1 : 0
18096
					}, options.duration || 500, options.easing, childComplete );
18097
		}
18098
	}
18099
 
18100
	function animComplete() {
18101
		element.css( {
18102
			visibility: "visible"
18103
		} );
18104
		$( pieces ).remove();
18105
		done();
18106
	}
18107
} );
18108
 
18109
 
18110
/*!
18111
 * jQuery UI Effects Fade 1.12.1
18112
 * http://jqueryui.com
18113
 *
18114
 * Copyright jQuery Foundation and other contributors
18115
 * Released under the MIT license.
18116
 * http://jquery.org/license
18117
 */
18118
 
18119
//>>label: Fade Effect
18120
//>>group: Effects
18121
//>>description: Fades the element.
18122
//>>docs: http://api.jqueryui.com/fade-effect/
18123
//>>demos: http://jqueryui.com/effect/
18124
 
18125
 
18126
 
18127
var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) {
18128
	var show = options.mode === "show";
18129
 
18130
	$( this )
18131
		.css( "opacity", show ? 0 : 1 )
18132
		.animate( {
18133
			opacity: show ? 1 : 0
18134
		}, {
18135
			queue: false,
18136
			duration: options.duration,
18137
			easing: options.easing,
18138
			complete: done
18139
		} );
18140
} );
18141
 
18142
 
18143
/*!
18144
 * jQuery UI Effects Fold 1.12.1
18145
 * http://jqueryui.com
18146
 *
18147
 * Copyright jQuery Foundation and other contributors
18148
 * Released under the MIT license.
18149
 * http://jquery.org/license
18150
 */
18151
 
18152
//>>label: Fold Effect
18153
//>>group: Effects
18154
//>>description: Folds an element first horizontally and then vertically.
18155
//>>docs: http://api.jqueryui.com/fold-effect/
18156
//>>demos: http://jqueryui.com/effect/
18157
 
18158
 
18159
 
18160
var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) {
18161
 
18162
	// Create element
18163
	var element = $( this ),
18164
		mode = options.mode,
18165
		show = mode === "show",
18166
		hide = mode === "hide",
18167
		size = options.size || 15,
18168
		percent = /([0-9]+)%/.exec( size ),
18169
		horizFirst = !!options.horizFirst,
18170
		ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ],
18171
		duration = options.duration / 2,
18172
 
18173
		placeholder = $.effects.createPlaceholder( element ),
18174
 
18175
		start = element.cssClip(),
18176
		animation1 = { clip: $.extend( {}, start ) },
18177
		animation2 = { clip: $.extend( {}, start ) },
18178
 
18179
		distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ],
18180
 
18181
		queuelen = element.queue().length;
18182
 
18183
	if ( percent ) {
18184
		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
18185
	}
18186
	animation1.clip[ ref[ 0 ] ] = size;
18187
	animation2.clip[ ref[ 0 ] ] = size;
18188
	animation2.clip[ ref[ 1 ] ] = 0;
18189
 
18190
	if ( show ) {
18191
		element.cssClip( animation2.clip );
18192
		if ( placeholder ) {
18193
			placeholder.css( $.effects.clipToBox( animation2 ) );
18194
		}
18195
 
18196
		animation2.clip = start;
18197
	}
18198
 
18199
	// Animate
18200
	element
18201
		.queue( function( next ) {
18202
			if ( placeholder ) {
18203
				placeholder
18204
					.animate( $.effects.clipToBox( animation1 ), duration, options.easing )
18205
					.animate( $.effects.clipToBox( animation2 ), duration, options.easing );
18206
			}
18207
 
18208
			next();
18209
		} )
18210
		.animate( animation1, duration, options.easing )
18211
		.animate( animation2, duration, options.easing )
18212
		.queue( done );
18213
 
18214
	$.effects.unshift( element, queuelen, 4 );
18215
} );
18216
 
18217
 
18218
/*!
18219
 * jQuery UI Effects Highlight 1.12.1
18220
 * http://jqueryui.com
18221
 *
18222
 * Copyright jQuery Foundation and other contributors
18223
 * Released under the MIT license.
18224
 * http://jquery.org/license
18225
 */
18226
 
18227
//>>label: Highlight Effect
18228
//>>group: Effects
18229
//>>description: Highlights the background of an element in a defined color for a custom duration.
18230
//>>docs: http://api.jqueryui.com/highlight-effect/
18231
//>>demos: http://jqueryui.com/effect/
18232
 
18233
 
18234
 
18235
var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) {
18236
	var element = $( this ),
18237
		animation = {
18238
			backgroundColor: element.css( "backgroundColor" )
18239
		};
18240
 
18241
	if ( options.mode === "hide" ) {
18242
		animation.opacity = 0;
18243
	}
18244
 
18245
	$.effects.saveStyle( element );
18246
 
18247
	element
18248
		.css( {
18249
			backgroundImage: "none",
18250
			backgroundColor: options.color || "#ffff99"
18251
		} )
18252
		.animate( animation, {
18253
			queue: false,
18254
			duration: options.duration,
18255
			easing: options.easing,
18256
			complete: done
18257
		} );
18258
} );
18259
 
18260
 
18261
/*!
18262
 * jQuery UI Effects Size 1.12.1
18263
 * http://jqueryui.com
18264
 *
18265
 * Copyright jQuery Foundation and other contributors
18266
 * Released under the MIT license.
18267
 * http://jquery.org/license
18268
 */
18269
 
18270
//>>label: Size Effect
18271
//>>group: Effects
18272
//>>description: Resize an element to a specified width and height.
18273
//>>docs: http://api.jqueryui.com/size-effect/
18274
//>>demos: http://jqueryui.com/effect/
18275
 
18276
 
18277
 
18278
var effectsEffectSize = $.effects.define( "size", function( options, done ) {
18279
 
18280
	// Create element
18281
	var baseline, factor, temp,
18282
		element = $( this ),
18283
 
18284
		// Copy for children
18285
		cProps = [ "fontSize" ],
18286
		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
18287
		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
18288
 
18289
		// Set options
18290
		mode = options.mode,
18291
		restore = mode !== "effect",
18292
		scale = options.scale || "both",
18293
		origin = options.origin || [ "middle", "center" ],
18294
		position = element.css( "position" ),
18295
		pos = element.position(),
18296
		original = $.effects.scaledDimensions( element ),
18297
		from = options.from || original,
18298
		to = options.to || $.effects.scaledDimensions( element, 0 );
18299
 
18300
	$.effects.createPlaceholder( element );
18301
 
18302
	if ( mode === "show" ) {
18303
		temp = from;
18304
		from = to;
18305
		to = temp;
18306
	}
18307
 
18308
	// Set scaling factor
18309
	factor = {
18310
		from: {
18311
			y: from.height / original.height,
18312
			x: from.width / original.width
18313
		},
18314
		to: {
18315
			y: to.height / original.height,
18316
			x: to.width / original.width
18317
		}
18318
	};
18319
 
18320
	// Scale the css box
18321
	if ( scale === "box" || scale === "both" ) {
18322
 
18323
		// Vertical props scaling
18324
		if ( factor.from.y !== factor.to.y ) {
18325
			from = $.effects.setTransition( element, vProps, factor.from.y, from );
18326
			to = $.effects.setTransition( element, vProps, factor.to.y, to );
18327
		}
18328
 
18329
		// Horizontal props scaling
18330
		if ( factor.from.x !== factor.to.x ) {
18331
			from = $.effects.setTransition( element, hProps, factor.from.x, from );
18332
			to = $.effects.setTransition( element, hProps, factor.to.x, to );
18333
		}
18334
	}
18335
 
18336
	// Scale the content
18337
	if ( scale === "content" || scale === "both" ) {
18338
 
18339
		// Vertical props scaling
18340
		if ( factor.from.y !== factor.to.y ) {
18341
			from = $.effects.setTransition( element, cProps, factor.from.y, from );
18342
			to = $.effects.setTransition( element, cProps, factor.to.y, to );
18343
		}
18344
	}
18345
 
18346
	// Adjust the position properties based on the provided origin points
18347
	if ( origin ) {
18348
		baseline = $.effects.getBaseline( origin, original );
18349
		from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top;
18350
		from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left;
18351
		to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top;
18352
		to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left;
18353
	}
18354
	element.css( from );
18355
 
18356
	// Animate the children if desired
18357
	if ( scale === "content" || scale === "both" ) {
18358
 
18359
		vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps );
18360
		hProps = hProps.concat( [ "marginLeft", "marginRight" ] );
18361
 
18362
		// Only animate children with width attributes specified
18363
		// TODO: is this right? should we include anything with css width specified as well
18364
		element.find( "*[width]" ).each( function() {
18365
			var child = $( this ),
18366
				childOriginal = $.effects.scaledDimensions( child ),
18367
				childFrom = {
18368
					height: childOriginal.height * factor.from.y,
18369
					width: childOriginal.width * factor.from.x,
18370
					outerHeight: childOriginal.outerHeight * factor.from.y,
18371
					outerWidth: childOriginal.outerWidth * factor.from.x
18372
				},
18373
				childTo = {
18374
					height: childOriginal.height * factor.to.y,
18375
					width: childOriginal.width * factor.to.x,
18376
					outerHeight: childOriginal.height * factor.to.y,
18377
					outerWidth: childOriginal.width * factor.to.x
18378
				};
18379
 
18380
			// Vertical props scaling
18381
			if ( factor.from.y !== factor.to.y ) {
18382
				childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom );
18383
				childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo );
18384
			}
18385
 
18386
			// Horizontal props scaling
18387
			if ( factor.from.x !== factor.to.x ) {
18388
				childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom );
18389
				childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo );
18390
			}
18391
 
18392
			if ( restore ) {
18393
				$.effects.saveStyle( child );
18394
			}
18395
 
18396
			// Animate children
18397
			child.css( childFrom );
18398
			child.animate( childTo, options.duration, options.easing, function() {
18399
 
18400
				// Restore children
18401
				if ( restore ) {
18402
					$.effects.restoreStyle( child );
18403
				}
18404
			} );
18405
		} );
18406
	}
18407
 
18408
	// Animate
18409
	element.animate( to, {
18410
		queue: false,
18411
		duration: options.duration,
18412
		easing: options.easing,
18413
		complete: function() {
18414
 
18415
			var offset = element.offset();
18416
 
18417
			if ( to.opacity === 0 ) {
18418
				element.css( "opacity", from.opacity );
18419
			}
18420
 
18421
			if ( !restore ) {
18422
				element
18423
					.css( "position", position === "static" ? "relative" : position )
18424
					.offset( offset );
18425
 
18426
				// Need to save style here so that automatic style restoration
18427
				// doesn't restore to the original styles from before the animation.
18428
				$.effects.saveStyle( element );
18429
			}
18430
 
18431
			done();
18432
		}
18433
	} );
18434
 
18435
} );
18436
 
18437
 
18438
/*!
18439
 * jQuery UI Effects Scale 1.12.1
18440
 * http://jqueryui.com
18441
 *
18442
 * Copyright jQuery Foundation and other contributors
18443
 * Released under the MIT license.
18444
 * http://jquery.org/license
18445
 */
18446
 
18447
//>>label: Scale Effect
18448
//>>group: Effects
18449
//>>description: Grows or shrinks an element and its content.
18450
//>>docs: http://api.jqueryui.com/scale-effect/
18451
//>>demos: http://jqueryui.com/effect/
18452
 
18453
 
18454
 
18455
var effectsEffectScale = $.effects.define( "scale", function( options, done ) {
18456
 
18457
	// Create element
18458
	var el = $( this ),
18459
		mode = options.mode,
18460
		percent = parseInt( options.percent, 10 ) ||
18461
			( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ),
18462
 
18463
		newOptions = $.extend( true, {
18464
			from: $.effects.scaledDimensions( el ),
18465
			to: $.effects.scaledDimensions( el, percent, options.direction || "both" ),
18466
			origin: options.origin || [ "middle", "center" ]
18467
		}, options );
18468
 
18469
	// Fade option to support puff
18470
	if ( options.fade ) {
18471
		newOptions.from.opacity = 1;
18472
		newOptions.to.opacity = 0;
18473
	}
18474
 
18475
	$.effects.effect.size.call( this, newOptions, done );
18476
} );
18477
 
18478
 
18479
/*!
18480
 * jQuery UI Effects Puff 1.12.1
18481
 * http://jqueryui.com
18482
 *
18483
 * Copyright jQuery Foundation and other contributors
18484
 * Released under the MIT license.
18485
 * http://jquery.org/license
18486
 */
18487
 
18488
//>>label: Puff Effect
18489
//>>group: Effects
18490
//>>description: Creates a puff effect by scaling the element up and hiding it at the same time.
18491
//>>docs: http://api.jqueryui.com/puff-effect/
18492
//>>demos: http://jqueryui.com/effect/
18493
 
18494
 
18495
 
18496
var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) {
18497
	var newOptions = $.extend( true, {}, options, {
18498
		fade: true,
18499
		percent: parseInt( options.percent, 10 ) || 150
18500
	} );
18501
 
18502
	$.effects.effect.scale.call( this, newOptions, done );
18503
} );
18504
 
18505
 
18506
/*!
18507
 * jQuery UI Effects Pulsate 1.12.1
18508
 * http://jqueryui.com
18509
 *
18510
 * Copyright jQuery Foundation and other contributors
18511
 * Released under the MIT license.
18512
 * http://jquery.org/license
18513
 */
18514
 
18515
//>>label: Pulsate Effect
18516
//>>group: Effects
18517
//>>description: Pulsates an element n times by changing the opacity to zero and back.
18518
//>>docs: http://api.jqueryui.com/pulsate-effect/
18519
//>>demos: http://jqueryui.com/effect/
18520
 
18521
 
18522
 
18523
var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) {
18524
	var element = $( this ),
18525
		mode = options.mode,
18526
		show = mode === "show",
18527
		hide = mode === "hide",
18528
		showhide = show || hide,
18529
 
18530
		// Showing or hiding leaves off the "last" animation
18531
		anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
18532
		duration = options.duration / anims,
18533
		animateTo = 0,
18534
		i = 1,
18535
		queuelen = element.queue().length;
18536
 
18537
	if ( show || !element.is( ":visible" ) ) {
18538
		element.css( "opacity", 0 ).show();
18539
		animateTo = 1;
18540
	}
18541
 
18542
	// Anims - 1 opacity "toggles"
18543
	for ( ; i < anims; i++ ) {
18544
		element.animate( { opacity: animateTo }, duration, options.easing );
18545
		animateTo = 1 - animateTo;
18546
	}
18547
 
18548
	element.animate( { opacity: animateTo }, duration, options.easing );
18549
 
18550
	element.queue( done );
18551
 
18552
	$.effects.unshift( element, queuelen, anims + 1 );
18553
} );
18554
 
18555
 
18556
/*!
18557
 * jQuery UI Effects Shake 1.12.1
18558
 * http://jqueryui.com
18559
 *
18560
 * Copyright jQuery Foundation and other contributors
18561
 * Released under the MIT license.
18562
 * http://jquery.org/license
18563
 */
18564
 
18565
//>>label: Shake Effect
18566
//>>group: Effects
18567
//>>description: Shakes an element horizontally or vertically n times.
18568
//>>docs: http://api.jqueryui.com/shake-effect/
18569
//>>demos: http://jqueryui.com/effect/
18570
 
18571
 
18572
 
18573
var effectsEffectShake = $.effects.define( "shake", function( options, done ) {
18574
 
18575
	var i = 1,
18576
		element = $( this ),
18577
		direction = options.direction || "left",
18578
		distance = options.distance || 20,
18579
		times = options.times || 3,
18580
		anims = times * 2 + 1,
18581
		speed = Math.round( options.duration / anims ),
18582
		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
18583
		positiveMotion = ( direction === "up" || direction === "left" ),
18584
		animation = {},
18585
		animation1 = {},
18586
		animation2 = {},
18587
 
18588
		queuelen = element.queue().length;
18589
 
18590
	$.effects.createPlaceholder( element );
18591
 
18592
	// Animation
18593
	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
18594
	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
18595
	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
18596
 
18597
	// Animate
18598
	element.animate( animation, speed, options.easing );
18599
 
18600
	// Shakes
18601
	for ( ; i < times; i++ ) {
18602
		element
18603
			.animate( animation1, speed, options.easing )
18604
			.animate( animation2, speed, options.easing );
18605
	}
18606
 
18607
	element
18608
		.animate( animation1, speed, options.easing )
18609
		.animate( animation, speed / 2, options.easing )
18610
		.queue( done );
18611
 
18612
	$.effects.unshift( element, queuelen, anims + 1 );
18613
} );
18614
 
18615
 
18616
/*!
18617
 * jQuery UI Effects Slide 1.12.1
18618
 * http://jqueryui.com
18619
 *
18620
 * Copyright jQuery Foundation and other contributors
18621
 * Released under the MIT license.
18622
 * http://jquery.org/license
18623
 */
18624
 
18625
//>>label: Slide Effect
18626
//>>group: Effects
18627
//>>description: Slides an element in and out of the viewport.
18628
//>>docs: http://api.jqueryui.com/slide-effect/
18629
//>>demos: http://jqueryui.com/effect/
18630
 
18631
 
18632
 
18633
var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) {
18634
	var startClip, startRef,
18635
		element = $( this ),
18636
		map = {
18637
			up: [ "bottom", "top" ],
18638
			down: [ "top", "bottom" ],
18639
			left: [ "right", "left" ],
18640
			right: [ "left", "right" ]
18641
		},
18642
		mode = options.mode,
18643
		direction = options.direction || "left",
18644
		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
18645
		positiveMotion = ( direction === "up" || direction === "left" ),
18646
		distance = options.distance ||
18647
			element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ),
18648
		animation = {};
18649
 
18650
	$.effects.createPlaceholder( element );
18651
 
18652
	startClip = element.cssClip();
18653
	startRef = element.position()[ ref ];
18654
 
18655
	// Define hide animation
18656
	animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef;
18657
	animation.clip = element.cssClip();
18658
	animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ];
18659
 
18660
	// Reverse the animation if we're showing
18661
	if ( mode === "show" ) {
18662
		element.cssClip( animation.clip );
18663
		element.css( ref, animation[ ref ] );
18664
		animation.clip = startClip;
18665
		animation[ ref ] = startRef;
18666
	}
18667
 
18668
	// Actually animate
18669
	element.animate( animation, {
18670
		queue: false,
18671
		duration: options.duration,
18672
		easing: options.easing,
18673
		complete: done
18674
	} );
18675
} );
18676
 
18677
 
18678
/*!
18679
 * jQuery UI Effects Transfer 1.12.1
18680
 * http://jqueryui.com
18681
 *
18682
 * Copyright jQuery Foundation and other contributors
18683
 * Released under the MIT license.
18684
 * http://jquery.org/license
18685
 */
18686
 
18687
//>>label: Transfer Effect
18688
//>>group: Effects
18689
//>>description: Displays a transfer effect from one element to another.
18690
//>>docs: http://api.jqueryui.com/transfer-effect/
18691
//>>demos: http://jqueryui.com/effect/
18692
 
18693
 
18694
 
18695
var effect;
18696
if ( $.uiBackCompat !== false ) {
18697
	effect = $.effects.define( "transfer", function( options, done ) {
18698
		$( this ).transfer( options, done );
18699
	} );
18700
}
18701
var effectsEffectTransfer = effect;
18702
 
18703
 
18704
 
18705
 
18706
}));