Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
27763 tejbeer 1
/*! jQuery UI - v1.12.1 - 2016-09-14
2
* http://jqueryui.com
3
* Includes: widget.js, position.js, data.js, disable-selection.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js, focusable.js, form-reset-mixin.js, jquery-1-7.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/draggable.js, widgets/droppable.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/resizable.js, widgets/selectable.js, widgets/selectmenu.js, widgets/slider.js, widgets/sortable.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js
4
* Copyright jQuery Foundation and other contributors; Licensed MIT */
5
 
6
(function( factory ) {
7
	if ( typeof define === "function" && define.amd ) {
8
 
9
		// AMD. Register as an anonymous module.
10
		define([ "jquery" ], factory );
11
	} else {
12
 
13
		// Browser globals
14
		factory( jQuery );
15
	}
16
}(function( $ ) {
17
 
18
$.ui = $.ui || {};
19
 
20
var version = $.ui.version = "1.12.1";
21
 
22
 
23
/*!
24
 * jQuery UI Widget 1.12.1
25
 * http://jqueryui.com
26
 *
27
 * Copyright jQuery Foundation and other contributors
28
 * Released under the MIT license.
29
 * http://jquery.org/license
30
 */
31
 
32
//>>label: Widget
33
//>>group: Core
34
//>>description: Provides a factory for creating stateful widgets with a common API.
35
//>>docs: http://api.jqueryui.com/jQuery.widget/
36
//>>demos: http://jqueryui.com/widget/
37
 
38
 
39
 
40
var widgetUuid = 0;
41
var widgetSlice = Array.prototype.slice;
42
 
43
$.cleanData = ( function( orig ) {
44
	return function( elems ) {
45
		var events, elem, i;
46
		for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
47
			try {
48
 
49
				// Only trigger remove when necessary to save time
50
				events = $._data( elem, "events" );
51
				if ( events && events.remove ) {
52
					$( elem ).triggerHandler( "remove" );
53
				}
54
 
55
			// Http://bugs.jquery.com/ticket/8235
56
			} catch ( e ) {}
57
		}
58
		orig( elems );
59
	};
60
} )( $.cleanData );
61
 
62
$.widget = function( name, base, prototype ) {
63
	var existingConstructor, constructor, basePrototype;
64
 
65
	// ProxiedPrototype allows the provided prototype to remain unmodified
66
	// so that it can be used as a mixin for multiple widgets (#8876)
67
	var proxiedPrototype = {};
68
 
69
	var namespace = name.split( "." )[ 0 ];
70
	name = name.split( "." )[ 1 ];
71
	var fullName = namespace + "-" + name;
72
 
73
	if ( !prototype ) {
74
		prototype = base;
75
		base = $.Widget;
76
	}
77
 
78
	if ( $.isArray( prototype ) ) {
79
		prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
80
	}
81
 
82
	// Create selector for plugin
83
	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
84
		return !!$.data( elem, fullName );
85
	};
86
 
87
	$[ namespace ] = $[ namespace ] || {};
88
	existingConstructor = $[ namespace ][ name ];
89
	constructor = $[ namespace ][ name ] = function( options, element ) {
90
 
91
		// Allow instantiation without "new" keyword
92
		if ( !this._createWidget ) {
93
			return new constructor( options, element );
94
		}
95
 
96
		// Allow instantiation without initializing for simple inheritance
97
		// must use "new" keyword (the code above always passes args)
98
		if ( arguments.length ) {
99
			this._createWidget( options, element );
100
		}
101
	};
102
 
103
	// Extend with the existing constructor to carry over any static properties
104
	$.extend( constructor, existingConstructor, {
105
		version: prototype.version,
106
 
107
		// Copy the object used to create the prototype in case we need to
108
		// redefine the widget later
109
		_proto: $.extend( {}, prototype ),
110
 
111
		// Track widgets that inherit from this widget in case this widget is
112
		// redefined after a widget inherits from it
113
		_childConstructors: []
114
	} );
115
 
116
	basePrototype = new base();
117
 
118
	// We need to make the options hash a property directly on the new instance
119
	// otherwise we'll modify the options hash on the prototype that we're
120
	// inheriting from
121
	basePrototype.options = $.widget.extend( {}, basePrototype.options );
122
	$.each( prototype, function( prop, value ) {
123
		if ( !$.isFunction( value ) ) {
124
			proxiedPrototype[ prop ] = value;
125
			return;
126
		}
127
		proxiedPrototype[ prop ] = ( function() {
128
			function _super() {
129
				return base.prototype[ prop ].apply( this, arguments );
130
			}
131
 
132
			function _superApply( args ) {
133
				return base.prototype[ prop ].apply( this, args );
134
			}
135
 
136
			return function() {
137
				var __super = this._super;
138
				var __superApply = this._superApply;
139
				var returnValue;
140
 
141
				this._super = _super;
142
				this._superApply = _superApply;
143
 
144
				returnValue = value.apply( this, arguments );
145
 
146
				this._super = __super;
147
				this._superApply = __superApply;
148
 
149
				return returnValue;
150
			};
151
		} )();
152
	} );
153
	constructor.prototype = $.widget.extend( basePrototype, {
154
 
155
		// TODO: remove support for widgetEventPrefix
156
		// always use the name + a colon as the prefix, e.g., draggable:start
157
		// don't prefix for widgets that aren't DOM-based
158
		widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
159
	}, proxiedPrototype, {
160
		constructor: constructor,
161
		namespace: namespace,
162
		widgetName: name,
163
		widgetFullName: fullName
164
	} );
165
 
166
	// If this widget is being redefined then we need to find all widgets that
167
	// are inheriting from it and redefine all of them so that they inherit from
168
	// the new version of this widget. We're essentially trying to replace one
169
	// level in the prototype chain.
170
	if ( existingConstructor ) {
171
		$.each( existingConstructor._childConstructors, function( i, child ) {
172
			var childPrototype = child.prototype;
173
 
174
			// Redefine the child widget using the same prototype that was
175
			// originally used, but inherit from the new version of the base
176
			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
177
				child._proto );
178
		} );
179
 
180
		// Remove the list of existing child constructors from the old constructor
181
		// so the old child constructors can be garbage collected
182
		delete existingConstructor._childConstructors;
183
	} else {
184
		base._childConstructors.push( constructor );
185
	}
186
 
187
	$.widget.bridge( name, constructor );
188
 
189
	return constructor;
190
};
191
 
192
$.widget.extend = function( target ) {
193
	var input = widgetSlice.call( arguments, 1 );
194
	var inputIndex = 0;
195
	var inputLength = input.length;
196
	var key;
197
	var value;
198
 
199
	for ( ; inputIndex < inputLength; inputIndex++ ) {
200
		for ( key in input[ inputIndex ] ) {
201
			value = input[ inputIndex ][ key ];
202
			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
203
 
204
				// Clone objects
205
				if ( $.isPlainObject( value ) ) {
206
					target[ key ] = $.isPlainObject( target[ key ] ) ?
207
						$.widget.extend( {}, target[ key ], value ) :
208
 
209
						// Don't extend strings, arrays, etc. with objects
210
						$.widget.extend( {}, value );
211
 
212
				// Copy everything else by reference
213
				} else {
214
					target[ key ] = value;
215
				}
216
			}
217
		}
218
	}
219
	return target;
220
};
221
 
222
$.widget.bridge = function( name, object ) {
223
	var fullName = object.prototype.widgetFullName || name;
224
	$.fn[ name ] = function( options ) {
225
		var isMethodCall = typeof options === "string";
226
		var args = widgetSlice.call( arguments, 1 );
227
		var returnValue = this;
228
 
229
		if ( isMethodCall ) {
230
 
231
			// If this is an empty collection, we need to have the instance method
232
			// return undefined instead of the jQuery instance
233
			if ( !this.length && options === "instance" ) {
234
				returnValue = undefined;
235
			} else {
236
				this.each( function() {
237
					var methodValue;
238
					var instance = $.data( this, fullName );
239
 
240
					if ( options === "instance" ) {
241
						returnValue = instance;
242
						return false;
243
					}
244
 
245
					if ( !instance ) {
246
						return $.error( "cannot call methods on " + name +
247
							" prior to initialization; " +
248
							"attempted to call method '" + options + "'" );
249
					}
250
 
251
					if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
252
						return $.error( "no such method '" + options + "' for " + name +
253
							" widget instance" );
254
					}
255
 
256
					methodValue = instance[ options ].apply( instance, args );
257
 
258
					if ( methodValue !== instance && methodValue !== undefined ) {
259
						returnValue = methodValue && methodValue.jquery ?
260
							returnValue.pushStack( methodValue.get() ) :
261
							methodValue;
262
						return false;
263
					}
264
				} );
265
			}
266
		} else {
267
 
268
			// Allow multiple hashes to be passed on init
269
			if ( args.length ) {
270
				options = $.widget.extend.apply( null, [ options ].concat( args ) );
271
			}
272
 
273
			this.each( function() {
274
				var instance = $.data( this, fullName );
275
				if ( instance ) {
276
					instance.option( options || {} );
277
					if ( instance._init ) {
278
						instance._init();
279
					}
280
				} else {
281
					$.data( this, fullName, new object( options, this ) );
282
				}
283
			} );
284
		}
285
 
286
		return returnValue;
287
	};
288
};
289
 
290
$.Widget = function( /* options, element */ ) {};
291
$.Widget._childConstructors = [];
292
 
293
$.Widget.prototype = {
294
	widgetName: "widget",
295
	widgetEventPrefix: "",
296
	defaultElement: "<div>",
297
 
298
	options: {
299
		classes: {},
300
		disabled: false,
301
 
302
		// Callbacks
303
		create: null
304
	},
305
 
306
	_createWidget: function( options, element ) {
307
		element = $( element || this.defaultElement || this )[ 0 ];
308
		this.element = $( element );
309
		this.uuid = widgetUuid++;
310
		this.eventNamespace = "." + this.widgetName + this.uuid;
311
 
312
		this.bindings = $();
313
		this.hoverable = $();
314
		this.focusable = $();
315
		this.classesElementLookup = {};
316
 
317
		if ( element !== this ) {
318
			$.data( element, this.widgetFullName, this );
319
			this._on( true, this.element, {
320
				remove: function( event ) {
321
					if ( event.target === element ) {
322
						this.destroy();
323
					}
324
				}
325
			} );
326
			this.document = $( element.style ?
327
 
328
				// Element within the document
329
				element.ownerDocument :
330
 
331
				// Element is window or document
332
				element.document || element );
333
			this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
334
		}
335
 
336
		this.options = $.widget.extend( {},
337
			this.options,
338
			this._getCreateOptions(),
339
			options );
340
 
341
		this._create();
342
 
343
		if ( this.options.disabled ) {
344
			this._setOptionDisabled( this.options.disabled );
345
		}
346
 
347
		this._trigger( "create", null, this._getCreateEventData() );
348
		this._init();
349
	},
350
 
351
	_getCreateOptions: function() {
352
		return {};
353
	},
354
 
355
	_getCreateEventData: $.noop,
356
 
357
	_create: $.noop,
358
 
359
	_init: $.noop,
360
 
361
	destroy: function() {
362
		var that = this;
363
 
364
		this._destroy();
365
		$.each( this.classesElementLookup, function( key, value ) {
366
			that._removeClass( value, key );
367
		} );
368
 
369
		// We can probably remove the unbind calls in 2.0
370
		// all event bindings should go through this._on()
371
		this.element
372
			.off( this.eventNamespace )
373
			.removeData( this.widgetFullName );
374
		this.widget()
375
			.off( this.eventNamespace )
376
			.removeAttr( "aria-disabled" );
377
 
378
		// Clean up events and states
379
		this.bindings.off( this.eventNamespace );
380
	},
381
 
382
	_destroy: $.noop,
383
 
384
	widget: function() {
385
		return this.element;
386
	},
387
 
388
	option: function( key, value ) {
389
		var options = key;
390
		var parts;
391
		var curOption;
392
		var i;
393
 
394
		if ( arguments.length === 0 ) {
395
 
396
			// Don't return a reference to the internal hash
397
			return $.widget.extend( {}, this.options );
398
		}
399
 
400
		if ( typeof key === "string" ) {
401
 
402
			// Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
403
			options = {};
404
			parts = key.split( "." );
405
			key = parts.shift();
406
			if ( parts.length ) {
407
				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
408
				for ( i = 0; i < parts.length - 1; i++ ) {
409
					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
410
					curOption = curOption[ parts[ i ] ];
411
				}
412
				key = parts.pop();
413
				if ( arguments.length === 1 ) {
414
					return curOption[ key ] === undefined ? null : curOption[ key ];
415
				}
416
				curOption[ key ] = value;
417
			} else {
418
				if ( arguments.length === 1 ) {
419
					return this.options[ key ] === undefined ? null : this.options[ key ];
420
				}
421
				options[ key ] = value;
422
			}
423
		}
424
 
425
		this._setOptions( options );
426
 
427
		return this;
428
	},
429
 
430
	_setOptions: function( options ) {
431
		var key;
432
 
433
		for ( key in options ) {
434
			this._setOption( key, options[ key ] );
435
		}
436
 
437
		return this;
438
	},
439
 
440
	_setOption: function( key, value ) {
441
		if ( key === "classes" ) {
442
			this._setOptionClasses( value );
443
		}
444
 
445
		this.options[ key ] = value;
446
 
447
		if ( key === "disabled" ) {
448
			this._setOptionDisabled( value );
449
		}
450
 
451
		return this;
452
	},
453
 
454
	_setOptionClasses: function( value ) {
455
		var classKey, elements, currentElements;
456
 
457
		for ( classKey in value ) {
458
			currentElements = this.classesElementLookup[ classKey ];
459
			if ( value[ classKey ] === this.options.classes[ classKey ] ||
460
					!currentElements ||
461
					!currentElements.length ) {
462
				continue;
463
			}
464
 
465
			// We are doing this to create a new jQuery object because the _removeClass() call
466
			// on the next line is going to destroy the reference to the current elements being
467
			// tracked. We need to save a copy of this collection so that we can add the new classes
468
			// below.
469
			elements = $( currentElements.get() );
470
			this._removeClass( currentElements, classKey );
471
 
472
			// We don't use _addClass() here, because that uses this.options.classes
473
			// for generating the string of classes. We want to use the value passed in from
474
			// _setOption(), this is the new value of the classes option which was passed to
475
			// _setOption(). We pass this value directly to _classes().
476
			elements.addClass( this._classes( {
477
				element: elements,
478
				keys: classKey,
479
				classes: value,
480
				add: true
481
			} ) );
482
		}
483
	},
484
 
485
	_setOptionDisabled: function( value ) {
486
		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
487
 
488
		// If the widget is becoming disabled, then nothing is interactive
489
		if ( value ) {
490
			this._removeClass( this.hoverable, null, "ui-state-hover" );
491
			this._removeClass( this.focusable, null, "ui-state-focus" );
492
		}
493
	},
494
 
495
	enable: function() {
496
		return this._setOptions( { disabled: false } );
497
	},
498
 
499
	disable: function() {
500
		return this._setOptions( { disabled: true } );
501
	},
502
 
503
	_classes: function( options ) {
504
		var full = [];
505
		var that = this;
506
 
507
		options = $.extend( {
508
			element: this.element,
509
			classes: this.options.classes || {}
510
		}, options );
511
 
512
		function processClassString( classes, checkOption ) {
513
			var current, i;
514
			for ( i = 0; i < classes.length; i++ ) {
515
				current = that.classesElementLookup[ classes[ i ] ] || $();
516
				if ( options.add ) {
517
					current = $( $.unique( current.get().concat( options.element.get() ) ) );
518
				} else {
519
					current = $( current.not( options.element ).get() );
520
				}
521
				that.classesElementLookup[ classes[ i ] ] = current;
522
				full.push( classes[ i ] );
523
				if ( checkOption && options.classes[ classes[ i ] ] ) {
524
					full.push( options.classes[ classes[ i ] ] );
525
				}
526
			}
527
		}
528
 
529
		this._on( options.element, {
530
			"remove": "_untrackClassesElement"
531
		} );
532
 
533
		if ( options.keys ) {
534
			processClassString( options.keys.match( /\S+/g ) || [], true );
535
		}
536
		if ( options.extra ) {
537
			processClassString( options.extra.match( /\S+/g ) || [] );
538
		}
539
 
540
		return full.join( " " );
541
	},
542
 
543
	_untrackClassesElement: function( event ) {
544
		var that = this;
545
		$.each( that.classesElementLookup, function( key, value ) {
546
			if ( $.inArray( event.target, value ) !== -1 ) {
547
				that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
548
			}
549
		} );
550
	},
551
 
552
	_removeClass: function( element, keys, extra ) {
553
		return this._toggleClass( element, keys, extra, false );
554
	},
555
 
556
	_addClass: function( element, keys, extra ) {
557
		return this._toggleClass( element, keys, extra, true );
558
	},
559
 
560
	_toggleClass: function( element, keys, extra, add ) {
561
		add = ( typeof add === "boolean" ) ? add : extra;
562
		var shift = ( typeof element === "string" || element === null ),
563
			options = {
564
				extra: shift ? keys : extra,
565
				keys: shift ? element : keys,
566
				element: shift ? this.element : element,
567
				add: add
568
			};
569
		options.element.toggleClass( this._classes( options ), add );
570
		return this;
571
	},
572
 
573
	_on: function( suppressDisabledCheck, element, handlers ) {
574
		var delegateElement;
575
		var instance = this;
576
 
577
		// No suppressDisabledCheck flag, shuffle arguments
578
		if ( typeof suppressDisabledCheck !== "boolean" ) {
579
			handlers = element;
580
			element = suppressDisabledCheck;
581
			suppressDisabledCheck = false;
582
		}
583
 
584
		// No element argument, shuffle and use this.element
585
		if ( !handlers ) {
586
			handlers = element;
587
			element = this.element;
588
			delegateElement = this.widget();
589
		} else {
590
			element = delegateElement = $( element );
591
			this.bindings = this.bindings.add( element );
592
		}
593
 
594
		$.each( handlers, function( event, handler ) {
595
			function handlerProxy() {
596
 
597
				// Allow widgets to customize the disabled handling
598
				// - disabled as an array instead of boolean
599
				// - disabled class as method for disabling individual parts
600
				if ( !suppressDisabledCheck &&
601
						( instance.options.disabled === true ||
602
						$( this ).hasClass( "ui-state-disabled" ) ) ) {
603
					return;
604
				}
605
				return ( typeof handler === "string" ? instance[ handler ] : handler )
606
					.apply( instance, arguments );
607
			}
608
 
609
			// Copy the guid so direct unbinding works
610
			if ( typeof handler !== "string" ) {
611
				handlerProxy.guid = handler.guid =
612
					handler.guid || handlerProxy.guid || $.guid++;
613
			}
614
 
615
			var match = event.match( /^([\w:-]*)\s*(.*)$/ );
616
			var eventName = match[ 1 ] + instance.eventNamespace;
617
			var selector = match[ 2 ];
618
 
619
			if ( selector ) {
620
				delegateElement.on( eventName, selector, handlerProxy );
621
			} else {
622
				element.on( eventName, handlerProxy );
623
			}
624
		} );
625
	},
626
 
627
	_off: function( element, eventName ) {
628
		eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
629
			this.eventNamespace;
630
		element.off( eventName ).off( eventName );
631
 
632
		// Clear the stack to avoid memory leaks (#10056)
633
		this.bindings = $( this.bindings.not( element ).get() );
634
		this.focusable = $( this.focusable.not( element ).get() );
635
		this.hoverable = $( this.hoverable.not( element ).get() );
636
	},
637
 
638
	_delay: function( handler, delay ) {
639
		function handlerProxy() {
640
			return ( typeof handler === "string" ? instance[ handler ] : handler )
641
				.apply( instance, arguments );
642
		}
643
		var instance = this;
644
		return setTimeout( handlerProxy, delay || 0 );
645
	},
646
 
647
	_hoverable: function( element ) {
648
		this.hoverable = this.hoverable.add( element );
649
		this._on( element, {
650
			mouseenter: function( event ) {
651
				this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
652
			},
653
			mouseleave: function( event ) {
654
				this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
655
			}
656
		} );
657
	},
658
 
659
	_focusable: function( element ) {
660
		this.focusable = this.focusable.add( element );
661
		this._on( element, {
662
			focusin: function( event ) {
663
				this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
664
			},
665
			focusout: function( event ) {
666
				this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
667
			}
668
		} );
669
	},
670
 
671
	_trigger: function( type, event, data ) {
672
		var prop, orig;
673
		var callback = this.options[ type ];
674
 
675
		data = data || {};
676
		event = $.Event( event );
677
		event.type = ( type === this.widgetEventPrefix ?
678
			type :
679
			this.widgetEventPrefix + type ).toLowerCase();
680
 
681
		// The original event may come from any element
682
		// so we need to reset the target on the new event
683
		event.target = this.element[ 0 ];
684
 
685
		// Copy original event properties over to the new event
686
		orig = event.originalEvent;
687
		if ( orig ) {
688
			for ( prop in orig ) {
689
				if ( !( prop in event ) ) {
690
					event[ prop ] = orig[ prop ];
691
				}
692
			}
693
		}
694
 
695
		this.element.trigger( event, data );
696
		return !( $.isFunction( callback ) &&
697
			callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
698
			event.isDefaultPrevented() );
699
	}
700
};
701
 
702
$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
703
	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
704
		if ( typeof options === "string" ) {
705
			options = { effect: options };
706
		}
707
 
708
		var hasOptions;
709
		var effectName = !options ?
710
			method :
711
			options === true || typeof options === "number" ?
712
				defaultEffect :
713
				options.effect || defaultEffect;
714
 
715
		options = options || {};
716
		if ( typeof options === "number" ) {
717
			options = { duration: options };
718
		}
719
 
720
		hasOptions = !$.isEmptyObject( options );
721
		options.complete = callback;
722
 
723
		if ( options.delay ) {
724
			element.delay( options.delay );
725
		}
726
 
727
		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
728
			element[ method ]( options );
729
		} else if ( effectName !== method && element[ effectName ] ) {
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 Effects 1.12.1
1301
 * http://jqueryui.com
1302
 *
1303
 * Copyright jQuery Foundation and other contributors
1304
 * Released under the MIT license.
1305
 * http://jquery.org/license
1306
 */
1307
 
1308
//>>label: Effects Core
1309
//>>group: Effects
1310
// jscs:disable maximumLineLength
1311
//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects.
1312
// jscs:enable maximumLineLength
1313
//>>docs: http://api.jqueryui.com/category/effects-core/
1314
//>>demos: http://jqueryui.com/effect/
1315
 
1316
 
1317
 
1318
var dataSpace = "ui-effects-",
1319
	dataSpaceStyle = "ui-effects-style",
1320
	dataSpaceAnimated = "ui-effects-animated",
1321
 
1322
	// Create a local jQuery because jQuery Color relies on it and the
1323
	// global may not exist with AMD and a custom build (#10199)
1324
	jQuery = $;
1325
 
1326
$.effects = {
1327
	effect: {}
1328
};
1329
 
1330
/*!
1331
 * jQuery Color Animations v2.1.2
1332
 * https://github.com/jquery/jquery-color
1333
 *
1334
 * Copyright 2014 jQuery Foundation and other contributors
1335
 * Released under the MIT license.
1336
 * http://jquery.org/license
1337
 *
1338
 * Date: Wed Jan 16 08:47:09 2013 -0600
1339
 */
1340
( function( jQuery, undefined ) {
1341
 
1342
	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " +
1343
		"borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
1344
 
1345
	// Plusequals test for += 100 -= 100
1346
	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
1347
 
1348
	// A set of RE's that can match strings and generate color tuples.
1349
	stringParsers = [ {
1350
			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1351
			parse: function( execResult ) {
1352
				return [
1353
					execResult[ 1 ],
1354
					execResult[ 2 ],
1355
					execResult[ 3 ],
1356
					execResult[ 4 ]
1357
				];
1358
			}
1359
		}, {
1360
			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1361
			parse: function( execResult ) {
1362
				return [
1363
					execResult[ 1 ] * 2.55,
1364
					execResult[ 2 ] * 2.55,
1365
					execResult[ 3 ] * 2.55,
1366
					execResult[ 4 ]
1367
				];
1368
			}
1369
		}, {
1370
 
1371
			// This regex ignores A-F because it's compared against an already lowercased string
1372
			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
1373
			parse: function( execResult ) {
1374
				return [
1375
					parseInt( execResult[ 1 ], 16 ),
1376
					parseInt( execResult[ 2 ], 16 ),
1377
					parseInt( execResult[ 3 ], 16 )
1378
				];
1379
			}
1380
		}, {
1381
 
1382
			// This regex ignores A-F because it's compared against an already lowercased string
1383
			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
1384
			parse: function( execResult ) {
1385
				return [
1386
					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
1387
					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
1388
					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
1389
				];
1390
			}
1391
		}, {
1392
			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1393
			space: "hsla",
1394
			parse: function( execResult ) {
1395
				return [
1396
					execResult[ 1 ],
1397
					execResult[ 2 ] / 100,
1398
					execResult[ 3 ] / 100,
1399
					execResult[ 4 ]
1400
				];
1401
			}
1402
		} ],
1403
 
1404
	// JQuery.Color( )
1405
	color = jQuery.Color = function( color, green, blue, alpha ) {
1406
		return new jQuery.Color.fn.parse( color, green, blue, alpha );
1407
	},
1408
	spaces = {
1409
		rgba: {
1410
			props: {
1411
				red: {
1412
					idx: 0,
1413
					type: "byte"
1414
				},
1415
				green: {
1416
					idx: 1,
1417
					type: "byte"
1418
				},
1419
				blue: {
1420
					idx: 2,
1421
					type: "byte"
1422
				}
1423
			}
1424
		},
1425
 
1426
		hsla: {
1427
			props: {
1428
				hue: {
1429
					idx: 0,
1430
					type: "degrees"
1431
				},
1432
				saturation: {
1433
					idx: 1,
1434
					type: "percent"
1435
				},
1436
				lightness: {
1437
					idx: 2,
1438
					type: "percent"
1439
				}
1440
			}
1441
		}
1442
	},
1443
	propTypes = {
1444
		"byte": {
1445
			floor: true,
1446
			max: 255
1447
		},
1448
		"percent": {
1449
			max: 1
1450
		},
1451
		"degrees": {
1452
			mod: 360,
1453
			floor: true
1454
		}
1455
	},
1456
	support = color.support = {},
1457
 
1458
	// Element for support tests
1459
	supportElem = jQuery( "<p>" )[ 0 ],
1460
 
1461
	// Colors = jQuery.Color.names
1462
	colors,
1463
 
1464
	// Local aliases of functions called often
1465
	each = jQuery.each;
1466
 
1467
// Determine rgba support immediately
1468
supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
1469
support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
1470
 
1471
// Define cache name and alpha properties
1472
// for rgba and hsla spaces
1473
each( spaces, function( spaceName, space ) {
1474
	space.cache = "_" + spaceName;
1475
	space.props.alpha = {
1476
		idx: 3,
1477
		type: "percent",
1478
		def: 1
1479
	};
1480
} );
1481
 
1482
function clamp( value, prop, allowEmpty ) {
1483
	var type = propTypes[ prop.type ] || {};
1484
 
1485
	if ( value == null ) {
1486
		return ( allowEmpty || !prop.def ) ? null : prop.def;
1487
	}
1488
 
1489
	// ~~ is an short way of doing floor for positive numbers
1490
	value = type.floor ? ~~value : parseFloat( value );
1491
 
1492
	// IE will pass in empty strings as value for alpha,
1493
	// which will hit this case
1494
	if ( isNaN( value ) ) {
1495
		return prop.def;
1496
	}
1497
 
1498
	if ( type.mod ) {
1499
 
1500
		// We add mod before modding to make sure that negatives values
1501
		// get converted properly: -10 -> 350
1502
		return ( value + type.mod ) % type.mod;
1503
	}
1504
 
1505
	// For now all property types without mod have min and max
1506
	return 0 > value ? 0 : type.max < value ? type.max : value;
1507
}
1508
 
1509
function stringParse( string ) {
1510
	var inst = color(),
1511
		rgba = inst._rgba = [];
1512
 
1513
	string = string.toLowerCase();
1514
 
1515
	each( stringParsers, function( i, parser ) {
1516
		var parsed,
1517
			match = parser.re.exec( string ),
1518
			values = match && parser.parse( match ),
1519
			spaceName = parser.space || "rgba";
1520
 
1521
		if ( values ) {
1522
			parsed = inst[ spaceName ]( values );
1523
 
1524
			// If this was an rgba parse the assignment might happen twice
1525
			// oh well....
1526
			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
1527
			rgba = inst._rgba = parsed._rgba;
1528
 
1529
			// Exit each( stringParsers ) here because we matched
1530
			return false;
1531
		}
1532
	} );
1533
 
1534
	// Found a stringParser that handled it
1535
	if ( rgba.length ) {
1536
 
1537
		// If this came from a parsed string, force "transparent" when alpha is 0
1538
		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
1539
		if ( rgba.join() === "0,0,0,0" ) {
1540
			jQuery.extend( rgba, colors.transparent );
1541
		}
1542
		return inst;
1543
	}
1544
 
1545
	// Named colors
1546
	return colors[ string ];
1547
}
1548
 
1549
color.fn = jQuery.extend( color.prototype, {
1550
	parse: function( red, green, blue, alpha ) {
1551
		if ( red === undefined ) {
1552
			this._rgba = [ null, null, null, null ];
1553
			return this;
1554
		}
1555
		if ( red.jquery || red.nodeType ) {
1556
			red = jQuery( red ).css( green );
1557
			green = undefined;
1558
		}
1559
 
1560
		var inst = this,
1561
			type = jQuery.type( red ),
1562
			rgba = this._rgba = [];
1563
 
1564
		// More than 1 argument specified - assume ( red, green, blue, alpha )
1565
		if ( green !== undefined ) {
1566
			red = [ red, green, blue, alpha ];
1567
			type = "array";
1568
		}
1569
 
1570
		if ( type === "string" ) {
1571
			return this.parse( stringParse( red ) || colors._default );
1572
		}
1573
 
1574
		if ( type === "array" ) {
1575
			each( spaces.rgba.props, function( key, prop ) {
1576
				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
1577
			} );
1578
			return this;
1579
		}
1580
 
1581
		if ( type === "object" ) {
1582
			if ( red instanceof color ) {
1583
				each( spaces, function( spaceName, space ) {
1584
					if ( red[ space.cache ] ) {
1585
						inst[ space.cache ] = red[ space.cache ].slice();
1586
					}
1587
				} );
1588
			} else {
1589
				each( spaces, function( spaceName, space ) {
1590
					var cache = space.cache;
1591
					each( space.props, function( key, prop ) {
1592
 
1593
						// If the cache doesn't exist, and we know how to convert
1594
						if ( !inst[ cache ] && space.to ) {
1595
 
1596
							// If the value was null, we don't need to copy it
1597
							// if the key was alpha, we don't need to copy it either
1598
							if ( key === "alpha" || red[ key ] == null ) {
1599
								return;
1600
							}
1601
							inst[ cache ] = space.to( inst._rgba );
1602
						}
1603
 
1604
						// This is the only case where we allow nulls for ALL properties.
1605
						// call clamp with alwaysAllowEmpty
1606
						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
1607
					} );
1608
 
1609
					// Everything defined but alpha?
1610
					if ( inst[ cache ] &&
1611
							jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
1612
 
1613
						// Use the default of 1
1614
						inst[ cache ][ 3 ] = 1;
1615
						if ( space.from ) {
1616
							inst._rgba = space.from( inst[ cache ] );
1617
						}
1618
					}
1619
				} );
1620
			}
1621
			return this;
1622
		}
1623
	},
1624
	is: function( compare ) {
1625
		var is = color( compare ),
1626
			same = true,
1627
			inst = this;
1628
 
1629
		each( spaces, function( _, space ) {
1630
			var localCache,
1631
				isCache = is[ space.cache ];
1632
			if ( isCache ) {
1633
				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
1634
				each( space.props, function( _, prop ) {
1635
					if ( isCache[ prop.idx ] != null ) {
1636
						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
1637
						return same;
1638
					}
1639
				} );
1640
			}
1641
			return same;
1642
		} );
1643
		return same;
1644
	},
1645
	_space: function() {
1646
		var used = [],
1647
			inst = this;
1648
		each( spaces, function( spaceName, space ) {
1649
			if ( inst[ space.cache ] ) {
1650
				used.push( spaceName );
1651
			}
1652
		} );
1653
		return used.pop();
1654
	},
1655
	transition: function( other, distance ) {
1656
		var end = color( other ),
1657
			spaceName = end._space(),
1658
			space = spaces[ spaceName ],
1659
			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
1660
			start = startColor[ space.cache ] || space.to( startColor._rgba ),
1661
			result = start.slice();
1662
 
1663
		end = end[ space.cache ];
1664
		each( space.props, function( key, prop ) {
1665
			var index = prop.idx,
1666
				startValue = start[ index ],
1667
				endValue = end[ index ],
1668
				type = propTypes[ prop.type ] || {};
1669
 
1670
			// If null, don't override start value
1671
			if ( endValue === null ) {
1672
				return;
1673
			}
1674
 
1675
			// If null - use end
1676
			if ( startValue === null ) {
1677
				result[ index ] = endValue;
1678
			} else {
1679
				if ( type.mod ) {
1680
					if ( endValue - startValue > type.mod / 2 ) {
1681
						startValue += type.mod;
1682
					} else if ( startValue - endValue > type.mod / 2 ) {
1683
						startValue -= type.mod;
1684
					}
1685
				}
1686
				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
1687
			}
1688
		} );
1689
		return this[ spaceName ]( result );
1690
	},
1691
	blend: function( opaque ) {
1692
 
1693
		// If we are already opaque - return ourself
1694
		if ( this._rgba[ 3 ] === 1 ) {
1695
			return this;
1696
		}
1697
 
1698
		var rgb = this._rgba.slice(),
1699
			a = rgb.pop(),
1700
			blend = color( opaque )._rgba;
1701
 
1702
		return color( jQuery.map( rgb, function( v, i ) {
1703
			return ( 1 - a ) * blend[ i ] + a * v;
1704
		} ) );
1705
	},
1706
	toRgbaString: function() {
1707
		var prefix = "rgba(",
1708
			rgba = jQuery.map( this._rgba, function( v, i ) {
1709
				return v == null ? ( i > 2 ? 1 : 0 ) : v;
1710
			} );
1711
 
1712
		if ( rgba[ 3 ] === 1 ) {
1713
			rgba.pop();
1714
			prefix = "rgb(";
1715
		}
1716
 
1717
		return prefix + rgba.join() + ")";
1718
	},
1719
	toHslaString: function() {
1720
		var prefix = "hsla(",
1721
			hsla = jQuery.map( this.hsla(), function( v, i ) {
1722
				if ( v == null ) {
1723
					v = i > 2 ? 1 : 0;
1724
				}
1725
 
1726
				// Catch 1 and 2
1727
				if ( i && i < 3 ) {
1728
					v = Math.round( v * 100 ) + "%";
1729
				}
1730
				return v;
1731
			} );
1732
 
1733
		if ( hsla[ 3 ] === 1 ) {
1734
			hsla.pop();
1735
			prefix = "hsl(";
1736
		}
1737
		return prefix + hsla.join() + ")";
1738
	},
1739
	toHexString: function( includeAlpha ) {
1740
		var rgba = this._rgba.slice(),
1741
			alpha = rgba.pop();
1742
 
1743
		if ( includeAlpha ) {
1744
			rgba.push( ~~( alpha * 255 ) );
1745
		}
1746
 
1747
		return "#" + jQuery.map( rgba, function( v ) {
1748
 
1749
			// Default to 0 when nulls exist
1750
			v = ( v || 0 ).toString( 16 );
1751
			return v.length === 1 ? "0" + v : v;
1752
		} ).join( "" );
1753
	},
1754
	toString: function() {
1755
		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
1756
	}
1757
} );
1758
color.fn.parse.prototype = color.fn;
1759
 
1760
// Hsla conversions adapted from:
1761
// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
1762
 
1763
function hue2rgb( p, q, h ) {
1764
	h = ( h + 1 ) % 1;
1765
	if ( h * 6 < 1 ) {
1766
		return p + ( q - p ) * h * 6;
1767
	}
1768
	if ( h * 2 < 1 ) {
1769
		return q;
1770
	}
1771
	if ( h * 3 < 2 ) {
1772
		return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
1773
	}
1774
	return p;
1775
}
1776
 
1777
spaces.hsla.to = function( rgba ) {
1778
	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
1779
		return [ null, null, null, rgba[ 3 ] ];
1780
	}
1781
	var r = rgba[ 0 ] / 255,
1782
		g = rgba[ 1 ] / 255,
1783
		b = rgba[ 2 ] / 255,
1784
		a = rgba[ 3 ],
1785
		max = Math.max( r, g, b ),
1786
		min = Math.min( r, g, b ),
1787
		diff = max - min,
1788
		add = max + min,
1789
		l = add * 0.5,
1790
		h, s;
1791
 
1792
	if ( min === max ) {
1793
		h = 0;
1794
	} else if ( r === max ) {
1795
		h = ( 60 * ( g - b ) / diff ) + 360;
1796
	} else if ( g === max ) {
1797
		h = ( 60 * ( b - r ) / diff ) + 120;
1798
	} else {
1799
		h = ( 60 * ( r - g ) / diff ) + 240;
1800
	}
1801
 
1802
	// Chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
1803
	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
1804
	if ( diff === 0 ) {
1805
		s = 0;
1806
	} else if ( l <= 0.5 ) {
1807
		s = diff / add;
1808
	} else {
1809
		s = diff / ( 2 - add );
1810
	}
1811
	return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ];
1812
};
1813
 
1814
spaces.hsla.from = function( hsla ) {
1815
	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
1816
		return [ null, null, null, hsla[ 3 ] ];
1817
	}
1818
	var h = hsla[ 0 ] / 360,
1819
		s = hsla[ 1 ],
1820
		l = hsla[ 2 ],
1821
		a = hsla[ 3 ],
1822
		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
1823
		p = 2 * l - q;
1824
 
1825
	return [
1826
		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
1827
		Math.round( hue2rgb( p, q, h ) * 255 ),
1828
		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
1829
		a
1830
	];
1831
};
1832
 
1833
each( spaces, function( spaceName, space ) {
1834
	var props = space.props,
1835
		cache = space.cache,
1836
		to = space.to,
1837
		from = space.from;
1838
 
1839
	// Makes rgba() and hsla()
1840
	color.fn[ spaceName ] = function( value ) {
1841
 
1842
		// Generate a cache for this space if it doesn't exist
1843
		if ( to && !this[ cache ] ) {
1844
			this[ cache ] = to( this._rgba );
1845
		}
1846
		if ( value === undefined ) {
1847
			return this[ cache ].slice();
1848
		}
1849
 
1850
		var ret,
1851
			type = jQuery.type( value ),
1852
			arr = ( type === "array" || type === "object" ) ? value : arguments,
1853
			local = this[ cache ].slice();
1854
 
1855
		each( props, function( key, prop ) {
1856
			var val = arr[ type === "object" ? key : prop.idx ];
1857
			if ( val == null ) {
1858
				val = local[ prop.idx ];
1859
			}
1860
			local[ prop.idx ] = clamp( val, prop );
1861
		} );
1862
 
1863
		if ( from ) {
1864
			ret = color( from( local ) );
1865
			ret[ cache ] = local;
1866
			return ret;
1867
		} else {
1868
			return color( local );
1869
		}
1870
	};
1871
 
1872
	// Makes red() green() blue() alpha() hue() saturation() lightness()
1873
	each( props, function( key, prop ) {
1874
 
1875
		// Alpha is included in more than one space
1876
		if ( color.fn[ key ] ) {
1877
			return;
1878
		}
1879
		color.fn[ key ] = function( value ) {
1880
			var vtype = jQuery.type( value ),
1881
				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
1882
				local = this[ fn ](),
1883
				cur = local[ prop.idx ],
1884
				match;
1885
 
1886
			if ( vtype === "undefined" ) {
1887
				return cur;
1888
			}
1889
 
1890
			if ( vtype === "function" ) {
1891
				value = value.call( this, cur );
1892
				vtype = jQuery.type( value );
1893
			}
1894
			if ( value == null && prop.empty ) {
1895
				return this;
1896
			}
1897
			if ( vtype === "string" ) {
1898
				match = rplusequals.exec( value );
1899
				if ( match ) {
1900
					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
1901
				}
1902
			}
1903
			local[ prop.idx ] = value;
1904
			return this[ fn ]( local );
1905
		};
1906
	} );
1907
} );
1908
 
1909
// Add cssHook and .fx.step function for each named hook.
1910
// accept a space separated string of properties
1911
color.hook = function( hook ) {
1912
	var hooks = hook.split( " " );
1913
	each( hooks, function( i, hook ) {
1914
		jQuery.cssHooks[ hook ] = {
1915
			set: function( elem, value ) {
1916
				var parsed, curElem,
1917
					backgroundColor = "";
1918
 
1919
				if ( value !== "transparent" && ( jQuery.type( value ) !== "string" ||
1920
						( parsed = stringParse( value ) ) ) ) {
1921
					value = color( parsed || value );
1922
					if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
1923
						curElem = hook === "backgroundColor" ? elem.parentNode : elem;
1924
						while (
1925
							( backgroundColor === "" || backgroundColor === "transparent" ) &&
1926
							curElem && curElem.style
1927
						) {
1928
							try {
1929
								backgroundColor = jQuery.css( curElem, "backgroundColor" );
1930
								curElem = curElem.parentNode;
1931
							} catch ( e ) {
1932
							}
1933
						}
1934
 
1935
						value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
1936
							backgroundColor :
1937
							"_default" );
1938
					}
1939
 
1940
					value = value.toRgbaString();
1941
				}
1942
				try {
1943
					elem.style[ hook ] = value;
1944
				} catch ( e ) {
1945
 
1946
					// Wrapped to prevent IE from throwing errors on "invalid" values like
1947
					// 'auto' or 'inherit'
1948
				}
1949
			}
1950
		};
1951
		jQuery.fx.step[ hook ] = function( fx ) {
1952
			if ( !fx.colorInit ) {
1953
				fx.start = color( fx.elem, hook );
1954
				fx.end = color( fx.end );
1955
				fx.colorInit = true;
1956
			}
1957
			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
1958
		};
1959
	} );
1960
 
1961
};
1962
 
1963
color.hook( stepHooks );
1964
 
1965
jQuery.cssHooks.borderColor = {
1966
	expand: function( value ) {
1967
		var expanded = {};
1968
 
1969
		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
1970
			expanded[ "border" + part + "Color" ] = value;
1971
		} );
1972
		return expanded;
1973
	}
1974
};
1975
 
1976
// Basic color names only.
1977
// Usage of any of the other color names requires adding yourself or including
1978
// jquery.color.svg-names.js.
1979
colors = jQuery.Color.names = {
1980
 
1981
	// 4.1. Basic color keywords
1982
	aqua: "#00ffff",
1983
	black: "#000000",
1984
	blue: "#0000ff",
1985
	fuchsia: "#ff00ff",
1986
	gray: "#808080",
1987
	green: "#008000",
1988
	lime: "#00ff00",
1989
	maroon: "#800000",
1990
	navy: "#000080",
1991
	olive: "#808000",
1992
	purple: "#800080",
1993
	red: "#ff0000",
1994
	silver: "#c0c0c0",
1995
	teal: "#008080",
1996
	white: "#ffffff",
1997
	yellow: "#ffff00",
1998
 
1999
	// 4.2.3. "transparent" color keyword
2000
	transparent: [ null, null, null, 0 ],
2001
 
2002
	_default: "#ffffff"
2003
};
2004
 
2005
} )( jQuery );
2006
 
2007
/******************************************************************************/
2008
/****************************** CLASS ANIMATIONS ******************************/
2009
/******************************************************************************/
2010
( function() {
2011
 
2012
var classAnimationActions = [ "add", "remove", "toggle" ],
2013
	shorthandStyles = {
2014
		border: 1,
2015
		borderBottom: 1,
2016
		borderColor: 1,
2017
		borderLeft: 1,
2018
		borderRight: 1,
2019
		borderTop: 1,
2020
		borderWidth: 1,
2021
		margin: 1,
2022
		padding: 1
2023
	};
2024
 
2025
$.each(
2026
	[ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ],
2027
	function( _, prop ) {
2028
		$.fx.step[ prop ] = function( fx ) {
2029
			if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
2030
				jQuery.style( fx.elem, prop, fx.end );
2031
				fx.setAttr = true;
2032
			}
2033
		};
2034
	}
2035
);
2036
 
2037
function getElementStyles( elem ) {
2038
	var key, len,
2039
		style = elem.ownerDocument.defaultView ?
2040
			elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
2041
			elem.currentStyle,
2042
		styles = {};
2043
 
2044
	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
2045
		len = style.length;
2046
		while ( len-- ) {
2047
			key = style[ len ];
2048
			if ( typeof style[ key ] === "string" ) {
2049
				styles[ $.camelCase( key ) ] = style[ key ];
2050
			}
2051
		}
2052
 
2053
	// Support: Opera, IE <9
2054
	} else {
2055
		for ( key in style ) {
2056
			if ( typeof style[ key ] === "string" ) {
2057
				styles[ key ] = style[ key ];
2058
			}
2059
		}
2060
	}
2061
 
2062
	return styles;
2063
}
2064
 
2065
function styleDifference( oldStyle, newStyle ) {
2066
	var diff = {},
2067
		name, value;
2068
 
2069
	for ( name in newStyle ) {
2070
		value = newStyle[ name ];
2071
		if ( oldStyle[ name ] !== value ) {
2072
			if ( !shorthandStyles[ name ] ) {
2073
				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
2074
					diff[ name ] = value;
2075
				}
2076
			}
2077
		}
2078
	}
2079
 
2080
	return diff;
2081
}
2082
 
2083
// Support: jQuery <1.8
2084
if ( !$.fn.addBack ) {
2085
	$.fn.addBack = function( selector ) {
2086
		return this.add( selector == null ?
2087
			this.prevObject : this.prevObject.filter( selector )
2088
		);
2089
	};
2090
}
2091
 
2092
$.effects.animateClass = function( value, duration, easing, callback ) {
2093
	var o = $.speed( duration, easing, callback );
2094
 
2095
	return this.queue( function() {
2096
		var animated = $( this ),
2097
			baseClass = animated.attr( "class" ) || "",
2098
			applyClassChange,
2099
			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
2100
 
2101
		// Map the animated objects to store the original styles.
2102
		allAnimations = allAnimations.map( function() {
2103
			var el = $( this );
2104
			return {
2105
				el: el,
2106
				start: getElementStyles( this )
2107
			};
2108
		} );
2109
 
2110
		// Apply class change
2111
		applyClassChange = function() {
2112
			$.each( classAnimationActions, function( i, action ) {
2113
				if ( value[ action ] ) {
2114
					animated[ action + "Class" ]( value[ action ] );
2115
				}
2116
			} );
2117
		};
2118
		applyClassChange();
2119
 
2120
		// Map all animated objects again - calculate new styles and diff
2121
		allAnimations = allAnimations.map( function() {
2122
			this.end = getElementStyles( this.el[ 0 ] );
2123
			this.diff = styleDifference( this.start, this.end );
2124
			return this;
2125
		} );
2126
 
2127
		// Apply original class
2128
		animated.attr( "class", baseClass );
2129
 
2130
		// Map all animated objects again - this time collecting a promise
2131
		allAnimations = allAnimations.map( function() {
2132
			var styleInfo = this,
2133
				dfd = $.Deferred(),
2134
				opts = $.extend( {}, o, {
2135
					queue: false,
2136
					complete: function() {
2137
						dfd.resolve( styleInfo );
2138
					}
2139
				} );
2140
 
2141
			this.el.animate( this.diff, opts );
2142
			return dfd.promise();
2143
		} );
2144
 
2145
		// Once all animations have completed:
2146
		$.when.apply( $, allAnimations.get() ).done( function() {
2147
 
2148
			// Set the final class
2149
			applyClassChange();
2150
 
2151
			// For each animated element,
2152
			// clear all css properties that were animated
2153
			$.each( arguments, function() {
2154
				var el = this.el;
2155
				$.each( this.diff, function( key ) {
2156
					el.css( key, "" );
2157
				} );
2158
			} );
2159
 
2160
			// This is guarnteed to be there if you use jQuery.speed()
2161
			// it also handles dequeuing the next anim...
2162
			o.complete.call( animated[ 0 ] );
2163
		} );
2164
	} );
2165
};
2166
 
2167
$.fn.extend( {
2168
	addClass: ( function( orig ) {
2169
		return function( classNames, speed, easing, callback ) {
2170
			return speed ?
2171
				$.effects.animateClass.call( this,
2172
					{ add: classNames }, speed, easing, callback ) :
2173
				orig.apply( this, arguments );
2174
		};
2175
	} )( $.fn.addClass ),
2176
 
2177
	removeClass: ( function( orig ) {
2178
		return function( classNames, speed, easing, callback ) {
2179
			return arguments.length > 1 ?
2180
				$.effects.animateClass.call( this,
2181
					{ remove: classNames }, speed, easing, callback ) :
2182
				orig.apply( this, arguments );
2183
		};
2184
	} )( $.fn.removeClass ),
2185
 
2186
	toggleClass: ( function( orig ) {
2187
		return function( classNames, force, speed, easing, callback ) {
2188
			if ( typeof force === "boolean" || force === undefined ) {
2189
				if ( !speed ) {
2190
 
2191
					// Without speed parameter
2192
					return orig.apply( this, arguments );
2193
				} else {
2194
					return $.effects.animateClass.call( this,
2195
						( force ? { add: classNames } : { remove: classNames } ),
2196
						speed, easing, callback );
2197
				}
2198
			} else {
2199
 
2200
				// Without force parameter
2201
				return $.effects.animateClass.call( this,
2202
					{ toggle: classNames }, force, speed, easing );
2203
			}
2204
		};
2205
	} )( $.fn.toggleClass ),
2206
 
2207
	switchClass: function( remove, add, speed, easing, callback ) {
2208
		return $.effects.animateClass.call( this, {
2209
			add: add,
2210
			remove: remove
2211
		}, speed, easing, callback );
2212
	}
2213
} );
2214
 
2215
} )();
2216
 
2217
/******************************************************************************/
2218
/*********************************** EFFECTS **********************************/
2219
/******************************************************************************/
2220
 
2221
( function() {
2222
 
2223
if ( $.expr && $.expr.filters && $.expr.filters.animated ) {
2224
	$.expr.filters.animated = ( function( orig ) {
2225
		return function( elem ) {
2226
			return !!$( elem ).data( dataSpaceAnimated ) || orig( elem );
2227
		};
2228
	} )( $.expr.filters.animated );
2229
}
2230
 
2231
if ( $.uiBackCompat !== false ) {
2232
	$.extend( $.effects, {
2233
 
2234
		// Saves a set of properties in a data storage
2235
		save: function( element, set ) {
2236
			var i = 0, length = set.length;
2237
			for ( ; i < length; i++ ) {
2238
				if ( set[ i ] !== null ) {
2239
					element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
2240
				}
2241
			}
2242
		},
2243
 
2244
		// Restores a set of previously saved properties from a data storage
2245
		restore: function( element, set ) {
2246
			var val, i = 0, length = set.length;
2247
			for ( ; i < length; i++ ) {
2248
				if ( set[ i ] !== null ) {
2249
					val = element.data( dataSpace + set[ i ] );
2250
					element.css( set[ i ], val );
2251
				}
2252
			}
2253
		},
2254
 
2255
		setMode: function( el, mode ) {
2256
			if ( mode === "toggle" ) {
2257
				mode = el.is( ":hidden" ) ? "show" : "hide";
2258
			}
2259
			return mode;
2260
		},
2261
 
2262
		// Wraps the element around a wrapper that copies position properties
2263
		createWrapper: function( element ) {
2264
 
2265
			// If the element is already wrapped, return it
2266
			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
2267
				return element.parent();
2268
			}
2269
 
2270
			// Wrap the element
2271
			var props = {
2272
					width: element.outerWidth( true ),
2273
					height: element.outerHeight( true ),
2274
					"float": element.css( "float" )
2275
				},
2276
				wrapper = $( "<div></div>" )
2277
					.addClass( "ui-effects-wrapper" )
2278
					.css( {
2279
						fontSize: "100%",
2280
						background: "transparent",
2281
						border: "none",
2282
						margin: 0,
2283
						padding: 0
2284
					} ),
2285
 
2286
				// Store the size in case width/height are defined in % - Fixes #5245
2287
				size = {
2288
					width: element.width(),
2289
					height: element.height()
2290
				},
2291
				active = document.activeElement;
2292
 
2293
			// Support: Firefox
2294
			// Firefox incorrectly exposes anonymous content
2295
			// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
2296
			try {
2297
				active.id;
2298
			} catch ( e ) {
2299
				active = document.body;
2300
			}
2301
 
2302
			element.wrap( wrapper );
2303
 
2304
			// Fixes #7595 - Elements lose focus when wrapped.
2305
			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
2306
				$( active ).trigger( "focus" );
2307
			}
2308
 
2309
			// Hotfix for jQuery 1.4 since some change in wrap() seems to actually
2310
			// lose the reference to the wrapped element
2311
			wrapper = element.parent();
2312
 
2313
			// Transfer positioning properties to the wrapper
2314
			if ( element.css( "position" ) === "static" ) {
2315
				wrapper.css( { position: "relative" } );
2316
				element.css( { position: "relative" } );
2317
			} else {
2318
				$.extend( props, {
2319
					position: element.css( "position" ),
2320
					zIndex: element.css( "z-index" )
2321
				} );
2322
				$.each( [ "top", "left", "bottom", "right" ], function( i, pos ) {
2323
					props[ pos ] = element.css( pos );
2324
					if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
2325
						props[ pos ] = "auto";
2326
					}
2327
				} );
2328
				element.css( {
2329
					position: "relative",
2330
					top: 0,
2331
					left: 0,
2332
					right: "auto",
2333
					bottom: "auto"
2334
				} );
2335
			}
2336
			element.css( size );
2337
 
2338
			return wrapper.css( props ).show();
2339
		},
2340
 
2341
		removeWrapper: function( element ) {
2342
			var active = document.activeElement;
2343
 
2344
			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
2345
				element.parent().replaceWith( element );
2346
 
2347
				// Fixes #7595 - Elements lose focus when wrapped.
2348
				if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
2349
					$( active ).trigger( "focus" );
2350
				}
2351
			}
2352
 
2353
			return element;
2354
		}
2355
	} );
2356
}
2357
 
2358
$.extend( $.effects, {
2359
	version: "1.12.1",
2360
 
2361
	define: function( name, mode, effect ) {
2362
		if ( !effect ) {
2363
			effect = mode;
2364
			mode = "effect";
2365
		}
2366
 
2367
		$.effects.effect[ name ] = effect;
2368
		$.effects.effect[ name ].mode = mode;
2369
 
2370
		return effect;
2371
	},
2372
 
2373
	scaledDimensions: function( element, percent, direction ) {
2374
		if ( percent === 0 ) {
2375
			return {
2376
				height: 0,
2377
				width: 0,
2378
				outerHeight: 0,
2379
				outerWidth: 0
2380
			};
2381
		}
2382
 
2383
		var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1,
2384
			y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1;
2385
 
2386
		return {
2387
			height: element.height() * y,
2388
			width: element.width() * x,
2389
			outerHeight: element.outerHeight() * y,
2390
			outerWidth: element.outerWidth() * x
2391
		};
2392
 
2393
	},
2394
 
2395
	clipToBox: function( animation ) {
2396
		return {
2397
			width: animation.clip.right - animation.clip.left,
2398
			height: animation.clip.bottom - animation.clip.top,
2399
			left: animation.clip.left,
2400
			top: animation.clip.top
2401
		};
2402
	},
2403
 
2404
	// Injects recently queued functions to be first in line (after "inprogress")
2405
	unshift: function( element, queueLength, count ) {
2406
		var queue = element.queue();
2407
 
2408
		if ( queueLength > 1 ) {
2409
			queue.splice.apply( queue,
2410
				[ 1, 0 ].concat( queue.splice( queueLength, count ) ) );
2411
		}
2412
		element.dequeue();
2413
	},
2414
 
2415
	saveStyle: function( element ) {
2416
		element.data( dataSpaceStyle, element[ 0 ].style.cssText );
2417
	},
2418
 
2419
	restoreStyle: function( element ) {
2420
		element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || "";
2421
		element.removeData( dataSpaceStyle );
2422
	},
2423
 
2424
	mode: function( element, mode ) {
2425
		var hidden = element.is( ":hidden" );
2426
 
2427
		if ( mode === "toggle" ) {
2428
			mode = hidden ? "show" : "hide";
2429
		}
2430
		if ( hidden ? mode === "hide" : mode === "show" ) {
2431
			mode = "none";
2432
		}
2433
		return mode;
2434
	},
2435
 
2436
	// Translates a [top,left] array into a baseline value
2437
	getBaseline: function( origin, original ) {
2438
		var y, x;
2439
 
2440
		switch ( origin[ 0 ] ) {
2441
		case "top":
2442
			y = 0;
2443
			break;
2444
		case "middle":
2445
			y = 0.5;
2446
			break;
2447
		case "bottom":
2448
			y = 1;
2449
			break;
2450
		default:
2451
			y = origin[ 0 ] / original.height;
2452
		}
2453
 
2454
		switch ( origin[ 1 ] ) {
2455
		case "left":
2456
			x = 0;
2457
			break;
2458
		case "center":
2459
			x = 0.5;
2460
			break;
2461
		case "right":
2462
			x = 1;
2463
			break;
2464
		default:
2465
			x = origin[ 1 ] / original.width;
2466
		}
2467
 
2468
		return {
2469
			x: x,
2470
			y: y
2471
		};
2472
	},
2473
 
2474
	// Creates a placeholder element so that the original element can be made absolute
2475
	createPlaceholder: function( element ) {
2476
		var placeholder,
2477
			cssPosition = element.css( "position" ),
2478
			position = element.position();
2479
 
2480
		// Lock in margins first to account for form elements, which
2481
		// will change margin if you explicitly set height
2482
		// see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380
2483
		// Support: Safari
2484
		element.css( {
2485
			marginTop: element.css( "marginTop" ),
2486
			marginBottom: element.css( "marginBottom" ),
2487
			marginLeft: element.css( "marginLeft" ),
2488
			marginRight: element.css( "marginRight" )
2489
		} )
2490
		.outerWidth( element.outerWidth() )
2491
		.outerHeight( element.outerHeight() );
2492
 
2493
		if ( /^(static|relative)/.test( cssPosition ) ) {
2494
			cssPosition = "absolute";
2495
 
2496
			placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( {
2497
 
2498
				// Convert inline to inline block to account for inline elements
2499
				// that turn to inline block based on content (like img)
2500
				display: /^(inline|ruby)/.test( element.css( "display" ) ) ?
2501
					"inline-block" :
2502
					"block",
2503
				visibility: "hidden",
2504
 
2505
				// Margins need to be set to account for margin collapse
2506
				marginTop: element.css( "marginTop" ),
2507
				marginBottom: element.css( "marginBottom" ),
2508
				marginLeft: element.css( "marginLeft" ),
2509
				marginRight: element.css( "marginRight" ),
2510
				"float": element.css( "float" )
2511
			} )
2512
			.outerWidth( element.outerWidth() )
2513
			.outerHeight( element.outerHeight() )
2514
			.addClass( "ui-effects-placeholder" );
2515
 
2516
			element.data( dataSpace + "placeholder", placeholder );
2517
		}
2518
 
2519
		element.css( {
2520
			position: cssPosition,
2521
			left: position.left,
2522
			top: position.top
2523
		} );
2524
 
2525
		return placeholder;
2526
	},
2527
 
2528
	removePlaceholder: function( element ) {
2529
		var dataKey = dataSpace + "placeholder",
2530
				placeholder = element.data( dataKey );
2531
 
2532
		if ( placeholder ) {
2533
			placeholder.remove();
2534
			element.removeData( dataKey );
2535
		}
2536
	},
2537
 
2538
	// Removes a placeholder if it exists and restores
2539
	// properties that were modified during placeholder creation
2540
	cleanUp: function( element ) {
2541
		$.effects.restoreStyle( element );
2542
		$.effects.removePlaceholder( element );
2543
	},
2544
 
2545
	setTransition: function( element, list, factor, value ) {
2546
		value = value || {};
2547
		$.each( list, function( i, x ) {
2548
			var unit = element.cssUnit( x );
2549
			if ( unit[ 0 ] > 0 ) {
2550
				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
2551
			}
2552
		} );
2553
		return value;
2554
	}
2555
} );
2556
 
2557
// Return an effect options object for the given parameters:
2558
function _normalizeArguments( effect, options, speed, callback ) {
2559
 
2560
	// Allow passing all options as the first parameter
2561
	if ( $.isPlainObject( effect ) ) {
2562
		options = effect;
2563
		effect = effect.effect;
2564
	}
2565
 
2566
	// Convert to an object
2567
	effect = { effect: effect };
2568
 
2569
	// Catch (effect, null, ...)
2570
	if ( options == null ) {
2571
		options = {};
2572
	}
2573
 
2574
	// Catch (effect, callback)
2575
	if ( $.isFunction( options ) ) {
2576
		callback = options;
2577
		speed = null;
2578
		options = {};
2579
	}
2580
 
2581
	// Catch (effect, speed, ?)
2582
	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
2583
		callback = speed;
2584
		speed = options;
2585
		options = {};
2586
	}
2587
 
2588
	// Catch (effect, options, callback)
2589
	if ( $.isFunction( speed ) ) {
2590
		callback = speed;
2591
		speed = null;
2592
	}
2593
 
2594
	// Add options to effect
2595
	if ( options ) {
2596
		$.extend( effect, options );
2597
	}
2598
 
2599
	speed = speed || options.duration;
2600
	effect.duration = $.fx.off ? 0 :
2601
		typeof speed === "number" ? speed :
2602
		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
2603
		$.fx.speeds._default;
2604
 
2605
	effect.complete = callback || options.complete;
2606
 
2607
	return effect;
2608
}
2609
 
2610
function standardAnimationOption( option ) {
2611
 
2612
	// Valid standard speeds (nothing, number, named speed)
2613
	if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
2614
		return true;
2615
	}
2616
 
2617
	// Invalid strings - treat as "normal" speed
2618
	if ( typeof option === "string" && !$.effects.effect[ option ] ) {
2619
		return true;
2620
	}
2621
 
2622
	// Complete callback
2623
	if ( $.isFunction( option ) ) {
2624
		return true;
2625
	}
2626
 
2627
	// Options hash (but not naming an effect)
2628
	if ( typeof option === "object" && !option.effect ) {
2629
		return true;
2630
	}
2631
 
2632
	// Didn't match any standard API
2633
	return false;
2634
}
2635
 
2636
$.fn.extend( {
2637
	effect: function( /* effect, options, speed, callback */ ) {
2638
		var args = _normalizeArguments.apply( this, arguments ),
2639
			effectMethod = $.effects.effect[ args.effect ],
2640
			defaultMode = effectMethod.mode,
2641
			queue = args.queue,
2642
			queueName = queue || "fx",
2643
			complete = args.complete,
2644
			mode = args.mode,
2645
			modes = [],
2646
			prefilter = function( next ) {
2647
				var el = $( this ),
2648
					normalizedMode = $.effects.mode( el, mode ) || defaultMode;
2649
 
2650
				// Sentinel for duck-punching the :animated psuedo-selector
2651
				el.data( dataSpaceAnimated, true );
2652
 
2653
				// Save effect mode for later use,
2654
				// we can't just call $.effects.mode again later,
2655
				// as the .show() below destroys the initial state
2656
				modes.push( normalizedMode );
2657
 
2658
				// See $.uiBackCompat inside of run() for removal of defaultMode in 1.13
2659
				if ( defaultMode && ( normalizedMode === "show" ||
2660
						( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) {
2661
					el.show();
2662
				}
2663
 
2664
				if ( !defaultMode || normalizedMode !== "none" ) {
2665
					$.effects.saveStyle( el );
2666
				}
2667
 
2668
				if ( $.isFunction( next ) ) {
2669
					next();
2670
				}
2671
			};
2672
 
2673
		if ( $.fx.off || !effectMethod ) {
2674
 
2675
			// Delegate to the original method (e.g., .show()) if possible
2676
			if ( mode ) {
2677
				return this[ mode ]( args.duration, complete );
2678
			} else {
2679
				return this.each( function() {
2680
					if ( complete ) {
2681
						complete.call( this );
2682
					}
2683
				} );
2684
			}
2685
		}
2686
 
2687
		function run( next ) {
2688
			var elem = $( this );
2689
 
2690
			function cleanup() {
2691
				elem.removeData( dataSpaceAnimated );
2692
 
2693
				$.effects.cleanUp( elem );
2694
 
2695
				if ( args.mode === "hide" ) {
2696
					elem.hide();
2697
				}
2698
 
2699
				done();
2700
			}
2701
 
2702
			function done() {
2703
				if ( $.isFunction( complete ) ) {
2704
					complete.call( elem[ 0 ] );
2705
				}
2706
 
2707
				if ( $.isFunction( next ) ) {
2708
					next();
2709
				}
2710
			}
2711
 
2712
			// Override mode option on a per element basis,
2713
			// as toggle can be either show or hide depending on element state
2714
			args.mode = modes.shift();
2715
 
2716
			if ( $.uiBackCompat !== false && !defaultMode ) {
2717
				if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
2718
 
2719
					// Call the core method to track "olddisplay" properly
2720
					elem[ mode ]();
2721
					done();
2722
				} else {
2723
					effectMethod.call( elem[ 0 ], args, done );
2724
				}
2725
			} else {
2726
				if ( args.mode === "none" ) {
2727
 
2728
					// Call the core method to track "olddisplay" properly
2729
					elem[ mode ]();
2730
					done();
2731
				} else {
2732
					effectMethod.call( elem[ 0 ], args, cleanup );
2733
				}
2734
			}
2735
		}
2736
 
2737
		// Run prefilter on all elements first to ensure that
2738
		// any showing or hiding happens before placeholder creation,
2739
		// which ensures that any layout changes are correctly captured.
2740
		return queue === false ?
2741
			this.each( prefilter ).each( run ) :
2742
			this.queue( queueName, prefilter ).queue( queueName, run );
2743
	},
2744
 
2745
	show: ( function( orig ) {
2746
		return function( option ) {
2747
			if ( standardAnimationOption( option ) ) {
2748
				return orig.apply( this, arguments );
2749
			} else {
2750
				var args = _normalizeArguments.apply( this, arguments );
2751
				args.mode = "show";
2752
				return this.effect.call( this, args );
2753
			}
2754
		};
2755
	} )( $.fn.show ),
2756
 
2757
	hide: ( function( orig ) {
2758
		return function( option ) {
2759
			if ( standardAnimationOption( option ) ) {
2760
				return orig.apply( this, arguments );
2761
			} else {
2762
				var args = _normalizeArguments.apply( this, arguments );
2763
				args.mode = "hide";
2764
				return this.effect.call( this, args );
2765
			}
2766
		};
2767
	} )( $.fn.hide ),
2768
 
2769
	toggle: ( function( orig ) {
2770
		return function( option ) {
2771
			if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
2772
				return orig.apply( this, arguments );
2773
			} else {
2774
				var args = _normalizeArguments.apply( this, arguments );
2775
				args.mode = "toggle";
2776
				return this.effect.call( this, args );
2777
			}
2778
		};
2779
	} )( $.fn.toggle ),
2780
 
2781
	cssUnit: function( key ) {
2782
		var style = this.css( key ),
2783
			val = [];
2784
 
2785
		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
2786
			if ( style.indexOf( unit ) > 0 ) {
2787
				val = [ parseFloat( style ), unit ];
2788
			}
2789
		} );
2790
		return val;
2791
	},
2792
 
2793
	cssClip: function( clipObj ) {
2794
		if ( clipObj ) {
2795
			return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " +
2796
				clipObj.bottom + "px " + clipObj.left + "px)" );
2797
		}
2798
		return parseClip( this.css( "clip" ), this );
2799
	},
2800
 
2801
	transfer: function( options, done ) {
2802
		var element = $( this ),
2803
			target = $( options.to ),
2804
			targetFixed = target.css( "position" ) === "fixed",
2805
			body = $( "body" ),
2806
			fixTop = targetFixed ? body.scrollTop() : 0,
2807
			fixLeft = targetFixed ? body.scrollLeft() : 0,
2808
			endPosition = target.offset(),
2809
			animation = {
2810
				top: endPosition.top - fixTop,
2811
				left: endPosition.left - fixLeft,
2812
				height: target.innerHeight(),
2813
				width: target.innerWidth()
2814
			},
2815
			startPosition = element.offset(),
2816
			transfer = $( "<div class='ui-effects-transfer'></div>" )
2817
				.appendTo( "body" )
2818
				.addClass( options.className )
2819
				.css( {
2820
					top: startPosition.top - fixTop,
2821
					left: startPosition.left - fixLeft,
2822
					height: element.innerHeight(),
2823
					width: element.innerWidth(),
2824
					position: targetFixed ? "fixed" : "absolute"
2825
				} )
2826
				.animate( animation, options.duration, options.easing, function() {
2827
					transfer.remove();
2828
					if ( $.isFunction( done ) ) {
2829
						done();
2830
					}
2831
				} );
2832
	}
2833
} );
2834
 
2835
function parseClip( str, element ) {
2836
		var outerWidth = element.outerWidth(),
2837
			outerHeight = element.outerHeight(),
2838
			clipRegex = /^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/,
2839
			values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ];
2840
 
2841
		return {
2842
			top: parseFloat( values[ 1 ] ) || 0,
2843
			right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ),
2844
			bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ),
2845
			left: parseFloat( values[ 4 ] ) || 0
2846
		};
2847
}
2848
 
2849
$.fx.step.clip = function( fx ) {
2850
	if ( !fx.clipInit ) {
2851
		fx.start = $( fx.elem ).cssClip();
2852
		if ( typeof fx.end === "string" ) {
2853
			fx.end = parseClip( fx.end, fx.elem );
2854
		}
2855
		fx.clipInit = true;
2856
	}
2857
 
2858
	$( fx.elem ).cssClip( {
2859
		top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top,
2860
		right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right,
2861
		bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom,
2862
		left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left
2863
	} );
2864
};
2865
 
2866
} )();
2867
 
2868
/******************************************************************************/
2869
/*********************************** EASING ***********************************/
2870
/******************************************************************************/
2871
 
2872
( function() {
2873
 
2874
// Based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
2875
 
2876
var baseEasings = {};
2877
 
2878
$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
2879
	baseEasings[ name ] = function( p ) {
2880
		return Math.pow( p, i + 2 );
2881
	};
2882
} );
2883
 
2884
$.extend( baseEasings, {
2885
	Sine: function( p ) {
2886
		return 1 - Math.cos( p * Math.PI / 2 );
2887
	},
2888
	Circ: function( p ) {
2889
		return 1 - Math.sqrt( 1 - p * p );
2890
	},
2891
	Elastic: function( p ) {
2892
		return p === 0 || p === 1 ? p :
2893
			-Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );
2894
	},
2895
	Back: function( p ) {
2896
		return p * p * ( 3 * p - 2 );
2897
	},
2898
	Bounce: function( p ) {
2899
		var pow2,
2900
			bounce = 4;
2901
 
2902
		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
2903
		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
2904
	}
2905
} );
2906
 
2907
$.each( baseEasings, function( name, easeIn ) {
2908
	$.easing[ "easeIn" + name ] = easeIn;
2909
	$.easing[ "easeOut" + name ] = function( p ) {
2910
		return 1 - easeIn( 1 - p );
2911
	};
2912
	$.easing[ "easeInOut" + name ] = function( p ) {
2913
		return p < 0.5 ?
2914
			easeIn( p * 2 ) / 2 :
2915
			1 - easeIn( p * -2 + 2 ) / 2;
2916
	};
2917
} );
2918
 
2919
} )();
2920
 
2921
var effect = $.effects;
2922
 
2923
 
2924
/*!
2925
 * jQuery UI Effects Blind 1.12.1
2926
 * http://jqueryui.com
2927
 *
2928
 * Copyright jQuery Foundation and other contributors
2929
 * Released under the MIT license.
2930
 * http://jquery.org/license
2931
 */
2932
 
2933
//>>label: Blind Effect
2934
//>>group: Effects
2935
//>>description: Blinds the element.
2936
//>>docs: http://api.jqueryui.com/blind-effect/
2937
//>>demos: http://jqueryui.com/effect/
2938
 
2939
 
2940
 
2941
var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) {
2942
	var map = {
2943
			up: [ "bottom", "top" ],
2944
			vertical: [ "bottom", "top" ],
2945
			down: [ "top", "bottom" ],
2946
			left: [ "right", "left" ],
2947
			horizontal: [ "right", "left" ],
2948
			right: [ "left", "right" ]
2949
		},
2950
		element = $( this ),
2951
		direction = options.direction || "up",
2952
		start = element.cssClip(),
2953
		animate = { clip: $.extend( {}, start ) },
2954
		placeholder = $.effects.createPlaceholder( element );
2955
 
2956
	animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ];
2957
 
2958
	if ( options.mode === "show" ) {
2959
		element.cssClip( animate.clip );
2960
		if ( placeholder ) {
2961
			placeholder.css( $.effects.clipToBox( animate ) );
2962
		}
2963
 
2964
		animate.clip = start;
2965
	}
2966
 
2967
	if ( placeholder ) {
2968
		placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing );
2969
	}
2970
 
2971
	element.animate( animate, {
2972
		queue: false,
2973
		duration: options.duration,
2974
		easing: options.easing,
2975
		complete: done
2976
	} );
2977
} );
2978
 
2979
 
2980
/*!
2981
 * jQuery UI Effects Bounce 1.12.1
2982
 * http://jqueryui.com
2983
 *
2984
 * Copyright jQuery Foundation and other contributors
2985
 * Released under the MIT license.
2986
 * http://jquery.org/license
2987
 */
2988
 
2989
//>>label: Bounce Effect
2990
//>>group: Effects
2991
//>>description: Bounces an element horizontally or vertically n times.
2992
//>>docs: http://api.jqueryui.com/bounce-effect/
2993
//>>demos: http://jqueryui.com/effect/
2994
 
2995
 
2996
 
2997
var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) {
2998
	var upAnim, downAnim, refValue,
2999
		element = $( this ),
3000
 
3001
		// Defaults:
3002
		mode = options.mode,
3003
		hide = mode === "hide",
3004
		show = mode === "show",
3005
		direction = options.direction || "up",
3006
		distance = options.distance,
3007
		times = options.times || 5,
3008
 
3009
		// Number of internal animations
3010
		anims = times * 2 + ( show || hide ? 1 : 0 ),
3011
		speed = options.duration / anims,
3012
		easing = options.easing,
3013
 
3014
		// Utility:
3015
		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3016
		motion = ( direction === "up" || direction === "left" ),
3017
		i = 0,
3018
 
3019
		queuelen = element.queue().length;
3020
 
3021
	$.effects.createPlaceholder( element );
3022
 
3023
	refValue = element.css( ref );
3024
 
3025
	// Default distance for the BIGGEST bounce is the outer Distance / 3
3026
	if ( !distance ) {
3027
		distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
3028
	}
3029
 
3030
	if ( show ) {
3031
		downAnim = { opacity: 1 };
3032
		downAnim[ ref ] = refValue;
3033
 
3034
		// If we are showing, force opacity 0 and set the initial position
3035
		// then do the "first" animation
3036
		element
3037
			.css( "opacity", 0 )
3038
			.css( ref, motion ? -distance * 2 : distance * 2 )
3039
			.animate( downAnim, speed, easing );
3040
	}
3041
 
3042
	// Start at the smallest distance if we are hiding
3043
	if ( hide ) {
3044
		distance = distance / Math.pow( 2, times - 1 );
3045
	}
3046
 
3047
	downAnim = {};
3048
	downAnim[ ref ] = refValue;
3049
 
3050
	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
3051
	for ( ; i < times; i++ ) {
3052
		upAnim = {};
3053
		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
3054
 
3055
		element
3056
			.animate( upAnim, speed, easing )
3057
			.animate( downAnim, speed, easing );
3058
 
3059
		distance = hide ? distance * 2 : distance / 2;
3060
	}
3061
 
3062
	// Last Bounce when Hiding
3063
	if ( hide ) {
3064
		upAnim = { opacity: 0 };
3065
		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
3066
 
3067
		element.animate( upAnim, speed, easing );
3068
	}
3069
 
3070
	element.queue( done );
3071
 
3072
	$.effects.unshift( element, queuelen, anims + 1 );
3073
} );
3074
 
3075
 
3076
/*!
3077
 * jQuery UI Effects Clip 1.12.1
3078
 * http://jqueryui.com
3079
 *
3080
 * Copyright jQuery Foundation and other contributors
3081
 * Released under the MIT license.
3082
 * http://jquery.org/license
3083
 */
3084
 
3085
//>>label: Clip Effect
3086
//>>group: Effects
3087
//>>description: Clips the element on and off like an old TV.
3088
//>>docs: http://api.jqueryui.com/clip-effect/
3089
//>>demos: http://jqueryui.com/effect/
3090
 
3091
 
3092
 
3093
var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) {
3094
	var start,
3095
		animate = {},
3096
		element = $( this ),
3097
		direction = options.direction || "vertical",
3098
		both = direction === "both",
3099
		horizontal = both || direction === "horizontal",
3100
		vertical = both || direction === "vertical";
3101
 
3102
	start = element.cssClip();
3103
	animate.clip = {
3104
		top: vertical ? ( start.bottom - start.top ) / 2 : start.top,
3105
		right: horizontal ? ( start.right - start.left ) / 2 : start.right,
3106
		bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom,
3107
		left: horizontal ? ( start.right - start.left ) / 2 : start.left
3108
	};
3109
 
3110
	$.effects.createPlaceholder( element );
3111
 
3112
	if ( options.mode === "show" ) {
3113
		element.cssClip( animate.clip );
3114
		animate.clip = start;
3115
	}
3116
 
3117
	element.animate( animate, {
3118
		queue: false,
3119
		duration: options.duration,
3120
		easing: options.easing,
3121
		complete: done
3122
	} );
3123
 
3124
} );
3125
 
3126
 
3127
/*!
3128
 * jQuery UI Effects Drop 1.12.1
3129
 * http://jqueryui.com
3130
 *
3131
 * Copyright jQuery Foundation and other contributors
3132
 * Released under the MIT license.
3133
 * http://jquery.org/license
3134
 */
3135
 
3136
//>>label: Drop Effect
3137
//>>group: Effects
3138
//>>description: Moves an element in one direction and hides it at the same time.
3139
//>>docs: http://api.jqueryui.com/drop-effect/
3140
//>>demos: http://jqueryui.com/effect/
3141
 
3142
 
3143
 
3144
var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) {
3145
 
3146
	var distance,
3147
		element = $( this ),
3148
		mode = options.mode,
3149
		show = mode === "show",
3150
		direction = options.direction || "left",
3151
		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3152
		motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=",
3153
		oppositeMotion = ( motion === "+=" ) ? "-=" : "+=",
3154
		animation = {
3155
			opacity: 0
3156
		};
3157
 
3158
	$.effects.createPlaceholder( element );
3159
 
3160
	distance = options.distance ||
3161
		element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
3162
 
3163
	animation[ ref ] = motion + distance;
3164
 
3165
	if ( show ) {
3166
		element.css( animation );
3167
 
3168
		animation[ ref ] = oppositeMotion + distance;
3169
		animation.opacity = 1;
3170
	}
3171
 
3172
	// Animate
3173
	element.animate( animation, {
3174
		queue: false,
3175
		duration: options.duration,
3176
		easing: options.easing,
3177
		complete: done
3178
	} );
3179
} );
3180
 
3181
 
3182
/*!
3183
 * jQuery UI Effects Explode 1.12.1
3184
 * http://jqueryui.com
3185
 *
3186
 * Copyright jQuery Foundation and other contributors
3187
 * Released under the MIT license.
3188
 * http://jquery.org/license
3189
 */
3190
 
3191
//>>label: Explode Effect
3192
//>>group: Effects
3193
// jscs:disable maximumLineLength
3194
//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness.
3195
// jscs:enable maximumLineLength
3196
//>>docs: http://api.jqueryui.com/explode-effect/
3197
//>>demos: http://jqueryui.com/effect/
3198
 
3199
 
3200
 
3201
var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) {
3202
 
3203
	var i, j, left, top, mx, my,
3204
		rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3,
3205
		cells = rows,
3206
		element = $( this ),
3207
		mode = options.mode,
3208
		show = mode === "show",
3209
 
3210
		// Show and then visibility:hidden the element before calculating offset
3211
		offset = element.show().css( "visibility", "hidden" ).offset(),
3212
 
3213
		// Width and height of a piece
3214
		width = Math.ceil( element.outerWidth() / cells ),
3215
		height = Math.ceil( element.outerHeight() / rows ),
3216
		pieces = [];
3217
 
3218
	// Children animate complete:
3219
	function childComplete() {
3220
		pieces.push( this );
3221
		if ( pieces.length === rows * cells ) {
3222
			animComplete();
3223
		}
3224
	}
3225
 
3226
	// Clone the element for each row and cell.
3227
	for ( i = 0; i < rows; i++ ) { // ===>
3228
		top = offset.top + i * height;
3229
		my = i - ( rows - 1 ) / 2;
3230
 
3231
		for ( j = 0; j < cells; j++ ) { // |||
3232
			left = offset.left + j * width;
3233
			mx = j - ( cells - 1 ) / 2;
3234
 
3235
			// Create a clone of the now hidden main element that will be absolute positioned
3236
			// within a wrapper div off the -left and -top equal to size of our pieces
3237
			element
3238
				.clone()
3239
				.appendTo( "body" )
3240
				.wrap( "<div></div>" )
3241
				.css( {
3242
					position: "absolute",
3243
					visibility: "visible",
3244
					left: -j * width,
3245
					top: -i * height
3246
				} )
3247
 
3248
				// Select the wrapper - make it overflow: hidden and absolute positioned based on
3249
				// where the original was located +left and +top equal to the size of pieces
3250
				.parent()
3251
					.addClass( "ui-effects-explode" )
3252
					.css( {
3253
						position: "absolute",
3254
						overflow: "hidden",
3255
						width: width,
3256
						height: height,
3257
						left: left + ( show ? mx * width : 0 ),
3258
						top: top + ( show ? my * height : 0 ),
3259
						opacity: show ? 0 : 1
3260
					} )
3261
					.animate( {
3262
						left: left + ( show ? 0 : mx * width ),
3263
						top: top + ( show ? 0 : my * height ),
3264
						opacity: show ? 1 : 0
3265
					}, options.duration || 500, options.easing, childComplete );
3266
		}
3267
	}
3268
 
3269
	function animComplete() {
3270
		element.css( {
3271
			visibility: "visible"
3272
		} );
3273
		$( pieces ).remove();
3274
		done();
3275
	}
3276
} );
3277
 
3278
 
3279
/*!
3280
 * jQuery UI Effects Fade 1.12.1
3281
 * http://jqueryui.com
3282
 *
3283
 * Copyright jQuery Foundation and other contributors
3284
 * Released under the MIT license.
3285
 * http://jquery.org/license
3286
 */
3287
 
3288
//>>label: Fade Effect
3289
//>>group: Effects
3290
//>>description: Fades the element.
3291
//>>docs: http://api.jqueryui.com/fade-effect/
3292
//>>demos: http://jqueryui.com/effect/
3293
 
3294
 
3295
 
3296
var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) {
3297
	var show = options.mode === "show";
3298
 
3299
	$( this )
3300
		.css( "opacity", show ? 0 : 1 )
3301
		.animate( {
3302
			opacity: show ? 1 : 0
3303
		}, {
3304
			queue: false,
3305
			duration: options.duration,
3306
			easing: options.easing,
3307
			complete: done
3308
		} );
3309
} );
3310
 
3311
 
3312
/*!
3313
 * jQuery UI Effects Fold 1.12.1
3314
 * http://jqueryui.com
3315
 *
3316
 * Copyright jQuery Foundation and other contributors
3317
 * Released under the MIT license.
3318
 * http://jquery.org/license
3319
 */
3320
 
3321
//>>label: Fold Effect
3322
//>>group: Effects
3323
//>>description: Folds an element first horizontally and then vertically.
3324
//>>docs: http://api.jqueryui.com/fold-effect/
3325
//>>demos: http://jqueryui.com/effect/
3326
 
3327
 
3328
 
3329
var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) {
3330
 
3331
	// Create element
3332
	var element = $( this ),
3333
		mode = options.mode,
3334
		show = mode === "show",
3335
		hide = mode === "hide",
3336
		size = options.size || 15,
3337
		percent = /([0-9]+)%/.exec( size ),
3338
		horizFirst = !!options.horizFirst,
3339
		ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ],
3340
		duration = options.duration / 2,
3341
 
3342
		placeholder = $.effects.createPlaceholder( element ),
3343
 
3344
		start = element.cssClip(),
3345
		animation1 = { clip: $.extend( {}, start ) },
3346
		animation2 = { clip: $.extend( {}, start ) },
3347
 
3348
		distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ],
3349
 
3350
		queuelen = element.queue().length;
3351
 
3352
	if ( percent ) {
3353
		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
3354
	}
3355
	animation1.clip[ ref[ 0 ] ] = size;
3356
	animation2.clip[ ref[ 0 ] ] = size;
3357
	animation2.clip[ ref[ 1 ] ] = 0;
3358
 
3359
	if ( show ) {
3360
		element.cssClip( animation2.clip );
3361
		if ( placeholder ) {
3362
			placeholder.css( $.effects.clipToBox( animation2 ) );
3363
		}
3364
 
3365
		animation2.clip = start;
3366
	}
3367
 
3368
	// Animate
3369
	element
3370
		.queue( function( next ) {
3371
			if ( placeholder ) {
3372
				placeholder
3373
					.animate( $.effects.clipToBox( animation1 ), duration, options.easing )
3374
					.animate( $.effects.clipToBox( animation2 ), duration, options.easing );
3375
			}
3376
 
3377
			next();
3378
		} )
3379
		.animate( animation1, duration, options.easing )
3380
		.animate( animation2, duration, options.easing )
3381
		.queue( done );
3382
 
3383
	$.effects.unshift( element, queuelen, 4 );
3384
} );
3385
 
3386
 
3387
/*!
3388
 * jQuery UI Effects Highlight 1.12.1
3389
 * http://jqueryui.com
3390
 *
3391
 * Copyright jQuery Foundation and other contributors
3392
 * Released under the MIT license.
3393
 * http://jquery.org/license
3394
 */
3395
 
3396
//>>label: Highlight Effect
3397
//>>group: Effects
3398
//>>description: Highlights the background of an element in a defined color for a custom duration.
3399
//>>docs: http://api.jqueryui.com/highlight-effect/
3400
//>>demos: http://jqueryui.com/effect/
3401
 
3402
 
3403
 
3404
var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) {
3405
	var element = $( this ),
3406
		animation = {
3407
			backgroundColor: element.css( "backgroundColor" )
3408
		};
3409
 
3410
	if ( options.mode === "hide" ) {
3411
		animation.opacity = 0;
3412
	}
3413
 
3414
	$.effects.saveStyle( element );
3415
 
3416
	element
3417
		.css( {
3418
			backgroundImage: "none",
3419
			backgroundColor: options.color || "#ffff99"
3420
		} )
3421
		.animate( animation, {
3422
			queue: false,
3423
			duration: options.duration,
3424
			easing: options.easing,
3425
			complete: done
3426
		} );
3427
} );
3428
 
3429
 
3430
/*!
3431
 * jQuery UI Effects Size 1.12.1
3432
 * http://jqueryui.com
3433
 *
3434
 * Copyright jQuery Foundation and other contributors
3435
 * Released under the MIT license.
3436
 * http://jquery.org/license
3437
 */
3438
 
3439
//>>label: Size Effect
3440
//>>group: Effects
3441
//>>description: Resize an element to a specified width and height.
3442
//>>docs: http://api.jqueryui.com/size-effect/
3443
//>>demos: http://jqueryui.com/effect/
3444
 
3445
 
3446
 
3447
var effectsEffectSize = $.effects.define( "size", function( options, done ) {
3448
 
3449
	// Create element
3450
	var baseline, factor, temp,
3451
		element = $( this ),
3452
 
3453
		// Copy for children
3454
		cProps = [ "fontSize" ],
3455
		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
3456
		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
3457
 
3458
		// Set options
3459
		mode = options.mode,
3460
		restore = mode !== "effect",
3461
		scale = options.scale || "both",
3462
		origin = options.origin || [ "middle", "center" ],
3463
		position = element.css( "position" ),
3464
		pos = element.position(),
3465
		original = $.effects.scaledDimensions( element ),
3466
		from = options.from || original,
3467
		to = options.to || $.effects.scaledDimensions( element, 0 );
3468
 
3469
	$.effects.createPlaceholder( element );
3470
 
3471
	if ( mode === "show" ) {
3472
		temp = from;
3473
		from = to;
3474
		to = temp;
3475
	}
3476
 
3477
	// Set scaling factor
3478
	factor = {
3479
		from: {
3480
			y: from.height / original.height,
3481
			x: from.width / original.width
3482
		},
3483
		to: {
3484
			y: to.height / original.height,
3485
			x: to.width / original.width
3486
		}
3487
	};
3488
 
3489
	// Scale the css box
3490
	if ( scale === "box" || scale === "both" ) {
3491
 
3492
		// Vertical props scaling
3493
		if ( factor.from.y !== factor.to.y ) {
3494
			from = $.effects.setTransition( element, vProps, factor.from.y, from );
3495
			to = $.effects.setTransition( element, vProps, factor.to.y, to );
3496
		}
3497
 
3498
		// Horizontal props scaling
3499
		if ( factor.from.x !== factor.to.x ) {
3500
			from = $.effects.setTransition( element, hProps, factor.from.x, from );
3501
			to = $.effects.setTransition( element, hProps, factor.to.x, to );
3502
		}
3503
	}
3504
 
3505
	// Scale the content
3506
	if ( scale === "content" || scale === "both" ) {
3507
 
3508
		// Vertical props scaling
3509
		if ( factor.from.y !== factor.to.y ) {
3510
			from = $.effects.setTransition( element, cProps, factor.from.y, from );
3511
			to = $.effects.setTransition( element, cProps, factor.to.y, to );
3512
		}
3513
	}
3514
 
3515
	// Adjust the position properties based on the provided origin points
3516
	if ( origin ) {
3517
		baseline = $.effects.getBaseline( origin, original );
3518
		from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top;
3519
		from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left;
3520
		to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top;
3521
		to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left;
3522
	}
3523
	element.css( from );
3524
 
3525
	// Animate the children if desired
3526
	if ( scale === "content" || scale === "both" ) {
3527
 
3528
		vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps );
3529
		hProps = hProps.concat( [ "marginLeft", "marginRight" ] );
3530
 
3531
		// Only animate children with width attributes specified
3532
		// TODO: is this right? should we include anything with css width specified as well
3533
		element.find( "*[width]" ).each( function() {
3534
			var child = $( this ),
3535
				childOriginal = $.effects.scaledDimensions( child ),
3536
				childFrom = {
3537
					height: childOriginal.height * factor.from.y,
3538
					width: childOriginal.width * factor.from.x,
3539
					outerHeight: childOriginal.outerHeight * factor.from.y,
3540
					outerWidth: childOriginal.outerWidth * factor.from.x
3541
				},
3542
				childTo = {
3543
					height: childOriginal.height * factor.to.y,
3544
					width: childOriginal.width * factor.to.x,
3545
					outerHeight: childOriginal.height * factor.to.y,
3546
					outerWidth: childOriginal.width * factor.to.x
3547
				};
3548
 
3549
			// Vertical props scaling
3550
			if ( factor.from.y !== factor.to.y ) {
3551
				childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom );
3552
				childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo );
3553
			}
3554
 
3555
			// Horizontal props scaling
3556
			if ( factor.from.x !== factor.to.x ) {
3557
				childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom );
3558
				childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo );
3559
			}
3560
 
3561
			if ( restore ) {
3562
				$.effects.saveStyle( child );
3563
			}
3564
 
3565
			// Animate children
3566
			child.css( childFrom );
3567
			child.animate( childTo, options.duration, options.easing, function() {
3568
 
3569
				// Restore children
3570
				if ( restore ) {
3571
					$.effects.restoreStyle( child );
3572
				}
3573
			} );
3574
		} );
3575
	}
3576
 
3577
	// Animate
3578
	element.animate( to, {
3579
		queue: false,
3580
		duration: options.duration,
3581
		easing: options.easing,
3582
		complete: function() {
3583
 
3584
			var offset = element.offset();
3585
 
3586
			if ( to.opacity === 0 ) {
3587
				element.css( "opacity", from.opacity );
3588
			}
3589
 
3590
			if ( !restore ) {
3591
				element
3592
					.css( "position", position === "static" ? "relative" : position )
3593
					.offset( offset );
3594
 
3595
				// Need to save style here so that automatic style restoration
3596
				// doesn't restore to the original styles from before the animation.
3597
				$.effects.saveStyle( element );
3598
			}
3599
 
3600
			done();
3601
		}
3602
	} );
3603
 
3604
} );
3605
 
3606
 
3607
/*!
3608
 * jQuery UI Effects Scale 1.12.1
3609
 * http://jqueryui.com
3610
 *
3611
 * Copyright jQuery Foundation and other contributors
3612
 * Released under the MIT license.
3613
 * http://jquery.org/license
3614
 */
3615
 
3616
//>>label: Scale Effect
3617
//>>group: Effects
3618
//>>description: Grows or shrinks an element and its content.
3619
//>>docs: http://api.jqueryui.com/scale-effect/
3620
//>>demos: http://jqueryui.com/effect/
3621
 
3622
 
3623
 
3624
var effectsEffectScale = $.effects.define( "scale", function( options, done ) {
3625
 
3626
	// Create element
3627
	var el = $( this ),
3628
		mode = options.mode,
3629
		percent = parseInt( options.percent, 10 ) ||
3630
			( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ),
3631
 
3632
		newOptions = $.extend( true, {
3633
			from: $.effects.scaledDimensions( el ),
3634
			to: $.effects.scaledDimensions( el, percent, options.direction || "both" ),
3635
			origin: options.origin || [ "middle", "center" ]
3636
		}, options );
3637
 
3638
	// Fade option to support puff
3639
	if ( options.fade ) {
3640
		newOptions.from.opacity = 1;
3641
		newOptions.to.opacity = 0;
3642
	}
3643
 
3644
	$.effects.effect.size.call( this, newOptions, done );
3645
} );
3646
 
3647
 
3648
/*!
3649
 * jQuery UI Effects Puff 1.12.1
3650
 * http://jqueryui.com
3651
 *
3652
 * Copyright jQuery Foundation and other contributors
3653
 * Released under the MIT license.
3654
 * http://jquery.org/license
3655
 */
3656
 
3657
//>>label: Puff Effect
3658
//>>group: Effects
3659
//>>description: Creates a puff effect by scaling the element up and hiding it at the same time.
3660
//>>docs: http://api.jqueryui.com/puff-effect/
3661
//>>demos: http://jqueryui.com/effect/
3662
 
3663
 
3664
 
3665
var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) {
3666
	var newOptions = $.extend( true, {}, options, {
3667
		fade: true,
3668
		percent: parseInt( options.percent, 10 ) || 150
3669
	} );
3670
 
3671
	$.effects.effect.scale.call( this, newOptions, done );
3672
} );
3673
 
3674
 
3675
/*!
3676
 * jQuery UI Effects Pulsate 1.12.1
3677
 * http://jqueryui.com
3678
 *
3679
 * Copyright jQuery Foundation and other contributors
3680
 * Released under the MIT license.
3681
 * http://jquery.org/license
3682
 */
3683
 
3684
//>>label: Pulsate Effect
3685
//>>group: Effects
3686
//>>description: Pulsates an element n times by changing the opacity to zero and back.
3687
//>>docs: http://api.jqueryui.com/pulsate-effect/
3688
//>>demos: http://jqueryui.com/effect/
3689
 
3690
 
3691
 
3692
var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) {
3693
	var element = $( this ),
3694
		mode = options.mode,
3695
		show = mode === "show",
3696
		hide = mode === "hide",
3697
		showhide = show || hide,
3698
 
3699
		// Showing or hiding leaves off the "last" animation
3700
		anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
3701
		duration = options.duration / anims,
3702
		animateTo = 0,
3703
		i = 1,
3704
		queuelen = element.queue().length;
3705
 
3706
	if ( show || !element.is( ":visible" ) ) {
3707
		element.css( "opacity", 0 ).show();
3708
		animateTo = 1;
3709
	}
3710
 
3711
	// Anims - 1 opacity "toggles"
3712
	for ( ; i < anims; i++ ) {
3713
		element.animate( { opacity: animateTo }, duration, options.easing );
3714
		animateTo = 1 - animateTo;
3715
	}
3716
 
3717
	element.animate( { opacity: animateTo }, duration, options.easing );
3718
 
3719
	element.queue( done );
3720
 
3721
	$.effects.unshift( element, queuelen, anims + 1 );
3722
} );
3723
 
3724
 
3725
/*!
3726
 * jQuery UI Effects Shake 1.12.1
3727
 * http://jqueryui.com
3728
 *
3729
 * Copyright jQuery Foundation and other contributors
3730
 * Released under the MIT license.
3731
 * http://jquery.org/license
3732
 */
3733
 
3734
//>>label: Shake Effect
3735
//>>group: Effects
3736
//>>description: Shakes an element horizontally or vertically n times.
3737
//>>docs: http://api.jqueryui.com/shake-effect/
3738
//>>demos: http://jqueryui.com/effect/
3739
 
3740
 
3741
 
3742
var effectsEffectShake = $.effects.define( "shake", function( options, done ) {
3743
 
3744
	var i = 1,
3745
		element = $( this ),
3746
		direction = options.direction || "left",
3747
		distance = options.distance || 20,
3748
		times = options.times || 3,
3749
		anims = times * 2 + 1,
3750
		speed = Math.round( options.duration / anims ),
3751
		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3752
		positiveMotion = ( direction === "up" || direction === "left" ),
3753
		animation = {},
3754
		animation1 = {},
3755
		animation2 = {},
3756
 
3757
		queuelen = element.queue().length;
3758
 
3759
	$.effects.createPlaceholder( element );
3760
 
3761
	// Animation
3762
	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
3763
	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
3764
	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
3765
 
3766
	// Animate
3767
	element.animate( animation, speed, options.easing );
3768
 
3769
	// Shakes
3770
	for ( ; i < times; i++ ) {
3771
		element
3772
			.animate( animation1, speed, options.easing )
3773
			.animate( animation2, speed, options.easing );
3774
	}
3775
 
3776
	element
3777
		.animate( animation1, speed, options.easing )
3778
		.animate( animation, speed / 2, options.easing )
3779
		.queue( done );
3780
 
3781
	$.effects.unshift( element, queuelen, anims + 1 );
3782
} );
3783
 
3784
 
3785
/*!
3786
 * jQuery UI Effects Slide 1.12.1
3787
 * http://jqueryui.com
3788
 *
3789
 * Copyright jQuery Foundation and other contributors
3790
 * Released under the MIT license.
3791
 * http://jquery.org/license
3792
 */
3793
 
3794
//>>label: Slide Effect
3795
//>>group: Effects
3796
//>>description: Slides an element in and out of the viewport.
3797
//>>docs: http://api.jqueryui.com/slide-effect/
3798
//>>demos: http://jqueryui.com/effect/
3799
 
3800
 
3801
 
3802
var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) {
3803
	var startClip, startRef,
3804
		element = $( this ),
3805
		map = {
3806
			up: [ "bottom", "top" ],
3807
			down: [ "top", "bottom" ],
3808
			left: [ "right", "left" ],
3809
			right: [ "left", "right" ]
3810
		},
3811
		mode = options.mode,
3812
		direction = options.direction || "left",
3813
		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3814
		positiveMotion = ( direction === "up" || direction === "left" ),
3815
		distance = options.distance ||
3816
			element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ),
3817
		animation = {};
3818
 
3819
	$.effects.createPlaceholder( element );
3820
 
3821
	startClip = element.cssClip();
3822
	startRef = element.position()[ ref ];
3823
 
3824
	// Define hide animation
3825
	animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef;
3826
	animation.clip = element.cssClip();
3827
	animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ];
3828
 
3829
	// Reverse the animation if we're showing
3830
	if ( mode === "show" ) {
3831
		element.cssClip( animation.clip );
3832
		element.css( ref, animation[ ref ] );
3833
		animation.clip = startClip;
3834
		animation[ ref ] = startRef;
3835
	}
3836
 
3837
	// Actually animate
3838
	element.animate( animation, {
3839
		queue: false,
3840
		duration: options.duration,
3841
		easing: options.easing,
3842
		complete: done
3843
	} );
3844
} );
3845
 
3846
 
3847
/*!
3848
 * jQuery UI Effects Transfer 1.12.1
3849
 * http://jqueryui.com
3850
 *
3851
 * Copyright jQuery Foundation and other contributors
3852
 * Released under the MIT license.
3853
 * http://jquery.org/license
3854
 */
3855
 
3856
//>>label: Transfer Effect
3857
//>>group: Effects
3858
//>>description: Displays a transfer effect from one element to another.
3859
//>>docs: http://api.jqueryui.com/transfer-effect/
3860
//>>demos: http://jqueryui.com/effect/
3861
 
3862
 
3863
 
3864
var effect;
3865
if ( $.uiBackCompat !== false ) {
3866
	effect = $.effects.define( "transfer", function( options, done ) {
3867
		$( this ).transfer( options, done );
3868
	} );
3869
}
3870
var effectsEffectTransfer = effect;
3871
 
3872
 
3873
/*!
3874
 * jQuery UI Focusable 1.12.1
3875
 * http://jqueryui.com
3876
 *
3877
 * Copyright jQuery Foundation and other contributors
3878
 * Released under the MIT license.
3879
 * http://jquery.org/license
3880
 */
3881
 
3882
//>>label: :focusable Selector
3883
//>>group: Core
3884
//>>description: Selects elements which can be focused.
3885
//>>docs: http://api.jqueryui.com/focusable-selector/
3886
 
3887
 
3888
 
3889
// Selectors
3890
$.ui.focusable = function( element, hasTabindex ) {
3891
	var map, mapName, img, focusableIfVisible, fieldset,
3892
		nodeName = element.nodeName.toLowerCase();
3893
 
3894
	if ( "area" === nodeName ) {
3895
		map = element.parentNode;
3896
		mapName = map.name;
3897
		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
3898
			return false;
3899
		}
3900
		img = $( "img[usemap='#" + mapName + "']" );
3901
		return img.length > 0 && img.is( ":visible" );
3902
	}
3903
 
3904
	if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) {
3905
		focusableIfVisible = !element.disabled;
3906
 
3907
		if ( focusableIfVisible ) {
3908
 
3909
			// Form controls within a disabled fieldset are disabled.
3910
			// However, controls within the fieldset's legend do not get disabled.
3911
			// Since controls generally aren't placed inside legends, we skip
3912
			// this portion of the check.
3913
			fieldset = $( element ).closest( "fieldset" )[ 0 ];
3914
			if ( fieldset ) {
3915
				focusableIfVisible = !fieldset.disabled;
3916
			}
3917
		}
3918
	} else if ( "a" === nodeName ) {
3919
		focusableIfVisible = element.href || hasTabindex;
3920
	} else {
3921
		focusableIfVisible = hasTabindex;
3922
	}
3923
 
3924
	return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) );
3925
};
3926
 
3927
// Support: IE 8 only
3928
// IE 8 doesn't resolve inherit to visible/hidden for computed values
3929
function visible( element ) {
3930
	var visibility = element.css( "visibility" );
3931
	while ( visibility === "inherit" ) {
3932
		element = element.parent();
3933
		visibility = element.css( "visibility" );
3934
	}
3935
	return visibility !== "hidden";
3936
}
3937
 
3938
$.extend( $.expr[ ":" ], {
3939
	focusable: function( element ) {
3940
		return $.ui.focusable( element, $.attr( element, "tabindex" ) != null );
3941
	}
3942
} );
3943
 
3944
var focusable = $.ui.focusable;
3945
 
3946
 
3947
 
3948
 
3949
// Support: IE8 Only
3950
// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop
3951
// with a string, so we need to find the proper form.
3952
var form = $.fn.form = function() {
3953
	return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form );
3954
};
3955
 
3956
 
3957
/*!
3958
 * jQuery UI Form Reset Mixin 1.12.1
3959
 * http://jqueryui.com
3960
 *
3961
 * Copyright jQuery Foundation and other contributors
3962
 * Released under the MIT license.
3963
 * http://jquery.org/license
3964
 */
3965
 
3966
//>>label: Form Reset Mixin
3967
//>>group: Core
3968
//>>description: Refresh input widgets when their form is reset
3969
//>>docs: http://api.jqueryui.com/form-reset-mixin/
3970
 
3971
 
3972
 
3973
var formResetMixin = $.ui.formResetMixin = {
3974
	_formResetHandler: function() {
3975
		var form = $( this );
3976
 
3977
		// Wait for the form reset to actually happen before refreshing
3978
		setTimeout( function() {
3979
			var instances = form.data( "ui-form-reset-instances" );
3980
			$.each( instances, function() {
3981
				this.refresh();
3982
			} );
3983
		} );
3984
	},
3985
 
3986
	_bindFormResetHandler: function() {
3987
		this.form = this.element.form();
3988
		if ( !this.form.length ) {
3989
			return;
3990
		}
3991
 
3992
		var instances = this.form.data( "ui-form-reset-instances" ) || [];
3993
		if ( !instances.length ) {
3994
 
3995
			// We don't use _on() here because we use a single event handler per form
3996
			this.form.on( "reset.ui-form-reset", this._formResetHandler );
3997
		}
3998
		instances.push( this );
3999
		this.form.data( "ui-form-reset-instances", instances );
4000
	},
4001
 
4002
	_unbindFormResetHandler: function() {
4003
		if ( !this.form.length ) {
4004
			return;
4005
		}
4006
 
4007
		var instances = this.form.data( "ui-form-reset-instances" );
4008
		instances.splice( $.inArray( this, instances ), 1 );
4009
		if ( instances.length ) {
4010
			this.form.data( "ui-form-reset-instances", instances );
4011
		} else {
4012
			this.form
4013
				.removeData( "ui-form-reset-instances" )
4014
				.off( "reset.ui-form-reset" );
4015
		}
4016
	}
4017
};
4018
 
4019
 
4020
/*!
4021
 * jQuery UI Support for jQuery core 1.7.x 1.12.1
4022
 * http://jqueryui.com
4023
 *
4024
 * Copyright jQuery Foundation and other contributors
4025
 * Released under the MIT license.
4026
 * http://jquery.org/license
4027
 *
4028
 */
4029
 
4030
//>>label: jQuery 1.7 Support
4031
//>>group: Core
4032
//>>description: Support version 1.7.x of jQuery core
4033
 
4034
 
4035
 
4036
// Support: jQuery 1.7 only
4037
// Not a great way to check versions, but since we only support 1.7+ and only
4038
// need to detect <1.8, this is a simple check that should suffice. Checking
4039
// for "1.7." would be a bit safer, but the version string is 1.7, not 1.7.0
4040
// and we'll never reach 1.70.0 (if we do, we certainly won't be supporting
4041
// 1.7 anymore). See #11197 for why we're not using feature detection.
4042
if ( $.fn.jquery.substring( 0, 3 ) === "1.7" ) {
4043
 
4044
	// Setters for .innerWidth(), .innerHeight(), .outerWidth(), .outerHeight()
4045
	// Unlike jQuery Core 1.8+, these only support numeric values to set the
4046
	// dimensions in pixels
4047
	$.each( [ "Width", "Height" ], function( i, name ) {
4048
		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
4049
			type = name.toLowerCase(),
4050
			orig = {
4051
				innerWidth: $.fn.innerWidth,
4052
				innerHeight: $.fn.innerHeight,
4053
				outerWidth: $.fn.outerWidth,
4054
				outerHeight: $.fn.outerHeight
4055
			};
4056
 
4057
		function reduce( elem, size, border, margin ) {
4058
			$.each( side, function() {
4059
				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
4060
				if ( border ) {
4061
					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
4062
				}
4063
				if ( margin ) {
4064
					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
4065
				}
4066
			} );
4067
			return size;
4068
		}
4069
 
4070
		$.fn[ "inner" + name ] = function( size ) {
4071
			if ( size === undefined ) {
4072
				return orig[ "inner" + name ].call( this );
4073
			}
4074
 
4075
			return this.each( function() {
4076
				$( this ).css( type, reduce( this, size ) + "px" );
4077
			} );
4078
		};
4079
 
4080
		$.fn[ "outer" + name ] = function( size, margin ) {
4081
			if ( typeof size !== "number" ) {
4082
				return orig[ "outer" + name ].call( this, size );
4083
			}
4084
 
4085
			return this.each( function() {
4086
				$( this ).css( type, reduce( this, size, true, margin ) + "px" );
4087
			} );
4088
		};
4089
	} );
4090
 
4091
	$.fn.addBack = function( selector ) {
4092
		return this.add( selector == null ?
4093
			this.prevObject : this.prevObject.filter( selector )
4094
		);
4095
	};
4096
}
4097
 
4098
;
4099
/*!
4100
 * jQuery UI Keycode 1.12.1
4101
 * http://jqueryui.com
4102
 *
4103
 * Copyright jQuery Foundation and other contributors
4104
 * Released under the MIT license.
4105
 * http://jquery.org/license
4106
 */
4107
 
4108
//>>label: Keycode
4109
//>>group: Core
4110
//>>description: Provide keycodes as keynames
4111
//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/
4112
 
4113
 
4114
var keycode = $.ui.keyCode = {
4115
	BACKSPACE: 8,
4116
	COMMA: 188,
4117
	DELETE: 46,
4118
	DOWN: 40,
4119
	END: 35,
4120
	ENTER: 13,
4121
	ESCAPE: 27,
4122
	HOME: 36,
4123
	LEFT: 37,
4124
	PAGE_DOWN: 34,
4125
	PAGE_UP: 33,
4126
	PERIOD: 190,
4127
	RIGHT: 39,
4128
	SPACE: 32,
4129
	TAB: 9,
4130
	UP: 38
4131
};
4132
 
4133
 
4134
 
4135
 
4136
// Internal use only
4137
var escapeSelector = $.ui.escapeSelector = ( function() {
4138
	var selectorEscape = /([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;
4139
	return function( selector ) {
4140
		return selector.replace( selectorEscape, "\\$1" );
4141
	};
4142
} )();
4143
 
4144
 
4145
/*!
4146
 * jQuery UI Labels 1.12.1
4147
 * http://jqueryui.com
4148
 *
4149
 * Copyright jQuery Foundation and other contributors
4150
 * Released under the MIT license.
4151
 * http://jquery.org/license
4152
 */
4153
 
4154
//>>label: labels
4155
//>>group: Core
4156
//>>description: Find all the labels associated with a given input
4157
//>>docs: http://api.jqueryui.com/labels/
4158
 
4159
 
4160
 
4161
var labels = $.fn.labels = function() {
4162
	var ancestor, selector, id, labels, ancestors;
4163
 
4164
	// Check control.labels first
4165
	if ( this[ 0 ].labels && this[ 0 ].labels.length ) {
4166
		return this.pushStack( this[ 0 ].labels );
4167
	}
4168
 
4169
	// Support: IE <= 11, FF <= 37, Android <= 2.3 only
4170
	// Above browsers do not support control.labels. Everything below is to support them
4171
	// as well as document fragments. control.labels does not work on document fragments
4172
	labels = this.eq( 0 ).parents( "label" );
4173
 
4174
	// Look for the label based on the id
4175
	id = this.attr( "id" );
4176
	if ( id ) {
4177
 
4178
		// We don't search against the document in case the element
4179
		// is disconnected from the DOM
4180
		ancestor = this.eq( 0 ).parents().last();
4181
 
4182
		// Get a full set of top level ancestors
4183
		ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() );
4184
 
4185
		// Create a selector for the label based on the id
4186
		selector = "label[for='" + $.ui.escapeSelector( id ) + "']";
4187
 
4188
		labels = labels.add( ancestors.find( selector ).addBack( selector ) );
4189
 
4190
	}
4191
 
4192
	// Return whatever we have found for labels
4193
	return this.pushStack( labels );
4194
};
4195
 
4196
 
4197
/*!
4198
 * jQuery UI Scroll Parent 1.12.1
4199
 * http://jqueryui.com
4200
 *
4201
 * Copyright jQuery Foundation and other contributors
4202
 * Released under the MIT license.
4203
 * http://jquery.org/license
4204
 */
4205
 
4206
//>>label: scrollParent
4207
//>>group: Core
4208
//>>description: Get the closest ancestor element that is scrollable.
4209
//>>docs: http://api.jqueryui.com/scrollParent/
4210
 
4211
 
4212
 
4213
var scrollParent = $.fn.scrollParent = function( includeHidden ) {
4214
	var position = this.css( "position" ),
4215
		excludeStaticParent = position === "absolute",
4216
		overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
4217
		scrollParent = this.parents().filter( function() {
4218
			var parent = $( this );
4219
			if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
4220
				return false;
4221
			}
4222
			return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
4223
				parent.css( "overflow-x" ) );
4224
		} ).eq( 0 );
4225
 
4226
	return position === "fixed" || !scrollParent.length ?
4227
		$( this[ 0 ].ownerDocument || document ) :
4228
		scrollParent;
4229
};
4230
 
4231
 
4232
/*!
4233
 * jQuery UI Tabbable 1.12.1
4234
 * http://jqueryui.com
4235
 *
4236
 * Copyright jQuery Foundation and other contributors
4237
 * Released under the MIT license.
4238
 * http://jquery.org/license
4239
 */
4240
 
4241
//>>label: :tabbable Selector
4242
//>>group: Core
4243
//>>description: Selects elements which can be tabbed to.
4244
//>>docs: http://api.jqueryui.com/tabbable-selector/
4245
 
4246
 
4247
 
4248
var tabbable = $.extend( $.expr[ ":" ], {
4249
	tabbable: function( element ) {
4250
		var tabIndex = $.attr( element, "tabindex" ),
4251
			hasTabindex = tabIndex != null;
4252
		return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex );
4253
	}
4254
} );
4255
 
4256
 
4257
/*!
4258
 * jQuery UI Unique ID 1.12.1
4259
 * http://jqueryui.com
4260
 *
4261
 * Copyright jQuery Foundation and other contributors
4262
 * Released under the MIT license.
4263
 * http://jquery.org/license
4264
 */
4265
 
4266
//>>label: uniqueId
4267
//>>group: Core
4268
//>>description: Functions to generate and remove uniqueId's
4269
//>>docs: http://api.jqueryui.com/uniqueId/
4270
 
4271
 
4272
 
4273
var uniqueId = $.fn.extend( {
4274
	uniqueId: ( function() {
4275
		var uuid = 0;
4276
 
4277
		return function() {
4278
			return this.each( function() {
4279
				if ( !this.id ) {
4280
					this.id = "ui-id-" + ( ++uuid );
4281
				}
4282
			} );
4283
		};
4284
	} )(),
4285
 
4286
	removeUniqueId: function() {
4287
		return this.each( function() {
4288
			if ( /^ui-id-\d+$/.test( this.id ) ) {
4289
				$( this ).removeAttr( "id" );
4290
			}
4291
		} );
4292
	}
4293
} );
4294
 
4295
 
4296
/*!
4297
 * jQuery UI Accordion 1.12.1
4298
 * http://jqueryui.com
4299
 *
4300
 * Copyright jQuery Foundation and other contributors
4301
 * Released under the MIT license.
4302
 * http://jquery.org/license
4303
 */
4304
 
4305
//>>label: Accordion
4306
//>>group: Widgets
4307
// jscs:disable maximumLineLength
4308
//>>description: Displays collapsible content panels for presenting information in a limited amount of space.
4309
// jscs:enable maximumLineLength
4310
//>>docs: http://api.jqueryui.com/accordion/
4311
//>>demos: http://jqueryui.com/accordion/
4312
//>>css.structure: ../../themes/base/core.css
4313
//>>css.structure: ../../themes/base/accordion.css
4314
//>>css.theme: ../../themes/base/theme.css
4315
 
4316
 
4317
 
4318
var widgetsAccordion = $.widget( "ui.accordion", {
4319
	version: "1.12.1",
4320
	options: {
4321
		active: 0,
4322
		animate: {},
4323
		classes: {
4324
			"ui-accordion-header": "ui-corner-top",
4325
			"ui-accordion-header-collapsed": "ui-corner-all",
4326
			"ui-accordion-content": "ui-corner-bottom"
4327
		},
4328
		collapsible: false,
4329
		event: "click",
4330
		header: "> li > :first-child, > :not(li):even",
4331
		heightStyle: "auto",
4332
		icons: {
4333
			activeHeader: "ui-icon-triangle-1-s",
4334
			header: "ui-icon-triangle-1-e"
4335
		},
4336
 
4337
		// Callbacks
4338
		activate: null,
4339
		beforeActivate: null
4340
	},
4341
 
4342
	hideProps: {
4343
		borderTopWidth: "hide",
4344
		borderBottomWidth: "hide",
4345
		paddingTop: "hide",
4346
		paddingBottom: "hide",
4347
		height: "hide"
4348
	},
4349
 
4350
	showProps: {
4351
		borderTopWidth: "show",
4352
		borderBottomWidth: "show",
4353
		paddingTop: "show",
4354
		paddingBottom: "show",
4355
		height: "show"
4356
	},
4357
 
4358
	_create: function() {
4359
		var options = this.options;
4360
 
4361
		this.prevShow = this.prevHide = $();
4362
		this._addClass( "ui-accordion", "ui-widget ui-helper-reset" );
4363
		this.element.attr( "role", "tablist" );
4364
 
4365
		// Don't allow collapsible: false and active: false / null
4366
		if ( !options.collapsible && ( options.active === false || options.active == null ) ) {
4367
			options.active = 0;
4368
		}
4369
 
4370
		this._processPanels();
4371
 
4372
		// handle negative values
4373
		if ( options.active < 0 ) {
4374
			options.active += this.headers.length;
4375
		}
4376
		this._refresh();
4377
	},
4378
 
4379
	_getCreateEventData: function() {
4380
		return {
4381
			header: this.active,
4382
			panel: !this.active.length ? $() : this.active.next()
4383
		};
4384
	},
4385
 
4386
	_createIcons: function() {
4387
		var icon, children,
4388
			icons = this.options.icons;
4389
 
4390
		if ( icons ) {
4391
			icon = $( "<span>" );
4392
			this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header );
4393
			icon.prependTo( this.headers );
4394
			children = this.active.children( ".ui-accordion-header-icon" );
4395
			this._removeClass( children, icons.header )
4396
				._addClass( children, null, icons.activeHeader )
4397
				._addClass( this.headers, "ui-accordion-icons" );
4398
		}
4399
	},
4400
 
4401
	_destroyIcons: function() {
4402
		this._removeClass( this.headers, "ui-accordion-icons" );
4403
		this.headers.children( ".ui-accordion-header-icon" ).remove();
4404
	},
4405
 
4406
	_destroy: function() {
4407
		var contents;
4408
 
4409
		// Clean up main element
4410
		this.element.removeAttr( "role" );
4411
 
4412
		// Clean up headers
4413
		this.headers
4414
			.removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" )
4415
			.removeUniqueId();
4416
 
4417
		this._destroyIcons();
4418
 
4419
		// Clean up content panels
4420
		contents = this.headers.next()
4421
			.css( "display", "" )
4422
			.removeAttr( "role aria-hidden aria-labelledby" )
4423
			.removeUniqueId();
4424
 
4425
		if ( this.options.heightStyle !== "content" ) {
4426
			contents.css( "height", "" );
4427
		}
4428
	},
4429
 
4430
	_setOption: function( key, value ) {
4431
		if ( key === "active" ) {
4432
 
4433
			// _activate() will handle invalid values and update this.options
4434
			this._activate( value );
4435
			return;
4436
		}
4437
 
4438
		if ( key === "event" ) {
4439
			if ( this.options.event ) {
4440
				this._off( this.headers, this.options.event );
4441
			}
4442
			this._setupEvents( value );
4443
		}
4444
 
4445
		this._super( key, value );
4446
 
4447
		// Setting collapsible: false while collapsed; open first panel
4448
		if ( key === "collapsible" && !value && this.options.active === false ) {
4449
			this._activate( 0 );
4450
		}
4451
 
4452
		if ( key === "icons" ) {
4453
			this._destroyIcons();
4454
			if ( value ) {
4455
				this._createIcons();
4456
			}
4457
		}
4458
	},
4459
 
4460
	_setOptionDisabled: function( value ) {
4461
		this._super( value );
4462
 
4463
		this.element.attr( "aria-disabled", value );
4464
 
4465
		// Support: IE8 Only
4466
		// #5332 / #6059 - opacity doesn't cascade to positioned elements in IE
4467
		// so we need to add the disabled class to the headers and panels
4468
		this._toggleClass( null, "ui-state-disabled", !!value );
4469
		this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled",
4470
			!!value );
4471
	},
4472
 
4473
	_keydown: function( event ) {
4474
		if ( event.altKey || event.ctrlKey ) {
4475
			return;
4476
		}
4477
 
4478
		var keyCode = $.ui.keyCode,
4479
			length = this.headers.length,
4480
			currentIndex = this.headers.index( event.target ),
4481
			toFocus = false;
4482
 
4483
		switch ( event.keyCode ) {
4484
		case keyCode.RIGHT:
4485
		case keyCode.DOWN:
4486
			toFocus = this.headers[ ( currentIndex + 1 ) % length ];
4487
			break;
4488
		case keyCode.LEFT:
4489
		case keyCode.UP:
4490
			toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
4491
			break;
4492
		case keyCode.SPACE:
4493
		case keyCode.ENTER:
4494
			this._eventHandler( event );
4495
			break;
4496
		case keyCode.HOME:
4497
			toFocus = this.headers[ 0 ];
4498
			break;
4499
		case keyCode.END:
4500
			toFocus = this.headers[ length - 1 ];
4501
			break;
4502
		}
4503
 
4504
		if ( toFocus ) {
4505
			$( event.target ).attr( "tabIndex", -1 );
4506
			$( toFocus ).attr( "tabIndex", 0 );
4507
			$( toFocus ).trigger( "focus" );
4508
			event.preventDefault();
4509
		}
4510
	},
4511
 
4512
	_panelKeyDown: function( event ) {
4513
		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
4514
			$( event.currentTarget ).prev().trigger( "focus" );
4515
		}
4516
	},
4517
 
4518
	refresh: function() {
4519
		var options = this.options;
4520
		this._processPanels();
4521
 
4522
		// Was collapsed or no panel
4523
		if ( ( options.active === false && options.collapsible === true ) ||
4524
				!this.headers.length ) {
4525
			options.active = false;
4526
			this.active = $();
4527
 
4528
		// active false only when collapsible is true
4529
		} else if ( options.active === false ) {
4530
			this._activate( 0 );
4531
 
4532
		// was active, but active panel is gone
4533
		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
4534
 
4535
			// all remaining panel are disabled
4536
			if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) {
4537
				options.active = false;
4538
				this.active = $();
4539
 
4540
			// activate previous panel
4541
			} else {
4542
				this._activate( Math.max( 0, options.active - 1 ) );
4543
			}
4544
 
4545
		// was active, active panel still exists
4546
		} else {
4547
 
4548
			// make sure active index is correct
4549
			options.active = this.headers.index( this.active );
4550
		}
4551
 
4552
		this._destroyIcons();
4553
 
4554
		this._refresh();
4555
	},
4556
 
4557
	_processPanels: function() {
4558
		var prevHeaders = this.headers,
4559
			prevPanels = this.panels;
4560
 
4561
		this.headers = this.element.find( this.options.header );
4562
		this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed",
4563
			"ui-state-default" );
4564
 
4565
		this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide();
4566
		this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" );
4567
 
4568
		// Avoid memory leaks (#10056)
4569
		if ( prevPanels ) {
4570
			this._off( prevHeaders.not( this.headers ) );
4571
			this._off( prevPanels.not( this.panels ) );
4572
		}
4573
	},
4574
 
4575
	_refresh: function() {
4576
		var maxHeight,
4577
			options = this.options,
4578
			heightStyle = options.heightStyle,
4579
			parent = this.element.parent();
4580
 
4581
		this.active = this._findActive( options.active );
4582
		this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" )
4583
			._removeClass( this.active, "ui-accordion-header-collapsed" );
4584
		this._addClass( this.active.next(), "ui-accordion-content-active" );
4585
		this.active.next().show();
4586
 
4587
		this.headers
4588
			.attr( "role", "tab" )
4589
			.each( function() {
4590
				var header = $( this ),
4591
					headerId = header.uniqueId().attr( "id" ),
4592
					panel = header.next(),
4593
					panelId = panel.uniqueId().attr( "id" );
4594
				header.attr( "aria-controls", panelId );
4595
				panel.attr( "aria-labelledby", headerId );
4596
			} )
4597
			.next()
4598
				.attr( "role", "tabpanel" );
4599
 
4600
		this.headers
4601
			.not( this.active )
4602
				.attr( {
4603
					"aria-selected": "false",
4604
					"aria-expanded": "false",
4605
					tabIndex: -1
4606
				} )
4607
				.next()
4608
					.attr( {
4609
						"aria-hidden": "true"
4610
					} )
4611
					.hide();
4612
 
4613
		// Make sure at least one header is in the tab order
4614
		if ( !this.active.length ) {
4615
			this.headers.eq( 0 ).attr( "tabIndex", 0 );
4616
		} else {
4617
			this.active.attr( {
4618
				"aria-selected": "true",
4619
				"aria-expanded": "true",
4620
				tabIndex: 0
4621
			} )
4622
				.next()
4623
					.attr( {
4624
						"aria-hidden": "false"
4625
					} );
4626
		}
4627
 
4628
		this._createIcons();
4629
 
4630
		this._setupEvents( options.event );
4631
 
4632
		if ( heightStyle === "fill" ) {
4633
			maxHeight = parent.height();
4634
			this.element.siblings( ":visible" ).each( function() {
4635
				var elem = $( this ),
4636
					position = elem.css( "position" );
4637
 
4638
				if ( position === "absolute" || position === "fixed" ) {
4639
					return;
4640
				}
4641
				maxHeight -= elem.outerHeight( true );
4642
			} );
4643
 
4644
			this.headers.each( function() {
4645
				maxHeight -= $( this ).outerHeight( true );
4646
			} );
4647
 
4648
			this.headers.next()
4649
				.each( function() {
4650
					$( this ).height( Math.max( 0, maxHeight -
4651
						$( this ).innerHeight() + $( this ).height() ) );
4652
				} )
4653
				.css( "overflow", "auto" );
4654
		} else if ( heightStyle === "auto" ) {
4655
			maxHeight = 0;
4656
			this.headers.next()
4657
				.each( function() {
4658
					var isVisible = $( this ).is( ":visible" );
4659
					if ( !isVisible ) {
4660
						$( this ).show();
4661
					}
4662
					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
4663
					if ( !isVisible ) {
4664
						$( this ).hide();
4665
					}
4666
				} )
4667
				.height( maxHeight );
4668
		}
4669
	},
4670
 
4671
	_activate: function( index ) {
4672
		var active = this._findActive( index )[ 0 ];
4673
 
4674
		// Trying to activate the already active panel
4675
		if ( active === this.active[ 0 ] ) {
4676
			return;
4677
		}
4678
 
4679
		// Trying to collapse, simulate a click on the currently active header
4680
		active = active || this.active[ 0 ];
4681
 
4682
		this._eventHandler( {
4683
			target: active,
4684
			currentTarget: active,
4685
			preventDefault: $.noop
4686
		} );
4687
	},
4688
 
4689
	_findActive: function( selector ) {
4690
		return typeof selector === "number" ? this.headers.eq( selector ) : $();
4691
	},
4692
 
4693
	_setupEvents: function( event ) {
4694
		var events = {
4695
			keydown: "_keydown"
4696
		};
4697
		if ( event ) {
4698
			$.each( event.split( " " ), function( index, eventName ) {
4699
				events[ eventName ] = "_eventHandler";
4700
			} );
4701
		}
4702
 
4703
		this._off( this.headers.add( this.headers.next() ) );
4704
		this._on( this.headers, events );
4705
		this._on( this.headers.next(), { keydown: "_panelKeyDown" } );
4706
		this._hoverable( this.headers );
4707
		this._focusable( this.headers );
4708
	},
4709
 
4710
	_eventHandler: function( event ) {
4711
		var activeChildren, clickedChildren,
4712
			options = this.options,
4713
			active = this.active,
4714
			clicked = $( event.currentTarget ),
4715
			clickedIsActive = clicked[ 0 ] === active[ 0 ],
4716
			collapsing = clickedIsActive && options.collapsible,
4717
			toShow = collapsing ? $() : clicked.next(),
4718
			toHide = active.next(),
4719
			eventData = {
4720
				oldHeader: active,
4721
				oldPanel: toHide,
4722
				newHeader: collapsing ? $() : clicked,
4723
				newPanel: toShow
4724
			};
4725
 
4726
		event.preventDefault();
4727
 
4728
		if (
4729
 
4730
				// click on active header, but not collapsible
4731
				( clickedIsActive && !options.collapsible ) ||
4732
 
4733
				// allow canceling activation
4734
				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
4735
			return;
4736
		}
4737
 
4738
		options.active = collapsing ? false : this.headers.index( clicked );
4739
 
4740
		// When the call to ._toggle() comes after the class changes
4741
		// it causes a very odd bug in IE 8 (see #6720)
4742
		this.active = clickedIsActive ? $() : clicked;
4743
		this._toggle( eventData );
4744
 
4745
		// Switch classes
4746
		// corner classes on the previously active header stay after the animation
4747
		this._removeClass( active, "ui-accordion-header-active", "ui-state-active" );
4748
		if ( options.icons ) {
4749
			activeChildren = active.children( ".ui-accordion-header-icon" );
4750
			this._removeClass( activeChildren, null, options.icons.activeHeader )
4751
				._addClass( activeChildren, null, options.icons.header );
4752
		}
4753
 
4754
		if ( !clickedIsActive ) {
4755
			this._removeClass( clicked, "ui-accordion-header-collapsed" )
4756
				._addClass( clicked, "ui-accordion-header-active", "ui-state-active" );
4757
			if ( options.icons ) {
4758
				clickedChildren = clicked.children( ".ui-accordion-header-icon" );
4759
				this._removeClass( clickedChildren, null, options.icons.header )
4760
					._addClass( clickedChildren, null, options.icons.activeHeader );
4761
			}
4762
 
4763
			this._addClass( clicked.next(), "ui-accordion-content-active" );
4764
		}
4765
	},
4766
 
4767
	_toggle: function( data ) {
4768
		var toShow = data.newPanel,
4769
			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
4770
 
4771
		// Handle activating a panel during the animation for another activation
4772
		this.prevShow.add( this.prevHide ).stop( true, true );
4773
		this.prevShow = toShow;
4774
		this.prevHide = toHide;
4775
 
4776
		if ( this.options.animate ) {
4777
			this._animate( toShow, toHide, data );
4778
		} else {
4779
			toHide.hide();
4780
			toShow.show();
4781
			this._toggleComplete( data );
4782
		}
4783
 
4784
		toHide.attr( {
4785
			"aria-hidden": "true"
4786
		} );
4787
		toHide.prev().attr( {
4788
			"aria-selected": "false",
4789
			"aria-expanded": "false"
4790
		} );
4791
 
4792
		// if we're switching panels, remove the old header from the tab order
4793
		// if we're opening from collapsed state, remove the previous header from the tab order
4794
		// if we're collapsing, then keep the collapsing header in the tab order
4795
		if ( toShow.length && toHide.length ) {
4796
			toHide.prev().attr( {
4797
				"tabIndex": -1,
4798
				"aria-expanded": "false"
4799
			} );
4800
		} else if ( toShow.length ) {
4801
			this.headers.filter( function() {
4802
				return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
4803
			} )
4804
				.attr( "tabIndex", -1 );
4805
		}
4806
 
4807
		toShow
4808
			.attr( "aria-hidden", "false" )
4809
			.prev()
4810
				.attr( {
4811
					"aria-selected": "true",
4812
					"aria-expanded": "true",
4813
					tabIndex: 0
4814
				} );
4815
	},
4816
 
4817
	_animate: function( toShow, toHide, data ) {
4818
		var total, easing, duration,
4819
			that = this,
4820
			adjust = 0,
4821
			boxSizing = toShow.css( "box-sizing" ),
4822
			down = toShow.length &&
4823
				( !toHide.length || ( toShow.index() < toHide.index() ) ),
4824
			animate = this.options.animate || {},
4825
			options = down && animate.down || animate,
4826
			complete = function() {
4827
				that._toggleComplete( data );
4828
			};
4829
 
4830
		if ( typeof options === "number" ) {
4831
			duration = options;
4832
		}
4833
		if ( typeof options === "string" ) {
4834
			easing = options;
4835
		}
4836
 
4837
		// fall back from options to animation in case of partial down settings
4838
		easing = easing || options.easing || animate.easing;
4839
		duration = duration || options.duration || animate.duration;
4840
 
4841
		if ( !toHide.length ) {
4842
			return toShow.animate( this.showProps, duration, easing, complete );
4843
		}
4844
		if ( !toShow.length ) {
4845
			return toHide.animate( this.hideProps, duration, easing, complete );
4846
		}
4847
 
4848
		total = toShow.show().outerHeight();
4849
		toHide.animate( this.hideProps, {
4850
			duration: duration,
4851
			easing: easing,
4852
			step: function( now, fx ) {
4853
				fx.now = Math.round( now );
4854
			}
4855
		} );
4856
		toShow
4857
			.hide()
4858
			.animate( this.showProps, {
4859
				duration: duration,
4860
				easing: easing,
4861
				complete: complete,
4862
				step: function( now, fx ) {
4863
					fx.now = Math.round( now );
4864
					if ( fx.prop !== "height" ) {
4865
						if ( boxSizing === "content-box" ) {
4866
							adjust += fx.now;
4867
						}
4868
					} else if ( that.options.heightStyle !== "content" ) {
4869
						fx.now = Math.round( total - toHide.outerHeight() - adjust );
4870
						adjust = 0;
4871
					}
4872
				}
4873
			} );
4874
	},
4875
 
4876
	_toggleComplete: function( data ) {
4877
		var toHide = data.oldPanel,
4878
			prev = toHide.prev();
4879
 
4880
		this._removeClass( toHide, "ui-accordion-content-active" );
4881
		this._removeClass( prev, "ui-accordion-header-active" )
4882
			._addClass( prev, "ui-accordion-header-collapsed" );
4883
 
4884
		// Work around for rendering bug in IE (#5421)
4885
		if ( toHide.length ) {
4886
			toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
4887
		}
4888
		this._trigger( "activate", null, data );
4889
	}
4890
} );
4891
 
4892
 
4893
 
4894
var safeActiveElement = $.ui.safeActiveElement = function( document ) {
4895
	var activeElement;
4896
 
4897
	// Support: IE 9 only
4898
	// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
4899
	try {
4900
		activeElement = document.activeElement;
4901
	} catch ( error ) {
4902
		activeElement = document.body;
4903
	}
4904
 
4905
	// Support: IE 9 - 11 only
4906
	// IE may return null instead of an element
4907
	// Interestingly, this only seems to occur when NOT in an iframe
4908
	if ( !activeElement ) {
4909
		activeElement = document.body;
4910
	}
4911
 
4912
	// Support: IE 11 only
4913
	// IE11 returns a seemingly empty object in some cases when accessing
4914
	// document.activeElement from an <iframe>
4915
	if ( !activeElement.nodeName ) {
4916
		activeElement = document.body;
4917
	}
4918
 
4919
	return activeElement;
4920
};
4921
 
4922
 
4923
/*!
4924
 * jQuery UI Menu 1.12.1
4925
 * http://jqueryui.com
4926
 *
4927
 * Copyright jQuery Foundation and other contributors
4928
 * Released under the MIT license.
4929
 * http://jquery.org/license
4930
 */
4931
 
4932
//>>label: Menu
4933
//>>group: Widgets
4934
//>>description: Creates nestable menus.
4935
//>>docs: http://api.jqueryui.com/menu/
4936
//>>demos: http://jqueryui.com/menu/
4937
//>>css.structure: ../../themes/base/core.css
4938
//>>css.structure: ../../themes/base/menu.css
4939
//>>css.theme: ../../themes/base/theme.css
4940
 
4941
 
4942
 
4943
var widgetsMenu = $.widget( "ui.menu", {
4944
	version: "1.12.1",
4945
	defaultElement: "<ul>",
4946
	delay: 300,
4947
	options: {
4948
		icons: {
4949
			submenu: "ui-icon-caret-1-e"
4950
		},
4951
		items: "> *",
4952
		menus: "ul",
4953
		position: {
4954
			my: "left top",
4955
			at: "right top"
4956
		},
4957
		role: "menu",
4958
 
4959
		// Callbacks
4960
		blur: null,
4961
		focus: null,
4962
		select: null
4963
	},
4964
 
4965
	_create: function() {
4966
		this.activeMenu = this.element;
4967
 
4968
		// Flag used to prevent firing of the click handler
4969
		// as the event bubbles up through nested menus
4970
		this.mouseHandled = false;
4971
		this.element
4972
			.uniqueId()
4973
			.attr( {
4974
				role: this.options.role,
4975
				tabIndex: 0
4976
			} );
4977
 
4978
		this._addClass( "ui-menu", "ui-widget ui-widget-content" );
4979
		this._on( {
4980
 
4981
			// Prevent focus from sticking to links inside menu after clicking
4982
			// them (focus should always stay on UL during navigation).
4983
			"mousedown .ui-menu-item": function( event ) {
4984
				event.preventDefault();
4985
			},
4986
			"click .ui-menu-item": function( event ) {
4987
				var target = $( event.target );
4988
				var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
4989
				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
4990
					this.select( event );
4991
 
4992
					// Only set the mouseHandled flag if the event will bubble, see #9469.
4993
					if ( !event.isPropagationStopped() ) {
4994
						this.mouseHandled = true;
4995
					}
4996
 
4997
					// Open submenu on click
4998
					if ( target.has( ".ui-menu" ).length ) {
4999
						this.expand( event );
5000
					} else if ( !this.element.is( ":focus" ) &&
5001
							active.closest( ".ui-menu" ).length ) {
5002
 
5003
						// Redirect focus to the menu
5004
						this.element.trigger( "focus", [ true ] );
5005
 
5006
						// If the active item is on the top level, let it stay active.
5007
						// Otherwise, blur the active item since it is no longer visible.
5008
						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
5009
							clearTimeout( this.timer );
5010
						}
5011
					}
5012
				}
5013
			},
5014
			"mouseenter .ui-menu-item": function( event ) {
5015
 
5016
				// Ignore mouse events while typeahead is active, see #10458.
5017
				// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
5018
				// is over an item in the menu
5019
				if ( this.previousFilter ) {
5020
					return;
5021
				}
5022
 
5023
				var actualTarget = $( event.target ).closest( ".ui-menu-item" ),
5024
					target = $( event.currentTarget );
5025
 
5026
				// Ignore bubbled events on parent items, see #11641
5027
				if ( actualTarget[ 0 ] !== target[ 0 ] ) {
5028
					return;
5029
				}
5030
 
5031
				// Remove ui-state-active class from siblings of the newly focused menu item
5032
				// to avoid a jump caused by adjacent elements both having a class with a border
5033
				this._removeClass( target.siblings().children( ".ui-state-active" ),
5034
					null, "ui-state-active" );
5035
				this.focus( event, target );
5036
			},
5037
			mouseleave: "collapseAll",
5038
			"mouseleave .ui-menu": "collapseAll",
5039
			focus: function( event, keepActiveItem ) {
5040
 
5041
				// If there's already an active item, keep it active
5042
				// If not, activate the first item
5043
				var item = this.active || this.element.find( this.options.items ).eq( 0 );
5044
 
5045
				if ( !keepActiveItem ) {
5046
					this.focus( event, item );
5047
				}
5048
			},
5049
			blur: function( event ) {
5050
				this._delay( function() {
5051
					var notContained = !$.contains(
5052
						this.element[ 0 ],
5053
						$.ui.safeActiveElement( this.document[ 0 ] )
5054
					);
5055
					if ( notContained ) {
5056
						this.collapseAll( event );
5057
					}
5058
				} );
5059
			},
5060
			keydown: "_keydown"
5061
		} );
5062
 
5063
		this.refresh();
5064
 
5065
		// Clicks outside of a menu collapse any open menus
5066
		this._on( this.document, {
5067
			click: function( event ) {
5068
				if ( this._closeOnDocumentClick( event ) ) {
5069
					this.collapseAll( event );
5070
				}
5071
 
5072
				// Reset the mouseHandled flag
5073
				this.mouseHandled = false;
5074
			}
5075
		} );
5076
	},
5077
 
5078
	_destroy: function() {
5079
		var items = this.element.find( ".ui-menu-item" )
5080
				.removeAttr( "role aria-disabled" ),
5081
			submenus = items.children( ".ui-menu-item-wrapper" )
5082
				.removeUniqueId()
5083
				.removeAttr( "tabIndex role aria-haspopup" );
5084
 
5085
		// Destroy (sub)menus
5086
		this.element
5087
			.removeAttr( "aria-activedescendant" )
5088
			.find( ".ui-menu" ).addBack()
5089
				.removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " +
5090
					"tabIndex" )
5091
				.removeUniqueId()
5092
				.show();
5093
 
5094
		submenus.children().each( function() {
5095
			var elem = $( this );
5096
			if ( elem.data( "ui-menu-submenu-caret" ) ) {
5097
				elem.remove();
5098
			}
5099
		} );
5100
	},
5101
 
5102
	_keydown: function( event ) {
5103
		var match, prev, character, skip,
5104
			preventDefault = true;
5105
 
5106
		switch ( event.keyCode ) {
5107
		case $.ui.keyCode.PAGE_UP:
5108
			this.previousPage( event );
5109
			break;
5110
		case $.ui.keyCode.PAGE_DOWN:
5111
			this.nextPage( event );
5112
			break;
5113
		case $.ui.keyCode.HOME:
5114
			this._move( "first", "first", event );
5115
			break;
5116
		case $.ui.keyCode.END:
5117
			this._move( "last", "last", event );
5118
			break;
5119
		case $.ui.keyCode.UP:
5120
			this.previous( event );
5121
			break;
5122
		case $.ui.keyCode.DOWN:
5123
			this.next( event );
5124
			break;
5125
		case $.ui.keyCode.LEFT:
5126
			this.collapse( event );
5127
			break;
5128
		case $.ui.keyCode.RIGHT:
5129
			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
5130
				this.expand( event );
5131
			}
5132
			break;
5133
		case $.ui.keyCode.ENTER:
5134
		case $.ui.keyCode.SPACE:
5135
			this._activate( event );
5136
			break;
5137
		case $.ui.keyCode.ESCAPE:
5138
			this.collapse( event );
5139
			break;
5140
		default:
5141
			preventDefault = false;
5142
			prev = this.previousFilter || "";
5143
			skip = false;
5144
 
5145
			// Support number pad values
5146
			character = event.keyCode >= 96 && event.keyCode <= 105 ?
5147
				( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode );
5148
 
5149
			clearTimeout( this.filterTimer );
5150
 
5151
			if ( character === prev ) {
5152
				skip = true;
5153
			} else {
5154
				character = prev + character;
5155
			}
5156
 
5157
			match = this._filterMenuItems( character );
5158
			match = skip && match.index( this.active.next() ) !== -1 ?
5159
				this.active.nextAll( ".ui-menu-item" ) :
5160
				match;
5161
 
5162
			// If no matches on the current filter, reset to the last character pressed
5163
			// to move down the menu to the first item that starts with that character
5164
			if ( !match.length ) {
5165
				character = String.fromCharCode( event.keyCode );
5166
				match = this._filterMenuItems( character );
5167
			}
5168
 
5169
			if ( match.length ) {
5170
				this.focus( event, match );
5171
				this.previousFilter = character;
5172
				this.filterTimer = this._delay( function() {
5173
					delete this.previousFilter;
5174
				}, 1000 );
5175
			} else {
5176
				delete this.previousFilter;
5177
			}
5178
		}
5179
 
5180
		if ( preventDefault ) {
5181
			event.preventDefault();
5182
		}
5183
	},
5184
 
5185
	_activate: function( event ) {
5186
		if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
5187
			if ( this.active.children( "[aria-haspopup='true']" ).length ) {
5188
				this.expand( event );
5189
			} else {
5190
				this.select( event );
5191
			}
5192
		}
5193
	},
5194
 
5195
	refresh: function() {
5196
		var menus, items, newSubmenus, newItems, newWrappers,
5197
			that = this,
5198
			icon = this.options.icons.submenu,
5199
			submenus = this.element.find( this.options.menus );
5200
 
5201
		this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length );
5202
 
5203
		// Initialize nested menus
5204
		newSubmenus = submenus.filter( ":not(.ui-menu)" )
5205
			.hide()
5206
			.attr( {
5207
				role: this.options.role,
5208
				"aria-hidden": "true",
5209
				"aria-expanded": "false"
5210
			} )
5211
			.each( function() {
5212
				var menu = $( this ),
5213
					item = menu.prev(),
5214
					submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true );
5215
 
5216
				that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon );
5217
				item
5218
					.attr( "aria-haspopup", "true" )
5219
					.prepend( submenuCaret );
5220
				menu.attr( "aria-labelledby", item.attr( "id" ) );
5221
			} );
5222
 
5223
		this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" );
5224
 
5225
		menus = submenus.add( this.element );
5226
		items = menus.find( this.options.items );
5227
 
5228
		// Initialize menu-items containing spaces and/or dashes only as dividers
5229
		items.not( ".ui-menu-item" ).each( function() {
5230
			var item = $( this );
5231
			if ( that._isDivider( item ) ) {
5232
				that._addClass( item, "ui-menu-divider", "ui-widget-content" );
5233
			}
5234
		} );
5235
 
5236
		// Don't refresh list items that are already adapted
5237
		newItems = items.not( ".ui-menu-item, .ui-menu-divider" );
5238
		newWrappers = newItems.children()
5239
			.not( ".ui-menu" )
5240
				.uniqueId()
5241
				.attr( {
5242
					tabIndex: -1,
5243
					role: this._itemRole()
5244
				} );
5245
		this._addClass( newItems, "ui-menu-item" )
5246
			._addClass( newWrappers, "ui-menu-item-wrapper" );
5247
 
5248
		// Add aria-disabled attribute to any disabled menu item
5249
		items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
5250
 
5251
		// If the active item has been removed, blur the menu
5252
		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
5253
			this.blur();
5254
		}
5255
	},
5256
 
5257
	_itemRole: function() {
5258
		return {
5259
			menu: "menuitem",
5260
			listbox: "option"
5261
		}[ this.options.role ];
5262
	},
5263
 
5264
	_setOption: function( key, value ) {
5265
		if ( key === "icons" ) {
5266
			var icons = this.element.find( ".ui-menu-icon" );
5267
			this._removeClass( icons, null, this.options.icons.submenu )
5268
				._addClass( icons, null, value.submenu );
5269
		}
5270
		this._super( key, value );
5271
	},
5272
 
5273
	_setOptionDisabled: function( value ) {
5274
		this._super( value );
5275
 
5276
		this.element.attr( "aria-disabled", String( value ) );
5277
		this._toggleClass( null, "ui-state-disabled", !!value );
5278
	},
5279
 
5280
	focus: function( event, item ) {
5281
		var nested, focused, activeParent;
5282
		this.blur( event, event && event.type === "focus" );
5283
 
5284
		this._scrollIntoView( item );
5285
 
5286
		this.active = item.first();
5287
 
5288
		focused = this.active.children( ".ui-menu-item-wrapper" );
5289
		this._addClass( focused, null, "ui-state-active" );
5290
 
5291
		// Only update aria-activedescendant if there's a role
5292
		// otherwise we assume focus is managed elsewhere
5293
		if ( this.options.role ) {
5294
			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
5295
		}
5296
 
5297
		// Highlight active parent menu item, if any
5298
		activeParent = this.active
5299
			.parent()
5300
				.closest( ".ui-menu-item" )
5301
					.children( ".ui-menu-item-wrapper" );
5302
		this._addClass( activeParent, null, "ui-state-active" );
5303
 
5304
		if ( event && event.type === "keydown" ) {
5305
			this._close();
5306
		} else {
5307
			this.timer = this._delay( function() {
5308
				this._close();
5309
			}, this.delay );
5310
		}
5311
 
5312
		nested = item.children( ".ui-menu" );
5313
		if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
5314
			this._startOpening( nested );
5315
		}
5316
		this.activeMenu = item.parent();
5317
 
5318
		this._trigger( "focus", event, { item: item } );
5319
	},
5320
 
5321
	_scrollIntoView: function( item ) {
5322
		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
5323
		if ( this._hasScroll() ) {
5324
			borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0;
5325
			paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0;
5326
			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
5327
			scroll = this.activeMenu.scrollTop();
5328
			elementHeight = this.activeMenu.height();
5329
			itemHeight = item.outerHeight();
5330
 
5331
			if ( offset < 0 ) {
5332
				this.activeMenu.scrollTop( scroll + offset );
5333
			} else if ( offset + itemHeight > elementHeight ) {
5334
				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
5335
			}
5336
		}
5337
	},
5338
 
5339
	blur: function( event, fromFocus ) {
5340
		if ( !fromFocus ) {
5341
			clearTimeout( this.timer );
5342
		}
5343
 
5344
		if ( !this.active ) {
5345
			return;
5346
		}
5347
 
5348
		this._removeClass( this.active.children( ".ui-menu-item-wrapper" ),
5349
			null, "ui-state-active" );
5350
 
5351
		this._trigger( "blur", event, { item: this.active } );
5352
		this.active = null;
5353
	},
5354
 
5355
	_startOpening: function( submenu ) {
5356
		clearTimeout( this.timer );
5357
 
5358
		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
5359
		// shift in the submenu position when mousing over the caret icon
5360
		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
5361
			return;
5362
		}
5363
 
5364
		this.timer = this._delay( function() {
5365
			this._close();
5366
			this._open( submenu );
5367
		}, this.delay );
5368
	},
5369
 
5370
	_open: function( submenu ) {
5371
		var position = $.extend( {
5372
			of: this.active
5373
		}, this.options.position );
5374
 
5375
		clearTimeout( this.timer );
5376
		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
5377
			.hide()
5378
			.attr( "aria-hidden", "true" );
5379
 
5380
		submenu
5381
			.show()
5382
			.removeAttr( "aria-hidden" )
5383
			.attr( "aria-expanded", "true" )
5384
			.position( position );
5385
	},
5386
 
5387
	collapseAll: function( event, all ) {
5388
		clearTimeout( this.timer );
5389
		this.timer = this._delay( function() {
5390
 
5391
			// If we were passed an event, look for the submenu that contains the event
5392
			var currentMenu = all ? this.element :
5393
				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
5394
 
5395
			// If we found no valid submenu ancestor, use the main menu to close all
5396
			// sub menus anyway
5397
			if ( !currentMenu.length ) {
5398
				currentMenu = this.element;
5399
			}
5400
 
5401
			this._close( currentMenu );
5402
 
5403
			this.blur( event );
5404
 
5405
			// Work around active item staying active after menu is blurred
5406
			this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" );
5407
 
5408
			this.activeMenu = currentMenu;
5409
		}, this.delay );
5410
	},
5411
 
5412
	// With no arguments, closes the currently active menu - if nothing is active
5413
	// it closes all menus.  If passed an argument, it will search for menus BELOW
5414
	_close: function( startMenu ) {
5415
		if ( !startMenu ) {
5416
			startMenu = this.active ? this.active.parent() : this.element;
5417
		}
5418
 
5419
		startMenu.find( ".ui-menu" )
5420
			.hide()
5421
			.attr( "aria-hidden", "true" )
5422
			.attr( "aria-expanded", "false" );
5423
	},
5424
 
5425
	_closeOnDocumentClick: function( event ) {
5426
		return !$( event.target ).closest( ".ui-menu" ).length;
5427
	},
5428
 
5429
	_isDivider: function( item ) {
5430
 
5431
		// Match hyphen, em dash, en dash
5432
		return !/[^\-\u2014\u2013\s]/.test( item.text() );
5433
	},
5434
 
5435
	collapse: function( event ) {
5436
		var newItem = this.active &&
5437
			this.active.parent().closest( ".ui-menu-item", this.element );
5438
		if ( newItem && newItem.length ) {
5439
			this._close();
5440
			this.focus( event, newItem );
5441
		}
5442
	},
5443
 
5444
	expand: function( event ) {
5445
		var newItem = this.active &&
5446
			this.active
5447
				.children( ".ui-menu " )
5448
					.find( this.options.items )
5449
						.first();
5450
 
5451
		if ( newItem && newItem.length ) {
5452
			this._open( newItem.parent() );
5453
 
5454
			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
5455
			this._delay( function() {
5456
				this.focus( event, newItem );
5457
			} );
5458
		}
5459
	},
5460
 
5461
	next: function( event ) {
5462
		this._move( "next", "first", event );
5463
	},
5464
 
5465
	previous: function( event ) {
5466
		this._move( "prev", "last", event );
5467
	},
5468
 
5469
	isFirstItem: function() {
5470
		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
5471
	},
5472
 
5473
	isLastItem: function() {
5474
		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
5475
	},
5476
 
5477
	_move: function( direction, filter, event ) {
5478
		var next;
5479
		if ( this.active ) {
5480
			if ( direction === "first" || direction === "last" ) {
5481
				next = this.active
5482
					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
5483
					.eq( -1 );
5484
			} else {
5485
				next = this.active
5486
					[ direction + "All" ]( ".ui-menu-item" )
5487
					.eq( 0 );
5488
			}
5489
		}
5490
		if ( !next || !next.length || !this.active ) {
5491
			next = this.activeMenu.find( this.options.items )[ filter ]();
5492
		}
5493
 
5494
		this.focus( event, next );
5495
	},
5496
 
5497
	nextPage: function( event ) {
5498
		var item, base, height;
5499
 
5500
		if ( !this.active ) {
5501
			this.next( event );
5502
			return;
5503
		}
5504
		if ( this.isLastItem() ) {
5505
			return;
5506
		}
5507
		if ( this._hasScroll() ) {
5508
			base = this.active.offset().top;
5509
			height = this.element.height();
5510
			this.active.nextAll( ".ui-menu-item" ).each( function() {
5511
				item = $( this );
5512
				return item.offset().top - base - height < 0;
5513
			} );
5514
 
5515
			this.focus( event, item );
5516
		} else {
5517
			this.focus( event, this.activeMenu.find( this.options.items )
5518
				[ !this.active ? "first" : "last" ]() );
5519
		}
5520
	},
5521
 
5522
	previousPage: function( event ) {
5523
		var item, base, height;
5524
		if ( !this.active ) {
5525
			this.next( event );
5526
			return;
5527
		}
5528
		if ( this.isFirstItem() ) {
5529
			return;
5530
		}
5531
		if ( this._hasScroll() ) {
5532
			base = this.active.offset().top;
5533
			height = this.element.height();
5534
			this.active.prevAll( ".ui-menu-item" ).each( function() {
5535
				item = $( this );
5536
				return item.offset().top - base + height > 0;
5537
			} );
5538
 
5539
			this.focus( event, item );
5540
		} else {
5541
			this.focus( event, this.activeMenu.find( this.options.items ).first() );
5542
		}
5543
	},
5544
 
5545
	_hasScroll: function() {
5546
		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
5547
	},
5548
 
5549
	select: function( event ) {
5550
 
5551
		// TODO: It should never be possible to not have an active item at this
5552
		// point, but the tests don't trigger mouseenter before click.
5553
		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
5554
		var ui = { item: this.active };
5555
		if ( !this.active.has( ".ui-menu" ).length ) {
5556
			this.collapseAll( event, true );
5557
		}
5558
		this._trigger( "select", event, ui );
5559
	},
5560
 
5561
	_filterMenuItems: function( character ) {
5562
		var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
5563
			regex = new RegExp( "^" + escapedCharacter, "i" );
5564
 
5565
		return this.activeMenu
5566
			.find( this.options.items )
5567
 
5568
				// Only match on items, not dividers or other content (#10571)
5569
				.filter( ".ui-menu-item" )
5570
					.filter( function() {
5571
						return regex.test(
5572
							$.trim( $( this ).children( ".ui-menu-item-wrapper" ).text() ) );
5573
					} );
5574
	}
5575
} );
5576
 
5577
 
5578
/*!
5579
 * jQuery UI Autocomplete 1.12.1
5580
 * http://jqueryui.com
5581
 *
5582
 * Copyright jQuery Foundation and other contributors
5583
 * Released under the MIT license.
5584
 * http://jquery.org/license
5585
 */
5586
 
5587
//>>label: Autocomplete
5588
//>>group: Widgets
5589
//>>description: Lists suggested words as the user is typing.
5590
//>>docs: http://api.jqueryui.com/autocomplete/
5591
//>>demos: http://jqueryui.com/autocomplete/
5592
//>>css.structure: ../../themes/base/core.css
5593
//>>css.structure: ../../themes/base/autocomplete.css
5594
//>>css.theme: ../../themes/base/theme.css
5595
 
5596
 
5597
 
5598
$.widget( "ui.autocomplete", {
5599
	version: "1.12.1",
5600
	defaultElement: "<input>",
5601
	options: {
5602
		appendTo: null,
5603
		autoFocus: false,
5604
		delay: 300,
5605
		minLength: 1,
5606
		position: {
5607
			my: "left top",
5608
			at: "left bottom",
5609
			collision: "none"
5610
		},
5611
		source: null,
5612
 
5613
		// Callbacks
5614
		change: null,
5615
		close: null,
5616
		focus: null,
5617
		open: null,
5618
		response: null,
5619
		search: null,
5620
		select: null
5621
	},
5622
 
5623
	requestIndex: 0,
5624
	pending: 0,
5625
 
5626
	_create: function() {
5627
 
5628
		// Some browsers only repeat keydown events, not keypress events,
5629
		// so we use the suppressKeyPress flag to determine if we've already
5630
		// handled the keydown event. #7269
5631
		// Unfortunately the code for & in keypress is the same as the up arrow,
5632
		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
5633
		// events when we know the keydown event was used to modify the
5634
		// search term. #7799
5635
		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
5636
			nodeName = this.element[ 0 ].nodeName.toLowerCase(),
5637
			isTextarea = nodeName === "textarea",
5638
			isInput = nodeName === "input";
5639
 
5640
		// Textareas are always multi-line
5641
		// Inputs are always single-line, even if inside a contentEditable element
5642
		// IE also treats inputs as contentEditable
5643
		// All other element types are determined by whether or not they're contentEditable
5644
		this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element );
5645
 
5646
		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
5647
		this.isNewMenu = true;
5648
 
5649
		this._addClass( "ui-autocomplete-input" );
5650
		this.element.attr( "autocomplete", "off" );
5651
 
5652
		this._on( this.element, {
5653
			keydown: function( event ) {
5654
				if ( this.element.prop( "readOnly" ) ) {
5655
					suppressKeyPress = true;
5656
					suppressInput = true;
5657
					suppressKeyPressRepeat = true;
5658
					return;
5659
				}
5660
 
5661
				suppressKeyPress = false;
5662
				suppressInput = false;
5663
				suppressKeyPressRepeat = false;
5664
				var keyCode = $.ui.keyCode;
5665
				switch ( event.keyCode ) {
5666
				case keyCode.PAGE_UP:
5667
					suppressKeyPress = true;
5668
					this._move( "previousPage", event );
5669
					break;
5670
				case keyCode.PAGE_DOWN:
5671
					suppressKeyPress = true;
5672
					this._move( "nextPage", event );
5673
					break;
5674
				case keyCode.UP:
5675
					suppressKeyPress = true;
5676
					this._keyEvent( "previous", event );
5677
					break;
5678
				case keyCode.DOWN:
5679
					suppressKeyPress = true;
5680
					this._keyEvent( "next", event );
5681
					break;
5682
				case keyCode.ENTER:
5683
 
5684
					// when menu is open and has focus
5685
					if ( this.menu.active ) {
5686
 
5687
						// #6055 - Opera still allows the keypress to occur
5688
						// which causes forms to submit
5689
						suppressKeyPress = true;
5690
						event.preventDefault();
5691
						this.menu.select( event );
5692
					}
5693
					break;
5694
				case keyCode.TAB:
5695
					if ( this.menu.active ) {
5696
						this.menu.select( event );
5697
					}
5698
					break;
5699
				case keyCode.ESCAPE:
5700
					if ( this.menu.element.is( ":visible" ) ) {
5701
						if ( !this.isMultiLine ) {
5702
							this._value( this.term );
5703
						}
5704
						this.close( event );
5705
 
5706
						// Different browsers have different default behavior for escape
5707
						// Single press can mean undo or clear
5708
						// Double press in IE means clear the whole form
5709
						event.preventDefault();
5710
					}
5711
					break;
5712
				default:
5713
					suppressKeyPressRepeat = true;
5714
 
5715
					// search timeout should be triggered before the input value is changed
5716
					this._searchTimeout( event );
5717
					break;
5718
				}
5719
			},
5720
			keypress: function( event ) {
5721
				if ( suppressKeyPress ) {
5722
					suppressKeyPress = false;
5723
					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
5724
						event.preventDefault();
5725
					}
5726
					return;
5727
				}
5728
				if ( suppressKeyPressRepeat ) {
5729
					return;
5730
				}
5731
 
5732
				// Replicate some key handlers to allow them to repeat in Firefox and Opera
5733
				var keyCode = $.ui.keyCode;
5734
				switch ( event.keyCode ) {
5735
				case keyCode.PAGE_UP:
5736
					this._move( "previousPage", event );
5737
					break;
5738
				case keyCode.PAGE_DOWN:
5739
					this._move( "nextPage", event );
5740
					break;
5741
				case keyCode.UP:
5742
					this._keyEvent( "previous", event );
5743
					break;
5744
				case keyCode.DOWN:
5745
					this._keyEvent( "next", event );
5746
					break;
5747
				}
5748
			},
5749
			input: function( event ) {
5750
				if ( suppressInput ) {
5751
					suppressInput = false;
5752
					event.preventDefault();
5753
					return;
5754
				}
5755
				this._searchTimeout( event );
5756
			},
5757
			focus: function() {
5758
				this.selectedItem = null;
5759
				this.previous = this._value();
5760
			},
5761
			blur: function( event ) {
5762
				if ( this.cancelBlur ) {
5763
					delete this.cancelBlur;
5764
					return;
5765
				}
5766
 
5767
				clearTimeout( this.searching );
5768
				this.close( event );
5769
				this._change( event );
5770
			}
5771
		} );
5772
 
5773
		this._initSource();
5774
		this.menu = $( "<ul>" )
5775
			.appendTo( this._appendTo() )
5776
			.menu( {
5777
 
5778
				// disable ARIA support, the live region takes care of that
5779
				role: null
5780
			} )
5781
			.hide()
5782
			.menu( "instance" );
5783
 
5784
		this._addClass( this.menu.element, "ui-autocomplete", "ui-front" );
5785
		this._on( this.menu.element, {
5786
			mousedown: function( event ) {
5787
 
5788
				// prevent moving focus out of the text field
5789
				event.preventDefault();
5790
 
5791
				// IE doesn't prevent moving focus even with event.preventDefault()
5792
				// so we set a flag to know when we should ignore the blur event
5793
				this.cancelBlur = true;
5794
				this._delay( function() {
5795
					delete this.cancelBlur;
5796
 
5797
					// Support: IE 8 only
5798
					// Right clicking a menu item or selecting text from the menu items will
5799
					// result in focus moving out of the input. However, we've already received
5800
					// and ignored the blur event because of the cancelBlur flag set above. So
5801
					// we restore focus to ensure that the menu closes properly based on the user's
5802
					// next actions.
5803
					if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
5804
						this.element.trigger( "focus" );
5805
					}
5806
				} );
5807
			},
5808
			menufocus: function( event, ui ) {
5809
				var label, item;
5810
 
5811
				// support: Firefox
5812
				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
5813
				if ( this.isNewMenu ) {
5814
					this.isNewMenu = false;
5815
					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
5816
						this.menu.blur();
5817
 
5818
						this.document.one( "mousemove", function() {
5819
							$( event.target ).trigger( event.originalEvent );
5820
						} );
5821
 
5822
						return;
5823
					}
5824
				}
5825
 
5826
				item = ui.item.data( "ui-autocomplete-item" );
5827
				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
5828
 
5829
					// use value to match what will end up in the input, if it was a key event
5830
					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
5831
						this._value( item.value );
5832
					}
5833
				}
5834
 
5835
				// Announce the value in the liveRegion
5836
				label = ui.item.attr( "aria-label" ) || item.value;
5837
				if ( label && $.trim( label ).length ) {
5838
					this.liveRegion.children().hide();
5839
					$( "<div>" ).text( label ).appendTo( this.liveRegion );
5840
				}
5841
			},
5842
			menuselect: function( event, ui ) {
5843
				var item = ui.item.data( "ui-autocomplete-item" ),
5844
					previous = this.previous;
5845
 
5846
				// Only trigger when focus was lost (click on menu)
5847
				if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
5848
					this.element.trigger( "focus" );
5849
					this.previous = previous;
5850
 
5851
					// #6109 - IE triggers two focus events and the second
5852
					// is asynchronous, so we need to reset the previous
5853
					// term synchronously and asynchronously :-(
5854
					this._delay( function() {
5855
						this.previous = previous;
5856
						this.selectedItem = item;
5857
					} );
5858
				}
5859
 
5860
				if ( false !== this._trigger( "select", event, { item: item } ) ) {
5861
					this._value( item.value );
5862
				}
5863
 
5864
				// reset the term after the select event
5865
				// this allows custom select handling to work properly
5866
				this.term = this._value();
5867
 
5868
				this.close( event );
5869
				this.selectedItem = item;
5870
			}
5871
		} );
5872
 
5873
		this.liveRegion = $( "<div>", {
5874
			role: "status",
5875
			"aria-live": "assertive",
5876
			"aria-relevant": "additions"
5877
		} )
5878
			.appendTo( this.document[ 0 ].body );
5879
 
5880
		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
5881
 
5882
		// Turning off autocomplete prevents the browser from remembering the
5883
		// value when navigating through history, so we re-enable autocomplete
5884
		// if the page is unloaded before the widget is destroyed. #7790
5885
		this._on( this.window, {
5886
			beforeunload: function() {
5887
				this.element.removeAttr( "autocomplete" );
5888
			}
5889
		} );
5890
	},
5891
 
5892
	_destroy: function() {
5893
		clearTimeout( this.searching );
5894
		this.element.removeAttr( "autocomplete" );
5895
		this.menu.element.remove();
5896
		this.liveRegion.remove();
5897
	},
5898
 
5899
	_setOption: function( key, value ) {
5900
		this._super( key, value );
5901
		if ( key === "source" ) {
5902
			this._initSource();
5903
		}
5904
		if ( key === "appendTo" ) {
5905
			this.menu.element.appendTo( this._appendTo() );
5906
		}
5907
		if ( key === "disabled" && value && this.xhr ) {
5908
			this.xhr.abort();
5909
		}
5910
	},
5911
 
5912
	_isEventTargetInWidget: function( event ) {
5913
		var menuElement = this.menu.element[ 0 ];
5914
 
5915
		return event.target === this.element[ 0 ] ||
5916
			event.target === menuElement ||
5917
			$.contains( menuElement, event.target );
5918
	},
5919
 
5920
	_closeOnClickOutside: function( event ) {
5921
		if ( !this._isEventTargetInWidget( event ) ) {
5922
			this.close();
5923
		}
5924
	},
5925
 
5926
	_appendTo: function() {
5927
		var element = this.options.appendTo;
5928
 
5929
		if ( element ) {
5930
			element = element.jquery || element.nodeType ?
5931
				$( element ) :
5932
				this.document.find( element ).eq( 0 );
5933
		}
5934
 
5935
		if ( !element || !element[ 0 ] ) {
5936
			element = this.element.closest( ".ui-front, dialog" );
5937
		}
5938
 
5939
		if ( !element.length ) {
5940
			element = this.document[ 0 ].body;
5941
		}
5942
 
5943
		return element;
5944
	},
5945
 
5946
	_initSource: function() {
5947
		var array, url,
5948
			that = this;
5949
		if ( $.isArray( this.options.source ) ) {
5950
			array = this.options.source;
5951
			this.source = function( request, response ) {
5952
				response( $.ui.autocomplete.filter( array, request.term ) );
5953
			};
5954
		} else if ( typeof this.options.source === "string" ) {
5955
			url = this.options.source;
5956
			this.source = function( request, response ) {
5957
				if ( that.xhr ) {
5958
					that.xhr.abort();
5959
				}
5960
				that.xhr = $.ajax( {
5961
					url: url,
5962
					data: request,
5963
					dataType: "json",
5964
					success: function( data ) {
5965
						response( data );
5966
					},
5967
					error: function() {
5968
						response( [] );
5969
					}
5970
				} );
5971
			};
5972
		} else {
5973
			this.source = this.options.source;
5974
		}
5975
	},
5976
 
5977
	_searchTimeout: function( event ) {
5978
		clearTimeout( this.searching );
5979
		this.searching = this._delay( function() {
5980
 
5981
			// Search if the value has changed, or if the user retypes the same value (see #7434)
5982
			var equalValues = this.term === this._value(),
5983
				menuVisible = this.menu.element.is( ":visible" ),
5984
				modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
5985
 
5986
			if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
5987
				this.selectedItem = null;
5988
				this.search( null, event );
5989
			}
5990
		}, this.options.delay );
5991
	},
5992
 
5993
	search: function( value, event ) {
5994
		value = value != null ? value : this._value();
5995
 
5996
		// Always save the actual value, not the one passed as an argument
5997
		this.term = this._value();
5998
 
5999
		if ( value.length < this.options.minLength ) {
6000
			return this.close( event );
6001
		}
6002
 
6003
		if ( this._trigger( "search", event ) === false ) {
6004
			return;
6005
		}
6006
 
6007
		return this._search( value );
6008
	},
6009
 
6010
	_search: function( value ) {
6011
		this.pending++;
6012
		this._addClass( "ui-autocomplete-loading" );
6013
		this.cancelSearch = false;
6014
 
6015
		this.source( { term: value }, this._response() );
6016
	},
6017
 
6018
	_response: function() {
6019
		var index = ++this.requestIndex;
6020
 
6021
		return $.proxy( function( content ) {
6022
			if ( index === this.requestIndex ) {
6023
				this.__response( content );
6024
			}
6025
 
6026
			this.pending--;
6027
			if ( !this.pending ) {
6028
				this._removeClass( "ui-autocomplete-loading" );
6029
			}
6030
		}, this );
6031
	},
6032
 
6033
	__response: function( content ) {
6034
		if ( content ) {
6035
			content = this._normalize( content );
6036
		}
6037
		this._trigger( "response", null, { content: content } );
6038
		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
6039
			this._suggest( content );
6040
			this._trigger( "open" );
6041
		} else {
6042
 
6043
			// use ._close() instead of .close() so we don't cancel future searches
6044
			this._close();
6045
		}
6046
	},
6047
 
6048
	close: function( event ) {
6049
		this.cancelSearch = true;
6050
		this._close( event );
6051
	},
6052
 
6053
	_close: function( event ) {
6054
 
6055
		// Remove the handler that closes the menu on outside clicks
6056
		this._off( this.document, "mousedown" );
6057
 
6058
		if ( this.menu.element.is( ":visible" ) ) {
6059
			this.menu.element.hide();
6060
			this.menu.blur();
6061
			this.isNewMenu = true;
6062
			this._trigger( "close", event );
6063
		}
6064
	},
6065
 
6066
	_change: function( event ) {
6067
		if ( this.previous !== this._value() ) {
6068
			this._trigger( "change", event, { item: this.selectedItem } );
6069
		}
6070
	},
6071
 
6072
	_normalize: function( items ) {
6073
 
6074
		// assume all items have the right format when the first item is complete
6075
		if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
6076
			return items;
6077
		}
6078
		return $.map( items, function( item ) {
6079
			if ( typeof item === "string" ) {
6080
				return {
6081
					label: item,
6082
					value: item
6083
				};
6084
			}
6085
			return $.extend( {}, item, {
6086
				label: item.label || item.value,
6087
				value: item.value || item.label
6088
			} );
6089
		} );
6090
	},
6091
 
6092
	_suggest: function( items ) {
6093
		var ul = this.menu.element.empty();
6094
		this._renderMenu( ul, items );
6095
		this.isNewMenu = true;
6096
		this.menu.refresh();
6097
 
6098
		// Size and position menu
6099
		ul.show();
6100
		this._resizeMenu();
6101
		ul.position( $.extend( {
6102
			of: this.element
6103
		}, this.options.position ) );
6104
 
6105
		if ( this.options.autoFocus ) {
6106
			this.menu.next();
6107
		}
6108
 
6109
		// Listen for interactions outside of the widget (#6642)
6110
		this._on( this.document, {
6111
			mousedown: "_closeOnClickOutside"
6112
		} );
6113
	},
6114
 
6115
	_resizeMenu: function() {
6116
		var ul = this.menu.element;
6117
		ul.outerWidth( Math.max(
6118
 
6119
			// Firefox wraps long text (possibly a rounding bug)
6120
			// so we add 1px to avoid the wrapping (#7513)
6121
			ul.width( "" ).outerWidth() + 1,
6122
			this.element.outerWidth()
6123
		) );
6124
	},
6125
 
6126
	_renderMenu: function( ul, items ) {
6127
		var that = this;
6128
		$.each( items, function( index, item ) {
6129
			that._renderItemData( ul, item );
6130
		} );
6131
	},
6132
 
6133
	_renderItemData: function( ul, item ) {
6134
		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
6135
	},
6136
 
6137
	_renderItem: function( ul, item ) {
6138
		return $( "<li>" )
6139
			.append( $( "<div>" ).text( item.label ) )
6140
			.appendTo( ul );
6141
	},
6142
 
6143
	_move: function( direction, event ) {
6144
		if ( !this.menu.element.is( ":visible" ) ) {
6145
			this.search( null, event );
6146
			return;
6147
		}
6148
		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
6149
				this.menu.isLastItem() && /^next/.test( direction ) ) {
6150
 
6151
			if ( !this.isMultiLine ) {
6152
				this._value( this.term );
6153
			}
6154
 
6155
			this.menu.blur();
6156
			return;
6157
		}
6158
		this.menu[ direction ]( event );
6159
	},
6160
 
6161
	widget: function() {
6162
		return this.menu.element;
6163
	},
6164
 
6165
	_value: function() {
6166
		return this.valueMethod.apply( this.element, arguments );
6167
	},
6168
 
6169
	_keyEvent: function( keyEvent, event ) {
6170
		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
6171
			this._move( keyEvent, event );
6172
 
6173
			// Prevents moving cursor to beginning/end of the text field in some browsers
6174
			event.preventDefault();
6175
		}
6176
	},
6177
 
6178
	// Support: Chrome <=50
6179
	// We should be able to just use this.element.prop( "isContentEditable" )
6180
	// but hidden elements always report false in Chrome.
6181
	// https://code.google.com/p/chromium/issues/detail?id=313082
6182
	_isContentEditable: function( element ) {
6183
		if ( !element.length ) {
6184
			return false;
6185
		}
6186
 
6187
		var editable = element.prop( "contentEditable" );
6188
 
6189
		if ( editable === "inherit" ) {
6190
		  return this._isContentEditable( element.parent() );
6191
		}
6192
 
6193
		return editable === "true";
6194
	}
6195
} );
6196
 
6197
$.extend( $.ui.autocomplete, {
6198
	escapeRegex: function( value ) {
6199
		return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
6200
	},
6201
	filter: function( array, term ) {
6202
		var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
6203
		return $.grep( array, function( value ) {
6204
			return matcher.test( value.label || value.value || value );
6205
		} );
6206
	}
6207
} );
6208
 
6209
// Live region extension, adding a `messages` option
6210
// NOTE: This is an experimental API. We are still investigating
6211
// a full solution for string manipulation and internationalization.
6212
$.widget( "ui.autocomplete", $.ui.autocomplete, {
6213
	options: {
6214
		messages: {
6215
			noResults: "No search results.",
6216
			results: function( amount ) {
6217
				return amount + ( amount > 1 ? " results are" : " result is" ) +
6218
					" available, use up and down arrow keys to navigate.";
6219
			}
6220
		}
6221
	},
6222
 
6223
	__response: function( content ) {
6224
		var message;
6225
		this._superApply( arguments );
6226
		if ( this.options.disabled || this.cancelSearch ) {
6227
			return;
6228
		}
6229
		if ( content && content.length ) {
6230
			message = this.options.messages.results( content.length );
6231
		} else {
6232
			message = this.options.messages.noResults;
6233
		}
6234
		this.liveRegion.children().hide();
6235
		$( "<div>" ).text( message ).appendTo( this.liveRegion );
6236
	}
6237
} );
6238
 
6239
var widgetsAutocomplete = $.ui.autocomplete;
6240
 
6241
 
6242
/*!
6243
 * jQuery UI Controlgroup 1.12.1
6244
 * http://jqueryui.com
6245
 *
6246
 * Copyright jQuery Foundation and other contributors
6247
 * Released under the MIT license.
6248
 * http://jquery.org/license
6249
 */
6250
 
6251
//>>label: Controlgroup
6252
//>>group: Widgets
6253
//>>description: Visually groups form control widgets
6254
//>>docs: http://api.jqueryui.com/controlgroup/
6255
//>>demos: http://jqueryui.com/controlgroup/
6256
//>>css.structure: ../../themes/base/core.css
6257
//>>css.structure: ../../themes/base/controlgroup.css
6258
//>>css.theme: ../../themes/base/theme.css
6259
 
6260
 
6261
var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g;
6262
 
6263
var widgetsControlgroup = $.widget( "ui.controlgroup", {
6264
	version: "1.12.1",
6265
	defaultElement: "<div>",
6266
	options: {
6267
		direction: "horizontal",
6268
		disabled: null,
6269
		onlyVisible: true,
6270
		items: {
6271
			"button": "input[type=button], input[type=submit], input[type=reset], button, a",
6272
			"controlgroupLabel": ".ui-controlgroup-label",
6273
			"checkboxradio": "input[type='checkbox'], input[type='radio']",
6274
			"selectmenu": "select",
6275
			"spinner": ".ui-spinner-input"
6276
		}
6277
	},
6278
 
6279
	_create: function() {
6280
		this._enhance();
6281
	},
6282
 
6283
	// To support the enhanced option in jQuery Mobile, we isolate DOM manipulation
6284
	_enhance: function() {
6285
		this.element.attr( "role", "toolbar" );
6286
		this.refresh();
6287
	},
6288
 
6289
	_destroy: function() {
6290
		this._callChildMethod( "destroy" );
6291
		this.childWidgets.removeData( "ui-controlgroup-data" );
6292
		this.element.removeAttr( "role" );
6293
		if ( this.options.items.controlgroupLabel ) {
6294
			this.element
6295
				.find( this.options.items.controlgroupLabel )
6296
				.find( ".ui-controlgroup-label-contents" )
6297
				.contents().unwrap();
6298
		}
6299
	},
6300
 
6301
	_initWidgets: function() {
6302
		var that = this,
6303
			childWidgets = [];
6304
 
6305
		// First we iterate over each of the items options
6306
		$.each( this.options.items, function( widget, selector ) {
6307
			var labels;
6308
			var options = {};
6309
 
6310
			// Make sure the widget has a selector set
6311
			if ( !selector ) {
6312
				return;
6313
			}
6314
 
6315
			if ( widget === "controlgroupLabel" ) {
6316
				labels = that.element.find( selector );
6317
				labels.each( function() {
6318
					var element = $( this );
6319
 
6320
					if ( element.children( ".ui-controlgroup-label-contents" ).length ) {
6321
						return;
6322
					}
6323
					element.contents()
6324
						.wrapAll( "<span class='ui-controlgroup-label-contents'></span>" );
6325
				} );
6326
				that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" );
6327
				childWidgets = childWidgets.concat( labels.get() );
6328
				return;
6329
			}
6330
 
6331
			// Make sure the widget actually exists
6332
			if ( !$.fn[ widget ] ) {
6333
				return;
6334
			}
6335
 
6336
			// We assume everything is in the middle to start because we can't determine
6337
			// first / last elements until all enhancments are done.
6338
			if ( that[ "_" + widget + "Options" ] ) {
6339
				options = that[ "_" + widget + "Options" ]( "middle" );
6340
			} else {
6341
				options = { classes: {} };
6342
			}
6343
 
6344
			// Find instances of this widget inside controlgroup and init them
6345
			that.element
6346
				.find( selector )
6347
				.each( function() {
6348
					var element = $( this );
6349
					var instance = element[ widget ]( "instance" );
6350
 
6351
					// We need to clone the default options for this type of widget to avoid
6352
					// polluting the variable options which has a wider scope than a single widget.
6353
					var instanceOptions = $.widget.extend( {}, options );
6354
 
6355
					// If the button is the child of a spinner ignore it
6356
					// TODO: Find a more generic solution
6357
					if ( widget === "button" && element.parent( ".ui-spinner" ).length ) {
6358
						return;
6359
					}
6360
 
6361
					// Create the widget if it doesn't exist
6362
					if ( !instance ) {
6363
						instance = element[ widget ]()[ widget ]( "instance" );
6364
					}
6365
					if ( instance ) {
6366
						instanceOptions.classes =
6367
							that._resolveClassesValues( instanceOptions.classes, instance );
6368
					}
6369
					element[ widget ]( instanceOptions );
6370
 
6371
					// Store an instance of the controlgroup to be able to reference
6372
					// from the outermost element for changing options and refresh
6373
					var widgetElement = element[ widget ]( "widget" );
6374
					$.data( widgetElement[ 0 ], "ui-controlgroup-data",
6375
						instance ? instance : element[ widget ]( "instance" ) );
6376
 
6377
					childWidgets.push( widgetElement[ 0 ] );
6378
				} );
6379
		} );
6380
 
6381
		this.childWidgets = $( $.unique( childWidgets ) );
6382
		this._addClass( this.childWidgets, "ui-controlgroup-item" );
6383
	},
6384
 
6385
	_callChildMethod: function( method ) {
6386
		this.childWidgets.each( function() {
6387
			var element = $( this ),
6388
				data = element.data( "ui-controlgroup-data" );
6389
			if ( data && data[ method ] ) {
6390
				data[ method ]();
6391
			}
6392
		} );
6393
	},
6394
 
6395
	_updateCornerClass: function( element, position ) {
6396
		var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all";
6397
		var add = this._buildSimpleOptions( position, "label" ).classes.label;
6398
 
6399
		this._removeClass( element, null, remove );
6400
		this._addClass( element, null, add );
6401
	},
6402
 
6403
	_buildSimpleOptions: function( position, key ) {
6404
		var direction = this.options.direction === "vertical";
6405
		var result = {
6406
			classes: {}
6407
		};
6408
		result.classes[ key ] = {
6409
			"middle": "",
6410
			"first": "ui-corner-" + ( direction ? "top" : "left" ),
6411
			"last": "ui-corner-" + ( direction ? "bottom" : "right" ),
6412
			"only": "ui-corner-all"
6413
		}[ position ];
6414
 
6415
		return result;
6416
	},
6417
 
6418
	_spinnerOptions: function( position ) {
6419
		var options = this._buildSimpleOptions( position, "ui-spinner" );
6420
 
6421
		options.classes[ "ui-spinner-up" ] = "";
6422
		options.classes[ "ui-spinner-down" ] = "";
6423
 
6424
		return options;
6425
	},
6426
 
6427
	_buttonOptions: function( position ) {
6428
		return this._buildSimpleOptions( position, "ui-button" );
6429
	},
6430
 
6431
	_checkboxradioOptions: function( position ) {
6432
		return this._buildSimpleOptions( position, "ui-checkboxradio-label" );
6433
	},
6434
 
6435
	_selectmenuOptions: function( position ) {
6436
		var direction = this.options.direction === "vertical";
6437
		return {
6438
			width: direction ? "auto" : false,
6439
			classes: {
6440
				middle: {
6441
					"ui-selectmenu-button-open": "",
6442
					"ui-selectmenu-button-closed": ""
6443
				},
6444
				first: {
6445
					"ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ),
6446
					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" )
6447
				},
6448
				last: {
6449
					"ui-selectmenu-button-open": direction ? "" : "ui-corner-tr",
6450
					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" )
6451
				},
6452
				only: {
6453
					"ui-selectmenu-button-open": "ui-corner-top",
6454
					"ui-selectmenu-button-closed": "ui-corner-all"
6455
				}
6456
 
6457
			}[ position ]
6458
		};
6459
	},
6460
 
6461
	_resolveClassesValues: function( classes, instance ) {
6462
		var result = {};
6463
		$.each( classes, function( key ) {
6464
			var current = instance.options.classes[ key ] || "";
6465
			current = $.trim( current.replace( controlgroupCornerRegex, "" ) );
6466
			result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " );
6467
		} );
6468
		return result;
6469
	},
6470
 
6471
	_setOption: function( key, value ) {
6472
		if ( key === "direction" ) {
6473
			this._removeClass( "ui-controlgroup-" + this.options.direction );
6474
		}
6475
 
6476
		this._super( key, value );
6477
		if ( key === "disabled" ) {
6478
			this._callChildMethod( value ? "disable" : "enable" );
6479
			return;
6480
		}
6481
 
6482
		this.refresh();
6483
	},
6484
 
6485
	refresh: function() {
6486
		var children,
6487
			that = this;
6488
 
6489
		this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction );
6490
 
6491
		if ( this.options.direction === "horizontal" ) {
6492
			this._addClass( null, "ui-helper-clearfix" );
6493
		}
6494
		this._initWidgets();
6495
 
6496
		children = this.childWidgets;
6497
 
6498
		// We filter here because we need to track all childWidgets not just the visible ones
6499
		if ( this.options.onlyVisible ) {
6500
			children = children.filter( ":visible" );
6501
		}
6502
 
6503
		if ( children.length ) {
6504
 
6505
			// We do this last because we need to make sure all enhancment is done
6506
			// before determining first and last
6507
			$.each( [ "first", "last" ], function( index, value ) {
6508
				var instance = children[ value ]().data( "ui-controlgroup-data" );
6509
 
6510
				if ( instance && that[ "_" + instance.widgetName + "Options" ] ) {
6511
					var options = that[ "_" + instance.widgetName + "Options" ](
6512
						children.length === 1 ? "only" : value
6513
					);
6514
					options.classes = that._resolveClassesValues( options.classes, instance );
6515
					instance.element[ instance.widgetName ]( options );
6516
				} else {
6517
					that._updateCornerClass( children[ value ](), value );
6518
				}
6519
			} );
6520
 
6521
			// Finally call the refresh method on each of the child widgets.
6522
			this._callChildMethod( "refresh" );
6523
		}
6524
	}
6525
} );
6526
 
6527
/*!
6528
 * jQuery UI Checkboxradio 1.12.1
6529
 * http://jqueryui.com
6530
 *
6531
 * Copyright jQuery Foundation and other contributors
6532
 * Released under the MIT license.
6533
 * http://jquery.org/license
6534
 */
6535
 
6536
//>>label: Checkboxradio
6537
//>>group: Widgets
6538
//>>description: Enhances a form with multiple themeable checkboxes or radio buttons.
6539
//>>docs: http://api.jqueryui.com/checkboxradio/
6540
//>>demos: http://jqueryui.com/checkboxradio/
6541
//>>css.structure: ../../themes/base/core.css
6542
//>>css.structure: ../../themes/base/button.css
6543
//>>css.structure: ../../themes/base/checkboxradio.css
6544
//>>css.theme: ../../themes/base/theme.css
6545
 
6546
 
6547
 
6548
$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
6549
	version: "1.12.1",
6550
	options: {
6551
		disabled: null,
6552
		label: null,
6553
		icon: true,
6554
		classes: {
6555
			"ui-checkboxradio-label": "ui-corner-all",
6556
			"ui-checkboxradio-icon": "ui-corner-all"
6557
		}
6558
	},
6559
 
6560
	_getCreateOptions: function() {
6561
		var disabled, labels;
6562
		var that = this;
6563
		var options = this._super() || {};
6564
 
6565
		// We read the type here, because it makes more sense to throw a element type error first,
6566
		// rather then the error for lack of a label. Often if its the wrong type, it
6567
		// won't have a label (e.g. calling on a div, btn, etc)
6568
		this._readType();
6569
 
6570
		labels = this.element.labels();
6571
 
6572
		// If there are multiple labels, use the last one
6573
		this.label = $( labels[ labels.length - 1 ] );
6574
		if ( !this.label.length ) {
6575
			$.error( "No label found for checkboxradio widget" );
6576
		}
6577
 
6578
		this.originalLabel = "";
6579
 
6580
		// We need to get the label text but this may also need to make sure it does not contain the
6581
		// input itself.
6582
		this.label.contents().not( this.element[ 0 ] ).each( function() {
6583
 
6584
			// The label contents could be text, html, or a mix. We concat each element to get a
6585
			// string representation of the label, without the input as part of it.
6586
			that.originalLabel += this.nodeType === 3 ? $( this ).text() : this.outerHTML;
6587
		} );
6588
 
6589
		// Set the label option if we found label text
6590
		if ( this.originalLabel ) {
6591
			options.label = this.originalLabel;
6592
		}
6593
 
6594
		disabled = this.element[ 0 ].disabled;
6595
		if ( disabled != null ) {
6596
			options.disabled = disabled;
6597
		}
6598
		return options;
6599
	},
6600
 
6601
	_create: function() {
6602
		var checked = this.element[ 0 ].checked;
6603
 
6604
		this._bindFormResetHandler();
6605
 
6606
		if ( this.options.disabled == null ) {
6607
			this.options.disabled = this.element[ 0 ].disabled;
6608
		}
6609
 
6610
		this._setOption( "disabled", this.options.disabled );
6611
		this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" );
6612
		this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" );
6613
 
6614
		if ( this.type === "radio" ) {
6615
			this._addClass( this.label, "ui-checkboxradio-radio-label" );
6616
		}
6617
 
6618
		if ( this.options.label && this.options.label !== this.originalLabel ) {
6619
			this._updateLabel();
6620
		} else if ( this.originalLabel ) {
6621
			this.options.label = this.originalLabel;
6622
		}
6623
 
6624
		this._enhance();
6625
 
6626
		if ( checked ) {
6627
			this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" );
6628
			if ( this.icon ) {
6629
				this._addClass( this.icon, null, "ui-state-hover" );
6630
			}
6631
		}
6632
 
6633
		this._on( {
6634
			change: "_toggleClasses",
6635
			focus: function() {
6636
				this._addClass( this.label, null, "ui-state-focus ui-visual-focus" );
6637
			},
6638
			blur: function() {
6639
				this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" );
6640
			}
6641
		} );
6642
	},
6643
 
6644
	_readType: function() {
6645
		var nodeName = this.element[ 0 ].nodeName.toLowerCase();
6646
		this.type = this.element[ 0 ].type;
6647
		if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) {
6648
			$.error( "Can't create checkboxradio on element.nodeName=" + nodeName +
6649
				" and element.type=" + this.type );
6650
		}
6651
	},
6652
 
6653
	// Support jQuery Mobile enhanced option
6654
	_enhance: function() {
6655
		this._updateIcon( this.element[ 0 ].checked );
6656
	},
6657
 
6658
	widget: function() {
6659
		return this.label;
6660
	},
6661
 
6662
	_getRadioGroup: function() {
6663
		var group;
6664
		var name = this.element[ 0 ].name;
6665
		var nameSelector = "input[name='" + $.ui.escapeSelector( name ) + "']";
6666
 
6667
		if ( !name ) {
6668
			return $( [] );
6669
		}
6670
 
6671
		if ( this.form.length ) {
6672
			group = $( this.form[ 0 ].elements ).filter( nameSelector );
6673
		} else {
6674
 
6675
			// Not inside a form, check all inputs that also are not inside a form
6676
			group = $( nameSelector ).filter( function() {
6677
				return $( this ).form().length === 0;
6678
			} );
6679
		}
6680
 
6681
		return group.not( this.element );
6682
	},
6683
 
6684
	_toggleClasses: function() {
6685
		var checked = this.element[ 0 ].checked;
6686
		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
6687
 
6688
		if ( this.options.icon && this.type === "checkbox" ) {
6689
			this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked )
6690
				._toggleClass( this.icon, null, "ui-icon-blank", !checked );
6691
		}
6692
 
6693
		if ( this.type === "radio" ) {
6694
			this._getRadioGroup()
6695
				.each( function() {
6696
					var instance = $( this ).checkboxradio( "instance" );
6697
 
6698
					if ( instance ) {
6699
						instance._removeClass( instance.label,
6700
							"ui-checkboxradio-checked", "ui-state-active" );
6701
					}
6702
				} );
6703
		}
6704
	},
6705
 
6706
	_destroy: function() {
6707
		this._unbindFormResetHandler();
6708
 
6709
		if ( this.icon ) {
6710
			this.icon.remove();
6711
			this.iconSpace.remove();
6712
		}
6713
	},
6714
 
6715
	_setOption: function( key, value ) {
6716
 
6717
		// We don't allow the value to be set to nothing
6718
		if ( key === "label" && !value ) {
6719
			return;
6720
		}
6721
 
6722
		this._super( key, value );
6723
 
6724
		if ( key === "disabled" ) {
6725
			this._toggleClass( this.label, null, "ui-state-disabled", value );
6726
			this.element[ 0 ].disabled = value;
6727
 
6728
			// Don't refresh when setting disabled
6729
			return;
6730
		}
6731
		this.refresh();
6732
	},
6733
 
6734
	_updateIcon: function( checked ) {
6735
		var toAdd = "ui-icon ui-icon-background ";
6736
 
6737
		if ( this.options.icon ) {
6738
			if ( !this.icon ) {
6739
				this.icon = $( "<span>" );
6740
				this.iconSpace = $( "<span> </span>" );
6741
				this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" );
6742
			}
6743
 
6744
			if ( this.type === "checkbox" ) {
6745
				toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank";
6746
				this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" );
6747
			} else {
6748
				toAdd += "ui-icon-blank";
6749
			}
6750
			this._addClass( this.icon, "ui-checkboxradio-icon", toAdd );
6751
			if ( !checked ) {
6752
				this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" );
6753
			}
6754
			this.icon.prependTo( this.label ).after( this.iconSpace );
6755
		} else if ( this.icon !== undefined ) {
6756
			this.icon.remove();
6757
			this.iconSpace.remove();
6758
			delete this.icon;
6759
		}
6760
	},
6761
 
6762
	_updateLabel: function() {
6763
 
6764
		// Remove the contents of the label ( minus the icon, icon space, and input )
6765
		var contents = this.label.contents().not( this.element[ 0 ] );
6766
		if ( this.icon ) {
6767
			contents = contents.not( this.icon[ 0 ] );
6768
		}
6769
		if ( this.iconSpace ) {
6770
			contents = contents.not( this.iconSpace[ 0 ] );
6771
		}
6772
		contents.remove();
6773
 
6774
		this.label.append( this.options.label );
6775
	},
6776
 
6777
	refresh: function() {
6778
		var checked = this.element[ 0 ].checked,
6779
			isDisabled = this.element[ 0 ].disabled;
6780
 
6781
		this._updateIcon( checked );
6782
		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
6783
		if ( this.options.label !== null ) {
6784
			this._updateLabel();
6785
		}
6786
 
6787
		if ( isDisabled !== this.options.disabled ) {
6788
			this._setOptions( { "disabled": isDisabled } );
6789
		}
6790
	}
6791
 
6792
} ] );
6793
 
6794
var widgetsCheckboxradio = $.ui.checkboxradio;
6795
 
6796
 
6797
/*!
6798
 * jQuery UI Button 1.12.1
6799
 * http://jqueryui.com
6800
 *
6801
 * Copyright jQuery Foundation and other contributors
6802
 * Released under the MIT license.
6803
 * http://jquery.org/license
6804
 */
6805
 
6806
//>>label: Button
6807
//>>group: Widgets
6808
//>>description: Enhances a form with themeable buttons.
6809
//>>docs: http://api.jqueryui.com/button/
6810
//>>demos: http://jqueryui.com/button/
6811
//>>css.structure: ../../themes/base/core.css
6812
//>>css.structure: ../../themes/base/button.css
6813
//>>css.theme: ../../themes/base/theme.css
6814
 
6815
 
6816
 
6817
$.widget( "ui.button", {
6818
	version: "1.12.1",
6819
	defaultElement: "<button>",
6820
	options: {
6821
		classes: {
6822
			"ui-button": "ui-corner-all"
6823
		},
6824
		disabled: null,
6825
		icon: null,
6826
		iconPosition: "beginning",
6827
		label: null,
6828
		showLabel: true
6829
	},
6830
 
6831
	_getCreateOptions: function() {
6832
		var disabled,
6833
 
6834
			// This is to support cases like in jQuery Mobile where the base widget does have
6835
			// an implementation of _getCreateOptions
6836
			options = this._super() || {};
6837
 
6838
		this.isInput = this.element.is( "input" );
6839
 
6840
		disabled = this.element[ 0 ].disabled;
6841
		if ( disabled != null ) {
6842
			options.disabled = disabled;
6843
		}
6844
 
6845
		this.originalLabel = this.isInput ? this.element.val() : this.element.html();
6846
		if ( this.originalLabel ) {
6847
			options.label = this.originalLabel;
6848
		}
6849
 
6850
		return options;
6851
	},
6852
 
6853
	_create: function() {
6854
		if ( !this.option.showLabel & !this.options.icon ) {
6855
			this.options.showLabel = true;
6856
		}
6857
 
6858
		// We have to check the option again here even though we did in _getCreateOptions,
6859
		// because null may have been passed on init which would override what was set in
6860
		// _getCreateOptions
6861
		if ( this.options.disabled == null ) {
6862
			this.options.disabled = this.element[ 0 ].disabled || false;
6863
		}
6864
 
6865
		this.hasTitle = !!this.element.attr( "title" );
6866
 
6867
		// Check to see if the label needs to be set or if its already correct
6868
		if ( this.options.label && this.options.label !== this.originalLabel ) {
6869
			if ( this.isInput ) {
6870
				this.element.val( this.options.label );
6871
			} else {
6872
				this.element.html( this.options.label );
6873
			}
6874
		}
6875
		this._addClass( "ui-button", "ui-widget" );
6876
		this._setOption( "disabled", this.options.disabled );
6877
		this._enhance();
6878
 
6879
		if ( this.element.is( "a" ) ) {
6880
			this._on( {
6881
				"keyup": function( event ) {
6882
					if ( event.keyCode === $.ui.keyCode.SPACE ) {
6883
						event.preventDefault();
6884
 
6885
						// Support: PhantomJS <= 1.9, IE 8 Only
6886
						// If a native click is available use it so we actually cause navigation
6887
						// otherwise just trigger a click event
6888
						if ( this.element[ 0 ].click ) {
6889
							this.element[ 0 ].click();
6890
						} else {
6891
							this.element.trigger( "click" );
6892
						}
6893
					}
6894
				}
6895
			} );
6896
		}
6897
	},
6898
 
6899
	_enhance: function() {
6900
		if ( !this.element.is( "button" ) ) {
6901
			this.element.attr( "role", "button" );
6902
		}
6903
 
6904
		if ( this.options.icon ) {
6905
			this._updateIcon( "icon", this.options.icon );
6906
			this._updateTooltip();
6907
		}
6908
	},
6909
 
6910
	_updateTooltip: function() {
6911
		this.title = this.element.attr( "title" );
6912
 
6913
		if ( !this.options.showLabel && !this.title ) {
6914
			this.element.attr( "title", this.options.label );
6915
		}
6916
	},
6917
 
6918
	_updateIcon: function( option, value ) {
6919
		var icon = option !== "iconPosition",
6920
			position = icon ? this.options.iconPosition : value,
6921
			displayBlock = position === "top" || position === "bottom";
6922
 
6923
		// Create icon
6924
		if ( !this.icon ) {
6925
			this.icon = $( "<span>" );
6926
 
6927
			this._addClass( this.icon, "ui-button-icon", "ui-icon" );
6928
 
6929
			if ( !this.options.showLabel ) {
6930
				this._addClass( "ui-button-icon-only" );
6931
			}
6932
		} else if ( icon ) {
6933
 
6934
			// If we are updating the icon remove the old icon class
6935
			this._removeClass( this.icon, null, this.options.icon );
6936
		}
6937
 
6938
		// If we are updating the icon add the new icon class
6939
		if ( icon ) {
6940
			this._addClass( this.icon, null, value );
6941
		}
6942
 
6943
		this._attachIcon( position );
6944
 
6945
		// If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove
6946
		// the iconSpace if there is one.
6947
		if ( displayBlock ) {
6948
			this._addClass( this.icon, null, "ui-widget-icon-block" );
6949
			if ( this.iconSpace ) {
6950
				this.iconSpace.remove();
6951
			}
6952
		} else {
6953
 
6954
			// Position is beginning or end so remove the ui-widget-icon-block class and add the
6955
			// space if it does not exist
6956
			if ( !this.iconSpace ) {
6957
				this.iconSpace = $( "<span> </span>" );
6958
				this._addClass( this.iconSpace, "ui-button-icon-space" );
6959
			}
6960
			this._removeClass( this.icon, null, "ui-wiget-icon-block" );
6961
			this._attachIconSpace( position );
6962
		}
6963
	},
6964
 
6965
	_destroy: function() {
6966
		this.element.removeAttr( "role" );
6967
 
6968
		if ( this.icon ) {
6969
			this.icon.remove();
6970
		}
6971
		if ( this.iconSpace ) {
6972
			this.iconSpace.remove();
6973
		}
6974
		if ( !this.hasTitle ) {
6975
			this.element.removeAttr( "title" );
6976
		}
6977
	},
6978
 
6979
	_attachIconSpace: function( iconPosition ) {
6980
		this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace );
6981
	},
6982
 
6983
	_attachIcon: function( iconPosition ) {
6984
		this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon );
6985
	},
6986
 
6987
	_setOptions: function( options ) {
6988
		var newShowLabel = options.showLabel === undefined ?
6989
				this.options.showLabel :
6990
				options.showLabel,
6991
			newIcon = options.icon === undefined ? this.options.icon : options.icon;
6992
 
6993
		if ( !newShowLabel && !newIcon ) {
6994
			options.showLabel = true;
6995
		}
6996
		this._super( options );
6997
	},
6998
 
6999
	_setOption: function( key, value ) {
7000
		if ( key === "icon" ) {
7001
			if ( value ) {
7002
				this._updateIcon( key, value );
7003
			} else if ( this.icon ) {
7004
				this.icon.remove();
7005
				if ( this.iconSpace ) {
7006
					this.iconSpace.remove();
7007
				}
7008
			}
7009
		}
7010
 
7011
		if ( key === "iconPosition" ) {
7012
			this._updateIcon( key, value );
7013
		}
7014
 
7015
		// Make sure we can't end up with a button that has neither text nor icon
7016
		if ( key === "showLabel" ) {
7017
				this._toggleClass( "ui-button-icon-only", null, !value );
7018
				this._updateTooltip();
7019
		}
7020
 
7021
		if ( key === "label" ) {
7022
			if ( this.isInput ) {
7023
				this.element.val( value );
7024
			} else {
7025
 
7026
				// If there is an icon, append it, else nothing then append the value
7027
				// this avoids removal of the icon when setting label text
7028
				this.element.html( value );
7029
				if ( this.icon ) {
7030
					this._attachIcon( this.options.iconPosition );
7031
					this._attachIconSpace( this.options.iconPosition );
7032
				}
7033
			}
7034
		}
7035
 
7036
		this._super( key, value );
7037
 
7038
		if ( key === "disabled" ) {
7039
			this._toggleClass( null, "ui-state-disabled", value );
7040
			this.element[ 0 ].disabled = value;
7041
			if ( value ) {
7042
				this.element.blur();
7043
			}
7044
		}
7045
	},
7046
 
7047
	refresh: function() {
7048
 
7049
		// Make sure to only check disabled if its an element that supports this otherwise
7050
		// check for the disabled class to determine state
7051
		var isDisabled = this.element.is( "input, button" ) ?
7052
			this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" );
7053
 
7054
		if ( isDisabled !== this.options.disabled ) {
7055
			this._setOptions( { disabled: isDisabled } );
7056
		}
7057
 
7058
		this._updateTooltip();
7059
	}
7060
} );
7061
 
7062
// DEPRECATED
7063
if ( $.uiBackCompat !== false ) {
7064
 
7065
	// Text and Icons options
7066
	$.widget( "ui.button", $.ui.button, {
7067
		options: {
7068
			text: true,
7069
			icons: {
7070
				primary: null,
7071
				secondary: null
7072
			}
7073
		},
7074
 
7075
		_create: function() {
7076
			if ( this.options.showLabel && !this.options.text ) {
7077
				this.options.showLabel = this.options.text;
7078
			}
7079
			if ( !this.options.showLabel && this.options.text ) {
7080
				this.options.text = this.options.showLabel;
7081
			}
7082
			if ( !this.options.icon && ( this.options.icons.primary ||
7083
					this.options.icons.secondary ) ) {
7084
				if ( this.options.icons.primary ) {
7085
					this.options.icon = this.options.icons.primary;
7086
				} else {
7087
					this.options.icon = this.options.icons.secondary;
7088
					this.options.iconPosition = "end";
7089
				}
7090
			} else if ( this.options.icon ) {
7091
				this.options.icons.primary = this.options.icon;
7092
			}
7093
			this._super();
7094
		},
7095
 
7096
		_setOption: function( key, value ) {
7097
			if ( key === "text" ) {
7098
				this._super( "showLabel", value );
7099
				return;
7100
			}
7101
			if ( key === "showLabel" ) {
7102
				this.options.text = value;
7103
			}
7104
			if ( key === "icon" ) {
7105
				this.options.icons.primary = value;
7106
			}
7107
			if ( key === "icons" ) {
7108
				if ( value.primary ) {
7109
					this._super( "icon", value.primary );
7110
					this._super( "iconPosition", "beginning" );
7111
				} else if ( value.secondary ) {
7112
					this._super( "icon", value.secondary );
7113
					this._super( "iconPosition", "end" );
7114
				}
7115
			}
7116
			this._superApply( arguments );
7117
		}
7118
	} );
7119
 
7120
	$.fn.button = ( function( orig ) {
7121
		return function() {
7122
			if ( !this.length || ( this.length && this[ 0 ].tagName !== "INPUT" ) ||
7123
					( this.length && this[ 0 ].tagName === "INPUT" && (
7124
						this.attr( "type" ) !== "checkbox" && this.attr( "type" ) !== "radio"
7125
					) ) ) {
7126
				return orig.apply( this, arguments );
7127
			}
7128
			if ( !$.ui.checkboxradio ) {
7129
				$.error( "Checkboxradio widget missing" );
7130
			}
7131
			if ( arguments.length === 0 ) {
7132
				return this.checkboxradio( {
7133
					"icon": false
7134
				} );
7135
			}
7136
			return this.checkboxradio.apply( this, arguments );
7137
		};
7138
	} )( $.fn.button );
7139
 
7140
	$.fn.buttonset = function() {
7141
		if ( !$.ui.controlgroup ) {
7142
			$.error( "Controlgroup widget missing" );
7143
		}
7144
		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) {
7145
			return this.controlgroup.apply( this,
7146
				[ arguments[ 0 ], "items.button", arguments[ 2 ] ] );
7147
		}
7148
		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) {
7149
			return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] );
7150
		}
7151
		if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) {
7152
			arguments[ 0 ].items = {
7153
				button: arguments[ 0 ].items
7154
			};
7155
		}
7156
		return this.controlgroup.apply( this, arguments );
7157
	};
7158
}
7159
 
7160
var widgetsButton = $.ui.button;
7161
 
7162
 
7163
// jscs:disable maximumLineLength
7164
/* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
7165
/*!
7166
 * jQuery UI Datepicker 1.12.1
7167
 * http://jqueryui.com
7168
 *
7169
 * Copyright jQuery Foundation and other contributors
7170
 * Released under the MIT license.
7171
 * http://jquery.org/license
7172
 */
7173
 
7174
//>>label: Datepicker
7175
//>>group: Widgets
7176
//>>description: Displays a calendar from an input or inline for selecting dates.
7177
//>>docs: http://api.jqueryui.com/datepicker/
7178
//>>demos: http://jqueryui.com/datepicker/
7179
//>>css.structure: ../../themes/base/core.css
7180
//>>css.structure: ../../themes/base/datepicker.css
7181
//>>css.theme: ../../themes/base/theme.css
7182
 
7183
 
7184
 
7185
$.extend( $.ui, { datepicker: { version: "1.12.1" } } );
7186
 
7187
var datepicker_instActive;
7188
 
7189
function datepicker_getZindex( elem ) {
7190
	var position, value;
7191
	while ( elem.length && elem[ 0 ] !== document ) {
7192
 
7193
		// Ignore z-index if position is set to a value where z-index is ignored by the browser
7194
		// This makes behavior of this function consistent across browsers
7195
		// WebKit always returns auto if the element is positioned
7196
		position = elem.css( "position" );
7197
		if ( position === "absolute" || position === "relative" || position === "fixed" ) {
7198
 
7199
			// IE returns 0 when zIndex is not specified
7200
			// other browsers return a string
7201
			// we ignore the case of nested elements with an explicit value of 0
7202
			// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
7203
			value = parseInt( elem.css( "zIndex" ), 10 );
7204
			if ( !isNaN( value ) && value !== 0 ) {
7205
				return value;
7206
			}
7207
		}
7208
		elem = elem.parent();
7209
	}
7210
 
7211
	return 0;
7212
}
7213
/* Date picker manager.
7214
   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
7215
   Settings for (groups of) date pickers are maintained in an instance object,
7216
   allowing multiple different settings on the same page. */
7217
 
7218
function Datepicker() {
7219
	this._curInst = null; // The current instance in use
7220
	this._keyEvent = false; // If the last event was a key event
7221
	this._disabledInputs = []; // List of date picker inputs that have been disabled
7222
	this._datepickerShowing = false; // True if the popup picker is showing , false if not
7223
	this._inDialog = false; // True if showing within a "dialog", false if not
7224
	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
7225
	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
7226
	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
7227
	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
7228
	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
7229
	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
7230
	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
7231
	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
7232
	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
7233
	this.regional = []; // Available regional settings, indexed by language code
7234
	this.regional[ "" ] = { // Default regional settings
7235
		closeText: "Done", // Display text for close link
7236
		prevText: "Prev", // Display text for previous month link
7237
		nextText: "Next", // Display text for next month link
7238
		currentText: "Today", // Display text for current month link
7239
		monthNames: [ "January","February","March","April","May","June",
7240
			"July","August","September","October","November","December" ], // Names of months for drop-down and formatting
7241
		monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting
7242
		dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting
7243
		dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting
7244
		dayNamesMin: [ "Su","Mo","Tu","We","Th","Fr","Sa" ], // Column headings for days starting at Sunday
7245
		weekHeader: "Wk", // Column header for week of the year
7246
		dateFormat: "mm/dd/yy", // See format options on parseDate
7247
		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
7248
		isRTL: false, // True if right-to-left language, false if left-to-right
7249
		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
7250
		yearSuffix: "" // Additional text to append to the year in the month headers
7251
	};
7252
	this._defaults = { // Global defaults for all the date picker instances
7253
		showOn: "focus", // "focus" for popup on focus,
7254
			// "button" for trigger button, or "both" for either
7255
		showAnim: "fadeIn", // Name of jQuery animation for popup
7256
		showOptions: {}, // Options for enhanced animations
7257
		defaultDate: null, // Used when field is blank: actual date,
7258
			// +/-number for offset from today, null for today
7259
		appendText: "", // Display text following the input box, e.g. showing the format
7260
		buttonText: "...", // Text for trigger button
7261
		buttonImage: "", // URL for trigger button image
7262
		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
7263
		hideIfNoPrevNext: false, // True to hide next/previous month links
7264
			// if not applicable, false to just disable them
7265
		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
7266
		gotoCurrent: false, // True if today link goes back to current selection instead
7267
		changeMonth: false, // True if month can be selected directly, false if only prev/next
7268
		changeYear: false, // True if year can be selected directly, false if only prev/next
7269
		yearRange: "c-10:c+10", // Range of years to display in drop-down,
7270
			// either relative to today's year (-nn:+nn), relative to currently displayed year
7271
			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
7272
		showOtherMonths: false, // True to show dates in other months, false to leave blank
7273
		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
7274
		showWeek: false, // True to show week of the year, false to not show it
7275
		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
7276
			// takes a Date and returns the number of the week for it
7277
		shortYearCutoff: "+10", // Short year values < this are in the current century,
7278
			// > this are in the previous century,
7279
			// string value starting with "+" for current year + value
7280
		minDate: null, // The earliest selectable date, or null for no limit
7281
		maxDate: null, // The latest selectable date, or null for no limit
7282
		duration: "fast", // Duration of display/closure
7283
		beforeShowDay: null, // Function that takes a date and returns an array with
7284
			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
7285
			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
7286
		beforeShow: null, // Function that takes an input field and
7287
			// returns a set of custom settings for the date picker
7288
		onSelect: null, // Define a callback function when a date is selected
7289
		onChangeMonthYear: null, // Define a callback function when the month or year is changed
7290
		onClose: null, // Define a callback function when the datepicker is closed
7291
		numberOfMonths: 1, // Number of months to show at a time
7292
		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
7293
		stepMonths: 1, // Number of months to step back/forward
7294
		stepBigMonths: 12, // Number of months to step back/forward for the big links
7295
		altField: "", // Selector for an alternate field to store selected dates into
7296
		altFormat: "", // The date format to use for the alternate field
7297
		constrainInput: true, // The input is constrained by the current date format
7298
		showButtonPanel: false, // True to show button panel, false to not show it
7299
		autoSize: false, // True to size the input for the date format, false to leave as is
7300
		disabled: false // The initial disabled state
7301
	};
7302
	$.extend( this._defaults, this.regional[ "" ] );
7303
	this.regional.en = $.extend( true, {}, this.regional[ "" ] );
7304
	this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
7305
	this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) );
7306
}
7307
 
7308
$.extend( Datepicker.prototype, {
7309
	/* Class name added to elements to indicate already configured with a date picker. */
7310
	markerClassName: "hasDatepicker",
7311
 
7312
	//Keep track of the maximum number of rows displayed (see #7043)
7313
	maxRows: 4,
7314
 
7315
	// TODO rename to "widget" when switching to widget factory
7316
	_widgetDatepicker: function() {
7317
		return this.dpDiv;
7318
	},
7319
 
7320
	/* Override the default settings for all instances of the date picker.
7321
	 * @param  settings  object - the new settings to use as defaults (anonymous object)
7322
	 * @return the manager object
7323
	 */
7324
	setDefaults: function( settings ) {
7325
		datepicker_extendRemove( this._defaults, settings || {} );
7326
		return this;
7327
	},
7328
 
7329
	/* Attach the date picker to a jQuery selection.
7330
	 * @param  target	element - the target input field or division or span
7331
	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
7332
	 */
7333
	_attachDatepicker: function( target, settings ) {
7334
		var nodeName, inline, inst;
7335
		nodeName = target.nodeName.toLowerCase();
7336
		inline = ( nodeName === "div" || nodeName === "span" );
7337
		if ( !target.id ) {
7338
			this.uuid += 1;
7339
			target.id = "dp" + this.uuid;
7340
		}
7341
		inst = this._newInst( $( target ), inline );
7342
		inst.settings = $.extend( {}, settings || {} );
7343
		if ( nodeName === "input" ) {
7344
			this._connectDatepicker( target, inst );
7345
		} else if ( inline ) {
7346
			this._inlineDatepicker( target, inst );
7347
		}
7348
	},
7349
 
7350
	/* Create a new instance object. */
7351
	_newInst: function( target, inline ) {
7352
		var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars
7353
		return { id: id, input: target, // associated target
7354
			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
7355
			drawMonth: 0, drawYear: 0, // month being drawn
7356
			inline: inline, // is datepicker inline or not
7357
			dpDiv: ( !inline ? this.dpDiv : // presentation div
7358
			datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) };
7359
	},
7360
 
7361
	/* Attach the date picker to an input field. */
7362
	_connectDatepicker: function( target, inst ) {
7363
		var input = $( target );
7364
		inst.append = $( [] );
7365
		inst.trigger = $( [] );
7366
		if ( input.hasClass( this.markerClassName ) ) {
7367
			return;
7368
		}
7369
		this._attachments( input, inst );
7370
		input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ).
7371
			on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp );
7372
		this._autoSize( inst );
7373
		$.data( target, "datepicker", inst );
7374
 
7375
		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
7376
		if ( inst.settings.disabled ) {
7377
			this._disableDatepicker( target );
7378
		}
7379
	},
7380
 
7381
	/* Make attachments based on settings. */
7382
	_attachments: function( input, inst ) {
7383
		var showOn, buttonText, buttonImage,
7384
			appendText = this._get( inst, "appendText" ),
7385
			isRTL = this._get( inst, "isRTL" );
7386
 
7387
		if ( inst.append ) {
7388
			inst.append.remove();
7389
		}
7390
		if ( appendText ) {
7391
			inst.append = $( "<span class='" + this._appendClass + "'>" + appendText + "</span>" );
7392
			input[ isRTL ? "before" : "after" ]( inst.append );
7393
		}
7394
 
7395
		input.off( "focus", this._showDatepicker );
7396
 
7397
		if ( inst.trigger ) {
7398
			inst.trigger.remove();
7399
		}
7400
 
7401
		showOn = this._get( inst, "showOn" );
7402
		if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field
7403
			input.on( "focus", this._showDatepicker );
7404
		}
7405
		if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked
7406
			buttonText = this._get( inst, "buttonText" );
7407
			buttonImage = this._get( inst, "buttonImage" );
7408
			inst.trigger = $( this._get( inst, "buttonImageOnly" ) ?
7409
				$( "<img/>" ).addClass( this._triggerClass ).
7410
					attr( { src: buttonImage, alt: buttonText, title: buttonText } ) :
7411
				$( "<button type='button'></button>" ).addClass( this._triggerClass ).
7412
					html( !buttonImage ? buttonText : $( "<img/>" ).attr(
7413
					{ src:buttonImage, alt:buttonText, title:buttonText } ) ) );
7414
			input[ isRTL ? "before" : "after" ]( inst.trigger );
7415
			inst.trigger.on( "click", function() {
7416
				if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) {
7417
					$.datepicker._hideDatepicker();
7418
				} else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) {
7419
					$.datepicker._hideDatepicker();
7420
					$.datepicker._showDatepicker( input[ 0 ] );
7421
				} else {
7422
					$.datepicker._showDatepicker( input[ 0 ] );
7423
				}
7424
				return false;
7425
			} );
7426
		}
7427
	},
7428
 
7429
	/* Apply the maximum length for the date format. */
7430
	_autoSize: function( inst ) {
7431
		if ( this._get( inst, "autoSize" ) && !inst.inline ) {
7432
			var findMax, max, maxI, i,
7433
				date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits
7434
				dateFormat = this._get( inst, "dateFormat" );
7435
 
7436
			if ( dateFormat.match( /[DM]/ ) ) {
7437
				findMax = function( names ) {
7438
					max = 0;
7439
					maxI = 0;
7440
					for ( i = 0; i < names.length; i++ ) {
7441
						if ( names[ i ].length > max ) {
7442
							max = names[ i ].length;
7443
							maxI = i;
7444
						}
7445
					}
7446
					return maxI;
7447
				};
7448
				date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ?
7449
					"monthNames" : "monthNamesShort" ) ) ) );
7450
				date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ?
7451
					"dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() );
7452
			}
7453
			inst.input.attr( "size", this._formatDate( inst, date ).length );
7454
		}
7455
	},
7456
 
7457
	/* Attach an inline date picker to a div. */
7458
	_inlineDatepicker: function( target, inst ) {
7459
		var divSpan = $( target );
7460
		if ( divSpan.hasClass( this.markerClassName ) ) {
7461
			return;
7462
		}
7463
		divSpan.addClass( this.markerClassName ).append( inst.dpDiv );
7464
		$.data( target, "datepicker", inst );
7465
		this._setDate( inst, this._getDefaultDate( inst ), true );
7466
		this._updateDatepicker( inst );
7467
		this._updateAlternate( inst );
7468
 
7469
		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7470
		if ( inst.settings.disabled ) {
7471
			this._disableDatepicker( target );
7472
		}
7473
 
7474
		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7475
		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7476
		inst.dpDiv.css( "display", "block" );
7477
	},
7478
 
7479
	/* Pop-up the date picker in a "dialog" box.
7480
	 * @param  input element - ignored
7481
	 * @param  date	string or Date - the initial date to display
7482
	 * @param  onSelect  function - the function to call when a date is selected
7483
	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
7484
	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
7485
	 *					event - with x/y coordinates or
7486
	 *					leave empty for default (screen centre)
7487
	 * @return the manager object
7488
	 */
7489
	_dialogDatepicker: function( input, date, onSelect, settings, pos ) {
7490
		var id, browserWidth, browserHeight, scrollX, scrollY,
7491
			inst = this._dialogInst; // internal instance
7492
 
7493
		if ( !inst ) {
7494
			this.uuid += 1;
7495
			id = "dp" + this.uuid;
7496
			this._dialogInput = $( "<input type='text' id='" + id +
7497
				"' style='position: absolute; top: -100px; width: 0px;'/>" );
7498
			this._dialogInput.on( "keydown", this._doKeyDown );
7499
			$( "body" ).append( this._dialogInput );
7500
			inst = this._dialogInst = this._newInst( this._dialogInput, false );
7501
			inst.settings = {};
7502
			$.data( this._dialogInput[ 0 ], "datepicker", inst );
7503
		}
7504
		datepicker_extendRemove( inst.settings, settings || {} );
7505
		date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date );
7506
		this._dialogInput.val( date );
7507
 
7508
		this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null );
7509
		if ( !this._pos ) {
7510
			browserWidth = document.documentElement.clientWidth;
7511
			browserHeight = document.documentElement.clientHeight;
7512
			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7513
			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7514
			this._pos = // should use actual width/height below
7515
				[ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ];
7516
		}
7517
 
7518
		// Move input on screen for focus, but hidden behind dialog
7519
		this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" );
7520
		inst.settings.onSelect = onSelect;
7521
		this._inDialog = true;
7522
		this.dpDiv.addClass( this._dialogClass );
7523
		this._showDatepicker( this._dialogInput[ 0 ] );
7524
		if ( $.blockUI ) {
7525
			$.blockUI( this.dpDiv );
7526
		}
7527
		$.data( this._dialogInput[ 0 ], "datepicker", inst );
7528
		return this;
7529
	},
7530
 
7531
	/* Detach a datepicker from its control.
7532
	 * @param  target	element - the target input field or division or span
7533
	 */
7534
	_destroyDatepicker: function( target ) {
7535
		var nodeName,
7536
			$target = $( target ),
7537
			inst = $.data( target, "datepicker" );
7538
 
7539
		if ( !$target.hasClass( this.markerClassName ) ) {
7540
			return;
7541
		}
7542
 
7543
		nodeName = target.nodeName.toLowerCase();
7544
		$.removeData( target, "datepicker" );
7545
		if ( nodeName === "input" ) {
7546
			inst.append.remove();
7547
			inst.trigger.remove();
7548
			$target.removeClass( this.markerClassName ).
7549
				off( "focus", this._showDatepicker ).
7550
				off( "keydown", this._doKeyDown ).
7551
				off( "keypress", this._doKeyPress ).
7552
				off( "keyup", this._doKeyUp );
7553
		} else if ( nodeName === "div" || nodeName === "span" ) {
7554
			$target.removeClass( this.markerClassName ).empty();
7555
		}
7556
 
7557
		if ( datepicker_instActive === inst ) {
7558
			datepicker_instActive = null;
7559
		}
7560
	},
7561
 
7562
	/* Enable the date picker to a jQuery selection.
7563
	 * @param  target	element - the target input field or division or span
7564
	 */
7565
	_enableDatepicker: function( target ) {
7566
		var nodeName, inline,
7567
			$target = $( target ),
7568
			inst = $.data( target, "datepicker" );
7569
 
7570
		if ( !$target.hasClass( this.markerClassName ) ) {
7571
			return;
7572
		}
7573
 
7574
		nodeName = target.nodeName.toLowerCase();
7575
		if ( nodeName === "input" ) {
7576
			target.disabled = false;
7577
			inst.trigger.filter( "button" ).
7578
				each( function() { this.disabled = false; } ).end().
7579
				filter( "img" ).css( { opacity: "1.0", cursor: "" } );
7580
		} else if ( nodeName === "div" || nodeName === "span" ) {
7581
			inline = $target.children( "." + this._inlineClass );
7582
			inline.children().removeClass( "ui-state-disabled" );
7583
			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
7584
				prop( "disabled", false );
7585
		}
7586
		this._disabledInputs = $.map( this._disabledInputs,
7587
			function( value ) { return ( value === target ? null : value ); } ); // delete entry
7588
	},
7589
 
7590
	/* Disable the date picker to a jQuery selection.
7591
	 * @param  target	element - the target input field or division or span
7592
	 */
7593
	_disableDatepicker: function( target ) {
7594
		var nodeName, inline,
7595
			$target = $( target ),
7596
			inst = $.data( target, "datepicker" );
7597
 
7598
		if ( !$target.hasClass( this.markerClassName ) ) {
7599
			return;
7600
		}
7601
 
7602
		nodeName = target.nodeName.toLowerCase();
7603
		if ( nodeName === "input" ) {
7604
			target.disabled = true;
7605
			inst.trigger.filter( "button" ).
7606
				each( function() { this.disabled = true; } ).end().
7607
				filter( "img" ).css( { opacity: "0.5", cursor: "default" } );
7608
		} else if ( nodeName === "div" || nodeName === "span" ) {
7609
			inline = $target.children( "." + this._inlineClass );
7610
			inline.children().addClass( "ui-state-disabled" );
7611
			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
7612
				prop( "disabled", true );
7613
		}
7614
		this._disabledInputs = $.map( this._disabledInputs,
7615
			function( value ) { return ( value === target ? null : value ); } ); // delete entry
7616
		this._disabledInputs[ this._disabledInputs.length ] = target;
7617
	},
7618
 
7619
	/* Is the first field in a jQuery collection disabled as a datepicker?
7620
	 * @param  target	element - the target input field or division or span
7621
	 * @return boolean - true if disabled, false if enabled
7622
	 */
7623
	_isDisabledDatepicker: function( target ) {
7624
		if ( !target ) {
7625
			return false;
7626
		}
7627
		for ( var i = 0; i < this._disabledInputs.length; i++ ) {
7628
			if ( this._disabledInputs[ i ] === target ) {
7629
				return true;
7630
			}
7631
		}
7632
		return false;
7633
	},
7634
 
7635
	/* Retrieve the instance data for the target control.
7636
	 * @param  target  element - the target input field or division or span
7637
	 * @return  object - the associated instance data
7638
	 * @throws  error if a jQuery problem getting data
7639
	 */
7640
	_getInst: function( target ) {
7641
		try {
7642
			return $.data( target, "datepicker" );
7643
		}
7644
		catch ( err ) {
7645
			throw "Missing instance data for this datepicker";
7646
		}
7647
	},
7648
 
7649
	/* Update or retrieve the settings for a date picker attached to an input field or division.
7650
	 * @param  target  element - the target input field or division or span
7651
	 * @param  name	object - the new settings to update or
7652
	 *				string - the name of the setting to change or retrieve,
7653
	 *				when retrieving also "all" for all instance settings or
7654
	 *				"defaults" for all global defaults
7655
	 * @param  value   any - the new value for the setting
7656
	 *				(omit if above is an object or to retrieve a value)
7657
	 */
7658
	_optionDatepicker: function( target, name, value ) {
7659
		var settings, date, minDate, maxDate,
7660
			inst = this._getInst( target );
7661
 
7662
		if ( arguments.length === 2 && typeof name === "string" ) {
7663
			return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) :
7664
				( inst ? ( name === "all" ? $.extend( {}, inst.settings ) :
7665
				this._get( inst, name ) ) : null ) );
7666
		}
7667
 
7668
		settings = name || {};
7669
		if ( typeof name === "string" ) {
7670
			settings = {};
7671
			settings[ name ] = value;
7672
		}
7673
 
7674
		if ( inst ) {
7675
			if ( this._curInst === inst ) {
7676
				this._hideDatepicker();
7677
			}
7678
 
7679
			date = this._getDateDatepicker( target, true );
7680
			minDate = this._getMinMaxDate( inst, "min" );
7681
			maxDate = this._getMinMaxDate( inst, "max" );
7682
			datepicker_extendRemove( inst.settings, settings );
7683
 
7684
			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
7685
			if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) {
7686
				inst.settings.minDate = this._formatDate( inst, minDate );
7687
			}
7688
			if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) {
7689
				inst.settings.maxDate = this._formatDate( inst, maxDate );
7690
			}
7691
			if ( "disabled" in settings ) {
7692
				if ( settings.disabled ) {
7693
					this._disableDatepicker( target );
7694
				} else {
7695
					this._enableDatepicker( target );
7696
				}
7697
			}
7698
			this._attachments( $( target ), inst );
7699
			this._autoSize( inst );
7700
			this._setDate( inst, date );
7701
			this._updateAlternate( inst );
7702
			this._updateDatepicker( inst );
7703
		}
7704
	},
7705
 
7706
	// Change method deprecated
7707
	_changeDatepicker: function( target, name, value ) {
7708
		this._optionDatepicker( target, name, value );
7709
	},
7710
 
7711
	/* Redraw the date picker attached to an input field or division.
7712
	 * @param  target  element - the target input field or division or span
7713
	 */
7714
	_refreshDatepicker: function( target ) {
7715
		var inst = this._getInst( target );
7716
		if ( inst ) {
7717
			this._updateDatepicker( inst );
7718
		}
7719
	},
7720
 
7721
	/* Set the dates for a jQuery selection.
7722
	 * @param  target element - the target input field or division or span
7723
	 * @param  date	Date - the new date
7724
	 */
7725
	_setDateDatepicker: function( target, date ) {
7726
		var inst = this._getInst( target );
7727
		if ( inst ) {
7728
			this._setDate( inst, date );
7729
			this._updateDatepicker( inst );
7730
			this._updateAlternate( inst );
7731
		}
7732
	},
7733
 
7734
	/* Get the date(s) for the first entry in a jQuery selection.
7735
	 * @param  target element - the target input field or division or span
7736
	 * @param  noDefault boolean - true if no default date is to be used
7737
	 * @return Date - the current date
7738
	 */
7739
	_getDateDatepicker: function( target, noDefault ) {
7740
		var inst = this._getInst( target );
7741
		if ( inst && !inst.inline ) {
7742
			this._setDateFromField( inst, noDefault );
7743
		}
7744
		return ( inst ? this._getDate( inst ) : null );
7745
	},
7746
 
7747
	/* Handle keystrokes. */
7748
	_doKeyDown: function( event ) {
7749
		var onSelect, dateStr, sel,
7750
			inst = $.datepicker._getInst( event.target ),
7751
			handled = true,
7752
			isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" );
7753
 
7754
		inst._keyEvent = true;
7755
		if ( $.datepicker._datepickerShowing ) {
7756
			switch ( event.keyCode ) {
7757
				case 9: $.datepicker._hideDatepicker();
7758
						handled = false;
7759
						break; // hide on tab out
7760
				case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." +
7761
									$.datepicker._currentClass + ")", inst.dpDiv );
7762
						if ( sel[ 0 ] ) {
7763
							$.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] );
7764
						}
7765
 
7766
						onSelect = $.datepicker._get( inst, "onSelect" );
7767
						if ( onSelect ) {
7768
							dateStr = $.datepicker._formatDate( inst );
7769
 
7770
							// Trigger custom callback
7771
							onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );
7772
						} else {
7773
							$.datepicker._hideDatepicker();
7774
						}
7775
 
7776
						return false; // don't submit the form
7777
				case 27: $.datepicker._hideDatepicker();
7778
						break; // hide on escape
7779
				case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7780
							-$.datepicker._get( inst, "stepBigMonths" ) :
7781
							-$.datepicker._get( inst, "stepMonths" ) ), "M" );
7782
						break; // previous month/year on page up/+ ctrl
7783
				case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7784
							+$.datepicker._get( inst, "stepBigMonths" ) :
7785
							+$.datepicker._get( inst, "stepMonths" ) ), "M" );
7786
						break; // next month/year on page down/+ ctrl
7787
				case 35: if ( event.ctrlKey || event.metaKey ) {
7788
							$.datepicker._clearDate( event.target );
7789
						}
7790
						handled = event.ctrlKey || event.metaKey;
7791
						break; // clear on ctrl or command +end
7792
				case 36: if ( event.ctrlKey || event.metaKey ) {
7793
							$.datepicker._gotoToday( event.target );
7794
						}
7795
						handled = event.ctrlKey || event.metaKey;
7796
						break; // current on ctrl or command +home
7797
				case 37: if ( event.ctrlKey || event.metaKey ) {
7798
							$.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" );
7799
						}
7800
						handled = event.ctrlKey || event.metaKey;
7801
 
7802
						// -1 day on ctrl or command +left
7803
						if ( event.originalEvent.altKey ) {
7804
							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7805
								-$.datepicker._get( inst, "stepBigMonths" ) :
7806
								-$.datepicker._get( inst, "stepMonths" ) ), "M" );
7807
						}
7808
 
7809
						// next month/year on alt +left on Mac
7810
						break;
7811
				case 38: if ( event.ctrlKey || event.metaKey ) {
7812
							$.datepicker._adjustDate( event.target, -7, "D" );
7813
						}
7814
						handled = event.ctrlKey || event.metaKey;
7815
						break; // -1 week on ctrl or command +up
7816
				case 39: if ( event.ctrlKey || event.metaKey ) {
7817
							$.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" );
7818
						}
7819
						handled = event.ctrlKey || event.metaKey;
7820
 
7821
						// +1 day on ctrl or command +right
7822
						if ( event.originalEvent.altKey ) {
7823
							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7824
								+$.datepicker._get( inst, "stepBigMonths" ) :
7825
								+$.datepicker._get( inst, "stepMonths" ) ), "M" );
7826
						}
7827
 
7828
						// next month/year on alt +right
7829
						break;
7830
				case 40: if ( event.ctrlKey || event.metaKey ) {
7831
							$.datepicker._adjustDate( event.target, +7, "D" );
7832
						}
7833
						handled = event.ctrlKey || event.metaKey;
7834
						break; // +1 week on ctrl or command +down
7835
				default: handled = false;
7836
			}
7837
		} else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home
7838
			$.datepicker._showDatepicker( this );
7839
		} else {
7840
			handled = false;
7841
		}
7842
 
7843
		if ( handled ) {
7844
			event.preventDefault();
7845
			event.stopPropagation();
7846
		}
7847
	},
7848
 
7849
	/* Filter entered characters - based on date format. */
7850
	_doKeyPress: function( event ) {
7851
		var chars, chr,
7852
			inst = $.datepicker._getInst( event.target );
7853
 
7854
		if ( $.datepicker._get( inst, "constrainInput" ) ) {
7855
			chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) );
7856
			chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode );
7857
			return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 );
7858
		}
7859
	},
7860
 
7861
	/* Synchronise manual entry and field/alternate field. */
7862
	_doKeyUp: function( event ) {
7863
		var date,
7864
			inst = $.datepicker._getInst( event.target );
7865
 
7866
		if ( inst.input.val() !== inst.lastVal ) {
7867
			try {
7868
				date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
7869
					( inst.input ? inst.input.val() : null ),
7870
					$.datepicker._getFormatConfig( inst ) );
7871
 
7872
				if ( date ) { // only if valid
7873
					$.datepicker._setDateFromField( inst );
7874
					$.datepicker._updateAlternate( inst );
7875
					$.datepicker._updateDatepicker( inst );
7876
				}
7877
			}
7878
			catch ( err ) {
7879
			}
7880
		}
7881
		return true;
7882
	},
7883
 
7884
	/* Pop-up the date picker for a given input field.
7885
	 * If false returned from beforeShow event handler do not show.
7886
	 * @param  input  element - the input field attached to the date picker or
7887
	 *					event - if triggered by focus
7888
	 */
7889
	_showDatepicker: function( input ) {
7890
		input = input.target || input;
7891
		if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger
7892
			input = $( "input", input.parentNode )[ 0 ];
7893
		}
7894
 
7895
		if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here
7896
			return;
7897
		}
7898
 
7899
		var inst, beforeShow, beforeShowSettings, isFixed,
7900
			offset, showAnim, duration;
7901
 
7902
		inst = $.datepicker._getInst( input );
7903
		if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) {
7904
			$.datepicker._curInst.dpDiv.stop( true, true );
7905
			if ( inst && $.datepicker._datepickerShowing ) {
7906
				$.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] );
7907
			}
7908
		}
7909
 
7910
		beforeShow = $.datepicker._get( inst, "beforeShow" );
7911
		beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {};
7912
		if ( beforeShowSettings === false ) {
7913
			return;
7914
		}
7915
		datepicker_extendRemove( inst.settings, beforeShowSettings );
7916
 
7917
		inst.lastVal = null;
7918
		$.datepicker._lastInput = input;
7919
		$.datepicker._setDateFromField( inst );
7920
 
7921
		if ( $.datepicker._inDialog ) { // hide cursor
7922
			input.value = "";
7923
		}
7924
		if ( !$.datepicker._pos ) { // position below input
7925
			$.datepicker._pos = $.datepicker._findPos( input );
7926
			$.datepicker._pos[ 1 ] += input.offsetHeight; // add the height
7927
		}
7928
 
7929
		isFixed = false;
7930
		$( input ).parents().each( function() {
7931
			isFixed |= $( this ).css( "position" ) === "fixed";
7932
			return !isFixed;
7933
		} );
7934
 
7935
		offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] };
7936
		$.datepicker._pos = null;
7937
 
7938
		//to avoid flashes on Firefox
7939
		inst.dpDiv.empty();
7940
 
7941
		// determine sizing offscreen
7942
		inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } );
7943
		$.datepicker._updateDatepicker( inst );
7944
 
7945
		// fix width for dynamic number of date pickers
7946
		// and adjust position before showing
7947
		offset = $.datepicker._checkOffset( inst, offset, isFixed );
7948
		inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ?
7949
			"static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none",
7950
			left: offset.left + "px", top: offset.top + "px" } );
7951
 
7952
		if ( !inst.inline ) {
7953
			showAnim = $.datepicker._get( inst, "showAnim" );
7954
			duration = $.datepicker._get( inst, "duration" );
7955
			inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
7956
			$.datepicker._datepickerShowing = true;
7957
 
7958
			if ( $.effects && $.effects.effect[ showAnim ] ) {
7959
				inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration );
7960
			} else {
7961
				inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null );
7962
			}
7963
 
7964
			if ( $.datepicker._shouldFocusInput( inst ) ) {
7965
				inst.input.trigger( "focus" );
7966
			}
7967
 
7968
			$.datepicker._curInst = inst;
7969
		}
7970
	},
7971
 
7972
	/* Generate the date picker content. */
7973
	_updateDatepicker: function( inst ) {
7974
		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
7975
		datepicker_instActive = inst; // for delegate hover events
7976
		inst.dpDiv.empty().append( this._generateHTML( inst ) );
7977
		this._attachHandlers( inst );
7978
 
7979
		var origyearshtml,
7980
			numMonths = this._getNumberOfMonths( inst ),
7981
			cols = numMonths[ 1 ],
7982
			width = 17,
7983
			activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
7984
 
7985
		if ( activeCell.length > 0 ) {
7986
			datepicker_handleMouseover.apply( activeCell.get( 0 ) );
7987
		}
7988
 
7989
		inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" );
7990
		if ( cols > 1 ) {
7991
			inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" );
7992
		}
7993
		inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) +
7994
			"Class" ]( "ui-datepicker-multi" );
7995
		inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) +
7996
			"Class" ]( "ui-datepicker-rtl" );
7997
 
7998
		if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
7999
			inst.input.trigger( "focus" );
8000
		}
8001
 
8002
		// Deffered render of the years select (to avoid flashes on Firefox)
8003
		if ( inst.yearshtml ) {
8004
			origyearshtml = inst.yearshtml;
8005
			setTimeout( function() {
8006
 
8007
				//assure that inst.yearshtml didn't change.
8008
				if ( origyearshtml === inst.yearshtml && inst.yearshtml ) {
8009
					inst.dpDiv.find( "select.ui-datepicker-year:first" ).replaceWith( inst.yearshtml );
8010
				}
8011
				origyearshtml = inst.yearshtml = null;
8012
			}, 0 );
8013
		}
8014
	},
8015
 
8016
	// #6694 - don't focus the input if it's already focused
8017
	// this breaks the change event in IE
8018
	// Support: IE and jQuery <1.9
8019
	_shouldFocusInput: function( inst ) {
8020
		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
8021
	},
8022
 
8023
	/* Check positioning to remain on screen. */
8024
	_checkOffset: function( inst, offset, isFixed ) {
8025
		var dpWidth = inst.dpDiv.outerWidth(),
8026
			dpHeight = inst.dpDiv.outerHeight(),
8027
			inputWidth = inst.input ? inst.input.outerWidth() : 0,
8028
			inputHeight = inst.input ? inst.input.outerHeight() : 0,
8029
			viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ),
8030
			viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() );
8031
 
8032
		offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 );
8033
		offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0;
8034
		offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0;
8035
 
8036
		// Now check if datepicker is showing outside window viewport - move to a better place if so.
8037
		offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ?
8038
			Math.abs( offset.left + dpWidth - viewWidth ) : 0 );
8039
		offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ?
8040
			Math.abs( dpHeight + inputHeight ) : 0 );
8041
 
8042
		return offset;
8043
	},
8044
 
8045
	/* Find an object's position on the screen. */
8046
	_findPos: function( obj ) {
8047
		var position,
8048
			inst = this._getInst( obj ),
8049
			isRTL = this._get( inst, "isRTL" );
8050
 
8051
		while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden( obj ) ) ) {
8052
			obj = obj[ isRTL ? "previousSibling" : "nextSibling" ];
8053
		}
8054
 
8055
		position = $( obj ).offset();
8056
		return [ position.left, position.top ];
8057
	},
8058
 
8059
	/* Hide the date picker from view.
8060
	 * @param  input  element - the input field attached to the date picker
8061
	 */
8062
	_hideDatepicker: function( input ) {
8063
		var showAnim, duration, postProcess, onClose,
8064
			inst = this._curInst;
8065
 
8066
		if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) {
8067
			return;
8068
		}
8069
 
8070
		if ( this._datepickerShowing ) {
8071
			showAnim = this._get( inst, "showAnim" );
8072
			duration = this._get( inst, "duration" );
8073
			postProcess = function() {
8074
				$.datepicker._tidyDialog( inst );
8075
			};
8076
 
8077
			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
8078
			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
8079
				inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess );
8080
			} else {
8081
				inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" :
8082
					( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess );
8083
			}
8084
 
8085
			if ( !showAnim ) {
8086
				postProcess();
8087
			}
8088
			this._datepickerShowing = false;
8089
 
8090
			onClose = this._get( inst, "onClose" );
8091
			if ( onClose ) {
8092
				onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] );
8093
			}
8094
 
8095
			this._lastInput = null;
8096
			if ( this._inDialog ) {
8097
				this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } );
8098
				if ( $.blockUI ) {
8099
					$.unblockUI();
8100
					$( "body" ).append( this.dpDiv );
8101
				}
8102
			}
8103
			this._inDialog = false;
8104
		}
8105
	},
8106
 
8107
	/* Tidy up after a dialog display. */
8108
	_tidyDialog: function( inst ) {
8109
		inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" );
8110
	},
8111
 
8112
	/* Close date picker if clicked elsewhere. */
8113
	_checkExternalClick: function( event ) {
8114
		if ( !$.datepicker._curInst ) {
8115
			return;
8116
		}
8117
 
8118
		var $target = $( event.target ),
8119
			inst = $.datepicker._getInst( $target[ 0 ] );
8120
 
8121
		if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId &&
8122
				$target.parents( "#" + $.datepicker._mainDivId ).length === 0 &&
8123
				!$target.hasClass( $.datepicker.markerClassName ) &&
8124
				!$target.closest( "." + $.datepicker._triggerClass ).length &&
8125
				$.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) ||
8126
			( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) {
8127
				$.datepicker._hideDatepicker();
8128
		}
8129
	},
8130
 
8131
	/* Adjust one of the date sub-fields. */
8132
	_adjustDate: function( id, offset, period ) {
8133
		var target = $( id ),
8134
			inst = this._getInst( target[ 0 ] );
8135
 
8136
		if ( this._isDisabledDatepicker( target[ 0 ] ) ) {
8137
			return;
8138
		}
8139
		this._adjustInstDate( inst, offset +
8140
			( period === "M" ? this._get( inst, "showCurrentAtPos" ) : 0 ), // undo positioning
8141
			period );
8142
		this._updateDatepicker( inst );
8143
	},
8144
 
8145
	/* Action for current link. */
8146
	_gotoToday: function( id ) {
8147
		var date,
8148
			target = $( id ),
8149
			inst = this._getInst( target[ 0 ] );
8150
 
8151
		if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) {
8152
			inst.selectedDay = inst.currentDay;
8153
			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8154
			inst.drawYear = inst.selectedYear = inst.currentYear;
8155
		} else {
8156
			date = new Date();
8157
			inst.selectedDay = date.getDate();
8158
			inst.drawMonth = inst.selectedMonth = date.getMonth();
8159
			inst.drawYear = inst.selectedYear = date.getFullYear();
8160
		}
8161
		this._notifyChange( inst );
8162
		this._adjustDate( target );
8163
	},
8164
 
8165
	/* Action for selecting a new month/year. */
8166
	_selectMonthYear: function( id, select, period ) {
8167
		var target = $( id ),
8168
			inst = this._getInst( target[ 0 ] );
8169
 
8170
		inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] =
8171
		inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] =
8172
			parseInt( select.options[ select.selectedIndex ].value, 10 );
8173
 
8174
		this._notifyChange( inst );
8175
		this._adjustDate( target );
8176
	},
8177
 
8178
	/* Action for selecting a day. */
8179
	_selectDay: function( id, month, year, td ) {
8180
		var inst,
8181
			target = $( id );
8182
 
8183
		if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) {
8184
			return;
8185
		}
8186
 
8187
		inst = this._getInst( target[ 0 ] );
8188
		inst.selectedDay = inst.currentDay = $( "a", td ).html();
8189
		inst.selectedMonth = inst.currentMonth = month;
8190
		inst.selectedYear = inst.currentYear = year;
8191
		this._selectDate( id, this._formatDate( inst,
8192
			inst.currentDay, inst.currentMonth, inst.currentYear ) );
8193
	},
8194
 
8195
	/* Erase the input field and hide the date picker. */
8196
	_clearDate: function( id ) {
8197
		var target = $( id );
8198
		this._selectDate( target, "" );
8199
	},
8200
 
8201
	/* Update the input field with the selected date. */
8202
	_selectDate: function( id, dateStr ) {
8203
		var onSelect,
8204
			target = $( id ),
8205
			inst = this._getInst( target[ 0 ] );
8206
 
8207
		dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) );
8208
		if ( inst.input ) {
8209
			inst.input.val( dateStr );
8210
		}
8211
		this._updateAlternate( inst );
8212
 
8213
		onSelect = this._get( inst, "onSelect" );
8214
		if ( onSelect ) {
8215
			onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );  // trigger custom callback
8216
		} else if ( inst.input ) {
8217
			inst.input.trigger( "change" ); // fire the change event
8218
		}
8219
 
8220
		if ( inst.inline ) {
8221
			this._updateDatepicker( inst );
8222
		} else {
8223
			this._hideDatepicker();
8224
			this._lastInput = inst.input[ 0 ];
8225
			if ( typeof( inst.input[ 0 ] ) !== "object" ) {
8226
				inst.input.trigger( "focus" ); // restore focus
8227
			}
8228
			this._lastInput = null;
8229
		}
8230
	},
8231
 
8232
	/* Update any alternate field to synchronise with the main field. */
8233
	_updateAlternate: function( inst ) {
8234
		var altFormat, date, dateStr,
8235
			altField = this._get( inst, "altField" );
8236
 
8237
		if ( altField ) { // update alternate field too
8238
			altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" );
8239
			date = this._getDate( inst );
8240
			dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) );
8241
			$( altField ).val( dateStr );
8242
		}
8243
	},
8244
 
8245
	/* Set as beforeShowDay function to prevent selection of weekends.
8246
	 * @param  date  Date - the date to customise
8247
	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
8248
	 */
8249
	noWeekends: function( date ) {
8250
		var day = date.getDay();
8251
		return [ ( day > 0 && day < 6 ), "" ];
8252
	},
8253
 
8254
	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
8255
	 * @param  date  Date - the date to get the week for
8256
	 * @return  number - the number of the week within the year that contains this date
8257
	 */
8258
	iso8601Week: function( date ) {
8259
		var time,
8260
			checkDate = new Date( date.getTime() );
8261
 
8262
		// Find Thursday of this week starting on Monday
8263
		checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) );
8264
 
8265
		time = checkDate.getTime();
8266
		checkDate.setMonth( 0 ); // Compare with Jan 1
8267
		checkDate.setDate( 1 );
8268
		return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1;
8269
	},
8270
 
8271
	/* Parse a string value into a date object.
8272
	 * See formatDate below for the possible formats.
8273
	 *
8274
	 * @param  format string - the expected format of the date
8275
	 * @param  value string - the date in the above format
8276
	 * @param  settings Object - attributes include:
8277
	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
8278
	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
8279
	 *					dayNames		string[7] - names of the days from Sunday (optional)
8280
	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
8281
	 *					monthNames		string[12] - names of the months (optional)
8282
	 * @return  Date - the extracted date value or null if value is blank
8283
	 */
8284
	parseDate: function( format, value, settings ) {
8285
		if ( format == null || value == null ) {
8286
			throw "Invalid arguments";
8287
		}
8288
 
8289
		value = ( typeof value === "object" ? value.toString() : value + "" );
8290
		if ( value === "" ) {
8291
			return null;
8292
		}
8293
 
8294
		var iFormat, dim, extra,
8295
			iValue = 0,
8296
			shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff,
8297
			shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
8298
				new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ),
8299
			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
8300
			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
8301
			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
8302
			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
8303
			year = -1,
8304
			month = -1,
8305
			day = -1,
8306
			doy = -1,
8307
			literal = false,
8308
			date,
8309
 
8310
			// Check whether a format character is doubled
8311
			lookAhead = function( match ) {
8312
				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8313
				if ( matches ) {
8314
					iFormat++;
8315
				}
8316
				return matches;
8317
			},
8318
 
8319
			// Extract a number from the string value
8320
			getNumber = function( match ) {
8321
				var isDoubled = lookAhead( match ),
8322
					size = ( match === "@" ? 14 : ( match === "!" ? 20 :
8323
					( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ),
8324
					minSize = ( match === "y" ? size : 1 ),
8325
					digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ),
8326
					num = value.substring( iValue ).match( digits );
8327
				if ( !num ) {
8328
					throw "Missing number at position " + iValue;
8329
				}
8330
				iValue += num[ 0 ].length;
8331
				return parseInt( num[ 0 ], 10 );
8332
			},
8333
 
8334
			// Extract a name from the string value and convert to an index
8335
			getName = function( match, shortNames, longNames ) {
8336
				var index = -1,
8337
					names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) {
8338
						return [ [ k, v ] ];
8339
					} ).sort( function( a, b ) {
8340
						return -( a[ 1 ].length - b[ 1 ].length );
8341
					} );
8342
 
8343
				$.each( names, function( i, pair ) {
8344
					var name = pair[ 1 ];
8345
					if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) {
8346
						index = pair[ 0 ];
8347
						iValue += name.length;
8348
						return false;
8349
					}
8350
				} );
8351
				if ( index !== -1 ) {
8352
					return index + 1;
8353
				} else {
8354
					throw "Unknown name at position " + iValue;
8355
				}
8356
			},
8357
 
8358
			// Confirm that a literal character matches the string value
8359
			checkLiteral = function() {
8360
				if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) {
8361
					throw "Unexpected literal at position " + iValue;
8362
				}
8363
				iValue++;
8364
			};
8365
 
8366
		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8367
			if ( literal ) {
8368
				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8369
					literal = false;
8370
				} else {
8371
					checkLiteral();
8372
				}
8373
			} else {
8374
				switch ( format.charAt( iFormat ) ) {
8375
					case "d":
8376
						day = getNumber( "d" );
8377
						break;
8378
					case "D":
8379
						getName( "D", dayNamesShort, dayNames );
8380
						break;
8381
					case "o":
8382
						doy = getNumber( "o" );
8383
						break;
8384
					case "m":
8385
						month = getNumber( "m" );
8386
						break;
8387
					case "M":
8388
						month = getName( "M", monthNamesShort, monthNames );
8389
						break;
8390
					case "y":
8391
						year = getNumber( "y" );
8392
						break;
8393
					case "@":
8394
						date = new Date( getNumber( "@" ) );
8395
						year = date.getFullYear();
8396
						month = date.getMonth() + 1;
8397
						day = date.getDate();
8398
						break;
8399
					case "!":
8400
						date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 );
8401
						year = date.getFullYear();
8402
						month = date.getMonth() + 1;
8403
						day = date.getDate();
8404
						break;
8405
					case "'":
8406
						if ( lookAhead( "'" ) ) {
8407
							checkLiteral();
8408
						} else {
8409
							literal = true;
8410
						}
8411
						break;
8412
					default:
8413
						checkLiteral();
8414
				}
8415
			}
8416
		}
8417
 
8418
		if ( iValue < value.length ) {
8419
			extra = value.substr( iValue );
8420
			if ( !/^\s+/.test( extra ) ) {
8421
				throw "Extra/unparsed characters found in date: " + extra;
8422
			}
8423
		}
8424
 
8425
		if ( year === -1 ) {
8426
			year = new Date().getFullYear();
8427
		} else if ( year < 100 ) {
8428
			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8429
				( year <= shortYearCutoff ? 0 : -100 );
8430
		}
8431
 
8432
		if ( doy > -1 ) {
8433
			month = 1;
8434
			day = doy;
8435
			do {
8436
				dim = this._getDaysInMonth( year, month - 1 );
8437
				if ( day <= dim ) {
8438
					break;
8439
				}
8440
				month++;
8441
				day -= dim;
8442
			} while ( true );
8443
		}
8444
 
8445
		date = this._daylightSavingAdjust( new Date( year, month - 1, day ) );
8446
		if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) {
8447
			throw "Invalid date"; // E.g. 31/02/00
8448
		}
8449
		return date;
8450
	},
8451
 
8452
	/* Standard date formats. */
8453
	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
8454
	COOKIE: "D, dd M yy",
8455
	ISO_8601: "yy-mm-dd",
8456
	RFC_822: "D, d M y",
8457
	RFC_850: "DD, dd-M-y",
8458
	RFC_1036: "D, d M y",
8459
	RFC_1123: "D, d M yy",
8460
	RFC_2822: "D, d M yy",
8461
	RSS: "D, d M y", // RFC 822
8462
	TICKS: "!",
8463
	TIMESTAMP: "@",
8464
	W3C: "yy-mm-dd", // ISO 8601
8465
 
8466
	_ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) +
8467
		Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ),
8468
 
8469
	/* Format a date object into a string value.
8470
	 * The format can be combinations of the following:
8471
	 * d  - day of month (no leading zero)
8472
	 * dd - day of month (two digit)
8473
	 * o  - day of year (no leading zeros)
8474
	 * oo - day of year (three digit)
8475
	 * D  - day name short
8476
	 * DD - day name long
8477
	 * m  - month of year (no leading zero)
8478
	 * mm - month of year (two digit)
8479
	 * M  - month name short
8480
	 * MM - month name long
8481
	 * y  - year (two digit)
8482
	 * yy - year (four digit)
8483
	 * @ - Unix timestamp (ms since 01/01/1970)
8484
	 * ! - Windows ticks (100ns since 01/01/0001)
8485
	 * "..." - literal text
8486
	 * '' - single quote
8487
	 *
8488
	 * @param  format string - the desired format of the date
8489
	 * @param  date Date - the date value to format
8490
	 * @param  settings Object - attributes include:
8491
	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
8492
	 *					dayNames		string[7] - names of the days from Sunday (optional)
8493
	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
8494
	 *					monthNames		string[12] - names of the months (optional)
8495
	 * @return  string - the date in the above format
8496
	 */
8497
	formatDate: function( format, date, settings ) {
8498
		if ( !date ) {
8499
			return "";
8500
		}
8501
 
8502
		var iFormat,
8503
			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
8504
			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
8505
			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
8506
			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
8507
 
8508
			// Check whether a format character is doubled
8509
			lookAhead = function( match ) {
8510
				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8511
				if ( matches ) {
8512
					iFormat++;
8513
				}
8514
				return matches;
8515
			},
8516
 
8517
			// Format a number, with leading zero if necessary
8518
			formatNumber = function( match, value, len ) {
8519
				var num = "" + value;
8520
				if ( lookAhead( match ) ) {
8521
					while ( num.length < len ) {
8522
						num = "0" + num;
8523
					}
8524
				}
8525
				return num;
8526
			},
8527
 
8528
			// Format a name, short or long as requested
8529
			formatName = function( match, value, shortNames, longNames ) {
8530
				return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] );
8531
			},
8532
			output = "",
8533
			literal = false;
8534
 
8535
		if ( date ) {
8536
			for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8537
				if ( literal ) {
8538
					if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8539
						literal = false;
8540
					} else {
8541
						output += format.charAt( iFormat );
8542
					}
8543
				} else {
8544
					switch ( format.charAt( iFormat ) ) {
8545
						case "d":
8546
							output += formatNumber( "d", date.getDate(), 2 );
8547
							break;
8548
						case "D":
8549
							output += formatName( "D", date.getDay(), dayNamesShort, dayNames );
8550
							break;
8551
						case "o":
8552
							output += formatNumber( "o",
8553
								Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 );
8554
							break;
8555
						case "m":
8556
							output += formatNumber( "m", date.getMonth() + 1, 2 );
8557
							break;
8558
						case "M":
8559
							output += formatName( "M", date.getMonth(), monthNamesShort, monthNames );
8560
							break;
8561
						case "y":
8562
							output += ( lookAhead( "y" ) ? date.getFullYear() :
8563
								( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 );
8564
							break;
8565
						case "@":
8566
							output += date.getTime();
8567
							break;
8568
						case "!":
8569
							output += date.getTime() * 10000 + this._ticksTo1970;
8570
							break;
8571
						case "'":
8572
							if ( lookAhead( "'" ) ) {
8573
								output += "'";
8574
							} else {
8575
								literal = true;
8576
							}
8577
							break;
8578
						default:
8579
							output += format.charAt( iFormat );
8580
					}
8581
				}
8582
			}
8583
		}
8584
		return output;
8585
	},
8586
 
8587
	/* Extract all possible characters from the date format. */
8588
	_possibleChars: function( format ) {
8589
		var iFormat,
8590
			chars = "",
8591
			literal = false,
8592
 
8593
			// Check whether a format character is doubled
8594
			lookAhead = function( match ) {
8595
				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8596
				if ( matches ) {
8597
					iFormat++;
8598
				}
8599
				return matches;
8600
			};
8601
 
8602
		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8603
			if ( literal ) {
8604
				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8605
					literal = false;
8606
				} else {
8607
					chars += format.charAt( iFormat );
8608
				}
8609
			} else {
8610
				switch ( format.charAt( iFormat ) ) {
8611
					case "d": case "m": case "y": case "@":
8612
						chars += "0123456789";
8613
						break;
8614
					case "D": case "M":
8615
						return null; // Accept anything
8616
					case "'":
8617
						if ( lookAhead( "'" ) ) {
8618
							chars += "'";
8619
						} else {
8620
							literal = true;
8621
						}
8622
						break;
8623
					default:
8624
						chars += format.charAt( iFormat );
8625
				}
8626
			}
8627
		}
8628
		return chars;
8629
	},
8630
 
8631
	/* Get a setting value, defaulting if necessary. */
8632
	_get: function( inst, name ) {
8633
		return inst.settings[ name ] !== undefined ?
8634
			inst.settings[ name ] : this._defaults[ name ];
8635
	},
8636
 
8637
	/* Parse existing date and initialise date picker. */
8638
	_setDateFromField: function( inst, noDefault ) {
8639
		if ( inst.input.val() === inst.lastVal ) {
8640
			return;
8641
		}
8642
 
8643
		var dateFormat = this._get( inst, "dateFormat" ),
8644
			dates = inst.lastVal = inst.input ? inst.input.val() : null,
8645
			defaultDate = this._getDefaultDate( inst ),
8646
			date = defaultDate,
8647
			settings = this._getFormatConfig( inst );
8648
 
8649
		try {
8650
			date = this.parseDate( dateFormat, dates, settings ) || defaultDate;
8651
		} catch ( event ) {
8652
			dates = ( noDefault ? "" : dates );
8653
		}
8654
		inst.selectedDay = date.getDate();
8655
		inst.drawMonth = inst.selectedMonth = date.getMonth();
8656
		inst.drawYear = inst.selectedYear = date.getFullYear();
8657
		inst.currentDay = ( dates ? date.getDate() : 0 );
8658
		inst.currentMonth = ( dates ? date.getMonth() : 0 );
8659
		inst.currentYear = ( dates ? date.getFullYear() : 0 );
8660
		this._adjustInstDate( inst );
8661
	},
8662
 
8663
	/* Retrieve the default date shown on opening. */
8664
	_getDefaultDate: function( inst ) {
8665
		return this._restrictMinMax( inst,
8666
			this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) );
8667
	},
8668
 
8669
	/* A date may be specified as an exact value or a relative one. */
8670
	_determineDate: function( inst, date, defaultDate ) {
8671
		var offsetNumeric = function( offset ) {
8672
				var date = new Date();
8673
				date.setDate( date.getDate() + offset );
8674
				return date;
8675
			},
8676
			offsetString = function( offset ) {
8677
				try {
8678
					return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
8679
						offset, $.datepicker._getFormatConfig( inst ) );
8680
				}
8681
				catch ( e ) {
8682
 
8683
					// Ignore
8684
				}
8685
 
8686
				var date = ( offset.toLowerCase().match( /^c/ ) ?
8687
					$.datepicker._getDate( inst ) : null ) || new Date(),
8688
					year = date.getFullYear(),
8689
					month = date.getMonth(),
8690
					day = date.getDate(),
8691
					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
8692
					matches = pattern.exec( offset );
8693
 
8694
				while ( matches ) {
8695
					switch ( matches[ 2 ] || "d" ) {
8696
						case "d" : case "D" :
8697
							day += parseInt( matches[ 1 ], 10 ); break;
8698
						case "w" : case "W" :
8699
							day += parseInt( matches[ 1 ], 10 ) * 7; break;
8700
						case "m" : case "M" :
8701
							month += parseInt( matches[ 1 ], 10 );
8702
							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
8703
							break;
8704
						case "y": case "Y" :
8705
							year += parseInt( matches[ 1 ], 10 );
8706
							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
8707
							break;
8708
					}
8709
					matches = pattern.exec( offset );
8710
				}
8711
				return new Date( year, month, day );
8712
			},
8713
			newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) :
8714
				( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) );
8715
 
8716
		newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate );
8717
		if ( newDate ) {
8718
			newDate.setHours( 0 );
8719
			newDate.setMinutes( 0 );
8720
			newDate.setSeconds( 0 );
8721
			newDate.setMilliseconds( 0 );
8722
		}
8723
		return this._daylightSavingAdjust( newDate );
8724
	},
8725
 
8726
	/* Handle switch to/from daylight saving.
8727
	 * Hours may be non-zero on daylight saving cut-over:
8728
	 * > 12 when midnight changeover, but then cannot generate
8729
	 * midnight datetime, so jump to 1AM, otherwise reset.
8730
	 * @param  date  (Date) the date to check
8731
	 * @return  (Date) the corrected date
8732
	 */
8733
	_daylightSavingAdjust: function( date ) {
8734
		if ( !date ) {
8735
			return null;
8736
		}
8737
		date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 );
8738
		return date;
8739
	},
8740
 
8741
	/* Set the date(s) directly. */
8742
	_setDate: function( inst, date, noChange ) {
8743
		var clear = !date,
8744
			origMonth = inst.selectedMonth,
8745
			origYear = inst.selectedYear,
8746
			newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) );
8747
 
8748
		inst.selectedDay = inst.currentDay = newDate.getDate();
8749
		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
8750
		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
8751
		if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) {
8752
			this._notifyChange( inst );
8753
		}
8754
		this._adjustInstDate( inst );
8755
		if ( inst.input ) {
8756
			inst.input.val( clear ? "" : this._formatDate( inst ) );
8757
		}
8758
	},
8759
 
8760
	/* Retrieve the date(s) directly. */
8761
	_getDate: function( inst ) {
8762
		var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null :
8763
			this._daylightSavingAdjust( new Date(
8764
			inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
8765
			return startDate;
8766
	},
8767
 
8768
	/* Attach the onxxx handlers.  These are declared statically so
8769
	 * they work with static code transformers like Caja.
8770
	 */
8771
	_attachHandlers: function( inst ) {
8772
		var stepMonths = this._get( inst, "stepMonths" ),
8773
			id = "#" + inst.id.replace( /\\\\/g, "\\" );
8774
		inst.dpDiv.find( "[data-handler]" ).map( function() {
8775
			var handler = {
8776
				prev: function() {
8777
					$.datepicker._adjustDate( id, -stepMonths, "M" );
8778
				},
8779
				next: function() {
8780
					$.datepicker._adjustDate( id, +stepMonths, "M" );
8781
				},
8782
				hide: function() {
8783
					$.datepicker._hideDatepicker();
8784
				},
8785
				today: function() {
8786
					$.datepicker._gotoToday( id );
8787
				},
8788
				selectDay: function() {
8789
					$.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this );
8790
					return false;
8791
				},
8792
				selectMonth: function() {
8793
					$.datepicker._selectMonthYear( id, this, "M" );
8794
					return false;
8795
				},
8796
				selectYear: function() {
8797
					$.datepicker._selectMonthYear( id, this, "Y" );
8798
					return false;
8799
				}
8800
			};
8801
			$( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] );
8802
		} );
8803
	},
8804
 
8805
	/* Generate the HTML for the current state of the date picker. */
8806
	_generateHTML: function( inst ) {
8807
		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
8808
			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
8809
			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
8810
			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
8811
			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
8812
			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
8813
			tempDate = new Date(),
8814
			today = this._daylightSavingAdjust(
8815
				new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time
8816
			isRTL = this._get( inst, "isRTL" ),
8817
			showButtonPanel = this._get( inst, "showButtonPanel" ),
8818
			hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ),
8819
			navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ),
8820
			numMonths = this._getNumberOfMonths( inst ),
8821
			showCurrentAtPos = this._get( inst, "showCurrentAtPos" ),
8822
			stepMonths = this._get( inst, "stepMonths" ),
8823
			isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ),
8824
			currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) :
8825
				new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ),
8826
			minDate = this._getMinMaxDate( inst, "min" ),
8827
			maxDate = this._getMinMaxDate( inst, "max" ),
8828
			drawMonth = inst.drawMonth - showCurrentAtPos,
8829
			drawYear = inst.drawYear;
8830
 
8831
		if ( drawMonth < 0 ) {
8832
			drawMonth += 12;
8833
			drawYear--;
8834
		}
8835
		if ( maxDate ) {
8836
			maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(),
8837
				maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) );
8838
			maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw );
8839
			while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) {
8840
				drawMonth--;
8841
				if ( drawMonth < 0 ) {
8842
					drawMonth = 11;
8843
					drawYear--;
8844
				}
8845
			}
8846
		}
8847
		inst.drawMonth = drawMonth;
8848
		inst.drawYear = drawYear;
8849
 
8850
		prevText = this._get( inst, "prevText" );
8851
		prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText,
8852
			this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ),
8853
			this._getFormatConfig( inst ) ) );
8854
 
8855
		prev = ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ?
8856
			"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
8857
			" title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" :
8858
			( hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" ) );
8859
 
8860
		nextText = this._get( inst, "nextText" );
8861
		nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText,
8862
			this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ),
8863
			this._getFormatConfig( inst ) ) );
8864
 
8865
		next = ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ?
8866
			"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
8867
			" title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" :
8868
			( hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" ) );
8869
 
8870
		currentText = this._get( inst, "currentText" );
8871
		gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today );
8872
		currentText = ( !navigationAsDateFormat ? currentText :
8873
			this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) );
8874
 
8875
		controls = ( !inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" +
8876
			this._get( inst, "closeText" ) + "</button>" : "" );
8877
 
8878
		buttonPanel = ( showButtonPanel ) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + ( isRTL ? controls : "" ) +
8879
			( this._isInRange( inst, gotoDate ) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" +
8880
			">" + currentText + "</button>" : "" ) + ( isRTL ? "" : controls ) + "</div>" : "";
8881
 
8882
		firstDay = parseInt( this._get( inst, "firstDay" ), 10 );
8883
		firstDay = ( isNaN( firstDay ) ? 0 : firstDay );
8884
 
8885
		showWeek = this._get( inst, "showWeek" );
8886
		dayNames = this._get( inst, "dayNames" );
8887
		dayNamesMin = this._get( inst, "dayNamesMin" );
8888
		monthNames = this._get( inst, "monthNames" );
8889
		monthNamesShort = this._get( inst, "monthNamesShort" );
8890
		beforeShowDay = this._get( inst, "beforeShowDay" );
8891
		showOtherMonths = this._get( inst, "showOtherMonths" );
8892
		selectOtherMonths = this._get( inst, "selectOtherMonths" );
8893
		defaultDate = this._getDefaultDate( inst );
8894
		html = "";
8895
 
8896
		for ( row = 0; row < numMonths[ 0 ]; row++ ) {
8897
			group = "";
8898
			this.maxRows = 4;
8899
			for ( col = 0; col < numMonths[ 1 ]; col++ ) {
8900
				selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) );
8901
				cornerClass = " ui-corner-all";
8902
				calender = "";
8903
				if ( isMultiMonth ) {
8904
					calender += "<div class='ui-datepicker-group";
8905
					if ( numMonths[ 1 ] > 1 ) {
8906
						switch ( col ) {
8907
							case 0: calender += " ui-datepicker-group-first";
8908
								cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break;
8909
							case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last";
8910
								cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break;
8911
							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
8912
						}
8913
					}
8914
					calender += "'>";
8915
				}
8916
				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
8917
					( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) +
8918
					( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) +
8919
					this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate,
8920
					row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers
8921
					"</div><table class='ui-datepicker-calendar'><thead>" +
8922
					"<tr>";
8923
				thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" );
8924
				for ( dow = 0; dow < 7; dow++ ) { // days of the week
8925
					day = ( dow + firstDay ) % 7;
8926
					thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" +
8927
						"<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>";
8928
				}
8929
				calender += thead + "</tr></thead><tbody>";
8930
				daysInMonth = this._getDaysInMonth( drawYear, drawMonth );
8931
				if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) {
8932
					inst.selectedDay = Math.min( inst.selectedDay, daysInMonth );
8933
				}
8934
				leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7;
8935
				curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate
8936
				numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043)
8937
				this.maxRows = numRows;
8938
				printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) );
8939
				for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows
8940
					calender += "<tr>";
8941
					tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
8942
						this._get( inst, "calculateWeek" )( printDate ) + "</td>" );
8943
					for ( dow = 0; dow < 7; dow++ ) { // create date picker days
8944
						daySettings = ( beforeShowDay ?
8945
							beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] );
8946
						otherMonth = ( printDate.getMonth() !== drawMonth );
8947
						unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] ||
8948
							( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate );
8949
						tbody += "<td class='" +
8950
							( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends
8951
							( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months
8952
							( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key
8953
							( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ?
8954
 
8955
							// or defaultDate is current printedDate and defaultDate is selectedDate
8956
							" " + this._dayOverClass : "" ) + // highlight selected day
8957
							( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) +  // highlight unselectable days
8958
							( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates
8959
							( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day
8960
							( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different)
8961
							( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "&#39;" ) + "'" : "" ) + // cell title
8962
							( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions
8963
							( otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
8964
							( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
8965
							( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) +
8966
							( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day
8967
							( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months
8968
							"' href='#'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date
8969
						printDate.setDate( printDate.getDate() + 1 );
8970
						printDate = this._daylightSavingAdjust( printDate );
8971
					}
8972
					calender += tbody + "</tr>";
8973
				}
8974
				drawMonth++;
8975
				if ( drawMonth > 11 ) {
8976
					drawMonth = 0;
8977
					drawYear++;
8978
				}
8979
				calender += "</tbody></table>" + ( isMultiMonth ? "</div>" +
8980
							( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" );
8981
				group += calender;
8982
			}
8983
			html += group;
8984
		}
8985
		html += buttonPanel;
8986
		inst._keyEvent = false;
8987
		return html;
8988
	},
8989
 
8990
	/* Generate the month and year header. */
8991
	_generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate,
8992
			secondary, monthNames, monthNamesShort ) {
8993
 
8994
		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
8995
			changeMonth = this._get( inst, "changeMonth" ),
8996
			changeYear = this._get( inst, "changeYear" ),
8997
			showMonthAfterYear = this._get( inst, "showMonthAfterYear" ),
8998
			html = "<div class='ui-datepicker-title'>",
8999
			monthHtml = "";
9000
 
9001
		// Month selection
9002
		if ( secondary || !changeMonth ) {
9003
			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>";
9004
		} else {
9005
			inMinYear = ( minDate && minDate.getFullYear() === drawYear );
9006
			inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear );
9007
			monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
9008
			for ( month = 0; month < 12; month++ ) {
9009
				if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) {
9010
					monthHtml += "<option value='" + month + "'" +
9011
						( month === drawMonth ? " selected='selected'" : "" ) +
9012
						">" + monthNamesShort[ month ] + "</option>";
9013
				}
9014
			}
9015
			monthHtml += "</select>";
9016
		}
9017
 
9018
		if ( !showMonthAfterYear ) {
9019
			html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" );
9020
		}
9021
 
9022
		// Year selection
9023
		if ( !inst.yearshtml ) {
9024
			inst.yearshtml = "";
9025
			if ( secondary || !changeYear ) {
9026
				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
9027
			} else {
9028
 
9029
				// determine range of years to display
9030
				years = this._get( inst, "yearRange" ).split( ":" );
9031
				thisYear = new Date().getFullYear();
9032
				determineYear = function( value ) {
9033
					var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) :
9034
						( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) :
9035
						parseInt( value, 10 ) ) );
9036
					return ( isNaN( year ) ? thisYear : year );
9037
				};
9038
				year = determineYear( years[ 0 ] );
9039
				endYear = Math.max( year, determineYear( years[ 1 ] || "" ) );
9040
				year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year );
9041
				endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear );
9042
				inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
9043
				for ( ; year <= endYear; year++ ) {
9044
					inst.yearshtml += "<option value='" + year + "'" +
9045
						( year === drawYear ? " selected='selected'" : "" ) +
9046
						">" + year + "</option>";
9047
				}
9048
				inst.yearshtml += "</select>";
9049
 
9050
				html += inst.yearshtml;
9051
				inst.yearshtml = null;
9052
			}
9053
		}
9054
 
9055
		html += this._get( inst, "yearSuffix" );
9056
		if ( showMonthAfterYear ) {
9057
			html += ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" ) + monthHtml;
9058
		}
9059
		html += "</div>"; // Close datepicker_header
9060
		return html;
9061
	},
9062
 
9063
	/* Adjust one of the date sub-fields. */
9064
	_adjustInstDate: function( inst, offset, period ) {
9065
		var year = inst.selectedYear + ( period === "Y" ? offset : 0 ),
9066
			month = inst.selectedMonth + ( period === "M" ? offset : 0 ),
9067
			day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ),
9068
			date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) );
9069
 
9070
		inst.selectedDay = date.getDate();
9071
		inst.drawMonth = inst.selectedMonth = date.getMonth();
9072
		inst.drawYear = inst.selectedYear = date.getFullYear();
9073
		if ( period === "M" || period === "Y" ) {
9074
			this._notifyChange( inst );
9075
		}
9076
	},
9077
 
9078
	/* Ensure a date is within any min/max bounds. */
9079
	_restrictMinMax: function( inst, date ) {
9080
		var minDate = this._getMinMaxDate( inst, "min" ),
9081
			maxDate = this._getMinMaxDate( inst, "max" ),
9082
			newDate = ( minDate && date < minDate ? minDate : date );
9083
		return ( maxDate && newDate > maxDate ? maxDate : newDate );
9084
	},
9085
 
9086
	/* Notify change of month/year. */
9087
	_notifyChange: function( inst ) {
9088
		var onChange = this._get( inst, "onChangeMonthYear" );
9089
		if ( onChange ) {
9090
			onChange.apply( ( inst.input ? inst.input[ 0 ] : null ),
9091
				[ inst.selectedYear, inst.selectedMonth + 1, inst ] );
9092
		}
9093
	},
9094
 
9095
	/* Determine the number of months to show. */
9096
	_getNumberOfMonths: function( inst ) {
9097
		var numMonths = this._get( inst, "numberOfMonths" );
9098
		return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) );
9099
	},
9100
 
9101
	/* Determine the current maximum date - ensure no time components are set. */
9102
	_getMinMaxDate: function( inst, minMax ) {
9103
		return this._determineDate( inst, this._get( inst, minMax + "Date" ), null );
9104
	},
9105
 
9106
	/* Find the number of days in a given month. */
9107
	_getDaysInMonth: function( year, month ) {
9108
		return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate();
9109
	},
9110
 
9111
	/* Find the day of the week of the first of a month. */
9112
	_getFirstDayOfMonth: function( year, month ) {
9113
		return new Date( year, month, 1 ).getDay();
9114
	},
9115
 
9116
	/* Determines if we should allow a "next/prev" month display change. */
9117
	_canAdjustMonth: function( inst, offset, curYear, curMonth ) {
9118
		var numMonths = this._getNumberOfMonths( inst ),
9119
			date = this._daylightSavingAdjust( new Date( curYear,
9120
			curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) );
9121
 
9122
		if ( offset < 0 ) {
9123
			date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) );
9124
		}
9125
		return this._isInRange( inst, date );
9126
	},
9127
 
9128
	/* Is the given date in the accepted range? */
9129
	_isInRange: function( inst, date ) {
9130
		var yearSplit, currentYear,
9131
			minDate = this._getMinMaxDate( inst, "min" ),
9132
			maxDate = this._getMinMaxDate( inst, "max" ),
9133
			minYear = null,
9134
			maxYear = null,
9135
			years = this._get( inst, "yearRange" );
9136
			if ( years ) {
9137
				yearSplit = years.split( ":" );
9138
				currentYear = new Date().getFullYear();
9139
				minYear = parseInt( yearSplit[ 0 ], 10 );
9140
				maxYear = parseInt( yearSplit[ 1 ], 10 );
9141
				if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) {
9142
					minYear += currentYear;
9143
				}
9144
				if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) {
9145
					maxYear += currentYear;
9146
				}
9147
			}
9148
 
9149
		return ( ( !minDate || date.getTime() >= minDate.getTime() ) &&
9150
			( !maxDate || date.getTime() <= maxDate.getTime() ) &&
9151
			( !minYear || date.getFullYear() >= minYear ) &&
9152
			( !maxYear || date.getFullYear() <= maxYear ) );
9153
	},
9154
 
9155
	/* Provide the configuration settings for formatting/parsing. */
9156
	_getFormatConfig: function( inst ) {
9157
		var shortYearCutoff = this._get( inst, "shortYearCutoff" );
9158
		shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff :
9159
			new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) );
9160
		return { shortYearCutoff: shortYearCutoff,
9161
			dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ),
9162
			monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) };
9163
	},
9164
 
9165
	/* Format the given date for display. */
9166
	_formatDate: function( inst, day, month, year ) {
9167
		if ( !day ) {
9168
			inst.currentDay = inst.selectedDay;
9169
			inst.currentMonth = inst.selectedMonth;
9170
			inst.currentYear = inst.selectedYear;
9171
		}
9172
		var date = ( day ? ( typeof day === "object" ? day :
9173
			this._daylightSavingAdjust( new Date( year, month, day ) ) ) :
9174
			this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
9175
		return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) );
9176
	}
9177
} );
9178
 
9179
/*
9180
 * Bind hover events for datepicker elements.
9181
 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9182
 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9183
 */
9184
function datepicker_bindHover( dpDiv ) {
9185
	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
9186
	return dpDiv.on( "mouseout", selector, function() {
9187
			$( this ).removeClass( "ui-state-hover" );
9188
			if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
9189
				$( this ).removeClass( "ui-datepicker-prev-hover" );
9190
			}
9191
			if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
9192
				$( this ).removeClass( "ui-datepicker-next-hover" );
9193
			}
9194
		} )
9195
		.on( "mouseover", selector, datepicker_handleMouseover );
9196
}
9197
 
9198
function datepicker_handleMouseover() {
9199
	if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) {
9200
		$( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" );
9201
		$( this ).addClass( "ui-state-hover" );
9202
		if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
9203
			$( this ).addClass( "ui-datepicker-prev-hover" );
9204
		}
9205
		if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
9206
			$( this ).addClass( "ui-datepicker-next-hover" );
9207
		}
9208
	}
9209
}
9210
 
9211
/* jQuery extend now ignores nulls! */
9212
function datepicker_extendRemove( target, props ) {
9213
	$.extend( target, props );
9214
	for ( var name in props ) {
9215
		if ( props[ name ] == null ) {
9216
			target[ name ] = props[ name ];
9217
		}
9218
	}
9219
	return target;
9220
}
9221
 
9222
/* Invoke the datepicker functionality.
9223
   @param  options  string - a command, optionally followed by additional parameters or
9224
					Object - settings for attaching new datepicker functionality
9225
   @return  jQuery object */
9226
$.fn.datepicker = function( options ) {
9227
 
9228
	/* Verify an empty collection wasn't passed - Fixes #6976 */
9229
	if ( !this.length ) {
9230
		return this;
9231
	}
9232
 
9233
	/* Initialise the date picker. */
9234
	if ( !$.datepicker.initialized ) {
9235
		$( document ).on( "mousedown", $.datepicker._checkExternalClick );
9236
		$.datepicker.initialized = true;
9237
	}
9238
 
9239
	/* Append datepicker main container to body if not exist. */
9240
	if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) {
9241
		$( "body" ).append( $.datepicker.dpDiv );
9242
	}
9243
 
9244
	var otherArgs = Array.prototype.slice.call( arguments, 1 );
9245
	if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) {
9246
		return $.datepicker[ "_" + options + "Datepicker" ].
9247
			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
9248
	}
9249
	if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) {
9250
		return $.datepicker[ "_" + options + "Datepicker" ].
9251
			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
9252
	}
9253
	return this.each( function() {
9254
		typeof options === "string" ?
9255
			$.datepicker[ "_" + options + "Datepicker" ].
9256
				apply( $.datepicker, [ this ].concat( otherArgs ) ) :
9257
			$.datepicker._attachDatepicker( this, options );
9258
	} );
9259
};
9260
 
9261
$.datepicker = new Datepicker(); // singleton instance
9262
$.datepicker.initialized = false;
9263
$.datepicker.uuid = new Date().getTime();
9264
$.datepicker.version = "1.12.1";
9265
 
9266
var widgetsDatepicker = $.datepicker;
9267
 
9268
 
9269
 
9270
 
9271
// This file is deprecated
9272
var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
9273
 
9274
/*!
9275
 * jQuery UI Mouse 1.12.1
9276
 * http://jqueryui.com
9277
 *
9278
 * Copyright jQuery Foundation and other contributors
9279
 * Released under the MIT license.
9280
 * http://jquery.org/license
9281
 */
9282
 
9283
//>>label: Mouse
9284
//>>group: Widgets
9285
//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
9286
//>>docs: http://api.jqueryui.com/mouse/
9287
 
9288
 
9289
 
9290
var mouseHandled = false;
9291
$( document ).on( "mouseup", function() {
9292
	mouseHandled = false;
9293
} );
9294
 
9295
var widgetsMouse = $.widget( "ui.mouse", {
9296
	version: "1.12.1",
9297
	options: {
9298
		cancel: "input, textarea, button, select, option",
9299
		distance: 1,
9300
		delay: 0
9301
	},
9302
	_mouseInit: function() {
9303
		var that = this;
9304
 
9305
		this.element
9306
			.on( "mousedown." + this.widgetName, function( event ) {
9307
				return that._mouseDown( event );
9308
			} )
9309
			.on( "click." + this.widgetName, function( event ) {
9310
				if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
9311
					$.removeData( event.target, that.widgetName + ".preventClickEvent" );
9312
					event.stopImmediatePropagation();
9313
					return false;
9314
				}
9315
			} );
9316
 
9317
		this.started = false;
9318
	},
9319
 
9320
	// TODO: make sure destroying one instance of mouse doesn't mess with
9321
	// other instances of mouse
9322
	_mouseDestroy: function() {
9323
		this.element.off( "." + this.widgetName );
9324
		if ( this._mouseMoveDelegate ) {
9325
			this.document
9326
				.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9327
				.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
9328
		}
9329
	},
9330
 
9331
	_mouseDown: function( event ) {
9332
 
9333
		// don't let more than one widget handle mouseStart
9334
		if ( mouseHandled ) {
9335
			return;
9336
		}
9337
 
9338
		this._mouseMoved = false;
9339
 
9340
		// We may have missed mouseup (out of window)
9341
		( this._mouseStarted && this._mouseUp( event ) );
9342
 
9343
		this._mouseDownEvent = event;
9344
 
9345
		var that = this,
9346
			btnIsLeft = ( event.which === 1 ),
9347
 
9348
			// event.target.nodeName works around a bug in IE 8 with
9349
			// disabled inputs (#7620)
9350
			elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
9351
				$( event.target ).closest( this.options.cancel ).length : false );
9352
		if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
9353
			return true;
9354
		}
9355
 
9356
		this.mouseDelayMet = !this.options.delay;
9357
		if ( !this.mouseDelayMet ) {
9358
			this._mouseDelayTimer = setTimeout( function() {
9359
				that.mouseDelayMet = true;
9360
			}, this.options.delay );
9361
		}
9362
 
9363
		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
9364
			this._mouseStarted = ( this._mouseStart( event ) !== false );
9365
			if ( !this._mouseStarted ) {
9366
				event.preventDefault();
9367
				return true;
9368
			}
9369
		}
9370
 
9371
		// Click event may never have fired (Gecko & Opera)
9372
		if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
9373
			$.removeData( event.target, this.widgetName + ".preventClickEvent" );
9374
		}
9375
 
9376
		// These delegates are required to keep context
9377
		this._mouseMoveDelegate = function( event ) {
9378
			return that._mouseMove( event );
9379
		};
9380
		this._mouseUpDelegate = function( event ) {
9381
			return that._mouseUp( event );
9382
		};
9383
 
9384
		this.document
9385
			.on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9386
			.on( "mouseup." + this.widgetName, this._mouseUpDelegate );
9387
 
9388
		event.preventDefault();
9389
 
9390
		mouseHandled = true;
9391
		return true;
9392
	},
9393
 
9394
	_mouseMove: function( event ) {
9395
 
9396
		// Only check for mouseups outside the document if you've moved inside the document
9397
		// at least once. This prevents the firing of mouseup in the case of IE<9, which will
9398
		// fire a mousemove event if content is placed under the cursor. See #7778
9399
		// Support: IE <9
9400
		if ( this._mouseMoved ) {
9401
 
9402
			// IE mouseup check - mouseup happened when mouse was out of window
9403
			if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
9404
					!event.button ) {
9405
				return this._mouseUp( event );
9406
 
9407
			// Iframe mouseup check - mouseup occurred in another document
9408
			} else if ( !event.which ) {
9409
 
9410
				// Support: Safari <=8 - 9
9411
				// Safari sets which to 0 if you press any of the following keys
9412
				// during a drag (#14461)
9413
				if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
9414
						event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
9415
					this.ignoreMissingWhich = true;
9416
				} else if ( !this.ignoreMissingWhich ) {
9417
					return this._mouseUp( event );
9418
				}
9419
			}
9420
		}
9421
 
9422
		if ( event.which || event.button ) {
9423
			this._mouseMoved = true;
9424
		}
9425
 
9426
		if ( this._mouseStarted ) {
9427
			this._mouseDrag( event );
9428
			return event.preventDefault();
9429
		}
9430
 
9431
		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
9432
			this._mouseStarted =
9433
				( this._mouseStart( this._mouseDownEvent, event ) !== false );
9434
			( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) );
9435
		}
9436
 
9437
		return !this._mouseStarted;
9438
	},
9439
 
9440
	_mouseUp: function( event ) {
9441
		this.document
9442
			.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9443
			.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
9444
 
9445
		if ( this._mouseStarted ) {
9446
			this._mouseStarted = false;
9447
 
9448
			if ( event.target === this._mouseDownEvent.target ) {
9449
				$.data( event.target, this.widgetName + ".preventClickEvent", true );
9450
			}
9451
 
9452
			this._mouseStop( event );
9453
		}
9454
 
9455
		if ( this._mouseDelayTimer ) {
9456
			clearTimeout( this._mouseDelayTimer );
9457
			delete this._mouseDelayTimer;
9458
		}
9459
 
9460
		this.ignoreMissingWhich = false;
9461
		mouseHandled = false;
9462
		event.preventDefault();
9463
	},
9464
 
9465
	_mouseDistanceMet: function( event ) {
9466
		return ( Math.max(
9467
				Math.abs( this._mouseDownEvent.pageX - event.pageX ),
9468
				Math.abs( this._mouseDownEvent.pageY - event.pageY )
9469
			) >= this.options.distance
9470
		);
9471
	},
9472
 
9473
	_mouseDelayMet: function( /* event */ ) {
9474
		return this.mouseDelayMet;
9475
	},
9476
 
9477
	// These are placeholder methods, to be overriden by extending plugin
9478
	_mouseStart: function( /* event */ ) {},
9479
	_mouseDrag: function( /* event */ ) {},
9480
	_mouseStop: function( /* event */ ) {},
9481
	_mouseCapture: function( /* event */ ) { return true; }
9482
} );
9483
 
9484
 
9485
 
9486
 
9487
// $.ui.plugin is deprecated. Use $.widget() extensions instead.
9488
var plugin = $.ui.plugin = {
9489
	add: function( module, option, set ) {
9490
		var i,
9491
			proto = $.ui[ module ].prototype;
9492
		for ( i in set ) {
9493
			proto.plugins[ i ] = proto.plugins[ i ] || [];
9494
			proto.plugins[ i ].push( [ option, set[ i ] ] );
9495
		}
9496
	},
9497
	call: function( instance, name, args, allowDisconnected ) {
9498
		var i,
9499
			set = instance.plugins[ name ];
9500
 
9501
		if ( !set ) {
9502
			return;
9503
		}
9504
 
9505
		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
9506
				instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
9507
			return;
9508
		}
9509
 
9510
		for ( i = 0; i < set.length; i++ ) {
9511
			if ( instance.options[ set[ i ][ 0 ] ] ) {
9512
				set[ i ][ 1 ].apply( instance.element, args );
9513
			}
9514
		}
9515
	}
9516
};
9517
 
9518
 
9519
 
9520
var safeBlur = $.ui.safeBlur = function( element ) {
9521
 
9522
	// Support: IE9 - 10 only
9523
	// If the <body> is blurred, IE will switch windows, see #9420
9524
	if ( element && element.nodeName.toLowerCase() !== "body" ) {
9525
		$( element ).trigger( "blur" );
9526
	}
9527
};
9528
 
9529
 
9530
/*!
9531
 * jQuery UI Draggable 1.12.1
9532
 * http://jqueryui.com
9533
 *
9534
 * Copyright jQuery Foundation and other contributors
9535
 * Released under the MIT license.
9536
 * http://jquery.org/license
9537
 */
9538
 
9539
//>>label: Draggable
9540
//>>group: Interactions
9541
//>>description: Enables dragging functionality for any element.
9542
//>>docs: http://api.jqueryui.com/draggable/
9543
//>>demos: http://jqueryui.com/draggable/
9544
//>>css.structure: ../../themes/base/draggable.css
9545
 
9546
 
9547
 
9548
$.widget( "ui.draggable", $.ui.mouse, {
9549
	version: "1.12.1",
9550
	widgetEventPrefix: "drag",
9551
	options: {
9552
		addClasses: true,
9553
		appendTo: "parent",
9554
		axis: false,
9555
		connectToSortable: false,
9556
		containment: false,
9557
		cursor: "auto",
9558
		cursorAt: false,
9559
		grid: false,
9560
		handle: false,
9561
		helper: "original",
9562
		iframeFix: false,
9563
		opacity: false,
9564
		refreshPositions: false,
9565
		revert: false,
9566
		revertDuration: 500,
9567
		scope: "default",
9568
		scroll: true,
9569
		scrollSensitivity: 20,
9570
		scrollSpeed: 20,
9571
		snap: false,
9572
		snapMode: "both",
9573
		snapTolerance: 20,
9574
		stack: false,
9575
		zIndex: false,
9576
 
9577
		// Callbacks
9578
		drag: null,
9579
		start: null,
9580
		stop: null
9581
	},
9582
	_create: function() {
9583
 
9584
		if ( this.options.helper === "original" ) {
9585
			this._setPositionRelative();
9586
		}
9587
		if ( this.options.addClasses ) {
9588
			this._addClass( "ui-draggable" );
9589
		}
9590
		this._setHandleClassName();
9591
 
9592
		this._mouseInit();
9593
	},
9594
 
9595
	_setOption: function( key, value ) {
9596
		this._super( key, value );
9597
		if ( key === "handle" ) {
9598
			this._removeHandleClassName();
9599
			this._setHandleClassName();
9600
		}
9601
	},
9602
 
9603
	_destroy: function() {
9604
		if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
9605
			this.destroyOnClear = true;
9606
			return;
9607
		}
9608
		this._removeHandleClassName();
9609
		this._mouseDestroy();
9610
	},
9611
 
9612
	_mouseCapture: function( event ) {
9613
		var o = this.options;
9614
 
9615
		// Among others, prevent a drag on a resizable-handle
9616
		if ( this.helper || o.disabled ||
9617
				$( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
9618
			return false;
9619
		}
9620
 
9621
		//Quit if we're not on a valid handle
9622
		this.handle = this._getHandle( event );
9623
		if ( !this.handle ) {
9624
			return false;
9625
		}
9626
 
9627
		this._blurActiveElement( event );
9628
 
9629
		this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
9630
 
9631
		return true;
9632
 
9633
	},
9634
 
9635
	_blockFrames: function( selector ) {
9636
		this.iframeBlocks = this.document.find( selector ).map( function() {
9637
			var iframe = $( this );
9638
 
9639
			return $( "<div>" )
9640
				.css( "position", "absolute" )
9641
				.appendTo( iframe.parent() )
9642
				.outerWidth( iframe.outerWidth() )
9643
				.outerHeight( iframe.outerHeight() )
9644
				.offset( iframe.offset() )[ 0 ];
9645
		} );
9646
	},
9647
 
9648
	_unblockFrames: function() {
9649
		if ( this.iframeBlocks ) {
9650
			this.iframeBlocks.remove();
9651
			delete this.iframeBlocks;
9652
		}
9653
	},
9654
 
9655
	_blurActiveElement: function( event ) {
9656
		var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
9657
			target = $( event.target );
9658
 
9659
		// Don't blur if the event occurred on an element that is within
9660
		// the currently focused element
9661
		// See #10527, #12472
9662
		if ( target.closest( activeElement ).length ) {
9663
			return;
9664
		}
9665
 
9666
		// Blur any element that currently has focus, see #4261
9667
		$.ui.safeBlur( activeElement );
9668
	},
9669
 
9670
	_mouseStart: function( event ) {
9671
 
9672
		var o = this.options;
9673
 
9674
		//Create and append the visible helper
9675
		this.helper = this._createHelper( event );
9676
 
9677
		this._addClass( this.helper, "ui-draggable-dragging" );
9678
 
9679
		//Cache the helper size
9680
		this._cacheHelperProportions();
9681
 
9682
		//If ddmanager is used for droppables, set the global draggable
9683
		if ( $.ui.ddmanager ) {
9684
			$.ui.ddmanager.current = this;
9685
		}
9686
 
9687
		/*
9688
		 * - Position generation -
9689
		 * This block generates everything position related - it's the core of draggables.
9690
		 */
9691
 
9692
		//Cache the margins of the original element
9693
		this._cacheMargins();
9694
 
9695
		//Store the helper's css position
9696
		this.cssPosition = this.helper.css( "position" );
9697
		this.scrollParent = this.helper.scrollParent( true );
9698
		this.offsetParent = this.helper.offsetParent();
9699
		this.hasFixedAncestor = this.helper.parents().filter( function() {
9700
				return $( this ).css( "position" ) === "fixed";
9701
			} ).length > 0;
9702
 
9703
		//The element's absolute position on the page minus margins
9704
		this.positionAbs = this.element.offset();
9705
		this._refreshOffsets( event );
9706
 
9707
		//Generate the original position
9708
		this.originalPosition = this.position = this._generatePosition( event, false );
9709
		this.originalPageX = event.pageX;
9710
		this.originalPageY = event.pageY;
9711
 
9712
		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
9713
		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
9714
 
9715
		//Set a containment if given in the options
9716
		this._setContainment();
9717
 
9718
		//Trigger event + callbacks
9719
		if ( this._trigger( "start", event ) === false ) {
9720
			this._clear();
9721
			return false;
9722
		}
9723
 
9724
		//Recache the helper size
9725
		this._cacheHelperProportions();
9726
 
9727
		//Prepare the droppable offsets
9728
		if ( $.ui.ddmanager && !o.dropBehaviour ) {
9729
			$.ui.ddmanager.prepareOffsets( this, event );
9730
		}
9731
 
9732
		// Execute the drag once - this causes the helper not to be visible before getting its
9733
		// correct position
9734
		this._mouseDrag( event, true );
9735
 
9736
		// If the ddmanager is used for droppables, inform the manager that dragging has started
9737
		// (see #5003)
9738
		if ( $.ui.ddmanager ) {
9739
			$.ui.ddmanager.dragStart( this, event );
9740
		}
9741
 
9742
		return true;
9743
	},
9744
 
9745
	_refreshOffsets: function( event ) {
9746
		this.offset = {
9747
			top: this.positionAbs.top - this.margins.top,
9748
			left: this.positionAbs.left - this.margins.left,
9749
			scroll: false,
9750
			parent: this._getParentOffset(),
9751
			relative: this._getRelativeOffset()
9752
		};
9753
 
9754
		this.offset.click = {
9755
			left: event.pageX - this.offset.left,
9756
			top: event.pageY - this.offset.top
9757
		};
9758
	},
9759
 
9760
	_mouseDrag: function( event, noPropagation ) {
9761
 
9762
		// reset any necessary cached properties (see #5009)
9763
		if ( this.hasFixedAncestor ) {
9764
			this.offset.parent = this._getParentOffset();
9765
		}
9766
 
9767
		//Compute the helpers position
9768
		this.position = this._generatePosition( event, true );
9769
		this.positionAbs = this._convertPositionTo( "absolute" );
9770
 
9771
		//Call plugins and callbacks and use the resulting position if something is returned
9772
		if ( !noPropagation ) {
9773
			var ui = this._uiHash();
9774
			if ( this._trigger( "drag", event, ui ) === false ) {
9775
				this._mouseUp( new $.Event( "mouseup", event ) );
9776
				return false;
9777
			}
9778
			this.position = ui.position;
9779
		}
9780
 
9781
		this.helper[ 0 ].style.left = this.position.left + "px";
9782
		this.helper[ 0 ].style.top = this.position.top + "px";
9783
 
9784
		if ( $.ui.ddmanager ) {
9785
			$.ui.ddmanager.drag( this, event );
9786
		}
9787
 
9788
		return false;
9789
	},
9790
 
9791
	_mouseStop: function( event ) {
9792
 
9793
		//If we are using droppables, inform the manager about the drop
9794
		var that = this,
9795
			dropped = false;
9796
		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
9797
			dropped = $.ui.ddmanager.drop( this, event );
9798
		}
9799
 
9800
		//if a drop comes from outside (a sortable)
9801
		if ( this.dropped ) {
9802
			dropped = this.dropped;
9803
			this.dropped = false;
9804
		}
9805
 
9806
		if ( ( this.options.revert === "invalid" && !dropped ) ||
9807
				( this.options.revert === "valid" && dropped ) ||
9808
				this.options.revert === true || ( $.isFunction( this.options.revert ) &&
9809
				this.options.revert.call( this.element, dropped ) )
9810
		) {
9811
			$( this.helper ).animate(
9812
				this.originalPosition,
9813
				parseInt( this.options.revertDuration, 10 ),
9814
				function() {
9815
					if ( that._trigger( "stop", event ) !== false ) {
9816
						that._clear();
9817
					}
9818
				}
9819
			);
9820
		} else {
9821
			if ( this._trigger( "stop", event ) !== false ) {
9822
				this._clear();
9823
			}
9824
		}
9825
 
9826
		return false;
9827
	},
9828
 
9829
	_mouseUp: function( event ) {
9830
		this._unblockFrames();
9831
 
9832
		// If the ddmanager is used for droppables, inform the manager that dragging has stopped
9833
		// (see #5003)
9834
		if ( $.ui.ddmanager ) {
9835
			$.ui.ddmanager.dragStop( this, event );
9836
		}
9837
 
9838
		// Only need to focus if the event occurred on the draggable itself, see #10527
9839
		if ( this.handleElement.is( event.target ) ) {
9840
 
9841
			// The interaction is over; whether or not the click resulted in a drag,
9842
			// focus the element
9843
			this.element.trigger( "focus" );
9844
		}
9845
 
9846
		return $.ui.mouse.prototype._mouseUp.call( this, event );
9847
	},
9848
 
9849
	cancel: function() {
9850
 
9851
		if ( this.helper.is( ".ui-draggable-dragging" ) ) {
9852
			this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
9853
		} else {
9854
			this._clear();
9855
		}
9856
 
9857
		return this;
9858
 
9859
	},
9860
 
9861
	_getHandle: function( event ) {
9862
		return this.options.handle ?
9863
			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
9864
			true;
9865
	},
9866
 
9867
	_setHandleClassName: function() {
9868
		this.handleElement = this.options.handle ?
9869
			this.element.find( this.options.handle ) : this.element;
9870
		this._addClass( this.handleElement, "ui-draggable-handle" );
9871
	},
9872
 
9873
	_removeHandleClassName: function() {
9874
		this._removeClass( this.handleElement, "ui-draggable-handle" );
9875
	},
9876
 
9877
	_createHelper: function( event ) {
9878
 
9879
		var o = this.options,
9880
			helperIsFunction = $.isFunction( o.helper ),
9881
			helper = helperIsFunction ?
9882
				$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
9883
				( o.helper === "clone" ?
9884
					this.element.clone().removeAttr( "id" ) :
9885
					this.element );
9886
 
9887
		if ( !helper.parents( "body" ).length ) {
9888
			helper.appendTo( ( o.appendTo === "parent" ?
9889
				this.element[ 0 ].parentNode :
9890
				o.appendTo ) );
9891
		}
9892
 
9893
		// Http://bugs.jqueryui.com/ticket/9446
9894
		// a helper function can return the original element
9895
		// which wouldn't have been set to relative in _create
9896
		if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
9897
			this._setPositionRelative();
9898
		}
9899
 
9900
		if ( helper[ 0 ] !== this.element[ 0 ] &&
9901
				!( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
9902
			helper.css( "position", "absolute" );
9903
		}
9904
 
9905
		return helper;
9906
 
9907
	},
9908
 
9909
	_setPositionRelative: function() {
9910
		if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
9911
			this.element[ 0 ].style.position = "relative";
9912
		}
9913
	},
9914
 
9915
	_adjustOffsetFromHelper: function( obj ) {
9916
		if ( typeof obj === "string" ) {
9917
			obj = obj.split( " " );
9918
		}
9919
		if ( $.isArray( obj ) ) {
9920
			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
9921
		}
9922
		if ( "left" in obj ) {
9923
			this.offset.click.left = obj.left + this.margins.left;
9924
		}
9925
		if ( "right" in obj ) {
9926
			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
9927
		}
9928
		if ( "top" in obj ) {
9929
			this.offset.click.top = obj.top + this.margins.top;
9930
		}
9931
		if ( "bottom" in obj ) {
9932
			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
9933
		}
9934
	},
9935
 
9936
	_isRootNode: function( element ) {
9937
		return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
9938
	},
9939
 
9940
	_getParentOffset: function() {
9941
 
9942
		//Get the offsetParent and cache its position
9943
		var po = this.offsetParent.offset(),
9944
			document = this.document[ 0 ];
9945
 
9946
		// This is a special case where we need to modify a offset calculated on start, since the
9947
		// following happened:
9948
		// 1. The position of the helper is absolute, so it's position is calculated based on the
9949
		// next positioned parent
9950
		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
9951
		// the document, which means that the scroll is included in the initial calculation of the
9952
		// offset of the parent, and never recalculated upon drag
9953
		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
9954
				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
9955
			po.left += this.scrollParent.scrollLeft();
9956
			po.top += this.scrollParent.scrollTop();
9957
		}
9958
 
9959
		if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
9960
			po = { top: 0, left: 0 };
9961
		}
9962
 
9963
		return {
9964
			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
9965
			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
9966
		};
9967
 
9968
	},
9969
 
9970
	_getRelativeOffset: function() {
9971
		if ( this.cssPosition !== "relative" ) {
9972
			return { top: 0, left: 0 };
9973
		}
9974
 
9975
		var p = this.element.position(),
9976
			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
9977
 
9978
		return {
9979
			top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
9980
				( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
9981
			left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
9982
				( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
9983
		};
9984
 
9985
	},
9986
 
9987
	_cacheMargins: function() {
9988
		this.margins = {
9989
			left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
9990
			top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
9991
			right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
9992
			bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
9993
		};
9994
	},
9995
 
9996
	_cacheHelperProportions: function() {
9997
		this.helperProportions = {
9998
			width: this.helper.outerWidth(),
9999
			height: this.helper.outerHeight()
10000
		};
10001
	},
10002
 
10003
	_setContainment: function() {
10004
 
10005
		var isUserScrollable, c, ce,
10006
			o = this.options,
10007
			document = this.document[ 0 ];
10008
 
10009
		this.relativeContainer = null;
10010
 
10011
		if ( !o.containment ) {
10012
			this.containment = null;
10013
			return;
10014
		}
10015
 
10016
		if ( o.containment === "window" ) {
10017
			this.containment = [
10018
				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
10019
				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
10020
				$( window ).scrollLeft() + $( window ).width() -
10021
					this.helperProportions.width - this.margins.left,
10022
				$( window ).scrollTop() +
10023
					( $( window ).height() || document.body.parentNode.scrollHeight ) -
10024
					this.helperProportions.height - this.margins.top
10025
			];
10026
			return;
10027
		}
10028
 
10029
		if ( o.containment === "document" ) {
10030
			this.containment = [
10031
				0,
10032
				0,
10033
				$( document ).width() - this.helperProportions.width - this.margins.left,
10034
				( $( document ).height() || document.body.parentNode.scrollHeight ) -
10035
					this.helperProportions.height - this.margins.top
10036
			];
10037
			return;
10038
		}
10039
 
10040
		if ( o.containment.constructor === Array ) {
10041
			this.containment = o.containment;
10042
			return;
10043
		}
10044
 
10045
		if ( o.containment === "parent" ) {
10046
			o.containment = this.helper[ 0 ].parentNode;
10047
		}
10048
 
10049
		c = $( o.containment );
10050
		ce = c[ 0 ];
10051
 
10052
		if ( !ce ) {
10053
			return;
10054
		}
10055
 
10056
		isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
10057
 
10058
		this.containment = [
10059
			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
10060
				( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
10061
			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
10062
				( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
10063
			( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
10064
				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
10065
				( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
10066
				this.helperProportions.width -
10067
				this.margins.left -
10068
				this.margins.right,
10069
			( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
10070
				( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
10071
				( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
10072
				this.helperProportions.height -
10073
				this.margins.top -
10074
				this.margins.bottom
10075
		];
10076
		this.relativeContainer = c;
10077
	},
10078
 
10079
	_convertPositionTo: function( d, pos ) {
10080
 
10081
		if ( !pos ) {
10082
			pos = this.position;
10083
		}
10084
 
10085
		var mod = d === "absolute" ? 1 : -1,
10086
			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
10087
 
10088
		return {
10089
			top: (
10090
 
10091
				// The absolute mouse position
10092
				pos.top	+
10093
 
10094
				// Only for relative positioned nodes: Relative offset from element to offset parent
10095
				this.offset.relative.top * mod +
10096
 
10097
				// The offsetParent's offset without borders (offset + border)
10098
				this.offset.parent.top * mod -
10099
				( ( this.cssPosition === "fixed" ?
10100
					-this.offset.scroll.top :
10101
					( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
10102
			),
10103
			left: (
10104
 
10105
				// The absolute mouse position
10106
				pos.left +
10107
 
10108
				// Only for relative positioned nodes: Relative offset from element to offset parent
10109
				this.offset.relative.left * mod +
10110
 
10111
				// The offsetParent's offset without borders (offset + border)
10112
				this.offset.parent.left * mod	-
10113
				( ( this.cssPosition === "fixed" ?
10114
					-this.offset.scroll.left :
10115
					( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
10116
			)
10117
		};
10118
 
10119
	},
10120
 
10121
	_generatePosition: function( event, constrainPosition ) {
10122
 
10123
		var containment, co, top, left,
10124
			o = this.options,
10125
			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
10126
			pageX = event.pageX,
10127
			pageY = event.pageY;
10128
 
10129
		// Cache the scroll
10130
		if ( !scrollIsRootNode || !this.offset.scroll ) {
10131
			this.offset.scroll = {
10132
				top: this.scrollParent.scrollTop(),
10133
				left: this.scrollParent.scrollLeft()
10134
			};
10135
		}
10136
 
10137
		/*
10138
		 * - Position constraining -
10139
		 * Constrain the position to a mix of grid, containment.
10140
		 */
10141
 
10142
		// If we are not dragging yet, we won't check for options
10143
		if ( constrainPosition ) {
10144
			if ( this.containment ) {
10145
				if ( this.relativeContainer ) {
10146
					co = this.relativeContainer.offset();
10147
					containment = [
10148
						this.containment[ 0 ] + co.left,
10149
						this.containment[ 1 ] + co.top,
10150
						this.containment[ 2 ] + co.left,
10151
						this.containment[ 3 ] + co.top
10152
					];
10153
				} else {
10154
					containment = this.containment;
10155
				}
10156
 
10157
				if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
10158
					pageX = containment[ 0 ] + this.offset.click.left;
10159
				}
10160
				if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
10161
					pageY = containment[ 1 ] + this.offset.click.top;
10162
				}
10163
				if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
10164
					pageX = containment[ 2 ] + this.offset.click.left;
10165
				}
10166
				if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
10167
					pageY = containment[ 3 ] + this.offset.click.top;
10168
				}
10169
			}
10170
 
10171
			if ( o.grid ) {
10172
 
10173
				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid
10174
				// argument errors in IE (see ticket #6950)
10175
				top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
10176
					this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
10177
				pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
10178
					top - this.offset.click.top > containment[ 3 ] ) ?
10179
						top :
10180
						( ( top - this.offset.click.top >= containment[ 1 ] ) ?
10181
							top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
10182
 
10183
				left = o.grid[ 0 ] ? this.originalPageX +
10184
					Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
10185
					this.originalPageX;
10186
				pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
10187
					left - this.offset.click.left > containment[ 2 ] ) ?
10188
						left :
10189
						( ( left - this.offset.click.left >= containment[ 0 ] ) ?
10190
							left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
10191
			}
10192
 
10193
			if ( o.axis === "y" ) {
10194
				pageX = this.originalPageX;
10195
			}
10196
 
10197
			if ( o.axis === "x" ) {
10198
				pageY = this.originalPageY;
10199
			}
10200
		}
10201
 
10202
		return {
10203
			top: (
10204
 
10205
				// The absolute mouse position
10206
				pageY -
10207
 
10208
				// Click offset (relative to the element)
10209
				this.offset.click.top -
10210
 
10211
				// Only for relative positioned nodes: Relative offset from element to offset parent
10212
				this.offset.relative.top -
10213
 
10214
				// The offsetParent's offset without borders (offset + border)
10215
				this.offset.parent.top +
10216
				( this.cssPosition === "fixed" ?
10217
					-this.offset.scroll.top :
10218
					( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
10219
			),
10220
			left: (
10221
 
10222
				// The absolute mouse position
10223
				pageX -
10224
 
10225
				// Click offset (relative to the element)
10226
				this.offset.click.left -
10227
 
10228
				// Only for relative positioned nodes: Relative offset from element to offset parent
10229
				this.offset.relative.left -
10230
 
10231
				// The offsetParent's offset without borders (offset + border)
10232
				this.offset.parent.left +
10233
				( this.cssPosition === "fixed" ?
10234
					-this.offset.scroll.left :
10235
					( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
10236
			)
10237
		};
10238
 
10239
	},
10240
 
10241
	_clear: function() {
10242
		this._removeClass( this.helper, "ui-draggable-dragging" );
10243
		if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
10244
			this.helper.remove();
10245
		}
10246
		this.helper = null;
10247
		this.cancelHelperRemoval = false;
10248
		if ( this.destroyOnClear ) {
10249
			this.destroy();
10250
		}
10251
	},
10252
 
10253
	// From now on bulk stuff - mainly helpers
10254
 
10255
	_trigger: function( type, event, ui ) {
10256
		ui = ui || this._uiHash();
10257
		$.ui.plugin.call( this, type, [ event, ui, this ], true );
10258
 
10259
		// Absolute position and offset (see #6884 ) have to be recalculated after plugins
10260
		if ( /^(drag|start|stop)/.test( type ) ) {
10261
			this.positionAbs = this._convertPositionTo( "absolute" );
10262
			ui.offset = this.positionAbs;
10263
		}
10264
		return $.Widget.prototype._trigger.call( this, type, event, ui );
10265
	},
10266
 
10267
	plugins: {},
10268
 
10269
	_uiHash: function() {
10270
		return {
10271
			helper: this.helper,
10272
			position: this.position,
10273
			originalPosition: this.originalPosition,
10274
			offset: this.positionAbs
10275
		};
10276
	}
10277
 
10278
} );
10279
 
10280
$.ui.plugin.add( "draggable", "connectToSortable", {
10281
	start: function( event, ui, draggable ) {
10282
		var uiSortable = $.extend( {}, ui, {
10283
			item: draggable.element
10284
		} );
10285
 
10286
		draggable.sortables = [];
10287
		$( draggable.options.connectToSortable ).each( function() {
10288
			var sortable = $( this ).sortable( "instance" );
10289
 
10290
			if ( sortable && !sortable.options.disabled ) {
10291
				draggable.sortables.push( sortable );
10292
 
10293
				// RefreshPositions is called at drag start to refresh the containerCache
10294
				// which is used in drag. This ensures it's initialized and synchronized
10295
				// with any changes that might have happened on the page since initialization.
10296
				sortable.refreshPositions();
10297
				sortable._trigger( "activate", event, uiSortable );
10298
			}
10299
		} );
10300
	},
10301
	stop: function( event, ui, draggable ) {
10302
		var uiSortable = $.extend( {}, ui, {
10303
			item: draggable.element
10304
		} );
10305
 
10306
		draggable.cancelHelperRemoval = false;
10307
 
10308
		$.each( draggable.sortables, function() {
10309
			var sortable = this;
10310
 
10311
			if ( sortable.isOver ) {
10312
				sortable.isOver = 0;
10313
 
10314
				// Allow this sortable to handle removing the helper
10315
				draggable.cancelHelperRemoval = true;
10316
				sortable.cancelHelperRemoval = false;
10317
 
10318
				// Use _storedCSS To restore properties in the sortable,
10319
				// as this also handles revert (#9675) since the draggable
10320
				// may have modified them in unexpected ways (#8809)
10321
				sortable._storedCSS = {
10322
					position: sortable.placeholder.css( "position" ),
10323
					top: sortable.placeholder.css( "top" ),
10324
					left: sortable.placeholder.css( "left" )
10325
				};
10326
 
10327
				sortable._mouseStop( event );
10328
 
10329
				// Once drag has ended, the sortable should return to using
10330
				// its original helper, not the shared helper from draggable
10331
				sortable.options.helper = sortable.options._helper;
10332
			} else {
10333
 
10334
				// Prevent this Sortable from removing the helper.
10335
				// However, don't set the draggable to remove the helper
10336
				// either as another connected Sortable may yet handle the removal.
10337
				sortable.cancelHelperRemoval = true;
10338
 
10339
				sortable._trigger( "deactivate", event, uiSortable );
10340
			}
10341
		} );
10342
	},
10343
	drag: function( event, ui, draggable ) {
10344
		$.each( draggable.sortables, function() {
10345
			var innermostIntersecting = false,
10346
				sortable = this;
10347
 
10348
			// Copy over variables that sortable's _intersectsWith uses
10349
			sortable.positionAbs = draggable.positionAbs;
10350
			sortable.helperProportions = draggable.helperProportions;
10351
			sortable.offset.click = draggable.offset.click;
10352
 
10353
			if ( sortable._intersectsWith( sortable.containerCache ) ) {
10354
				innermostIntersecting = true;
10355
 
10356
				$.each( draggable.sortables, function() {
10357
 
10358
					// Copy over variables that sortable's _intersectsWith uses
10359
					this.positionAbs = draggable.positionAbs;
10360
					this.helperProportions = draggable.helperProportions;
10361
					this.offset.click = draggable.offset.click;
10362
 
10363
					if ( this !== sortable &&
10364
							this._intersectsWith( this.containerCache ) &&
10365
							$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
10366
						innermostIntersecting = false;
10367
					}
10368
 
10369
					return innermostIntersecting;
10370
				} );
10371
			}
10372
 
10373
			if ( innermostIntersecting ) {
10374
 
10375
				// If it intersects, we use a little isOver variable and set it once,
10376
				// so that the move-in stuff gets fired only once.
10377
				if ( !sortable.isOver ) {
10378
					sortable.isOver = 1;
10379
 
10380
					// Store draggable's parent in case we need to reappend to it later.
10381
					draggable._parent = ui.helper.parent();
10382
 
10383
					sortable.currentItem = ui.helper
10384
						.appendTo( sortable.element )
10385
						.data( "ui-sortable-item", true );
10386
 
10387
					// Store helper option to later restore it
10388
					sortable.options._helper = sortable.options.helper;
10389
 
10390
					sortable.options.helper = function() {
10391
						return ui.helper[ 0 ];
10392
					};
10393
 
10394
					// Fire the start events of the sortable with our passed browser event,
10395
					// and our own helper (so it doesn't create a new one)
10396
					event.target = sortable.currentItem[ 0 ];
10397
					sortable._mouseCapture( event, true );
10398
					sortable._mouseStart( event, true, true );
10399
 
10400
					// Because the browser event is way off the new appended portlet,
10401
					// modify necessary variables to reflect the changes
10402
					sortable.offset.click.top = draggable.offset.click.top;
10403
					sortable.offset.click.left = draggable.offset.click.left;
10404
					sortable.offset.parent.left -= draggable.offset.parent.left -
10405
						sortable.offset.parent.left;
10406
					sortable.offset.parent.top -= draggable.offset.parent.top -
10407
						sortable.offset.parent.top;
10408
 
10409
					draggable._trigger( "toSortable", event );
10410
 
10411
					// Inform draggable that the helper is in a valid drop zone,
10412
					// used solely in the revert option to handle "valid/invalid".
10413
					draggable.dropped = sortable.element;
10414
 
10415
					// Need to refreshPositions of all sortables in the case that
10416
					// adding to one sortable changes the location of the other sortables (#9675)
10417
					$.each( draggable.sortables, function() {
10418
						this.refreshPositions();
10419
					} );
10420
 
10421
					// Hack so receive/update callbacks work (mostly)
10422
					draggable.currentItem = draggable.element;
10423
					sortable.fromOutside = draggable;
10424
				}
10425
 
10426
				if ( sortable.currentItem ) {
10427
					sortable._mouseDrag( event );
10428
 
10429
					// Copy the sortable's position because the draggable's can potentially reflect
10430
					// a relative position, while sortable is always absolute, which the dragged
10431
					// element has now become. (#8809)
10432
					ui.position = sortable.position;
10433
				}
10434
			} else {
10435
 
10436
				// If it doesn't intersect with the sortable, and it intersected before,
10437
				// we fake the drag stop of the sortable, but make sure it doesn't remove
10438
				// the helper by using cancelHelperRemoval.
10439
				if ( sortable.isOver ) {
10440
 
10441
					sortable.isOver = 0;
10442
					sortable.cancelHelperRemoval = true;
10443
 
10444
					// Calling sortable's mouseStop would trigger a revert,
10445
					// so revert must be temporarily false until after mouseStop is called.
10446
					sortable.options._revert = sortable.options.revert;
10447
					sortable.options.revert = false;
10448
 
10449
					sortable._trigger( "out", event, sortable._uiHash( sortable ) );
10450
					sortable._mouseStop( event, true );
10451
 
10452
					// Restore sortable behaviors that were modfied
10453
					// when the draggable entered the sortable area (#9481)
10454
					sortable.options.revert = sortable.options._revert;
10455
					sortable.options.helper = sortable.options._helper;
10456
 
10457
					if ( sortable.placeholder ) {
10458
						sortable.placeholder.remove();
10459
					}
10460
 
10461
					// Restore and recalculate the draggable's offset considering the sortable
10462
					// may have modified them in unexpected ways. (#8809, #10669)
10463
					ui.helper.appendTo( draggable._parent );
10464
					draggable._refreshOffsets( event );
10465
					ui.position = draggable._generatePosition( event, true );
10466
 
10467
					draggable._trigger( "fromSortable", event );
10468
 
10469
					// Inform draggable that the helper is no longer in a valid drop zone
10470
					draggable.dropped = false;
10471
 
10472
					// Need to refreshPositions of all sortables just in case removing
10473
					// from one sortable changes the location of other sortables (#9675)
10474
					$.each( draggable.sortables, function() {
10475
						this.refreshPositions();
10476
					} );
10477
				}
10478
			}
10479
		} );
10480
	}
10481
} );
10482
 
10483
$.ui.plugin.add( "draggable", "cursor", {
10484
	start: function( event, ui, instance ) {
10485
		var t = $( "body" ),
10486
			o = instance.options;
10487
 
10488
		if ( t.css( "cursor" ) ) {
10489
			o._cursor = t.css( "cursor" );
10490
		}
10491
		t.css( "cursor", o.cursor );
10492
	},
10493
	stop: function( event, ui, instance ) {
10494
		var o = instance.options;
10495
		if ( o._cursor ) {
10496
			$( "body" ).css( "cursor", o._cursor );
10497
		}
10498
	}
10499
} );
10500
 
10501
$.ui.plugin.add( "draggable", "opacity", {
10502
	start: function( event, ui, instance ) {
10503
		var t = $( ui.helper ),
10504
			o = instance.options;
10505
		if ( t.css( "opacity" ) ) {
10506
			o._opacity = t.css( "opacity" );
10507
		}
10508
		t.css( "opacity", o.opacity );
10509
	},
10510
	stop: function( event, ui, instance ) {
10511
		var o = instance.options;
10512
		if ( o._opacity ) {
10513
			$( ui.helper ).css( "opacity", o._opacity );
10514
		}
10515
	}
10516
} );
10517
 
10518
$.ui.plugin.add( "draggable", "scroll", {
10519
	start: function( event, ui, i ) {
10520
		if ( !i.scrollParentNotHidden ) {
10521
			i.scrollParentNotHidden = i.helper.scrollParent( false );
10522
		}
10523
 
10524
		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
10525
				i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
10526
			i.overflowOffset = i.scrollParentNotHidden.offset();
10527
		}
10528
	},
10529
	drag: function( event, ui, i  ) {
10530
 
10531
		var o = i.options,
10532
			scrolled = false,
10533
			scrollParent = i.scrollParentNotHidden[ 0 ],
10534
			document = i.document[ 0 ];
10535
 
10536
		if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
10537
			if ( !o.axis || o.axis !== "x" ) {
10538
				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
10539
						o.scrollSensitivity ) {
10540
					scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
10541
				} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
10542
					scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
10543
				}
10544
			}
10545
 
10546
			if ( !o.axis || o.axis !== "y" ) {
10547
				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
10548
						o.scrollSensitivity ) {
10549
					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
10550
				} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
10551
					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
10552
				}
10553
			}
10554
 
10555
		} else {
10556
 
10557
			if ( !o.axis || o.axis !== "x" ) {
10558
				if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
10559
					scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
10560
				} else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
10561
						o.scrollSensitivity ) {
10562
					scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
10563
				}
10564
			}
10565
 
10566
			if ( !o.axis || o.axis !== "y" ) {
10567
				if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
10568
					scrolled = $( document ).scrollLeft(
10569
						$( document ).scrollLeft() - o.scrollSpeed
10570
					);
10571
				} else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
10572
						o.scrollSensitivity ) {
10573
					scrolled = $( document ).scrollLeft(
10574
						$( document ).scrollLeft() + o.scrollSpeed
10575
					);
10576
				}
10577
			}
10578
 
10579
		}
10580
 
10581
		if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
10582
			$.ui.ddmanager.prepareOffsets( i, event );
10583
		}
10584
 
10585
	}
10586
} );
10587
 
10588
$.ui.plugin.add( "draggable", "snap", {
10589
	start: function( event, ui, i ) {
10590
 
10591
		var o = i.options;
10592
 
10593
		i.snapElements = [];
10594
 
10595
		$( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
10596
			.each( function() {
10597
				var $t = $( this ),
10598
					$o = $t.offset();
10599
				if ( this !== i.element[ 0 ] ) {
10600
					i.snapElements.push( {
10601
						item: this,
10602
						width: $t.outerWidth(), height: $t.outerHeight(),
10603
						top: $o.top, left: $o.left
10604
					} );
10605
				}
10606
			} );
10607
 
10608
	},
10609
	drag: function( event, ui, inst ) {
10610
 
10611
		var ts, bs, ls, rs, l, r, t, b, i, first,
10612
			o = inst.options,
10613
			d = o.snapTolerance,
10614
			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
10615
			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
10616
 
10617
		for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
10618
 
10619
			l = inst.snapElements[ i ].left - inst.margins.left;
10620
			r = l + inst.snapElements[ i ].width;
10621
			t = inst.snapElements[ i ].top - inst.margins.top;
10622
			b = t + inst.snapElements[ i ].height;
10623
 
10624
			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
10625
					!$.contains( inst.snapElements[ i ].item.ownerDocument,
10626
					inst.snapElements[ i ].item ) ) {
10627
				if ( inst.snapElements[ i ].snapping ) {
10628
					( inst.options.snap.release &&
10629
						inst.options.snap.release.call(
10630
							inst.element,
10631
							event,
10632
							$.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
10633
						) );
10634
				}
10635
				inst.snapElements[ i ].snapping = false;
10636
				continue;
10637
			}
10638
 
10639
			if ( o.snapMode !== "inner" ) {
10640
				ts = Math.abs( t - y2 ) <= d;
10641
				bs = Math.abs( b - y1 ) <= d;
10642
				ls = Math.abs( l - x2 ) <= d;
10643
				rs = Math.abs( r - x1 ) <= d;
10644
				if ( ts ) {
10645
					ui.position.top = inst._convertPositionTo( "relative", {
10646
						top: t - inst.helperProportions.height,
10647
						left: 0
10648
					} ).top;
10649
				}
10650
				if ( bs ) {
10651
					ui.position.top = inst._convertPositionTo( "relative", {
10652
						top: b,
10653
						left: 0
10654
					} ).top;
10655
				}
10656
				if ( ls ) {
10657
					ui.position.left = inst._convertPositionTo( "relative", {
10658
						top: 0,
10659
						left: l - inst.helperProportions.width
10660
					} ).left;
10661
				}
10662
				if ( rs ) {
10663
					ui.position.left = inst._convertPositionTo( "relative", {
10664
						top: 0,
10665
						left: r
10666
					} ).left;
10667
				}
10668
			}
10669
 
10670
			first = ( ts || bs || ls || rs );
10671
 
10672
			if ( o.snapMode !== "outer" ) {
10673
				ts = Math.abs( t - y1 ) <= d;
10674
				bs = Math.abs( b - y2 ) <= d;
10675
				ls = Math.abs( l - x1 ) <= d;
10676
				rs = Math.abs( r - x2 ) <= d;
10677
				if ( ts ) {
10678
					ui.position.top = inst._convertPositionTo( "relative", {
10679
						top: t,
10680
						left: 0
10681
					} ).top;
10682
				}
10683
				if ( bs ) {
10684
					ui.position.top = inst._convertPositionTo( "relative", {
10685
						top: b - inst.helperProportions.height,
10686
						left: 0
10687
					} ).top;
10688
				}
10689
				if ( ls ) {
10690
					ui.position.left = inst._convertPositionTo( "relative", {
10691
						top: 0,
10692
						left: l
10693
					} ).left;
10694
				}
10695
				if ( rs ) {
10696
					ui.position.left = inst._convertPositionTo( "relative", {
10697
						top: 0,
10698
						left: r - inst.helperProportions.width
10699
					} ).left;
10700
				}
10701
			}
10702
 
10703
			if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
10704
				( inst.options.snap.snap &&
10705
					inst.options.snap.snap.call(
10706
						inst.element,
10707
						event,
10708
						$.extend( inst._uiHash(), {
10709
							snapItem: inst.snapElements[ i ].item
10710
						} ) ) );
10711
			}
10712
			inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
10713
 
10714
		}
10715
 
10716
	}
10717
} );
10718
 
10719
$.ui.plugin.add( "draggable", "stack", {
10720
	start: function( event, ui, instance ) {
10721
		var min,
10722
			o = instance.options,
10723
			group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
10724
				return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
10725
					( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
10726
			} );
10727
 
10728
		if ( !group.length ) { return; }
10729
 
10730
		min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
10731
		$( group ).each( function( i ) {
10732
			$( this ).css( "zIndex", min + i );
10733
		} );
10734
		this.css( "zIndex", ( min + group.length ) );
10735
	}
10736
} );
10737
 
10738
$.ui.plugin.add( "draggable", "zIndex", {
10739
	start: function( event, ui, instance ) {
10740
		var t = $( ui.helper ),
10741
			o = instance.options;
10742
 
10743
		if ( t.css( "zIndex" ) ) {
10744
			o._zIndex = t.css( "zIndex" );
10745
		}
10746
		t.css( "zIndex", o.zIndex );
10747
	},
10748
	stop: function( event, ui, instance ) {
10749
		var o = instance.options;
10750
 
10751
		if ( o._zIndex ) {
10752
			$( ui.helper ).css( "zIndex", o._zIndex );
10753
		}
10754
	}
10755
} );
10756
 
10757
var widgetsDraggable = $.ui.draggable;
10758
 
10759
 
10760
/*!
10761
 * jQuery UI Resizable 1.12.1
10762
 * http://jqueryui.com
10763
 *
10764
 * Copyright jQuery Foundation and other contributors
10765
 * Released under the MIT license.
10766
 * http://jquery.org/license
10767
 */
10768
 
10769
//>>label: Resizable
10770
//>>group: Interactions
10771
//>>description: Enables resize functionality for any element.
10772
//>>docs: http://api.jqueryui.com/resizable/
10773
//>>demos: http://jqueryui.com/resizable/
10774
//>>css.structure: ../../themes/base/core.css
10775
//>>css.structure: ../../themes/base/resizable.css
10776
//>>css.theme: ../../themes/base/theme.css
10777
 
10778
 
10779
 
10780
$.widget( "ui.resizable", $.ui.mouse, {
10781
	version: "1.12.1",
10782
	widgetEventPrefix: "resize",
10783
	options: {
10784
		alsoResize: false,
10785
		animate: false,
10786
		animateDuration: "slow",
10787
		animateEasing: "swing",
10788
		aspectRatio: false,
10789
		autoHide: false,
10790
		classes: {
10791
			"ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se"
10792
		},
10793
		containment: false,
10794
		ghost: false,
10795
		grid: false,
10796
		handles: "e,s,se",
10797
		helper: false,
10798
		maxHeight: null,
10799
		maxWidth: null,
10800
		minHeight: 10,
10801
		minWidth: 10,
10802
 
10803
		// See #7960
10804
		zIndex: 90,
10805
 
10806
		// Callbacks
10807
		resize: null,
10808
		start: null,
10809
		stop: null
10810
	},
10811
 
10812
	_num: function( value ) {
10813
		return parseFloat( value ) || 0;
10814
	},
10815
 
10816
	_isNumber: function( value ) {
10817
		return !isNaN( parseFloat( value ) );
10818
	},
10819
 
10820
	_hasScroll: function( el, a ) {
10821
 
10822
		if ( $( el ).css( "overflow" ) === "hidden" ) {
10823
			return false;
10824
		}
10825
 
10826
		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
10827
			has = false;
10828
 
10829
		if ( el[ scroll ] > 0 ) {
10830
			return true;
10831
		}
10832
 
10833
		// TODO: determine which cases actually cause this to happen
10834
		// if the element doesn't have the scroll set, see if it's possible to
10835
		// set the scroll
10836
		el[ scroll ] = 1;
10837
		has = ( el[ scroll ] > 0 );
10838
		el[ scroll ] = 0;
10839
		return has;
10840
	},
10841
 
10842
	_create: function() {
10843
 
10844
		var margins,
10845
			o = this.options,
10846
			that = this;
10847
		this._addClass( "ui-resizable" );
10848
 
10849
		$.extend( this, {
10850
			_aspectRatio: !!( o.aspectRatio ),
10851
			aspectRatio: o.aspectRatio,
10852
			originalElement: this.element,
10853
			_proportionallyResizeElements: [],
10854
			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
10855
		} );
10856
 
10857
		// Wrap the element if it cannot hold child nodes
10858
		if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) {
10859
 
10860
			this.element.wrap(
10861
				$( "<div class='ui-wrapper' style='overflow: hidden;'></div>" ).css( {
10862
					position: this.element.css( "position" ),
10863
					width: this.element.outerWidth(),
10864
					height: this.element.outerHeight(),
10865
					top: this.element.css( "top" ),
10866
					left: this.element.css( "left" )
10867
				} )
10868
			);
10869
 
10870
			this.element = this.element.parent().data(
10871
				"ui-resizable", this.element.resizable( "instance" )
10872
			);
10873
 
10874
			this.elementIsWrapper = true;
10875
 
10876
			margins = {
10877
				marginTop: this.originalElement.css( "marginTop" ),
10878
				marginRight: this.originalElement.css( "marginRight" ),
10879
				marginBottom: this.originalElement.css( "marginBottom" ),
10880
				marginLeft: this.originalElement.css( "marginLeft" )
10881
			};
10882
 
10883
			this.element.css( margins );
10884
			this.originalElement.css( "margin", 0 );
10885
 
10886
			// support: Safari
10887
			// Prevent Safari textarea resize
10888
			this.originalResizeStyle = this.originalElement.css( "resize" );
10889
			this.originalElement.css( "resize", "none" );
10890
 
10891
			this._proportionallyResizeElements.push( this.originalElement.css( {
10892
				position: "static",
10893
				zoom: 1,
10894
				display: "block"
10895
			} ) );
10896
 
10897
			// Support: IE9
10898
			// avoid IE jump (hard set the margin)
10899
			this.originalElement.css( margins );
10900
 
10901
			this._proportionallyResize();
10902
		}
10903
 
10904
		this._setupHandles();
10905
 
10906
		if ( o.autoHide ) {
10907
			$( this.element )
10908
				.on( "mouseenter", function() {
10909
					if ( o.disabled ) {
10910
						return;
10911
					}
10912
					that._removeClass( "ui-resizable-autohide" );
10913
					that._handles.show();
10914
				} )
10915
				.on( "mouseleave", function() {
10916
					if ( o.disabled ) {
10917
						return;
10918
					}
10919
					if ( !that.resizing ) {
10920
						that._addClass( "ui-resizable-autohide" );
10921
						that._handles.hide();
10922
					}
10923
				} );
10924
		}
10925
 
10926
		this._mouseInit();
10927
	},
10928
 
10929
	_destroy: function() {
10930
 
10931
		this._mouseDestroy();
10932
 
10933
		var wrapper,
10934
			_destroy = function( exp ) {
10935
				$( exp )
10936
					.removeData( "resizable" )
10937
					.removeData( "ui-resizable" )
10938
					.off( ".resizable" )
10939
					.find( ".ui-resizable-handle" )
10940
						.remove();
10941
			};
10942
 
10943
		// TODO: Unwrap at same DOM position
10944
		if ( this.elementIsWrapper ) {
10945
			_destroy( this.element );
10946
			wrapper = this.element;
10947
			this.originalElement.css( {
10948
				position: wrapper.css( "position" ),
10949
				width: wrapper.outerWidth(),
10950
				height: wrapper.outerHeight(),
10951
				top: wrapper.css( "top" ),
10952
				left: wrapper.css( "left" )
10953
			} ).insertAfter( wrapper );
10954
			wrapper.remove();
10955
		}
10956
 
10957
		this.originalElement.css( "resize", this.originalResizeStyle );
10958
		_destroy( this.originalElement );
10959
 
10960
		return this;
10961
	},
10962
 
10963
	_setOption: function( key, value ) {
10964
		this._super( key, value );
10965
 
10966
		switch ( key ) {
10967
		case "handles":
10968
			this._removeHandles();
10969
			this._setupHandles();
10970
			break;
10971
		default:
10972
			break;
10973
		}
10974
	},
10975
 
10976
	_setupHandles: function() {
10977
		var o = this.options, handle, i, n, hname, axis, that = this;
10978
		this.handles = o.handles ||
10979
			( !$( ".ui-resizable-handle", this.element ).length ?
10980
				"e,s,se" : {
10981
					n: ".ui-resizable-n",
10982
					e: ".ui-resizable-e",
10983
					s: ".ui-resizable-s",
10984
					w: ".ui-resizable-w",
10985
					se: ".ui-resizable-se",
10986
					sw: ".ui-resizable-sw",
10987
					ne: ".ui-resizable-ne",
10988
					nw: ".ui-resizable-nw"
10989
				} );
10990
 
10991
		this._handles = $();
10992
		if ( this.handles.constructor === String ) {
10993
 
10994
			if ( this.handles === "all" ) {
10995
				this.handles = "n,e,s,w,se,sw,ne,nw";
10996
			}
10997
 
10998
			n = this.handles.split( "," );
10999
			this.handles = {};
11000
 
11001
			for ( i = 0; i < n.length; i++ ) {
11002
 
11003
				handle = $.trim( n[ i ] );
11004
				hname = "ui-resizable-" + handle;
11005
				axis = $( "<div>" );
11006
				this._addClass( axis, "ui-resizable-handle " + hname );
11007
 
11008
				axis.css( { zIndex: o.zIndex } );
11009
 
11010
				this.handles[ handle ] = ".ui-resizable-" + handle;
11011
				this.element.append( axis );
11012
			}
11013
 
11014
		}
11015
 
11016
		this._renderAxis = function( target ) {
11017
 
11018
			var i, axis, padPos, padWrapper;
11019
 
11020
			target = target || this.element;
11021
 
11022
			for ( i in this.handles ) {
11023
 
11024
				if ( this.handles[ i ].constructor === String ) {
11025
					this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show();
11026
				} else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
11027
					this.handles[ i ] = $( this.handles[ i ] );
11028
					this._on( this.handles[ i ], { "mousedown": that._mouseDown } );
11029
				}
11030
 
11031
				if ( this.elementIsWrapper &&
11032
						this.originalElement[ 0 ]
11033
							.nodeName
11034
							.match( /^(textarea|input|select|button)$/i ) ) {
11035
					axis = $( this.handles[ i ], this.element );
11036
 
11037
					padWrapper = /sw|ne|nw|se|n|s/.test( i ) ?
11038
						axis.outerHeight() :
11039
						axis.outerWidth();
11040
 
11041
					padPos = [ "padding",
11042
						/ne|nw|n/.test( i ) ? "Top" :
11043
						/se|sw|s/.test( i ) ? "Bottom" :
11044
						/^e$/.test( i ) ? "Right" : "Left" ].join( "" );
11045
 
11046
					target.css( padPos, padWrapper );
11047
 
11048
					this._proportionallyResize();
11049
				}
11050
 
11051
				this._handles = this._handles.add( this.handles[ i ] );
11052
			}
11053
		};
11054
 
11055
		// TODO: make renderAxis a prototype function
11056
		this._renderAxis( this.element );
11057
 
11058
		this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
11059
		this._handles.disableSelection();
11060
 
11061
		this._handles.on( "mouseover", function() {
11062
			if ( !that.resizing ) {
11063
				if ( this.className ) {
11064
					axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i );
11065
				}
11066
				that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se";
11067
			}
11068
		} );
11069
 
11070
		if ( o.autoHide ) {
11071
			this._handles.hide();
11072
			this._addClass( "ui-resizable-autohide" );
11073
		}
11074
	},
11075
 
11076
	_removeHandles: function() {
11077
		this._handles.remove();
11078
	},
11079
 
11080
	_mouseCapture: function( event ) {
11081
		var i, handle,
11082
			capture = false;
11083
 
11084
		for ( i in this.handles ) {
11085
			handle = $( this.handles[ i ] )[ 0 ];
11086
			if ( handle === event.target || $.contains( handle, event.target ) ) {
11087
				capture = true;
11088
			}
11089
		}
11090
 
11091
		return !this.options.disabled && capture;
11092
	},
11093
 
11094
	_mouseStart: function( event ) {
11095
 
11096
		var curleft, curtop, cursor,
11097
			o = this.options,
11098
			el = this.element;
11099
 
11100
		this.resizing = true;
11101
 
11102
		this._renderProxy();
11103
 
11104
		curleft = this._num( this.helper.css( "left" ) );
11105
		curtop = this._num( this.helper.css( "top" ) );
11106
 
11107
		if ( o.containment ) {
11108
			curleft += $( o.containment ).scrollLeft() || 0;
11109
			curtop += $( o.containment ).scrollTop() || 0;
11110
		}
11111
 
11112
		this.offset = this.helper.offset();
11113
		this.position = { left: curleft, top: curtop };
11114
 
11115
		this.size = this._helper ? {
11116
				width: this.helper.width(),
11117
				height: this.helper.height()
11118
			} : {
11119
				width: el.width(),
11120
				height: el.height()
11121
			};
11122
 
11123
		this.originalSize = this._helper ? {
11124
				width: el.outerWidth(),
11125
				height: el.outerHeight()
11126
			} : {
11127
				width: el.width(),
11128
				height: el.height()
11129
			};
11130
 
11131
		this.sizeDiff = {
11132
			width: el.outerWidth() - el.width(),
11133
			height: el.outerHeight() - el.height()
11134
		};
11135
 
11136
		this.originalPosition = { left: curleft, top: curtop };
11137
		this.originalMousePosition = { left: event.pageX, top: event.pageY };
11138
 
11139
		this.aspectRatio = ( typeof o.aspectRatio === "number" ) ?
11140
			o.aspectRatio :
11141
			( ( this.originalSize.width / this.originalSize.height ) || 1 );
11142
 
11143
		cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" );
11144
		$( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor );
11145
 
11146
		this._addClass( "ui-resizable-resizing" );
11147
		this._propagate( "start", event );
11148
		return true;
11149
	},
11150
 
11151
	_mouseDrag: function( event ) {
11152
 
11153
		var data, props,
11154
			smp = this.originalMousePosition,
11155
			a = this.axis,
11156
			dx = ( event.pageX - smp.left ) || 0,
11157
			dy = ( event.pageY - smp.top ) || 0,
11158
			trigger = this._change[ a ];
11159
 
11160
		this._updatePrevProperties();
11161
 
11162
		if ( !trigger ) {
11163
			return false;
11164
		}
11165
 
11166
		data = trigger.apply( this, [ event, dx, dy ] );
11167
 
11168
		this._updateVirtualBoundaries( event.shiftKey );
11169
		if ( this._aspectRatio || event.shiftKey ) {
11170
			data = this._updateRatio( data, event );
11171
		}
11172
 
11173
		data = this._respectSize( data, event );
11174
 
11175
		this._updateCache( data );
11176
 
11177
		this._propagate( "resize", event );
11178
 
11179
		props = this._applyChanges();
11180
 
11181
		if ( !this._helper && this._proportionallyResizeElements.length ) {
11182
			this._proportionallyResize();
11183
		}
11184
 
11185
		if ( !$.isEmptyObject( props ) ) {
11186
			this._updatePrevProperties();
11187
			this._trigger( "resize", event, this.ui() );
11188
			this._applyChanges();
11189
		}
11190
 
11191
		return false;
11192
	},
11193
 
11194
	_mouseStop: function( event ) {
11195
 
11196
		this.resizing = false;
11197
		var pr, ista, soffseth, soffsetw, s, left, top,
11198
			o = this.options, that = this;
11199
 
11200
		if ( this._helper ) {
11201
 
11202
			pr = this._proportionallyResizeElements;
11203
			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName );
11204
			soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height;
11205
			soffsetw = ista ? 0 : that.sizeDiff.width;
11206
 
11207
			s = {
11208
				width: ( that.helper.width()  - soffsetw ),
11209
				height: ( that.helper.height() - soffseth )
11210
			};
11211
			left = ( parseFloat( that.element.css( "left" ) ) +
11212
				( that.position.left - that.originalPosition.left ) ) || null;
11213
			top = ( parseFloat( that.element.css( "top" ) ) +
11214
				( that.position.top - that.originalPosition.top ) ) || null;
11215
 
11216
			if ( !o.animate ) {
11217
				this.element.css( $.extend( s, { top: top, left: left } ) );
11218
			}
11219
 
11220
			that.helper.height( that.size.height );
11221
			that.helper.width( that.size.width );
11222
 
11223
			if ( this._helper && !o.animate ) {
11224
				this._proportionallyResize();
11225
			}
11226
		}
11227
 
11228
		$( "body" ).css( "cursor", "auto" );
11229
 
11230
		this._removeClass( "ui-resizable-resizing" );
11231
 
11232
		this._propagate( "stop", event );
11233
 
11234
		if ( this._helper ) {
11235
			this.helper.remove();
11236
		}
11237
 
11238
		return false;
11239
 
11240
	},
11241
 
11242
	_updatePrevProperties: function() {
11243
		this.prevPosition = {
11244
			top: this.position.top,
11245
			left: this.position.left
11246
		};
11247
		this.prevSize = {
11248
			width: this.size.width,
11249
			height: this.size.height
11250
		};
11251
	},
11252
 
11253
	_applyChanges: function() {
11254
		var props = {};
11255
 
11256
		if ( this.position.top !== this.prevPosition.top ) {
11257
			props.top = this.position.top + "px";
11258
		}
11259
		if ( this.position.left !== this.prevPosition.left ) {
11260
			props.left = this.position.left + "px";
11261
		}
11262
		if ( this.size.width !== this.prevSize.width ) {
11263
			props.width = this.size.width + "px";
11264
		}
11265
		if ( this.size.height !== this.prevSize.height ) {
11266
			props.height = this.size.height + "px";
11267
		}
11268
 
11269
		this.helper.css( props );
11270
 
11271
		return props;
11272
	},
11273
 
11274
	_updateVirtualBoundaries: function( forceAspectRatio ) {
11275
		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
11276
			o = this.options;
11277
 
11278
		b = {
11279
			minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0,
11280
			maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity,
11281
			minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0,
11282
			maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity
11283
		};
11284
 
11285
		if ( this._aspectRatio || forceAspectRatio ) {
11286
			pMinWidth = b.minHeight * this.aspectRatio;
11287
			pMinHeight = b.minWidth / this.aspectRatio;
11288
			pMaxWidth = b.maxHeight * this.aspectRatio;
11289
			pMaxHeight = b.maxWidth / this.aspectRatio;
11290
 
11291
			if ( pMinWidth > b.minWidth ) {
11292
				b.minWidth = pMinWidth;
11293
			}
11294
			if ( pMinHeight > b.minHeight ) {
11295
				b.minHeight = pMinHeight;
11296
			}
11297
			if ( pMaxWidth < b.maxWidth ) {
11298
				b.maxWidth = pMaxWidth;
11299
			}
11300
			if ( pMaxHeight < b.maxHeight ) {
11301
				b.maxHeight = pMaxHeight;
11302
			}
11303
		}
11304
		this._vBoundaries = b;
11305
	},
11306
 
11307
	_updateCache: function( data ) {
11308
		this.offset = this.helper.offset();
11309
		if ( this._isNumber( data.left ) ) {
11310
			this.position.left = data.left;
11311
		}
11312
		if ( this._isNumber( data.top ) ) {
11313
			this.position.top = data.top;
11314
		}
11315
		if ( this._isNumber( data.height ) ) {
11316
			this.size.height = data.height;
11317
		}
11318
		if ( this._isNumber( data.width ) ) {
11319
			this.size.width = data.width;
11320
		}
11321
	},
11322
 
11323
	_updateRatio: function( data ) {
11324
 
11325
		var cpos = this.position,
11326
			csize = this.size,
11327
			a = this.axis;
11328
 
11329
		if ( this._isNumber( data.height ) ) {
11330
			data.width = ( data.height * this.aspectRatio );
11331
		} else if ( this._isNumber( data.width ) ) {
11332
			data.height = ( data.width / this.aspectRatio );
11333
		}
11334
 
11335
		if ( a === "sw" ) {
11336
			data.left = cpos.left + ( csize.width - data.width );
11337
			data.top = null;
11338
		}
11339
		if ( a === "nw" ) {
11340
			data.top = cpos.top + ( csize.height - data.height );
11341
			data.left = cpos.left + ( csize.width - data.width );
11342
		}
11343
 
11344
		return data;
11345
	},
11346
 
11347
	_respectSize: function( data ) {
11348
 
11349
		var o = this._vBoundaries,
11350
			a = this.axis,
11351
			ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ),
11352
			ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ),
11353
			isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ),
11354
			isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ),
11355
			dw = this.originalPosition.left + this.originalSize.width,
11356
			dh = this.originalPosition.top + this.originalSize.height,
11357
			cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a );
11358
		if ( isminw ) {
11359
			data.width = o.minWidth;
11360
		}
11361
		if ( isminh ) {
11362
			data.height = o.minHeight;
11363
		}
11364
		if ( ismaxw ) {
11365
			data.width = o.maxWidth;
11366
		}
11367
		if ( ismaxh ) {
11368
			data.height = o.maxHeight;
11369
		}
11370
 
11371
		if ( isminw && cw ) {
11372
			data.left = dw - o.minWidth;
11373
		}
11374
		if ( ismaxw && cw ) {
11375
			data.left = dw - o.maxWidth;
11376
		}
11377
		if ( isminh && ch ) {
11378
			data.top = dh - o.minHeight;
11379
		}
11380
		if ( ismaxh && ch ) {
11381
			data.top = dh - o.maxHeight;
11382
		}
11383
 
11384
		// Fixing jump error on top/left - bug #2330
11385
		if ( !data.width && !data.height && !data.left && data.top ) {
11386
			data.top = null;
11387
		} else if ( !data.width && !data.height && !data.top && data.left ) {
11388
			data.left = null;
11389
		}
11390
 
11391
		return data;
11392
	},
11393
 
11394
	_getPaddingPlusBorderDimensions: function( element ) {
11395
		var i = 0,
11396
			widths = [],
11397
			borders = [
11398
				element.css( "borderTopWidth" ),
11399
				element.css( "borderRightWidth" ),
11400
				element.css( "borderBottomWidth" ),
11401
				element.css( "borderLeftWidth" )
11402
			],
11403
			paddings = [
11404
				element.css( "paddingTop" ),
11405
				element.css( "paddingRight" ),
11406
				element.css( "paddingBottom" ),
11407
				element.css( "paddingLeft" )
11408
			];
11409
 
11410
		for ( ; i < 4; i++ ) {
11411
			widths[ i ] = ( parseFloat( borders[ i ] ) || 0 );
11412
			widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 );
11413
		}
11414
 
11415
		return {
11416
			height: widths[ 0 ] + widths[ 2 ],
11417
			width: widths[ 1 ] + widths[ 3 ]
11418
		};
11419
	},
11420
 
11421
	_proportionallyResize: function() {
11422
 
11423
		if ( !this._proportionallyResizeElements.length ) {
11424
			return;
11425
		}
11426
 
11427
		var prel,
11428
			i = 0,
11429
			element = this.helper || this.element;
11430
 
11431
		for ( ; i < this._proportionallyResizeElements.length; i++ ) {
11432
 
11433
			prel = this._proportionallyResizeElements[ i ];
11434
 
11435
			// TODO: Seems like a bug to cache this.outerDimensions
11436
			// considering that we are in a loop.
11437
			if ( !this.outerDimensions ) {
11438
				this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
11439
			}
11440
 
11441
			prel.css( {
11442
				height: ( element.height() - this.outerDimensions.height ) || 0,
11443
				width: ( element.width() - this.outerDimensions.width ) || 0
11444
			} );
11445
 
11446
		}
11447
 
11448
	},
11449
 
11450
	_renderProxy: function() {
11451
 
11452
		var el = this.element, o = this.options;
11453
		this.elementOffset = el.offset();
11454
 
11455
		if ( this._helper ) {
11456
 
11457
			this.helper = this.helper || $( "<div style='overflow:hidden;'></div>" );
11458
 
11459
			this._addClass( this.helper, this._helper );
11460
			this.helper.css( {
11461
				width: this.element.outerWidth(),
11462
				height: this.element.outerHeight(),
11463
				position: "absolute",
11464
				left: this.elementOffset.left + "px",
11465
				top: this.elementOffset.top + "px",
11466
				zIndex: ++o.zIndex //TODO: Don't modify option
11467
			} );
11468
 
11469
			this.helper
11470
				.appendTo( "body" )
11471
				.disableSelection();
11472
 
11473
		} else {
11474
			this.helper = this.element;
11475
		}
11476
 
11477
	},
11478
 
11479
	_change: {
11480
		e: function( event, dx ) {
11481
			return { width: this.originalSize.width + dx };
11482
		},
11483
		w: function( event, dx ) {
11484
			var cs = this.originalSize, sp = this.originalPosition;
11485
			return { left: sp.left + dx, width: cs.width - dx };
11486
		},
11487
		n: function( event, dx, dy ) {
11488
			var cs = this.originalSize, sp = this.originalPosition;
11489
			return { top: sp.top + dy, height: cs.height - dy };
11490
		},
11491
		s: function( event, dx, dy ) {
11492
			return { height: this.originalSize.height + dy };
11493
		},
11494
		se: function( event, dx, dy ) {
11495
			return $.extend( this._change.s.apply( this, arguments ),
11496
				this._change.e.apply( this, [ event, dx, dy ] ) );
11497
		},
11498
		sw: function( event, dx, dy ) {
11499
			return $.extend( this._change.s.apply( this, arguments ),
11500
				this._change.w.apply( this, [ event, dx, dy ] ) );
11501
		},
11502
		ne: function( event, dx, dy ) {
11503
			return $.extend( this._change.n.apply( this, arguments ),
11504
				this._change.e.apply( this, [ event, dx, dy ] ) );
11505
		},
11506
		nw: function( event, dx, dy ) {
11507
			return $.extend( this._change.n.apply( this, arguments ),
11508
				this._change.w.apply( this, [ event, dx, dy ] ) );
11509
		}
11510
	},
11511
 
11512
	_propagate: function( n, event ) {
11513
		$.ui.plugin.call( this, n, [ event, this.ui() ] );
11514
		( n !== "resize" && this._trigger( n, event, this.ui() ) );
11515
	},
11516
 
11517
	plugins: {},
11518
 
11519
	ui: function() {
11520
		return {
11521
			originalElement: this.originalElement,
11522
			element: this.element,
11523
			helper: this.helper,
11524
			position: this.position,
11525
			size: this.size,
11526
			originalSize: this.originalSize,
11527
			originalPosition: this.originalPosition
11528
		};
11529
	}
11530
 
11531
} );
11532
 
11533
/*
11534
 * Resizable Extensions
11535
 */
11536
 
11537
$.ui.plugin.add( "resizable", "animate", {
11538
 
11539
	stop: function( event ) {
11540
		var that = $( this ).resizable( "instance" ),
11541
			o = that.options,
11542
			pr = that._proportionallyResizeElements,
11543
			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ),
11544
			soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height,
11545
			soffsetw = ista ? 0 : that.sizeDiff.width,
11546
			style = {
11547
				width: ( that.size.width - soffsetw ),
11548
				height: ( that.size.height - soffseth )
11549
			},
11550
			left = ( parseFloat( that.element.css( "left" ) ) +
11551
				( that.position.left - that.originalPosition.left ) ) || null,
11552
			top = ( parseFloat( that.element.css( "top" ) ) +
11553
				( that.position.top - that.originalPosition.top ) ) || null;
11554
 
11555
		that.element.animate(
11556
			$.extend( style, top && left ? { top: top, left: left } : {} ), {
11557
				duration: o.animateDuration,
11558
				easing: o.animateEasing,
11559
				step: function() {
11560
 
11561
					var data = {
11562
						width: parseFloat( that.element.css( "width" ) ),
11563
						height: parseFloat( that.element.css( "height" ) ),
11564
						top: parseFloat( that.element.css( "top" ) ),
11565
						left: parseFloat( that.element.css( "left" ) )
11566
					};
11567
 
11568
					if ( pr && pr.length ) {
11569
						$( pr[ 0 ] ).css( { width: data.width, height: data.height } );
11570
					}
11571
 
11572
					// Propagating resize, and updating values for each animation step
11573
					that._updateCache( data );
11574
					that._propagate( "resize", event );
11575
 
11576
				}
11577
			}
11578
		);
11579
	}
11580
 
11581
} );
11582
 
11583
$.ui.plugin.add( "resizable", "containment", {
11584
 
11585
	start: function() {
11586
		var element, p, co, ch, cw, width, height,
11587
			that = $( this ).resizable( "instance" ),
11588
			o = that.options,
11589
			el = that.element,
11590
			oc = o.containment,
11591
			ce = ( oc instanceof $ ) ?
11592
				oc.get( 0 ) :
11593
				( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
11594
 
11595
		if ( !ce ) {
11596
			return;
11597
		}
11598
 
11599
		that.containerElement = $( ce );
11600
 
11601
		if ( /document/.test( oc ) || oc === document ) {
11602
			that.containerOffset = {
11603
				left: 0,
11604
				top: 0
11605
			};
11606
			that.containerPosition = {
11607
				left: 0,
11608
				top: 0
11609
			};
11610
 
11611
			that.parentData = {
11612
				element: $( document ),
11613
				left: 0,
11614
				top: 0,
11615
				width: $( document ).width(),
11616
				height: $( document ).height() || document.body.parentNode.scrollHeight
11617
			};
11618
		} else {
11619
			element = $( ce );
11620
			p = [];
11621
			$( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) {
11622
				p[ i ] = that._num( element.css( "padding" + name ) );
11623
			} );
11624
 
11625
			that.containerOffset = element.offset();
11626
			that.containerPosition = element.position();
11627
			that.containerSize = {
11628
				height: ( element.innerHeight() - p[ 3 ] ),
11629
				width: ( element.innerWidth() - p[ 1 ] )
11630
			};
11631
 
11632
			co = that.containerOffset;
11633
			ch = that.containerSize.height;
11634
			cw = that.containerSize.width;
11635
			width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
11636
			height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
11637
 
11638
			that.parentData = {
11639
				element: ce,
11640
				left: co.left,
11641
				top: co.top,
11642
				width: width,
11643
				height: height
11644
			};
11645
		}
11646
	},
11647
 
11648
	resize: function( event ) {
11649
		var woset, hoset, isParent, isOffsetRelative,
11650
			that = $( this ).resizable( "instance" ),
11651
			o = that.options,
11652
			co = that.containerOffset,
11653
			cp = that.position,
11654
			pRatio = that._aspectRatio || event.shiftKey,
11655
			cop = {
11656
				top: 0,
11657
				left: 0
11658
			},
11659
			ce = that.containerElement,
11660
			continueResize = true;
11661
 
11662
		if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
11663
			cop = co;
11664
		}
11665
 
11666
		if ( cp.left < ( that._helper ? co.left : 0 ) ) {
11667
			that.size.width = that.size.width +
11668
				( that._helper ?
11669
					( that.position.left - co.left ) :
11670
					( that.position.left - cop.left ) );
11671
 
11672
			if ( pRatio ) {
11673
				that.size.height = that.size.width / that.aspectRatio;
11674
				continueResize = false;
11675
			}
11676
			that.position.left = o.helper ? co.left : 0;
11677
		}
11678
 
11679
		if ( cp.top < ( that._helper ? co.top : 0 ) ) {
11680
			that.size.height = that.size.height +
11681
				( that._helper ?
11682
					( that.position.top - co.top ) :
11683
					that.position.top );
11684
 
11685
			if ( pRatio ) {
11686
				that.size.width = that.size.height * that.aspectRatio;
11687
				continueResize = false;
11688
			}
11689
			that.position.top = that._helper ? co.top : 0;
11690
		}
11691
 
11692
		isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
11693
		isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
11694
 
11695
		if ( isParent && isOffsetRelative ) {
11696
			that.offset.left = that.parentData.left + that.position.left;
11697
			that.offset.top = that.parentData.top + that.position.top;
11698
		} else {
11699
			that.offset.left = that.element.offset().left;
11700
			that.offset.top = that.element.offset().top;
11701
		}
11702
 
11703
		woset = Math.abs( that.sizeDiff.width +
11704
			( that._helper ?
11705
				that.offset.left - cop.left :
11706
				( that.offset.left - co.left ) ) );
11707
 
11708
		hoset = Math.abs( that.sizeDiff.height +
11709
			( that._helper ?
11710
				that.offset.top - cop.top :
11711
				( that.offset.top - co.top ) ) );
11712
 
11713
		if ( woset + that.size.width >= that.parentData.width ) {
11714
			that.size.width = that.parentData.width - woset;
11715
			if ( pRatio ) {
11716
				that.size.height = that.size.width / that.aspectRatio;
11717
				continueResize = false;
11718
			}
11719
		}
11720
 
11721
		if ( hoset + that.size.height >= that.parentData.height ) {
11722
			that.size.height = that.parentData.height - hoset;
11723
			if ( pRatio ) {
11724
				that.size.width = that.size.height * that.aspectRatio;
11725
				continueResize = false;
11726
			}
11727
		}
11728
 
11729
		if ( !continueResize ) {
11730
			that.position.left = that.prevPosition.left;
11731
			that.position.top = that.prevPosition.top;
11732
			that.size.width = that.prevSize.width;
11733
			that.size.height = that.prevSize.height;
11734
		}
11735
	},
11736
 
11737
	stop: function() {
11738
		var that = $( this ).resizable( "instance" ),
11739
			o = that.options,
11740
			co = that.containerOffset,
11741
			cop = that.containerPosition,
11742
			ce = that.containerElement,
11743
			helper = $( that.helper ),
11744
			ho = helper.offset(),
11745
			w = helper.outerWidth() - that.sizeDiff.width,
11746
			h = helper.outerHeight() - that.sizeDiff.height;
11747
 
11748
		if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
11749
			$( this ).css( {
11750
				left: ho.left - cop.left - co.left,
11751
				width: w,
11752
				height: h
11753
			} );
11754
		}
11755
 
11756
		if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
11757
			$( this ).css( {
11758
				left: ho.left - cop.left - co.left,
11759
				width: w,
11760
				height: h
11761
			} );
11762
		}
11763
	}
11764
} );
11765
 
11766
$.ui.plugin.add( "resizable", "alsoResize", {
11767
 
11768
	start: function() {
11769
		var that = $( this ).resizable( "instance" ),
11770
			o = that.options;
11771
 
11772
		$( o.alsoResize ).each( function() {
11773
			var el = $( this );
11774
			el.data( "ui-resizable-alsoresize", {
11775
				width: parseFloat( el.width() ), height: parseFloat( el.height() ),
11776
				left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
11777
			} );
11778
		} );
11779
	},
11780
 
11781
	resize: function( event, ui ) {
11782
		var that = $( this ).resizable( "instance" ),
11783
			o = that.options,
11784
			os = that.originalSize,
11785
			op = that.originalPosition,
11786
			delta = {
11787
				height: ( that.size.height - os.height ) || 0,
11788
				width: ( that.size.width - os.width ) || 0,
11789
				top: ( that.position.top - op.top ) || 0,
11790
				left: ( that.position.left - op.left ) || 0
11791
			};
11792
 
11793
			$( o.alsoResize ).each( function() {
11794
				var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {},
11795
					css = el.parents( ui.originalElement[ 0 ] ).length ?
11796
							[ "width", "height" ] :
11797
							[ "width", "height", "top", "left" ];
11798
 
11799
				$.each( css, function( i, prop ) {
11800
					var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 );
11801
					if ( sum && sum >= 0 ) {
11802
						style[ prop ] = sum || null;
11803
					}
11804
				} );
11805
 
11806
				el.css( style );
11807
			} );
11808
	},
11809
 
11810
	stop: function() {
11811
		$( this ).removeData( "ui-resizable-alsoresize" );
11812
	}
11813
} );
11814
 
11815
$.ui.plugin.add( "resizable", "ghost", {
11816
 
11817
	start: function() {
11818
 
11819
		var that = $( this ).resizable( "instance" ), cs = that.size;
11820
 
11821
		that.ghost = that.originalElement.clone();
11822
		that.ghost.css( {
11823
			opacity: 0.25,
11824
			display: "block",
11825
			position: "relative",
11826
			height: cs.height,
11827
			width: cs.width,
11828
			margin: 0,
11829
			left: 0,
11830
			top: 0
11831
		} );
11832
 
11833
		that._addClass( that.ghost, "ui-resizable-ghost" );
11834
 
11835
		// DEPRECATED
11836
		// TODO: remove after 1.12
11837
		if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) {
11838
 
11839
			// Ghost option
11840
			that.ghost.addClass( this.options.ghost );
11841
		}
11842
 
11843
		that.ghost.appendTo( that.helper );
11844
 
11845
	},
11846
 
11847
	resize: function() {
11848
		var that = $( this ).resizable( "instance" );
11849
		if ( that.ghost ) {
11850
			that.ghost.css( {
11851
				position: "relative",
11852
				height: that.size.height,
11853
				width: that.size.width
11854
			} );
11855
		}
11856
	},
11857
 
11858
	stop: function() {
11859
		var that = $( this ).resizable( "instance" );
11860
		if ( that.ghost && that.helper ) {
11861
			that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) );
11862
		}
11863
	}
11864
 
11865
} );
11866
 
11867
$.ui.plugin.add( "resizable", "grid", {
11868
 
11869
	resize: function() {
11870
		var outerDimensions,
11871
			that = $( this ).resizable( "instance" ),
11872
			o = that.options,
11873
			cs = that.size,
11874
			os = that.originalSize,
11875
			op = that.originalPosition,
11876
			a = that.axis,
11877
			grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
11878
			gridX = ( grid[ 0 ] || 1 ),
11879
			gridY = ( grid[ 1 ] || 1 ),
11880
			ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX,
11881
			oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY,
11882
			newWidth = os.width + ox,
11883
			newHeight = os.height + oy,
11884
			isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ),
11885
			isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ),
11886
			isMinWidth = o.minWidth && ( o.minWidth > newWidth ),
11887
			isMinHeight = o.minHeight && ( o.minHeight > newHeight );
11888
 
11889
		o.grid = grid;
11890
 
11891
		if ( isMinWidth ) {
11892
			newWidth += gridX;
11893
		}
11894
		if ( isMinHeight ) {
11895
			newHeight += gridY;
11896
		}
11897
		if ( isMaxWidth ) {
11898
			newWidth -= gridX;
11899
		}
11900
		if ( isMaxHeight ) {
11901
			newHeight -= gridY;
11902
		}
11903
 
11904
		if ( /^(se|s|e)$/.test( a ) ) {
11905
			that.size.width = newWidth;
11906
			that.size.height = newHeight;
11907
		} else if ( /^(ne)$/.test( a ) ) {
11908
			that.size.width = newWidth;
11909
			that.size.height = newHeight;
11910
			that.position.top = op.top - oy;
11911
		} else if ( /^(sw)$/.test( a ) ) {
11912
			that.size.width = newWidth;
11913
			that.size.height = newHeight;
11914
			that.position.left = op.left - ox;
11915
		} else {
11916
			if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) {
11917
				outerDimensions = that._getPaddingPlusBorderDimensions( this );
11918
			}
11919
 
11920
			if ( newHeight - gridY > 0 ) {
11921
				that.size.height = newHeight;
11922
				that.position.top = op.top - oy;
11923
			} else {
11924
				newHeight = gridY - outerDimensions.height;
11925
				that.size.height = newHeight;
11926
				that.position.top = op.top + os.height - newHeight;
11927
			}
11928
			if ( newWidth - gridX > 0 ) {
11929
				that.size.width = newWidth;
11930
				that.position.left = op.left - ox;
11931
			} else {
11932
				newWidth = gridX - outerDimensions.width;
11933
				that.size.width = newWidth;
11934
				that.position.left = op.left + os.width - newWidth;
11935
			}
11936
		}
11937
	}
11938
 
11939
} );
11940
 
11941
var widgetsResizable = $.ui.resizable;
11942
 
11943
 
11944
/*!
11945
 * jQuery UI Dialog 1.12.1
11946
 * http://jqueryui.com
11947
 *
11948
 * Copyright jQuery Foundation and other contributors
11949
 * Released under the MIT license.
11950
 * http://jquery.org/license
11951
 */
11952
 
11953
//>>label: Dialog
11954
//>>group: Widgets
11955
//>>description: Displays customizable dialog windows.
11956
//>>docs: http://api.jqueryui.com/dialog/
11957
//>>demos: http://jqueryui.com/dialog/
11958
//>>css.structure: ../../themes/base/core.css
11959
//>>css.structure: ../../themes/base/dialog.css
11960
//>>css.theme: ../../themes/base/theme.css
11961
 
11962
 
11963
 
11964
$.widget( "ui.dialog", {
11965
	version: "1.12.1",
11966
	options: {
11967
		appendTo: "body",
11968
		autoOpen: true,
11969
		buttons: [],
11970
		classes: {
11971
			"ui-dialog": "ui-corner-all",
11972
			"ui-dialog-titlebar": "ui-corner-all"
11973
		},
11974
		closeOnEscape: true,
11975
		closeText: "Close",
11976
		draggable: true,
11977
		hide: null,
11978
		height: "auto",
11979
		maxHeight: null,
11980
		maxWidth: null,
11981
		minHeight: 150,
11982
		minWidth: 150,
11983
		modal: false,
11984
		position: {
11985
			my: "center",
11986
			at: "center",
11987
			of: window,
11988
			collision: "fit",
11989
 
11990
			// Ensure the titlebar is always visible
11991
			using: function( pos ) {
11992
				var topOffset = $( this ).css( pos ).offset().top;
11993
				if ( topOffset < 0 ) {
11994
					$( this ).css( "top", pos.top - topOffset );
11995
				}
11996
			}
11997
		},
11998
		resizable: true,
11999
		show: null,
12000
		title: null,
12001
		width: 300,
12002
 
12003
		// Callbacks
12004
		beforeClose: null,
12005
		close: null,
12006
		drag: null,
12007
		dragStart: null,
12008
		dragStop: null,
12009
		focus: null,
12010
		open: null,
12011
		resize: null,
12012
		resizeStart: null,
12013
		resizeStop: null
12014
	},
12015
 
12016
	sizeRelatedOptions: {
12017
		buttons: true,
12018
		height: true,
12019
		maxHeight: true,
12020
		maxWidth: true,
12021
		minHeight: true,
12022
		minWidth: true,
12023
		width: true
12024
	},
12025
 
12026
	resizableRelatedOptions: {
12027
		maxHeight: true,
12028
		maxWidth: true,
12029
		minHeight: true,
12030
		minWidth: true
12031
	},
12032
 
12033
	_create: function() {
12034
		this.originalCss = {
12035
			display: this.element[ 0 ].style.display,
12036
			width: this.element[ 0 ].style.width,
12037
			minHeight: this.element[ 0 ].style.minHeight,
12038
			maxHeight: this.element[ 0 ].style.maxHeight,
12039
			height: this.element[ 0 ].style.height
12040
		};
12041
		this.originalPosition = {
12042
			parent: this.element.parent(),
12043
			index: this.element.parent().children().index( this.element )
12044
		};
12045
		this.originalTitle = this.element.attr( "title" );
12046
		if ( this.options.title == null && this.originalTitle != null ) {
12047
			this.options.title = this.originalTitle;
12048
		}
12049
 
12050
		// Dialogs can't be disabled
12051
		if ( this.options.disabled ) {
12052
			this.options.disabled = false;
12053
		}
12054
 
12055
		this._createWrapper();
12056
 
12057
		this.element
12058
			.show()
12059
			.removeAttr( "title" )
12060
			.appendTo( this.uiDialog );
12061
 
12062
		this._addClass( "ui-dialog-content", "ui-widget-content" );
12063
 
12064
		this._createTitlebar();
12065
		this._createButtonPane();
12066
 
12067
		if ( this.options.draggable && $.fn.draggable ) {
12068
			this._makeDraggable();
12069
		}
12070
		if ( this.options.resizable && $.fn.resizable ) {
12071
			this._makeResizable();
12072
		}
12073
 
12074
		this._isOpen = false;
12075
 
12076
		this._trackFocus();
12077
	},
12078
 
12079
	_init: function() {
12080
		if ( this.options.autoOpen ) {
12081
			this.open();
12082
		}
12083
	},
12084
 
12085
	_appendTo: function() {
12086
		var element = this.options.appendTo;
12087
		if ( element && ( element.jquery || element.nodeType ) ) {
12088
			return $( element );
12089
		}
12090
		return this.document.find( element || "body" ).eq( 0 );
12091
	},
12092
 
12093
	_destroy: function() {
12094
		var next,
12095
			originalPosition = this.originalPosition;
12096
 
12097
		this._untrackInstance();
12098
		this._destroyOverlay();
12099
 
12100
		this.element
12101
			.removeUniqueId()
12102
			.css( this.originalCss )
12103
 
12104
			// Without detaching first, the following becomes really slow
12105
			.detach();
12106
 
12107
		this.uiDialog.remove();
12108
 
12109
		if ( this.originalTitle ) {
12110
			this.element.attr( "title", this.originalTitle );
12111
		}
12112
 
12113
		next = originalPosition.parent.children().eq( originalPosition.index );
12114
 
12115
		// Don't try to place the dialog next to itself (#8613)
12116
		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
12117
			next.before( this.element );
12118
		} else {
12119
			originalPosition.parent.append( this.element );
12120
		}
12121
	},
12122
 
12123
	widget: function() {
12124
		return this.uiDialog;
12125
	},
12126
 
12127
	disable: $.noop,
12128
	enable: $.noop,
12129
 
12130
	close: function( event ) {
12131
		var that = this;
12132
 
12133
		if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
12134
			return;
12135
		}
12136
 
12137
		this._isOpen = false;
12138
		this._focusedElement = null;
12139
		this._destroyOverlay();
12140
		this._untrackInstance();
12141
 
12142
		if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) {
12143
 
12144
			// Hiding a focused element doesn't trigger blur in WebKit
12145
			// so in case we have nothing to focus on, explicitly blur the active element
12146
			// https://bugs.webkit.org/show_bug.cgi?id=47182
12147
			$.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) );
12148
		}
12149
 
12150
		this._hide( this.uiDialog, this.options.hide, function() {
12151
			that._trigger( "close", event );
12152
		} );
12153
	},
12154
 
12155
	isOpen: function() {
12156
		return this._isOpen;
12157
	},
12158
 
12159
	moveToTop: function() {
12160
		this._moveToTop();
12161
	},
12162
 
12163
	_moveToTop: function( event, silent ) {
12164
		var moved = false,
12165
			zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() {
12166
				return +$( this ).css( "z-index" );
12167
			} ).get(),
12168
			zIndexMax = Math.max.apply( null, zIndices );
12169
 
12170
		if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
12171
			this.uiDialog.css( "z-index", zIndexMax + 1 );
12172
			moved = true;
12173
		}
12174
 
12175
		if ( moved && !silent ) {
12176
			this._trigger( "focus", event );
12177
		}
12178
		return moved;
12179
	},
12180
 
12181
	open: function() {
12182
		var that = this;
12183
		if ( this._isOpen ) {
12184
			if ( this._moveToTop() ) {
12185
				this._focusTabbable();
12186
			}
12187
			return;
12188
		}
12189
 
12190
		this._isOpen = true;
12191
		this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
12192
 
12193
		this._size();
12194
		this._position();
12195
		this._createOverlay();
12196
		this._moveToTop( null, true );
12197
 
12198
		// Ensure the overlay is moved to the top with the dialog, but only when
12199
		// opening. The overlay shouldn't move after the dialog is open so that
12200
		// modeless dialogs opened after the modal dialog stack properly.
12201
		if ( this.overlay ) {
12202
			this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
12203
		}
12204
 
12205
		this._show( this.uiDialog, this.options.show, function() {
12206
			that._focusTabbable();
12207
			that._trigger( "focus" );
12208
		} );
12209
 
12210
		// Track the dialog immediately upon openening in case a focus event
12211
		// somehow occurs outside of the dialog before an element inside the
12212
		// dialog is focused (#10152)
12213
		this._makeFocusTarget();
12214
 
12215
		this._trigger( "open" );
12216
	},
12217
 
12218
	_focusTabbable: function() {
12219
 
12220
		// Set focus to the first match:
12221
		// 1. An element that was focused previously
12222
		// 2. First element inside the dialog matching [autofocus]
12223
		// 3. Tabbable element inside the content element
12224
		// 4. Tabbable element inside the buttonpane
12225
		// 5. The close button
12226
		// 6. The dialog itself
12227
		var hasFocus = this._focusedElement;
12228
		if ( !hasFocus ) {
12229
			hasFocus = this.element.find( "[autofocus]" );
12230
		}
12231
		if ( !hasFocus.length ) {
12232
			hasFocus = this.element.find( ":tabbable" );
12233
		}
12234
		if ( !hasFocus.length ) {
12235
			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
12236
		}
12237
		if ( !hasFocus.length ) {
12238
			hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
12239
		}
12240
		if ( !hasFocus.length ) {
12241
			hasFocus = this.uiDialog;
12242
		}
12243
		hasFocus.eq( 0 ).trigger( "focus" );
12244
	},
12245
 
12246
	_keepFocus: function( event ) {
12247
		function checkFocus() {
12248
			var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
12249
				isActive = this.uiDialog[ 0 ] === activeElement ||
12250
					$.contains( this.uiDialog[ 0 ], activeElement );
12251
			if ( !isActive ) {
12252
				this._focusTabbable();
12253
			}
12254
		}
12255
		event.preventDefault();
12256
		checkFocus.call( this );
12257
 
12258
		// support: IE
12259
		// IE <= 8 doesn't prevent moving focus even with event.preventDefault()
12260
		// so we check again later
12261
		this._delay( checkFocus );
12262
	},
12263
 
12264
	_createWrapper: function() {
12265
		this.uiDialog = $( "<div>" )
12266
			.hide()
12267
			.attr( {
12268
 
12269
				// Setting tabIndex makes the div focusable
12270
				tabIndex: -1,
12271
				role: "dialog"
12272
			} )
12273
			.appendTo( this._appendTo() );
12274
 
12275
		this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" );
12276
		this._on( this.uiDialog, {
12277
			keydown: function( event ) {
12278
				if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
12279
						event.keyCode === $.ui.keyCode.ESCAPE ) {
12280
					event.preventDefault();
12281
					this.close( event );
12282
					return;
12283
				}
12284
 
12285
				// Prevent tabbing out of dialogs
12286
				if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
12287
					return;
12288
				}
12289
				var tabbables = this.uiDialog.find( ":tabbable" ),
12290
					first = tabbables.filter( ":first" ),
12291
					last = tabbables.filter( ":last" );
12292
 
12293
				if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) &&
12294
						!event.shiftKey ) {
12295
					this._delay( function() {
12296
						first.trigger( "focus" );
12297
					} );
12298
					event.preventDefault();
12299
				} else if ( ( event.target === first[ 0 ] ||
12300
						event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) {
12301
					this._delay( function() {
12302
						last.trigger( "focus" );
12303
					} );
12304
					event.preventDefault();
12305
				}
12306
			},
12307
			mousedown: function( event ) {
12308
				if ( this._moveToTop( event ) ) {
12309
					this._focusTabbable();
12310
				}
12311
			}
12312
		} );
12313
 
12314
		// We assume that any existing aria-describedby attribute means
12315
		// that the dialog content is marked up properly
12316
		// otherwise we brute force the content as the description
12317
		if ( !this.element.find( "[aria-describedby]" ).length ) {
12318
			this.uiDialog.attr( {
12319
				"aria-describedby": this.element.uniqueId().attr( "id" )
12320
			} );
12321
		}
12322
	},
12323
 
12324
	_createTitlebar: function() {
12325
		var uiDialogTitle;
12326
 
12327
		this.uiDialogTitlebar = $( "<div>" );
12328
		this._addClass( this.uiDialogTitlebar,
12329
			"ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" );
12330
		this._on( this.uiDialogTitlebar, {
12331
			mousedown: function( event ) {
12332
 
12333
				// Don't prevent click on close button (#8838)
12334
				// Focusing a dialog that is partially scrolled out of view
12335
				// causes the browser to scroll it into view, preventing the click event
12336
				if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
12337
 
12338
					// Dialog isn't getting focus when dragging (#8063)
12339
					this.uiDialog.trigger( "focus" );
12340
				}
12341
			}
12342
		} );
12343
 
12344
		// Support: IE
12345
		// Use type="button" to prevent enter keypresses in textboxes from closing the
12346
		// dialog in IE (#9312)
12347
		this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
12348
			.button( {
12349
				label: $( "<a>" ).text( this.options.closeText ).html(),
12350
				icon: "ui-icon-closethick",
12351
				showLabel: false
12352
			} )
12353
			.appendTo( this.uiDialogTitlebar );
12354
 
12355
		this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" );
12356
		this._on( this.uiDialogTitlebarClose, {
12357
			click: function( event ) {
12358
				event.preventDefault();
12359
				this.close( event );
12360
			}
12361
		} );
12362
 
12363
		uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar );
12364
		this._addClass( uiDialogTitle, "ui-dialog-title" );
12365
		this._title( uiDialogTitle );
12366
 
12367
		this.uiDialogTitlebar.prependTo( this.uiDialog );
12368
 
12369
		this.uiDialog.attr( {
12370
			"aria-labelledby": uiDialogTitle.attr( "id" )
12371
		} );
12372
	},
12373
 
12374
	_title: function( title ) {
12375
		if ( this.options.title ) {
12376
			title.text( this.options.title );
12377
		} else {
12378
			title.html( "&#160;" );
12379
		}
12380
	},
12381
 
12382
	_createButtonPane: function() {
12383
		this.uiDialogButtonPane = $( "<div>" );
12384
		this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane",
12385
			"ui-widget-content ui-helper-clearfix" );
12386
 
12387
		this.uiButtonSet = $( "<div>" )
12388
			.appendTo( this.uiDialogButtonPane );
12389
		this._addClass( this.uiButtonSet, "ui-dialog-buttonset" );
12390
 
12391
		this._createButtons();
12392
	},
12393
 
12394
	_createButtons: function() {
12395
		var that = this,
12396
			buttons = this.options.buttons;
12397
 
12398
		// If we already have a button pane, remove it
12399
		this.uiDialogButtonPane.remove();
12400
		this.uiButtonSet.empty();
12401
 
12402
		if ( $.isEmptyObject( buttons ) || ( $.isArray( buttons ) && !buttons.length ) ) {
12403
			this._removeClass( this.uiDialog, "ui-dialog-buttons" );
12404
			return;
12405
		}
12406
 
12407
		$.each( buttons, function( name, props ) {
12408
			var click, buttonOptions;
12409
			props = $.isFunction( props ) ?
12410
				{ click: props, text: name } :
12411
				props;
12412
 
12413
			// Default to a non-submitting button
12414
			props = $.extend( { type: "button" }, props );
12415
 
12416
			// Change the context for the click callback to be the main element
12417
			click = props.click;
12418
			buttonOptions = {
12419
				icon: props.icon,
12420
				iconPosition: props.iconPosition,
12421
				showLabel: props.showLabel,
12422
 
12423
				// Deprecated options
12424
				icons: props.icons,
12425
				text: props.text
12426
			};
12427
 
12428
			delete props.click;
12429
			delete props.icon;
12430
			delete props.iconPosition;
12431
			delete props.showLabel;
12432
 
12433
			// Deprecated options
12434
			delete props.icons;
12435
			if ( typeof props.text === "boolean" ) {
12436
				delete props.text;
12437
			}
12438
 
12439
			$( "<button></button>", props )
12440
				.button( buttonOptions )
12441
				.appendTo( that.uiButtonSet )
12442
				.on( "click", function() {
12443
					click.apply( that.element[ 0 ], arguments );
12444
				} );
12445
		} );
12446
		this._addClass( this.uiDialog, "ui-dialog-buttons" );
12447
		this.uiDialogButtonPane.appendTo( this.uiDialog );
12448
	},
12449
 
12450
	_makeDraggable: function() {
12451
		var that = this,
12452
			options = this.options;
12453
 
12454
		function filteredUi( ui ) {
12455
			return {
12456
				position: ui.position,
12457
				offset: ui.offset
12458
			};
12459
		}
12460
 
12461
		this.uiDialog.draggable( {
12462
			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
12463
			handle: ".ui-dialog-titlebar",
12464
			containment: "document",
12465
			start: function( event, ui ) {
12466
				that._addClass( $( this ), "ui-dialog-dragging" );
12467
				that._blockFrames();
12468
				that._trigger( "dragStart", event, filteredUi( ui ) );
12469
			},
12470
			drag: function( event, ui ) {
12471
				that._trigger( "drag", event, filteredUi( ui ) );
12472
			},
12473
			stop: function( event, ui ) {
12474
				var left = ui.offset.left - that.document.scrollLeft(),
12475
					top = ui.offset.top - that.document.scrollTop();
12476
 
12477
				options.position = {
12478
					my: "left top",
12479
					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12480
						"top" + ( top >= 0 ? "+" : "" ) + top,
12481
					of: that.window
12482
				};
12483
				that._removeClass( $( this ), "ui-dialog-dragging" );
12484
				that._unblockFrames();
12485
				that._trigger( "dragStop", event, filteredUi( ui ) );
12486
			}
12487
		} );
12488
	},
12489
 
12490
	_makeResizable: function() {
12491
		var that = this,
12492
			options = this.options,
12493
			handles = options.resizable,
12494
 
12495
			// .ui-resizable has position: relative defined in the stylesheet
12496
			// but dialogs have to use absolute or fixed positioning
12497
			position = this.uiDialog.css( "position" ),
12498
			resizeHandles = typeof handles === "string" ?
12499
				handles :
12500
				"n,e,s,w,se,sw,ne,nw";
12501
 
12502
		function filteredUi( ui ) {
12503
			return {
12504
				originalPosition: ui.originalPosition,
12505
				originalSize: ui.originalSize,
12506
				position: ui.position,
12507
				size: ui.size
12508
			};
12509
		}
12510
 
12511
		this.uiDialog.resizable( {
12512
			cancel: ".ui-dialog-content",
12513
			containment: "document",
12514
			alsoResize: this.element,
12515
			maxWidth: options.maxWidth,
12516
			maxHeight: options.maxHeight,
12517
			minWidth: options.minWidth,
12518
			minHeight: this._minHeight(),
12519
			handles: resizeHandles,
12520
			start: function( event, ui ) {
12521
				that._addClass( $( this ), "ui-dialog-resizing" );
12522
				that._blockFrames();
12523
				that._trigger( "resizeStart", event, filteredUi( ui ) );
12524
			},
12525
			resize: function( event, ui ) {
12526
				that._trigger( "resize", event, filteredUi( ui ) );
12527
			},
12528
			stop: function( event, ui ) {
12529
				var offset = that.uiDialog.offset(),
12530
					left = offset.left - that.document.scrollLeft(),
12531
					top = offset.top - that.document.scrollTop();
12532
 
12533
				options.height = that.uiDialog.height();
12534
				options.width = that.uiDialog.width();
12535
				options.position = {
12536
					my: "left top",
12537
					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12538
						"top" + ( top >= 0 ? "+" : "" ) + top,
12539
					of: that.window
12540
				};
12541
				that._removeClass( $( this ), "ui-dialog-resizing" );
12542
				that._unblockFrames();
12543
				that._trigger( "resizeStop", event, filteredUi( ui ) );
12544
			}
12545
		} )
12546
			.css( "position", position );
12547
	},
12548
 
12549
	_trackFocus: function() {
12550
		this._on( this.widget(), {
12551
			focusin: function( event ) {
12552
				this._makeFocusTarget();
12553
				this._focusedElement = $( event.target );
12554
			}
12555
		} );
12556
	},
12557
 
12558
	_makeFocusTarget: function() {
12559
		this._untrackInstance();
12560
		this._trackingInstances().unshift( this );
12561
	},
12562
 
12563
	_untrackInstance: function() {
12564
		var instances = this._trackingInstances(),
12565
			exists = $.inArray( this, instances );
12566
		if ( exists !== -1 ) {
12567
			instances.splice( exists, 1 );
12568
		}
12569
	},
12570
 
12571
	_trackingInstances: function() {
12572
		var instances = this.document.data( "ui-dialog-instances" );
12573
		if ( !instances ) {
12574
			instances = [];
12575
			this.document.data( "ui-dialog-instances", instances );
12576
		}
12577
		return instances;
12578
	},
12579
 
12580
	_minHeight: function() {
12581
		var options = this.options;
12582
 
12583
		return options.height === "auto" ?
12584
			options.minHeight :
12585
			Math.min( options.minHeight, options.height );
12586
	},
12587
 
12588
	_position: function() {
12589
 
12590
		// Need to show the dialog to get the actual offset in the position plugin
12591
		var isVisible = this.uiDialog.is( ":visible" );
12592
		if ( !isVisible ) {
12593
			this.uiDialog.show();
12594
		}
12595
		this.uiDialog.position( this.options.position );
12596
		if ( !isVisible ) {
12597
			this.uiDialog.hide();
12598
		}
12599
	},
12600
 
12601
	_setOptions: function( options ) {
12602
		var that = this,
12603
			resize = false,
12604
			resizableOptions = {};
12605
 
12606
		$.each( options, function( key, value ) {
12607
			that._setOption( key, value );
12608
 
12609
			if ( key in that.sizeRelatedOptions ) {
12610
				resize = true;
12611
			}
12612
			if ( key in that.resizableRelatedOptions ) {
12613
				resizableOptions[ key ] = value;
12614
			}
12615
		} );
12616
 
12617
		if ( resize ) {
12618
			this._size();
12619
			this._position();
12620
		}
12621
		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12622
			this.uiDialog.resizable( "option", resizableOptions );
12623
		}
12624
	},
12625
 
12626
	_setOption: function( key, value ) {
12627
		var isDraggable, isResizable,
12628
			uiDialog = this.uiDialog;
12629
 
12630
		if ( key === "disabled" ) {
12631
			return;
12632
		}
12633
 
12634
		this._super( key, value );
12635
 
12636
		if ( key === "appendTo" ) {
12637
			this.uiDialog.appendTo( this._appendTo() );
12638
		}
12639
 
12640
		if ( key === "buttons" ) {
12641
			this._createButtons();
12642
		}
12643
 
12644
		if ( key === "closeText" ) {
12645
			this.uiDialogTitlebarClose.button( {
12646
 
12647
				// Ensure that we always pass a string
12648
				label: $( "<a>" ).text( "" + this.options.closeText ).html()
12649
			} );
12650
		}
12651
 
12652
		if ( key === "draggable" ) {
12653
			isDraggable = uiDialog.is( ":data(ui-draggable)" );
12654
			if ( isDraggable && !value ) {
12655
				uiDialog.draggable( "destroy" );
12656
			}
12657
 
12658
			if ( !isDraggable && value ) {
12659
				this._makeDraggable();
12660
			}
12661
		}
12662
 
12663
		if ( key === "position" ) {
12664
			this._position();
12665
		}
12666
 
12667
		if ( key === "resizable" ) {
12668
 
12669
			// currently resizable, becoming non-resizable
12670
			isResizable = uiDialog.is( ":data(ui-resizable)" );
12671
			if ( isResizable && !value ) {
12672
				uiDialog.resizable( "destroy" );
12673
			}
12674
 
12675
			// Currently resizable, changing handles
12676
			if ( isResizable && typeof value === "string" ) {
12677
				uiDialog.resizable( "option", "handles", value );
12678
			}
12679
 
12680
			// Currently non-resizable, becoming resizable
12681
			if ( !isResizable && value !== false ) {
12682
				this._makeResizable();
12683
			}
12684
		}
12685
 
12686
		if ( key === "title" ) {
12687
			this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
12688
		}
12689
	},
12690
 
12691
	_size: function() {
12692
 
12693
		// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
12694
		// divs will both have width and height set, so we need to reset them
12695
		var nonContentHeight, minContentHeight, maxContentHeight,
12696
			options = this.options;
12697
 
12698
		// Reset content sizing
12699
		this.element.show().css( {
12700
			width: "auto",
12701
			minHeight: 0,
12702
			maxHeight: "none",
12703
			height: 0
12704
		} );
12705
 
12706
		if ( options.minWidth > options.width ) {
12707
			options.width = options.minWidth;
12708
		}
12709
 
12710
		// Reset wrapper sizing
12711
		// determine the height of all the non-content elements
12712
		nonContentHeight = this.uiDialog.css( {
12713
			height: "auto",
12714
			width: options.width
12715
		} )
12716
			.outerHeight();
12717
		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
12718
		maxContentHeight = typeof options.maxHeight === "number" ?
12719
			Math.max( 0, options.maxHeight - nonContentHeight ) :
12720
			"none";
12721
 
12722
		if ( options.height === "auto" ) {
12723
			this.element.css( {
12724
				minHeight: minContentHeight,
12725
				maxHeight: maxContentHeight,
12726
				height: "auto"
12727
			} );
12728
		} else {
12729
			this.element.height( Math.max( 0, options.height - nonContentHeight ) );
12730
		}
12731
 
12732
		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12733
			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
12734
		}
12735
	},
12736
 
12737
	_blockFrames: function() {
12738
		this.iframeBlocks = this.document.find( "iframe" ).map( function() {
12739
			var iframe = $( this );
12740
 
12741
			return $( "<div>" )
12742
				.css( {
12743
					position: "absolute",
12744
					width: iframe.outerWidth(),
12745
					height: iframe.outerHeight()
12746
				} )
12747
				.appendTo( iframe.parent() )
12748
				.offset( iframe.offset() )[ 0 ];
12749
		} );
12750
	},
12751
 
12752
	_unblockFrames: function() {
12753
		if ( this.iframeBlocks ) {
12754
			this.iframeBlocks.remove();
12755
			delete this.iframeBlocks;
12756
		}
12757
	},
12758
 
12759
	_allowInteraction: function( event ) {
12760
		if ( $( event.target ).closest( ".ui-dialog" ).length ) {
12761
			return true;
12762
		}
12763
 
12764
		// TODO: Remove hack when datepicker implements
12765
		// the .ui-front logic (#8989)
12766
		return !!$( event.target ).closest( ".ui-datepicker" ).length;
12767
	},
12768
 
12769
	_createOverlay: function() {
12770
		if ( !this.options.modal ) {
12771
			return;
12772
		}
12773
 
12774
		// We use a delay in case the overlay is created from an
12775
		// event that we're going to be cancelling (#2804)
12776
		var isOpening = true;
12777
		this._delay( function() {
12778
			isOpening = false;
12779
		} );
12780
 
12781
		if ( !this.document.data( "ui-dialog-overlays" ) ) {
12782
 
12783
			// Prevent use of anchors and inputs
12784
			// Using _on() for an event handler shared across many instances is
12785
			// safe because the dialogs stack and must be closed in reverse order
12786
			this._on( this.document, {
12787
				focusin: function( event ) {
12788
					if ( isOpening ) {
12789
						return;
12790
					}
12791
 
12792
					if ( !this._allowInteraction( event ) ) {
12793
						event.preventDefault();
12794
						this._trackingInstances()[ 0 ]._focusTabbable();
12795
					}
12796
				}
12797
			} );
12798
		}
12799
 
12800
		this.overlay = $( "<div>" )
12801
			.appendTo( this._appendTo() );
12802
 
12803
		this._addClass( this.overlay, null, "ui-widget-overlay ui-front" );
12804
		this._on( this.overlay, {
12805
			mousedown: "_keepFocus"
12806
		} );
12807
		this.document.data( "ui-dialog-overlays",
12808
			( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 );
12809
	},
12810
 
12811
	_destroyOverlay: function() {
12812
		if ( !this.options.modal ) {
12813
			return;
12814
		}
12815
 
12816
		if ( this.overlay ) {
12817
			var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
12818
 
12819
			if ( !overlays ) {
12820
				this._off( this.document, "focusin" );
12821
				this.document.removeData( "ui-dialog-overlays" );
12822
			} else {
12823
				this.document.data( "ui-dialog-overlays", overlays );
12824
			}
12825
 
12826
			this.overlay.remove();
12827
			this.overlay = null;
12828
		}
12829
	}
12830
} );
12831
 
12832
// DEPRECATED
12833
// TODO: switch return back to widget declaration at top of file when this is removed
12834
if ( $.uiBackCompat !== false ) {
12835
 
12836
	// Backcompat for dialogClass option
12837
	$.widget( "ui.dialog", $.ui.dialog, {
12838
		options: {
12839
			dialogClass: ""
12840
		},
12841
		_createWrapper: function() {
12842
			this._super();
12843
			this.uiDialog.addClass( this.options.dialogClass );
12844
		},
12845
		_setOption: function( key, value ) {
12846
			if ( key === "dialogClass" ) {
12847
				this.uiDialog
12848
					.removeClass( this.options.dialogClass )
12849
					.addClass( value );
12850
			}
12851
			this._superApply( arguments );
12852
		}
12853
	} );
12854
}
12855
 
12856
var widgetsDialog = $.ui.dialog;
12857
 
12858
 
12859
/*!
12860
 * jQuery UI Droppable 1.12.1
12861
 * http://jqueryui.com
12862
 *
12863
 * Copyright jQuery Foundation and other contributors
12864
 * Released under the MIT license.
12865
 * http://jquery.org/license
12866
 */
12867
 
12868
//>>label: Droppable
12869
//>>group: Interactions
12870
//>>description: Enables drop targets for draggable elements.
12871
//>>docs: http://api.jqueryui.com/droppable/
12872
//>>demos: http://jqueryui.com/droppable/
12873
 
12874
 
12875
 
12876
$.widget( "ui.droppable", {
12877
	version: "1.12.1",
12878
	widgetEventPrefix: "drop",
12879
	options: {
12880
		accept: "*",
12881
		addClasses: true,
12882
		greedy: false,
12883
		scope: "default",
12884
		tolerance: "intersect",
12885
 
12886
		// Callbacks
12887
		activate: null,
12888
		deactivate: null,
12889
		drop: null,
12890
		out: null,
12891
		over: null
12892
	},
12893
	_create: function() {
12894
 
12895
		var proportions,
12896
			o = this.options,
12897
			accept = o.accept;
12898
 
12899
		this.isover = false;
12900
		this.isout = true;
12901
 
12902
		this.accept = $.isFunction( accept ) ? accept : function( d ) {
12903
			return d.is( accept );
12904
		};
12905
 
12906
		this.proportions = function( /* valueToWrite */ ) {
12907
			if ( arguments.length ) {
12908
 
12909
				// Store the droppable's proportions
12910
				proportions = arguments[ 0 ];
12911
			} else {
12912
 
12913
				// Retrieve or derive the droppable's proportions
12914
				return proportions ?
12915
					proportions :
12916
					proportions = {
12917
						width: this.element[ 0 ].offsetWidth,
12918
						height: this.element[ 0 ].offsetHeight
12919
					};
12920
			}
12921
		};
12922
 
12923
		this._addToManager( o.scope );
12924
 
12925
		o.addClasses && this._addClass( "ui-droppable" );
12926
 
12927
	},
12928
 
12929
	_addToManager: function( scope ) {
12930
 
12931
		// Add the reference and positions to the manager
12932
		$.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
12933
		$.ui.ddmanager.droppables[ scope ].push( this );
12934
	},
12935
 
12936
	_splice: function( drop ) {
12937
		var i = 0;
12938
		for ( ; i < drop.length; i++ ) {
12939
			if ( drop[ i ] === this ) {
12940
				drop.splice( i, 1 );
12941
			}
12942
		}
12943
	},
12944
 
12945
	_destroy: function() {
12946
		var drop = $.ui.ddmanager.droppables[ this.options.scope ];
12947
 
12948
		this._splice( drop );
12949
	},
12950
 
12951
	_setOption: function( key, value ) {
12952
 
12953
		if ( key === "accept" ) {
12954
			this.accept = $.isFunction( value ) ? value : function( d ) {
12955
				return d.is( value );
12956
			};
12957
		} else if ( key === "scope" ) {
12958
			var drop = $.ui.ddmanager.droppables[ this.options.scope ];
12959
 
12960
			this._splice( drop );
12961
			this._addToManager( value );
12962
		}
12963
 
12964
		this._super( key, value );
12965
	},
12966
 
12967
	_activate: function( event ) {
12968
		var draggable = $.ui.ddmanager.current;
12969
 
12970
		this._addActiveClass();
12971
		if ( draggable ) {
12972
			this._trigger( "activate", event, this.ui( draggable ) );
12973
		}
12974
	},
12975
 
12976
	_deactivate: function( event ) {
12977
		var draggable = $.ui.ddmanager.current;
12978
 
12979
		this._removeActiveClass();
12980
		if ( draggable ) {
12981
			this._trigger( "deactivate", event, this.ui( draggable ) );
12982
		}
12983
	},
12984
 
12985
	_over: function( event ) {
12986
 
12987
		var draggable = $.ui.ddmanager.current;
12988
 
12989
		// Bail if draggable and droppable are same element
12990
		if ( !draggable || ( draggable.currentItem ||
12991
				draggable.element )[ 0 ] === this.element[ 0 ] ) {
12992
			return;
12993
		}
12994
 
12995
		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
12996
				draggable.element ) ) ) {
12997
			this._addHoverClass();
12998
			this._trigger( "over", event, this.ui( draggable ) );
12999
		}
13000
 
13001
	},
13002
 
13003
	_out: function( event ) {
13004
 
13005
		var draggable = $.ui.ddmanager.current;
13006
 
13007
		// Bail if draggable and droppable are same element
13008
		if ( !draggable || ( draggable.currentItem ||
13009
				draggable.element )[ 0 ] === this.element[ 0 ] ) {
13010
			return;
13011
		}
13012
 
13013
		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
13014
				draggable.element ) ) ) {
13015
			this._removeHoverClass();
13016
			this._trigger( "out", event, this.ui( draggable ) );
13017
		}
13018
 
13019
	},
13020
 
13021
	_drop: function( event, custom ) {
13022
 
13023
		var draggable = custom || $.ui.ddmanager.current,
13024
			childrenIntersection = false;
13025
 
13026
		// Bail if draggable and droppable are same element
13027
		if ( !draggable || ( draggable.currentItem ||
13028
				draggable.element )[ 0 ] === this.element[ 0 ] ) {
13029
			return false;
13030
		}
13031
 
13032
		this.element
13033
			.find( ":data(ui-droppable)" )
13034
			.not( ".ui-draggable-dragging" )
13035
			.each( function() {
13036
				var inst = $( this ).droppable( "instance" );
13037
				if (
13038
					inst.options.greedy &&
13039
					!inst.options.disabled &&
13040
					inst.options.scope === draggable.options.scope &&
13041
					inst.accept.call(
13042
						inst.element[ 0 ], ( draggable.currentItem || draggable.element )
13043
					) &&
13044
					intersect(
13045
						draggable,
13046
						$.extend( inst, { offset: inst.element.offset() } ),
13047
						inst.options.tolerance, event
13048
					)
13049
				) {
13050
					childrenIntersection = true;
13051
					return false; }
13052
			} );
13053
		if ( childrenIntersection ) {
13054
			return false;
13055
		}
13056
 
13057
		if ( this.accept.call( this.element[ 0 ],
13058
				( draggable.currentItem || draggable.element ) ) ) {
13059
			this._removeActiveClass();
13060
			this._removeHoverClass();
13061
 
13062
			this._trigger( "drop", event, this.ui( draggable ) );
13063
			return this.element;
13064
		}
13065
 
13066
		return false;
13067
 
13068
	},
13069
 
13070
	ui: function( c ) {
13071
		return {
13072
			draggable: ( c.currentItem || c.element ),
13073
			helper: c.helper,
13074
			position: c.position,
13075
			offset: c.positionAbs
13076
		};
13077
	},
13078
 
13079
	// Extension points just to make backcompat sane and avoid duplicating logic
13080
	// TODO: Remove in 1.13 along with call to it below
13081
	_addHoverClass: function() {
13082
		this._addClass( "ui-droppable-hover" );
13083
	},
13084
 
13085
	_removeHoverClass: function() {
13086
		this._removeClass( "ui-droppable-hover" );
13087
	},
13088
 
13089
	_addActiveClass: function() {
13090
		this._addClass( "ui-droppable-active" );
13091
	},
13092
 
13093
	_removeActiveClass: function() {
13094
		this._removeClass( "ui-droppable-active" );
13095
	}
13096
} );
13097
 
13098
var intersect = $.ui.intersect = ( function() {
13099
	function isOverAxis( x, reference, size ) {
13100
		return ( x >= reference ) && ( x < ( reference + size ) );
13101
	}
13102
 
13103
	return function( draggable, droppable, toleranceMode, event ) {
13104
 
13105
		if ( !droppable.offset ) {
13106
			return false;
13107
		}
13108
 
13109
		var x1 = ( draggable.positionAbs ||
13110
				draggable.position.absolute ).left + draggable.margins.left,
13111
			y1 = ( draggable.positionAbs ||
13112
				draggable.position.absolute ).top + draggable.margins.top,
13113
			x2 = x1 + draggable.helperProportions.width,
13114
			y2 = y1 + draggable.helperProportions.height,
13115
			l = droppable.offset.left,
13116
			t = droppable.offset.top,
13117
			r = l + droppable.proportions().width,
13118
			b = t + droppable.proportions().height;
13119
 
13120
		switch ( toleranceMode ) {
13121
		case "fit":
13122
			return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
13123
		case "intersect":
13124
			return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
13125
				x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
13126
				t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
13127
				y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
13128
		case "pointer":
13129
			return isOverAxis( event.pageY, t, droppable.proportions().height ) &&
13130
				isOverAxis( event.pageX, l, droppable.proportions().width );
13131
		case "touch":
13132
			return (
13133
				( y1 >= t && y1 <= b ) || // Top edge touching
13134
				( y2 >= t && y2 <= b ) || // Bottom edge touching
13135
				( y1 < t && y2 > b ) // Surrounded vertically
13136
			) && (
13137
				( x1 >= l && x1 <= r ) || // Left edge touching
13138
				( x2 >= l && x2 <= r ) || // Right edge touching
13139
				( x1 < l && x2 > r ) // Surrounded horizontally
13140
			);
13141
		default:
13142
			return false;
13143
		}
13144
	};
13145
} )();
13146
 
13147
/*
13148
	This manager tracks offsets of draggables and droppables
13149
*/
13150
$.ui.ddmanager = {
13151
	current: null,
13152
	droppables: { "default": [] },
13153
	prepareOffsets: function( t, event ) {
13154
 
13155
		var i, j,
13156
			m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
13157
			type = event ? event.type : null, // workaround for #2317
13158
			list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
13159
 
13160
		droppablesLoop: for ( i = 0; i < m.length; i++ ) {
13161
 
13162
			// No disabled and non-accepted
13163
			if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ],
13164
					( t.currentItem || t.element ) ) ) ) {
13165
				continue;
13166
			}
13167
 
13168
			// Filter out elements in the current dragged item
13169
			for ( j = 0; j < list.length; j++ ) {
13170
				if ( list[ j ] === m[ i ].element[ 0 ] ) {
13171
					m[ i ].proportions().height = 0;
13172
					continue droppablesLoop;
13173
				}
13174
			}
13175
 
13176
			m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
13177
			if ( !m[ i ].visible ) {
13178
				continue;
13179
			}
13180
 
13181
			// Activate the droppable if used directly from draggables
13182
			if ( type === "mousedown" ) {
13183
				m[ i ]._activate.call( m[ i ], event );
13184
			}
13185
 
13186
			m[ i ].offset = m[ i ].element.offset();
13187
			m[ i ].proportions( {
13188
				width: m[ i ].element[ 0 ].offsetWidth,
13189
				height: m[ i ].element[ 0 ].offsetHeight
13190
			} );
13191
 
13192
		}
13193
 
13194
	},
13195
	drop: function( draggable, event ) {
13196
 
13197
		var dropped = false;
13198
 
13199
		// Create a copy of the droppables in case the list changes during the drop (#9116)
13200
		$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
13201
 
13202
			if ( !this.options ) {
13203
				return;
13204
			}
13205
			if ( !this.options.disabled && this.visible &&
13206
					intersect( draggable, this, this.options.tolerance, event ) ) {
13207
				dropped = this._drop.call( this, event ) || dropped;
13208
			}
13209
 
13210
			if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ],
13211
					( draggable.currentItem || draggable.element ) ) ) {
13212
				this.isout = true;
13213
				this.isover = false;
13214
				this._deactivate.call( this, event );
13215
			}
13216
 
13217
		} );
13218
		return dropped;
13219
 
13220
	},
13221
	dragStart: function( draggable, event ) {
13222
 
13223
		// Listen for scrolling so that if the dragging causes scrolling the position of the
13224
		// droppables can be recalculated (see #5003)
13225
		draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() {
13226
			if ( !draggable.options.refreshPositions ) {
13227
				$.ui.ddmanager.prepareOffsets( draggable, event );
13228
			}
13229
		} );
13230
	},
13231
	drag: function( draggable, event ) {
13232
 
13233
		// If you have a highly dynamic page, you might try this option. It renders positions
13234
		// every time you move the mouse.
13235
		if ( draggable.options.refreshPositions ) {
13236
			$.ui.ddmanager.prepareOffsets( draggable, event );
13237
		}
13238
 
13239
		// Run through all droppables and check their positions based on specific tolerance options
13240
		$.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
13241
 
13242
			if ( this.options.disabled || this.greedyChild || !this.visible ) {
13243
				return;
13244
			}
13245
 
13246
			var parentInstance, scope, parent,
13247
				intersects = intersect( draggable, this, this.options.tolerance, event ),
13248
				c = !intersects && this.isover ?
13249
					"isout" :
13250
					( intersects && !this.isover ? "isover" : null );
13251
			if ( !c ) {
13252
				return;
13253
			}
13254
 
13255
			if ( this.options.greedy ) {
13256
 
13257
				// find droppable parents with same scope
13258
				scope = this.options.scope;
13259
				parent = this.element.parents( ":data(ui-droppable)" ).filter( function() {
13260
					return $( this ).droppable( "instance" ).options.scope === scope;
13261
				} );
13262
 
13263
				if ( parent.length ) {
13264
					parentInstance = $( parent[ 0 ] ).droppable( "instance" );
13265
					parentInstance.greedyChild = ( c === "isover" );
13266
				}
13267
			}
13268
 
13269
			// We just moved into a greedy child
13270
			if ( parentInstance && c === "isover" ) {
13271
				parentInstance.isover = false;
13272
				parentInstance.isout = true;
13273
				parentInstance._out.call( parentInstance, event );
13274
			}
13275
 
13276
			this[ c ] = true;
13277
			this[ c === "isout" ? "isover" : "isout" ] = false;
13278
			this[ c === "isover" ? "_over" : "_out" ].call( this, event );
13279
 
13280
			// We just moved out of a greedy child
13281
			if ( parentInstance && c === "isout" ) {
13282
				parentInstance.isout = false;
13283
				parentInstance.isover = true;
13284
				parentInstance._over.call( parentInstance, event );
13285
			}
13286
		} );
13287
 
13288
	},
13289
	dragStop: function( draggable, event ) {
13290
		draggable.element.parentsUntil( "body" ).off( "scroll.droppable" );
13291
 
13292
		// Call prepareOffsets one final time since IE does not fire return scroll events when
13293
		// overflow was caused by drag (see #5003)
13294
		if ( !draggable.options.refreshPositions ) {
13295
			$.ui.ddmanager.prepareOffsets( draggable, event );
13296
		}
13297
	}
13298
};
13299
 
13300
// DEPRECATED
13301
// TODO: switch return back to widget declaration at top of file when this is removed
13302
if ( $.uiBackCompat !== false ) {
13303
 
13304
	// Backcompat for activeClass and hoverClass options
13305
	$.widget( "ui.droppable", $.ui.droppable, {
13306
		options: {
13307
			hoverClass: false,
13308
			activeClass: false
13309
		},
13310
		_addActiveClass: function() {
13311
			this._super();
13312
			if ( this.options.activeClass ) {
13313
				this.element.addClass( this.options.activeClass );
13314
			}
13315
		},
13316
		_removeActiveClass: function() {
13317
			this._super();
13318
			if ( this.options.activeClass ) {
13319
				this.element.removeClass( this.options.activeClass );
13320
			}
13321
		},
13322
		_addHoverClass: function() {
13323
			this._super();
13324
			if ( this.options.hoverClass ) {
13325
				this.element.addClass( this.options.hoverClass );
13326
			}
13327
		},
13328
		_removeHoverClass: function() {
13329
			this._super();
13330
			if ( this.options.hoverClass ) {
13331
				this.element.removeClass( this.options.hoverClass );
13332
			}
13333
		}
13334
	} );
13335
}
13336
 
13337
var widgetsDroppable = $.ui.droppable;
13338
 
13339
 
13340
/*!
13341
 * jQuery UI Progressbar 1.12.1
13342
 * http://jqueryui.com
13343
 *
13344
 * Copyright jQuery Foundation and other contributors
13345
 * Released under the MIT license.
13346
 * http://jquery.org/license
13347
 */
13348
 
13349
//>>label: Progressbar
13350
//>>group: Widgets
13351
// jscs:disable maximumLineLength
13352
//>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators.
13353
// jscs:enable maximumLineLength
13354
//>>docs: http://api.jqueryui.com/progressbar/
13355
//>>demos: http://jqueryui.com/progressbar/
13356
//>>css.structure: ../../themes/base/core.css
13357
//>>css.structure: ../../themes/base/progressbar.css
13358
//>>css.theme: ../../themes/base/theme.css
13359
 
13360
 
13361
 
13362
var widgetsProgressbar = $.widget( "ui.progressbar", {
13363
	version: "1.12.1",
13364
	options: {
13365
		classes: {
13366
			"ui-progressbar": "ui-corner-all",
13367
			"ui-progressbar-value": "ui-corner-left",
13368
			"ui-progressbar-complete": "ui-corner-right"
13369
		},
13370
		max: 100,
13371
		value: 0,
13372
 
13373
		change: null,
13374
		complete: null
13375
	},
13376
 
13377
	min: 0,
13378
 
13379
	_create: function() {
13380
 
13381
		// Constrain initial value
13382
		this.oldValue = this.options.value = this._constrainedValue();
13383
 
13384
		this.element.attr( {
13385
 
13386
			// Only set static values; aria-valuenow and aria-valuemax are
13387
			// set inside _refreshValue()
13388
			role: "progressbar",
13389
			"aria-valuemin": this.min
13390
		} );
13391
		this._addClass( "ui-progressbar", "ui-widget ui-widget-content" );
13392
 
13393
		this.valueDiv = $( "<div>" ).appendTo( this.element );
13394
		this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" );
13395
		this._refreshValue();
13396
	},
13397
 
13398
	_destroy: function() {
13399
		this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" );
13400
 
13401
		this.valueDiv.remove();
13402
	},
13403
 
13404
	value: function( newValue ) {
13405
		if ( newValue === undefined ) {
13406
			return this.options.value;
13407
		}
13408
 
13409
		this.options.value = this._constrainedValue( newValue );
13410
		this._refreshValue();
13411
	},
13412
 
13413
	_constrainedValue: function( newValue ) {
13414
		if ( newValue === undefined ) {
13415
			newValue = this.options.value;
13416
		}
13417
 
13418
		this.indeterminate = newValue === false;
13419
 
13420
		// Sanitize value
13421
		if ( typeof newValue !== "number" ) {
13422
			newValue = 0;
13423
		}
13424
 
13425
		return this.indeterminate ? false :
13426
			Math.min( this.options.max, Math.max( this.min, newValue ) );
13427
	},
13428
 
13429
	_setOptions: function( options ) {
13430
 
13431
		// Ensure "value" option is set after other values (like max)
13432
		var value = options.value;
13433
		delete options.value;
13434
 
13435
		this._super( options );
13436
 
13437
		this.options.value = this._constrainedValue( value );
13438
		this._refreshValue();
13439
	},
13440
 
13441
	_setOption: function( key, value ) {
13442
		if ( key === "max" ) {
13443
 
13444
			// Don't allow a max less than min
13445
			value = Math.max( this.min, value );
13446
		}
13447
		this._super( key, value );
13448
	},
13449
 
13450
	_setOptionDisabled: function( value ) {
13451
		this._super( value );
13452
 
13453
		this.element.attr( "aria-disabled", value );
13454
		this._toggleClass( null, "ui-state-disabled", !!value );
13455
	},
13456
 
13457
	_percentage: function() {
13458
		return this.indeterminate ?
13459
			100 :
13460
			100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
13461
	},
13462
 
13463
	_refreshValue: function() {
13464
		var value = this.options.value,
13465
			percentage = this._percentage();
13466
 
13467
		this.valueDiv
13468
			.toggle( this.indeterminate || value > this.min )
13469
			.width( percentage.toFixed( 0 ) + "%" );
13470
 
13471
		this
13472
			._toggleClass( this.valueDiv, "ui-progressbar-complete", null,
13473
				value === this.options.max )
13474
			._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate );
13475
 
13476
		if ( this.indeterminate ) {
13477
			this.element.removeAttr( "aria-valuenow" );
13478
			if ( !this.overlayDiv ) {
13479
				this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv );
13480
				this._addClass( this.overlayDiv, "ui-progressbar-overlay" );
13481
			}
13482
		} else {
13483
			this.element.attr( {
13484
				"aria-valuemax": this.options.max,
13485
				"aria-valuenow": value
13486
			} );
13487
			if ( this.overlayDiv ) {
13488
				this.overlayDiv.remove();
13489
				this.overlayDiv = null;
13490
			}
13491
		}
13492
 
13493
		if ( this.oldValue !== value ) {
13494
			this.oldValue = value;
13495
			this._trigger( "change" );
13496
		}
13497
		if ( value === this.options.max ) {
13498
			this._trigger( "complete" );
13499
		}
13500
	}
13501
} );
13502
 
13503
 
13504
/*!
13505
 * jQuery UI Selectable 1.12.1
13506
 * http://jqueryui.com
13507
 *
13508
 * Copyright jQuery Foundation and other contributors
13509
 * Released under the MIT license.
13510
 * http://jquery.org/license
13511
 */
13512
 
13513
//>>label: Selectable
13514
//>>group: Interactions
13515
//>>description: Allows groups of elements to be selected with the mouse.
13516
//>>docs: http://api.jqueryui.com/selectable/
13517
//>>demos: http://jqueryui.com/selectable/
13518
//>>css.structure: ../../themes/base/selectable.css
13519
 
13520
 
13521
 
13522
var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, {
13523
	version: "1.12.1",
13524
	options: {
13525
		appendTo: "body",
13526
		autoRefresh: true,
13527
		distance: 0,
13528
		filter: "*",
13529
		tolerance: "touch",
13530
 
13531
		// Callbacks
13532
		selected: null,
13533
		selecting: null,
13534
		start: null,
13535
		stop: null,
13536
		unselected: null,
13537
		unselecting: null
13538
	},
13539
	_create: function() {
13540
		var that = this;
13541
 
13542
		this._addClass( "ui-selectable" );
13543
 
13544
		this.dragged = false;
13545
 
13546
		// Cache selectee children based on filter
13547
		this.refresh = function() {
13548
			that.elementPos = $( that.element[ 0 ] ).offset();
13549
			that.selectees = $( that.options.filter, that.element[ 0 ] );
13550
			that._addClass( that.selectees, "ui-selectee" );
13551
			that.selectees.each( function() {
13552
				var $this = $( this ),
13553
					selecteeOffset = $this.offset(),
13554
					pos = {
13555
						left: selecteeOffset.left - that.elementPos.left,
13556
						top: selecteeOffset.top - that.elementPos.top
13557
					};
13558
				$.data( this, "selectable-item", {
13559
					element: this,
13560
					$element: $this,
13561
					left: pos.left,
13562
					top: pos.top,
13563
					right: pos.left + $this.outerWidth(),
13564
					bottom: pos.top + $this.outerHeight(),
13565
					startselected: false,
13566
					selected: $this.hasClass( "ui-selected" ),
13567
					selecting: $this.hasClass( "ui-selecting" ),
13568
					unselecting: $this.hasClass( "ui-unselecting" )
13569
				} );
13570
			} );
13571
		};
13572
		this.refresh();
13573
 
13574
		this._mouseInit();
13575
 
13576
		this.helper = $( "<div>" );
13577
		this._addClass( this.helper, "ui-selectable-helper" );
13578
	},
13579
 
13580
	_destroy: function() {
13581
		this.selectees.removeData( "selectable-item" );
13582
		this._mouseDestroy();
13583
	},
13584
 
13585
	_mouseStart: function( event ) {
13586
		var that = this,
13587
			options = this.options;
13588
 
13589
		this.opos = [ event.pageX, event.pageY ];
13590
		this.elementPos = $( this.element[ 0 ] ).offset();
13591
 
13592
		if ( this.options.disabled ) {
13593
			return;
13594
		}
13595
 
13596
		this.selectees = $( options.filter, this.element[ 0 ] );
13597
 
13598
		this._trigger( "start", event );
13599
 
13600
		$( options.appendTo ).append( this.helper );
13601
 
13602
		// position helper (lasso)
13603
		this.helper.css( {
13604
			"left": event.pageX,
13605
			"top": event.pageY,
13606
			"width": 0,
13607
			"height": 0
13608
		} );
13609
 
13610
		if ( options.autoRefresh ) {
13611
			this.refresh();
13612
		}
13613
 
13614
		this.selectees.filter( ".ui-selected" ).each( function() {
13615
			var selectee = $.data( this, "selectable-item" );
13616
			selectee.startselected = true;
13617
			if ( !event.metaKey && !event.ctrlKey ) {
13618
				that._removeClass( selectee.$element, "ui-selected" );
13619
				selectee.selected = false;
13620
				that._addClass( selectee.$element, "ui-unselecting" );
13621
				selectee.unselecting = true;
13622
 
13623
				// selectable UNSELECTING callback
13624
				that._trigger( "unselecting", event, {
13625
					unselecting: selectee.element
13626
				} );
13627
			}
13628
		} );
13629
 
13630
		$( event.target ).parents().addBack().each( function() {
13631
			var doSelect,
13632
				selectee = $.data( this, "selectable-item" );
13633
			if ( selectee ) {
13634
				doSelect = ( !event.metaKey && !event.ctrlKey ) ||
13635
					!selectee.$element.hasClass( "ui-selected" );
13636
				that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
13637
					._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
13638
				selectee.unselecting = !doSelect;
13639
				selectee.selecting = doSelect;
13640
				selectee.selected = doSelect;
13641
 
13642
				// selectable (UN)SELECTING callback
13643
				if ( doSelect ) {
13644
					that._trigger( "selecting", event, {
13645
						selecting: selectee.element
13646
					} );
13647
				} else {
13648
					that._trigger( "unselecting", event, {
13649
						unselecting: selectee.element
13650
					} );
13651
				}
13652
				return false;
13653
			}
13654
		} );
13655
 
13656
	},
13657
 
13658
	_mouseDrag: function( event ) {
13659
 
13660
		this.dragged = true;
13661
 
13662
		if ( this.options.disabled ) {
13663
			return;
13664
		}
13665
 
13666
		var tmp,
13667
			that = this,
13668
			options = this.options,
13669
			x1 = this.opos[ 0 ],
13670
			y1 = this.opos[ 1 ],
13671
			x2 = event.pageX,
13672
			y2 = event.pageY;
13673
 
13674
		if ( x1 > x2 ) { tmp = x2; x2 = x1; x1 = tmp; }
13675
		if ( y1 > y2 ) { tmp = y2; y2 = y1; y1 = tmp; }
13676
		this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
13677
 
13678
		this.selectees.each( function() {
13679
			var selectee = $.data( this, "selectable-item" ),
13680
				hit = false,
13681
				offset = {};
13682
 
13683
			//prevent helper from being selected if appendTo: selectable
13684
			if ( !selectee || selectee.element === that.element[ 0 ] ) {
13685
				return;
13686
			}
13687
 
13688
			offset.left   = selectee.left   + that.elementPos.left;
13689
			offset.right  = selectee.right  + that.elementPos.left;
13690
			offset.top    = selectee.top    + that.elementPos.top;
13691
			offset.bottom = selectee.bottom + that.elementPos.top;
13692
 
13693
			if ( options.tolerance === "touch" ) {
13694
				hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
13695
                    offset.bottom < y1 ) );
13696
			} else if ( options.tolerance === "fit" ) {
13697
				hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
13698
                    offset.bottom < y2 );
13699
			}
13700
 
13701
			if ( hit ) {
13702
 
13703
				// SELECT
13704
				if ( selectee.selected ) {
13705
					that._removeClass( selectee.$element, "ui-selected" );
13706
					selectee.selected = false;
13707
				}
13708
				if ( selectee.unselecting ) {
13709
					that._removeClass( selectee.$element, "ui-unselecting" );
13710
					selectee.unselecting = false;
13711
				}
13712
				if ( !selectee.selecting ) {
13713
					that._addClass( selectee.$element, "ui-selecting" );
13714
					selectee.selecting = true;
13715
 
13716
					// selectable SELECTING callback
13717
					that._trigger( "selecting", event, {
13718
						selecting: selectee.element
13719
					} );
13720
				}
13721
			} else {
13722
 
13723
				// UNSELECT
13724
				if ( selectee.selecting ) {
13725
					if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
13726
						that._removeClass( selectee.$element, "ui-selecting" );
13727
						selectee.selecting = false;
13728
						that._addClass( selectee.$element, "ui-selected" );
13729
						selectee.selected = true;
13730
					} else {
13731
						that._removeClass( selectee.$element, "ui-selecting" );
13732
						selectee.selecting = false;
13733
						if ( selectee.startselected ) {
13734
							that._addClass( selectee.$element, "ui-unselecting" );
13735
							selectee.unselecting = true;
13736
						}
13737
 
13738
						// selectable UNSELECTING callback
13739
						that._trigger( "unselecting", event, {
13740
							unselecting: selectee.element
13741
						} );
13742
					}
13743
				}
13744
				if ( selectee.selected ) {
13745
					if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
13746
						that._removeClass( selectee.$element, "ui-selected" );
13747
						selectee.selected = false;
13748
 
13749
						that._addClass( selectee.$element, "ui-unselecting" );
13750
						selectee.unselecting = true;
13751
 
13752
						// selectable UNSELECTING callback
13753
						that._trigger( "unselecting", event, {
13754
							unselecting: selectee.element
13755
						} );
13756
					}
13757
				}
13758
			}
13759
		} );
13760
 
13761
		return false;
13762
	},
13763
 
13764
	_mouseStop: function( event ) {
13765
		var that = this;
13766
 
13767
		this.dragged = false;
13768
 
13769
		$( ".ui-unselecting", this.element[ 0 ] ).each( function() {
13770
			var selectee = $.data( this, "selectable-item" );
13771
			that._removeClass( selectee.$element, "ui-unselecting" );
13772
			selectee.unselecting = false;
13773
			selectee.startselected = false;
13774
			that._trigger( "unselected", event, {
13775
				unselected: selectee.element
13776
			} );
13777
		} );
13778
		$( ".ui-selecting", this.element[ 0 ] ).each( function() {
13779
			var selectee = $.data( this, "selectable-item" );
13780
			that._removeClass( selectee.$element, "ui-selecting" )
13781
				._addClass( selectee.$element, "ui-selected" );
13782
			selectee.selecting = false;
13783
			selectee.selected = true;
13784
			selectee.startselected = true;
13785
			that._trigger( "selected", event, {
13786
				selected: selectee.element
13787
			} );
13788
		} );
13789
		this._trigger( "stop", event );
13790
 
13791
		this.helper.remove();
13792
 
13793
		return false;
13794
	}
13795
 
13796
} );
13797
 
13798
 
13799
/*!
13800
 * jQuery UI Selectmenu 1.12.1
13801
 * http://jqueryui.com
13802
 *
13803
 * Copyright jQuery Foundation and other contributors
13804
 * Released under the MIT license.
13805
 * http://jquery.org/license
13806
 */
13807
 
13808
//>>label: Selectmenu
13809
//>>group: Widgets
13810
// jscs:disable maximumLineLength
13811
//>>description: Duplicates and extends the functionality of a native HTML select element, allowing it to be customizable in behavior and appearance far beyond the limitations of a native select.
13812
// jscs:enable maximumLineLength
13813
//>>docs: http://api.jqueryui.com/selectmenu/
13814
//>>demos: http://jqueryui.com/selectmenu/
13815
//>>css.structure: ../../themes/base/core.css
13816
//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css
13817
//>>css.theme: ../../themes/base/theme.css
13818
 
13819
 
13820
 
13821
var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
13822
	version: "1.12.1",
13823
	defaultElement: "<select>",
13824
	options: {
13825
		appendTo: null,
13826
		classes: {
13827
			"ui-selectmenu-button-open": "ui-corner-top",
13828
			"ui-selectmenu-button-closed": "ui-corner-all"
13829
		},
13830
		disabled: null,
13831
		icons: {
13832
			button: "ui-icon-triangle-1-s"
13833
		},
13834
		position: {
13835
			my: "left top",
13836
			at: "left bottom",
13837
			collision: "none"
13838
		},
13839
		width: false,
13840
 
13841
		// Callbacks
13842
		change: null,
13843
		close: null,
13844
		focus: null,
13845
		open: null,
13846
		select: null
13847
	},
13848
 
13849
	_create: function() {
13850
		var selectmenuId = this.element.uniqueId().attr( "id" );
13851
		this.ids = {
13852
			element: selectmenuId,
13853
			button: selectmenuId + "-button",
13854
			menu: selectmenuId + "-menu"
13855
		};
13856
 
13857
		this._drawButton();
13858
		this._drawMenu();
13859
		this._bindFormResetHandler();
13860
 
13861
		this._rendered = false;
13862
		this.menuItems = $();
13863
	},
13864
 
13865
	_drawButton: function() {
13866
		var icon,
13867
			that = this,
13868
			item = this._parseOption(
13869
				this.element.find( "option:selected" ),
13870
				this.element[ 0 ].selectedIndex
13871
			);
13872
 
13873
		// Associate existing label with the new button
13874
		this.labels = this.element.labels().attr( "for", this.ids.button );
13875
		this._on( this.labels, {
13876
			click: function( event ) {
13877
				this.button.focus();
13878
				event.preventDefault();
13879
			}
13880
		} );
13881
 
13882
		// Hide original select element
13883
		this.element.hide();
13884
 
13885
		// Create button
13886
		this.button = $( "<span>", {
13887
			tabindex: this.options.disabled ? -1 : 0,
13888
			id: this.ids.button,
13889
			role: "combobox",
13890
			"aria-expanded": "false",
13891
			"aria-autocomplete": "list",
13892
			"aria-owns": this.ids.menu,
13893
			"aria-haspopup": "true",
13894
			title: this.element.attr( "title" )
13895
		} )
13896
			.insertAfter( this.element );
13897
 
13898
		this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed",
13899
			"ui-button ui-widget" );
13900
 
13901
		icon = $( "<span>" ).appendTo( this.button );
13902
		this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button );
13903
		this.buttonItem = this._renderButtonItem( item )
13904
			.appendTo( this.button );
13905
 
13906
		if ( this.options.width !== false ) {
13907
			this._resizeButton();
13908
		}
13909
 
13910
		this._on( this.button, this._buttonEvents );
13911
		this.button.one( "focusin", function() {
13912
 
13913
			// Delay rendering the menu items until the button receives focus.
13914
			// The menu may have already been rendered via a programmatic open.
13915
			if ( !that._rendered ) {
13916
				that._refreshMenu();
13917
			}
13918
		} );
13919
	},
13920
 
13921
	_drawMenu: function() {
13922
		var that = this;
13923
 
13924
		// Create menu
13925
		this.menu = $( "<ul>", {
13926
			"aria-hidden": "true",
13927
			"aria-labelledby": this.ids.button,
13928
			id: this.ids.menu
13929
		} );
13930
 
13931
		// Wrap menu
13932
		this.menuWrap = $( "<div>" ).append( this.menu );
13933
		this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" );
13934
		this.menuWrap.appendTo( this._appendTo() );
13935
 
13936
		// Initialize menu widget
13937
		this.menuInstance = this.menu
13938
			.menu( {
13939
				classes: {
13940
					"ui-menu": "ui-corner-bottom"
13941
				},
13942
				role: "listbox",
13943
				select: function( event, ui ) {
13944
					event.preventDefault();
13945
 
13946
					// Support: IE8
13947
					// If the item was selected via a click, the text selection
13948
					// will be destroyed in IE
13949
					that._setSelection();
13950
 
13951
					that._select( ui.item.data( "ui-selectmenu-item" ), event );
13952
				},
13953
				focus: function( event, ui ) {
13954
					var item = ui.item.data( "ui-selectmenu-item" );
13955
 
13956
					// Prevent inital focus from firing and check if its a newly focused item
13957
					if ( that.focusIndex != null && item.index !== that.focusIndex ) {
13958
						that._trigger( "focus", event, { item: item } );
13959
						if ( !that.isOpen ) {
13960
							that._select( item, event );
13961
						}
13962
					}
13963
					that.focusIndex = item.index;
13964
 
13965
					that.button.attr( "aria-activedescendant",
13966
						that.menuItems.eq( item.index ).attr( "id" ) );
13967
				}
13968
			} )
13969
			.menu( "instance" );
13970
 
13971
		// Don't close the menu on mouseleave
13972
		this.menuInstance._off( this.menu, "mouseleave" );
13973
 
13974
		// Cancel the menu's collapseAll on document click
13975
		this.menuInstance._closeOnDocumentClick = function() {
13976
			return false;
13977
		};
13978
 
13979
		// Selects often contain empty items, but never contain dividers
13980
		this.menuInstance._isDivider = function() {
13981
			return false;
13982
		};
13983
	},
13984
 
13985
	refresh: function() {
13986
		this._refreshMenu();
13987
		this.buttonItem.replaceWith(
13988
			this.buttonItem = this._renderButtonItem(
13989
 
13990
				// Fall back to an empty object in case there are no options
13991
				this._getSelectedItem().data( "ui-selectmenu-item" ) || {}
13992
			)
13993
		);
13994
		if ( this.options.width === null ) {
13995
			this._resizeButton();
13996
		}
13997
	},
13998
 
13999
	_refreshMenu: function() {
14000
		var item,
14001
			options = this.element.find( "option" );
14002
 
14003
		this.menu.empty();
14004
 
14005
		this._parseOptions( options );
14006
		this._renderMenu( this.menu, this.items );
14007
 
14008
		this.menuInstance.refresh();
14009
		this.menuItems = this.menu.find( "li" )
14010
			.not( ".ui-selectmenu-optgroup" )
14011
				.find( ".ui-menu-item-wrapper" );
14012
 
14013
		this._rendered = true;
14014
 
14015
		if ( !options.length ) {
14016
			return;
14017
		}
14018
 
14019
		item = this._getSelectedItem();
14020
 
14021
		// Update the menu to have the correct item focused
14022
		this.menuInstance.focus( null, item );
14023
		this._setAria( item.data( "ui-selectmenu-item" ) );
14024
 
14025
		// Set disabled state
14026
		this._setOption( "disabled", this.element.prop( "disabled" ) );
14027
	},
14028
 
14029
	open: function( event ) {
14030
		if ( this.options.disabled ) {
14031
			return;
14032
		}
14033
 
14034
		// If this is the first time the menu is being opened, render the items
14035
		if ( !this._rendered ) {
14036
			this._refreshMenu();
14037
		} else {
14038
 
14039
			// Menu clears focus on close, reset focus to selected item
14040
			this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" );
14041
			this.menuInstance.focus( null, this._getSelectedItem() );
14042
		}
14043
 
14044
		// If there are no options, don't open the menu
14045
		if ( !this.menuItems.length ) {
14046
			return;
14047
		}
14048
 
14049
		this.isOpen = true;
14050
		this._toggleAttr();
14051
		this._resizeMenu();
14052
		this._position();
14053
 
14054
		this._on( this.document, this._documentClick );
14055
 
14056
		this._trigger( "open", event );
14057
	},
14058
 
14059
	_position: function() {
14060
		this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
14061
	},
14062
 
14063
	close: function( event ) {
14064
		if ( !this.isOpen ) {
14065
			return;
14066
		}
14067
 
14068
		this.isOpen = false;
14069
		this._toggleAttr();
14070
 
14071
		this.range = null;
14072
		this._off( this.document );
14073
 
14074
		this._trigger( "close", event );
14075
	},
14076
 
14077
	widget: function() {
14078
		return this.button;
14079
	},
14080
 
14081
	menuWidget: function() {
14082
		return this.menu;
14083
	},
14084
 
14085
	_renderButtonItem: function( item ) {
14086
		var buttonItem = $( "<span>" );
14087
 
14088
		this._setText( buttonItem, item.label );
14089
		this._addClass( buttonItem, "ui-selectmenu-text" );
14090
 
14091
		return buttonItem;
14092
	},
14093
 
14094
	_renderMenu: function( ul, items ) {
14095
		var that = this,
14096
			currentOptgroup = "";
14097
 
14098
		$.each( items, function( index, item ) {
14099
			var li;
14100
 
14101
			if ( item.optgroup !== currentOptgroup ) {
14102
				li = $( "<li>", {
14103
					text: item.optgroup
14104
				} );
14105
				that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" +
14106
					( item.element.parent( "optgroup" ).prop( "disabled" ) ?
14107
						" ui-state-disabled" :
14108
						"" ) );
14109
 
14110
				li.appendTo( ul );
14111
 
14112
				currentOptgroup = item.optgroup;
14113
			}
14114
 
14115
			that._renderItemData( ul, item );
14116
		} );
14117
	},
14118
 
14119
	_renderItemData: function( ul, item ) {
14120
		return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
14121
	},
14122
 
14123
	_renderItem: function( ul, item ) {
14124
		var li = $( "<li>" ),
14125
			wrapper = $( "<div>", {
14126
				title: item.element.attr( "title" )
14127
			} );
14128
 
14129
		if ( item.disabled ) {
14130
			this._addClass( li, null, "ui-state-disabled" );
14131
		}
14132
		this._setText( wrapper, item.label );
14133
 
14134
		return li.append( wrapper ).appendTo( ul );
14135
	},
14136
 
14137
	_setText: function( element, value ) {
14138
		if ( value ) {
14139
			element.text( value );
14140
		} else {
14141
			element.html( "&#160;" );
14142
		}
14143
	},
14144
 
14145
	_move: function( direction, event ) {
14146
		var item, next,
14147
			filter = ".ui-menu-item";
14148
 
14149
		if ( this.isOpen ) {
14150
			item = this.menuItems.eq( this.focusIndex ).parent( "li" );
14151
		} else {
14152
			item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
14153
			filter += ":not(.ui-state-disabled)";
14154
		}
14155
 
14156
		if ( direction === "first" || direction === "last" ) {
14157
			next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
14158
		} else {
14159
			next = item[ direction + "All" ]( filter ).eq( 0 );
14160
		}
14161
 
14162
		if ( next.length ) {
14163
			this.menuInstance.focus( event, next );
14164
		}
14165
	},
14166
 
14167
	_getSelectedItem: function() {
14168
		return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
14169
	},
14170
 
14171
	_toggle: function( event ) {
14172
		this[ this.isOpen ? "close" : "open" ]( event );
14173
	},
14174
 
14175
	_setSelection: function() {
14176
		var selection;
14177
 
14178
		if ( !this.range ) {
14179
			return;
14180
		}
14181
 
14182
		if ( window.getSelection ) {
14183
			selection = window.getSelection();
14184
			selection.removeAllRanges();
14185
			selection.addRange( this.range );
14186
 
14187
		// Support: IE8
14188
		} else {
14189
			this.range.select();
14190
		}
14191
 
14192
		// Support: IE
14193
		// Setting the text selection kills the button focus in IE, but
14194
		// restoring the focus doesn't kill the selection.
14195
		this.button.focus();
14196
	},
14197
 
14198
	_documentClick: {
14199
		mousedown: function( event ) {
14200
			if ( !this.isOpen ) {
14201
				return;
14202
			}
14203
 
14204
			if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" +
14205
					$.ui.escapeSelector( this.ids.button ) ).length ) {
14206
				this.close( event );
14207
			}
14208
		}
14209
	},
14210
 
14211
	_buttonEvents: {
14212
 
14213
		// Prevent text selection from being reset when interacting with the selectmenu (#10144)
14214
		mousedown: function() {
14215
			var selection;
14216
 
14217
			if ( window.getSelection ) {
14218
				selection = window.getSelection();
14219
				if ( selection.rangeCount ) {
14220
					this.range = selection.getRangeAt( 0 );
14221
				}
14222
 
14223
			// Support: IE8
14224
			} else {
14225
				this.range = document.selection.createRange();
14226
			}
14227
		},
14228
 
14229
		click: function( event ) {
14230
			this._setSelection();
14231
			this._toggle( event );
14232
		},
14233
 
14234
		keydown: function( event ) {
14235
			var preventDefault = true;
14236
			switch ( event.keyCode ) {
14237
			case $.ui.keyCode.TAB:
14238
			case $.ui.keyCode.ESCAPE:
14239
				this.close( event );
14240
				preventDefault = false;
14241
				break;
14242
			case $.ui.keyCode.ENTER:
14243
				if ( this.isOpen ) {
14244
					this._selectFocusedItem( event );
14245
				}
14246
				break;
14247
			case $.ui.keyCode.UP:
14248
				if ( event.altKey ) {
14249
					this._toggle( event );
14250
				} else {
14251
					this._move( "prev", event );
14252
				}
14253
				break;
14254
			case $.ui.keyCode.DOWN:
14255
				if ( event.altKey ) {
14256
					this._toggle( event );
14257
				} else {
14258
					this._move( "next", event );
14259
				}
14260
				break;
14261
			case $.ui.keyCode.SPACE:
14262
				if ( this.isOpen ) {
14263
					this._selectFocusedItem( event );
14264
				} else {
14265
					this._toggle( event );
14266
				}
14267
				break;
14268
			case $.ui.keyCode.LEFT:
14269
				this._move( "prev", event );
14270
				break;
14271
			case $.ui.keyCode.RIGHT:
14272
				this._move( "next", event );
14273
				break;
14274
			case $.ui.keyCode.HOME:
14275
			case $.ui.keyCode.PAGE_UP:
14276
				this._move( "first", event );
14277
				break;
14278
			case $.ui.keyCode.END:
14279
			case $.ui.keyCode.PAGE_DOWN:
14280
				this._move( "last", event );
14281
				break;
14282
			default:
14283
				this.menu.trigger( event );
14284
				preventDefault = false;
14285
			}
14286
 
14287
			if ( preventDefault ) {
14288
				event.preventDefault();
14289
			}
14290
		}
14291
	},
14292
 
14293
	_selectFocusedItem: function( event ) {
14294
		var item = this.menuItems.eq( this.focusIndex ).parent( "li" );
14295
		if ( !item.hasClass( "ui-state-disabled" ) ) {
14296
			this._select( item.data( "ui-selectmenu-item" ), event );
14297
		}
14298
	},
14299
 
14300
	_select: function( item, event ) {
14301
		var oldIndex = this.element[ 0 ].selectedIndex;
14302
 
14303
		// Change native select element
14304
		this.element[ 0 ].selectedIndex = item.index;
14305
		this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) );
14306
		this._setAria( item );
14307
		this._trigger( "select", event, { item: item } );
14308
 
14309
		if ( item.index !== oldIndex ) {
14310
			this._trigger( "change", event, { item: item } );
14311
		}
14312
 
14313
		this.close( event );
14314
	},
14315
 
14316
	_setAria: function( item ) {
14317
		var id = this.menuItems.eq( item.index ).attr( "id" );
14318
 
14319
		this.button.attr( {
14320
			"aria-labelledby": id,
14321
			"aria-activedescendant": id
14322
		} );
14323
		this.menu.attr( "aria-activedescendant", id );
14324
	},
14325
 
14326
	_setOption: function( key, value ) {
14327
		if ( key === "icons" ) {
14328
			var icon = this.button.find( "span.ui-icon" );
14329
			this._removeClass( icon, null, this.options.icons.button )
14330
				._addClass( icon, null, value.button );
14331
		}
14332
 
14333
		this._super( key, value );
14334
 
14335
		if ( key === "appendTo" ) {
14336
			this.menuWrap.appendTo( this._appendTo() );
14337
		}
14338
 
14339
		if ( key === "width" ) {
14340
			this._resizeButton();
14341
		}
14342
	},
14343
 
14344
	_setOptionDisabled: function( value ) {
14345
		this._super( value );
14346
 
14347
		this.menuInstance.option( "disabled", value );
14348
		this.button.attr( "aria-disabled", value );
14349
		this._toggleClass( this.button, null, "ui-state-disabled", value );
14350
 
14351
		this.element.prop( "disabled", value );
14352
		if ( value ) {
14353
			this.button.attr( "tabindex", -1 );
14354
			this.close();
14355
		} else {
14356
			this.button.attr( "tabindex", 0 );
14357
		}
14358
	},
14359
 
14360
	_appendTo: function() {
14361
		var element = this.options.appendTo;
14362
 
14363
		if ( element ) {
14364
			element = element.jquery || element.nodeType ?
14365
				$( element ) :
14366
				this.document.find( element ).eq( 0 );
14367
		}
14368
 
14369
		if ( !element || !element[ 0 ] ) {
14370
			element = this.element.closest( ".ui-front, dialog" );
14371
		}
14372
 
14373
		if ( !element.length ) {
14374
			element = this.document[ 0 ].body;
14375
		}
14376
 
14377
		return element;
14378
	},
14379
 
14380
	_toggleAttr: function() {
14381
		this.button.attr( "aria-expanded", this.isOpen );
14382
 
14383
		// We can't use two _toggleClass() calls here, because we need to make sure
14384
		// we always remove classes first and add them second, otherwise if both classes have the
14385
		// same theme class, it will be removed after we add it.
14386
		this._removeClass( this.button, "ui-selectmenu-button-" +
14387
			( this.isOpen ? "closed" : "open" ) )
14388
			._addClass( this.button, "ui-selectmenu-button-" +
14389
				( this.isOpen ? "open" : "closed" ) )
14390
			._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen );
14391
 
14392
		this.menu.attr( "aria-hidden", !this.isOpen );
14393
	},
14394
 
14395
	_resizeButton: function() {
14396
		var width = this.options.width;
14397
 
14398
		// For `width: false`, just remove inline style and stop
14399
		if ( width === false ) {
14400
			this.button.css( "width", "" );
14401
			return;
14402
		}
14403
 
14404
		// For `width: null`, match the width of the original element
14405
		if ( width === null ) {
14406
			width = this.element.show().outerWidth();
14407
			this.element.hide();
14408
		}
14409
 
14410
		this.button.outerWidth( width );
14411
	},
14412
 
14413
	_resizeMenu: function() {
14414
		this.menu.outerWidth( Math.max(
14415
			this.button.outerWidth(),
14416
 
14417
			// Support: IE10
14418
			// IE10 wraps long text (possibly a rounding bug)
14419
			// so we add 1px to avoid the wrapping
14420
			this.menu.width( "" ).outerWidth() + 1
14421
		) );
14422
	},
14423
 
14424
	_getCreateOptions: function() {
14425
		var options = this._super();
14426
 
14427
		options.disabled = this.element.prop( "disabled" );
14428
 
14429
		return options;
14430
	},
14431
 
14432
	_parseOptions: function( options ) {
14433
		var that = this,
14434
			data = [];
14435
		options.each( function( index, item ) {
14436
			data.push( that._parseOption( $( item ), index ) );
14437
		} );
14438
		this.items = data;
14439
	},
14440
 
14441
	_parseOption: function( option, index ) {
14442
		var optgroup = option.parent( "optgroup" );
14443
 
14444
		return {
14445
			element: option,
14446
			index: index,
14447
			value: option.val(),
14448
			label: option.text(),
14449
			optgroup: optgroup.attr( "label" ) || "",
14450
			disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
14451
		};
14452
	},
14453
 
14454
	_destroy: function() {
14455
		this._unbindFormResetHandler();
14456
		this.menuWrap.remove();
14457
		this.button.remove();
14458
		this.element.show();
14459
		this.element.removeUniqueId();
14460
		this.labels.attr( "for", this.ids.element );
14461
	}
14462
} ] );
14463
 
14464
 
14465
/*!
14466
 * jQuery UI Slider 1.12.1
14467
 * http://jqueryui.com
14468
 *
14469
 * Copyright jQuery Foundation and other contributors
14470
 * Released under the MIT license.
14471
 * http://jquery.org/license
14472
 */
14473
 
14474
//>>label: Slider
14475
//>>group: Widgets
14476
//>>description: Displays a flexible slider with ranges and accessibility via keyboard.
14477
//>>docs: http://api.jqueryui.com/slider/
14478
//>>demos: http://jqueryui.com/slider/
14479
//>>css.structure: ../../themes/base/core.css
14480
//>>css.structure: ../../themes/base/slider.css
14481
//>>css.theme: ../../themes/base/theme.css
14482
 
14483
 
14484
 
14485
var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, {
14486
	version: "1.12.1",
14487
	widgetEventPrefix: "slide",
14488
 
14489
	options: {
14490
		animate: false,
14491
		classes: {
14492
			"ui-slider": "ui-corner-all",
14493
			"ui-slider-handle": "ui-corner-all",
14494
 
14495
			// Note: ui-widget-header isn't the most fittingly semantic framework class for this
14496
			// element, but worked best visually with a variety of themes
14497
			"ui-slider-range": "ui-corner-all ui-widget-header"
14498
		},
14499
		distance: 0,
14500
		max: 100,
14501
		min: 0,
14502
		orientation: "horizontal",
14503
		range: false,
14504
		step: 1,
14505
		value: 0,
14506
		values: null,
14507
 
14508
		// Callbacks
14509
		change: null,
14510
		slide: null,
14511
		start: null,
14512
		stop: null
14513
	},
14514
 
14515
	// Number of pages in a slider
14516
	// (how many times can you page up/down to go through the whole range)
14517
	numPages: 5,
14518
 
14519
	_create: function() {
14520
		this._keySliding = false;
14521
		this._mouseSliding = false;
14522
		this._animateOff = true;
14523
		this._handleIndex = null;
14524
		this._detectOrientation();
14525
		this._mouseInit();
14526
		this._calculateNewMax();
14527
 
14528
		this._addClass( "ui-slider ui-slider-" + this.orientation,
14529
			"ui-widget ui-widget-content" );
14530
 
14531
		this._refresh();
14532
 
14533
		this._animateOff = false;
14534
	},
14535
 
14536
	_refresh: function() {
14537
		this._createRange();
14538
		this._createHandles();
14539
		this._setupEvents();
14540
		this._refreshValue();
14541
	},
14542
 
14543
	_createHandles: function() {
14544
		var i, handleCount,
14545
			options = this.options,
14546
			existingHandles = this.element.find( ".ui-slider-handle" ),
14547
			handle = "<span tabindex='0'></span>",
14548
			handles = [];
14549
 
14550
		handleCount = ( options.values && options.values.length ) || 1;
14551
 
14552
		if ( existingHandles.length > handleCount ) {
14553
			existingHandles.slice( handleCount ).remove();
14554
			existingHandles = existingHandles.slice( 0, handleCount );
14555
		}
14556
 
14557
		for ( i = existingHandles.length; i < handleCount; i++ ) {
14558
			handles.push( handle );
14559
		}
14560
 
14561
		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
14562
 
14563
		this._addClass( this.handles, "ui-slider-handle", "ui-state-default" );
14564
 
14565
		this.handle = this.handles.eq( 0 );
14566
 
14567
		this.handles.each( function( i ) {
14568
			$( this )
14569
				.data( "ui-slider-handle-index", i )
14570
				.attr( "tabIndex", 0 );
14571
		} );
14572
	},
14573
 
14574
	_createRange: function() {
14575
		var options = this.options;
14576
 
14577
		if ( options.range ) {
14578
			if ( options.range === true ) {
14579
				if ( !options.values ) {
14580
					options.values = [ this._valueMin(), this._valueMin() ];
14581
				} else if ( options.values.length && options.values.length !== 2 ) {
14582
					options.values = [ options.values[ 0 ], options.values[ 0 ] ];
14583
				} else if ( $.isArray( options.values ) ) {
14584
					options.values = options.values.slice( 0 );
14585
				}
14586
			}
14587
 
14588
			if ( !this.range || !this.range.length ) {
14589
				this.range = $( "<div>" )
14590
					.appendTo( this.element );
14591
 
14592
				this._addClass( this.range, "ui-slider-range" );
14593
			} else {
14594
				this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" );
14595
 
14596
				// Handle range switching from true to min/max
14597
				this.range.css( {
14598
					"left": "",
14599
					"bottom": ""
14600
				} );
14601
			}
14602
			if ( options.range === "min" || options.range === "max" ) {
14603
				this._addClass( this.range, "ui-slider-range-" + options.range );
14604
			}
14605
		} else {
14606
			if ( this.range ) {
14607
				this.range.remove();
14608
			}
14609
			this.range = null;
14610
		}
14611
	},
14612
 
14613
	_setupEvents: function() {
14614
		this._off( this.handles );
14615
		this._on( this.handles, this._handleEvents );
14616
		this._hoverable( this.handles );
14617
		this._focusable( this.handles );
14618
	},
14619
 
14620
	_destroy: function() {
14621
		this.handles.remove();
14622
		if ( this.range ) {
14623
			this.range.remove();
14624
		}
14625
 
14626
		this._mouseDestroy();
14627
	},
14628
 
14629
	_mouseCapture: function( event ) {
14630
		var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
14631
			that = this,
14632
			o = this.options;
14633
 
14634
		if ( o.disabled ) {
14635
			return false;
14636
		}
14637
 
14638
		this.elementSize = {
14639
			width: this.element.outerWidth(),
14640
			height: this.element.outerHeight()
14641
		};
14642
		this.elementOffset = this.element.offset();
14643
 
14644
		position = { x: event.pageX, y: event.pageY };
14645
		normValue = this._normValueFromMouse( position );
14646
		distance = this._valueMax() - this._valueMin() + 1;
14647
		this.handles.each( function( i ) {
14648
			var thisDistance = Math.abs( normValue - that.values( i ) );
14649
			if ( ( distance > thisDistance ) ||
14650
				( distance === thisDistance &&
14651
					( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) {
14652
				distance = thisDistance;
14653
				closestHandle = $( this );
14654
				index = i;
14655
			}
14656
		} );
14657
 
14658
		allowed = this._start( event, index );
14659
		if ( allowed === false ) {
14660
			return false;
14661
		}
14662
		this._mouseSliding = true;
14663
 
14664
		this._handleIndex = index;
14665
 
14666
		this._addClass( closestHandle, null, "ui-state-active" );
14667
		closestHandle.trigger( "focus" );
14668
 
14669
		offset = closestHandle.offset();
14670
		mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
14671
		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
14672
			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
14673
			top: event.pageY - offset.top -
14674
				( closestHandle.height() / 2 ) -
14675
				( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) -
14676
				( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) +
14677
				( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 )
14678
		};
14679
 
14680
		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
14681
			this._slide( event, index, normValue );
14682
		}
14683
		this._animateOff = true;
14684
		return true;
14685
	},
14686
 
14687
	_mouseStart: function() {
14688
		return true;
14689
	},
14690
 
14691
	_mouseDrag: function( event ) {
14692
		var position = { x: event.pageX, y: event.pageY },
14693
			normValue = this._normValueFromMouse( position );
14694
 
14695
		this._slide( event, this._handleIndex, normValue );
14696
 
14697
		return false;
14698
	},
14699
 
14700
	_mouseStop: function( event ) {
14701
		this._removeClass( this.handles, null, "ui-state-active" );
14702
		this._mouseSliding = false;
14703
 
14704
		this._stop( event, this._handleIndex );
14705
		this._change( event, this._handleIndex );
14706
 
14707
		this._handleIndex = null;
14708
		this._clickOffset = null;
14709
		this._animateOff = false;
14710
 
14711
		return false;
14712
	},
14713
 
14714
	_detectOrientation: function() {
14715
		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
14716
	},
14717
 
14718
	_normValueFromMouse: function( position ) {
14719
		var pixelTotal,
14720
			pixelMouse,
14721
			percentMouse,
14722
			valueTotal,
14723
			valueMouse;
14724
 
14725
		if ( this.orientation === "horizontal" ) {
14726
			pixelTotal = this.elementSize.width;
14727
			pixelMouse = position.x - this.elementOffset.left -
14728
				( this._clickOffset ? this._clickOffset.left : 0 );
14729
		} else {
14730
			pixelTotal = this.elementSize.height;
14731
			pixelMouse = position.y - this.elementOffset.top -
14732
				( this._clickOffset ? this._clickOffset.top : 0 );
14733
		}
14734
 
14735
		percentMouse = ( pixelMouse / pixelTotal );
14736
		if ( percentMouse > 1 ) {
14737
			percentMouse = 1;
14738
		}
14739
		if ( percentMouse < 0 ) {
14740
			percentMouse = 0;
14741
		}
14742
		if ( this.orientation === "vertical" ) {
14743
			percentMouse = 1 - percentMouse;
14744
		}
14745
 
14746
		valueTotal = this._valueMax() - this._valueMin();
14747
		valueMouse = this._valueMin() + percentMouse * valueTotal;
14748
 
14749
		return this._trimAlignValue( valueMouse );
14750
	},
14751
 
14752
	_uiHash: function( index, value, values ) {
14753
		var uiHash = {
14754
			handle: this.handles[ index ],
14755
			handleIndex: index,
14756
			value: value !== undefined ? value : this.value()
14757
		};
14758
 
14759
		if ( this._hasMultipleValues() ) {
14760
			uiHash.value = value !== undefined ? value : this.values( index );
14761
			uiHash.values = values || this.values();
14762
		}
14763
 
14764
		return uiHash;
14765
	},
14766
 
14767
	_hasMultipleValues: function() {
14768
		return this.options.values && this.options.values.length;
14769
	},
14770
 
14771
	_start: function( event, index ) {
14772
		return this._trigger( "start", event, this._uiHash( index ) );
14773
	},
14774
 
14775
	_slide: function( event, index, newVal ) {
14776
		var allowed, otherVal,
14777
			currentValue = this.value(),
14778
			newValues = this.values();
14779
 
14780
		if ( this._hasMultipleValues() ) {
14781
			otherVal = this.values( index ? 0 : 1 );
14782
			currentValue = this.values( index );
14783
 
14784
			if ( this.options.values.length === 2 && this.options.range === true ) {
14785
				newVal =  index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal );
14786
			}
14787
 
14788
			newValues[ index ] = newVal;
14789
		}
14790
 
14791
		if ( newVal === currentValue ) {
14792
			return;
14793
		}
14794
 
14795
		allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) );
14796
 
14797
		// A slide can be canceled by returning false from the slide callback
14798
		if ( allowed === false ) {
14799
			return;
14800
		}
14801
 
14802
		if ( this._hasMultipleValues() ) {
14803
			this.values( index, newVal );
14804
		} else {
14805
			this.value( newVal );
14806
		}
14807
	},
14808
 
14809
	_stop: function( event, index ) {
14810
		this._trigger( "stop", event, this._uiHash( index ) );
14811
	},
14812
 
14813
	_change: function( event, index ) {
14814
		if ( !this._keySliding && !this._mouseSliding ) {
14815
 
14816
			//store the last changed value index for reference when handles overlap
14817
			this._lastChangedValue = index;
14818
			this._trigger( "change", event, this._uiHash( index ) );
14819
		}
14820
	},
14821
 
14822
	value: function( newValue ) {
14823
		if ( arguments.length ) {
14824
			this.options.value = this._trimAlignValue( newValue );
14825
			this._refreshValue();
14826
			this._change( null, 0 );
14827
			return;
14828
		}
14829
 
14830
		return this._value();
14831
	},
14832
 
14833
	values: function( index, newValue ) {
14834
		var vals,
14835
			newValues,
14836
			i;
14837
 
14838
		if ( arguments.length > 1 ) {
14839
			this.options.values[ index ] = this._trimAlignValue( newValue );
14840
			this._refreshValue();
14841
			this._change( null, index );
14842
			return;
14843
		}
14844
 
14845
		if ( arguments.length ) {
14846
			if ( $.isArray( arguments[ 0 ] ) ) {
14847
				vals = this.options.values;
14848
				newValues = arguments[ 0 ];
14849
				for ( i = 0; i < vals.length; i += 1 ) {
14850
					vals[ i ] = this._trimAlignValue( newValues[ i ] );
14851
					this._change( null, i );
14852
				}
14853
				this._refreshValue();
14854
			} else {
14855
				if ( this._hasMultipleValues() ) {
14856
					return this._values( index );
14857
				} else {
14858
					return this.value();
14859
				}
14860
			}
14861
		} else {
14862
			return this._values();
14863
		}
14864
	},
14865
 
14866
	_setOption: function( key, value ) {
14867
		var i,
14868
			valsLength = 0;
14869
 
14870
		if ( key === "range" && this.options.range === true ) {
14871
			if ( value === "min" ) {
14872
				this.options.value = this._values( 0 );
14873
				this.options.values = null;
14874
			} else if ( value === "max" ) {
14875
				this.options.value = this._values( this.options.values.length - 1 );
14876
				this.options.values = null;
14877
			}
14878
		}
14879
 
14880
		if ( $.isArray( this.options.values ) ) {
14881
			valsLength = this.options.values.length;
14882
		}
14883
 
14884
		this._super( key, value );
14885
 
14886
		switch ( key ) {
14887
			case "orientation":
14888
				this._detectOrientation();
14889
				this._removeClass( "ui-slider-horizontal ui-slider-vertical" )
14890
					._addClass( "ui-slider-" + this.orientation );
14891
				this._refreshValue();
14892
				if ( this.options.range ) {
14893
					this._refreshRange( value );
14894
				}
14895
 
14896
				// Reset positioning from previous orientation
14897
				this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
14898
				break;
14899
			case "value":
14900
				this._animateOff = true;
14901
				this._refreshValue();
14902
				this._change( null, 0 );
14903
				this._animateOff = false;
14904
				break;
14905
			case "values":
14906
				this._animateOff = true;
14907
				this._refreshValue();
14908
 
14909
				// Start from the last handle to prevent unreachable handles (#9046)
14910
				for ( i = valsLength - 1; i >= 0; i-- ) {
14911
					this._change( null, i );
14912
				}
14913
				this._animateOff = false;
14914
				break;
14915
			case "step":
14916
			case "min":
14917
			case "max":
14918
				this._animateOff = true;
14919
				this._calculateNewMax();
14920
				this._refreshValue();
14921
				this._animateOff = false;
14922
				break;
14923
			case "range":
14924
				this._animateOff = true;
14925
				this._refresh();
14926
				this._animateOff = false;
14927
				break;
14928
		}
14929
	},
14930
 
14931
	_setOptionDisabled: function( value ) {
14932
		this._super( value );
14933
 
14934
		this._toggleClass( null, "ui-state-disabled", !!value );
14935
	},
14936
 
14937
	//internal value getter
14938
	// _value() returns value trimmed by min and max, aligned by step
14939
	_value: function() {
14940
		var val = this.options.value;
14941
		val = this._trimAlignValue( val );
14942
 
14943
		return val;
14944
	},
14945
 
14946
	//internal values getter
14947
	// _values() returns array of values trimmed by min and max, aligned by step
14948
	// _values( index ) returns single value trimmed by min and max, aligned by step
14949
	_values: function( index ) {
14950
		var val,
14951
			vals,
14952
			i;
14953
 
14954
		if ( arguments.length ) {
14955
			val = this.options.values[ index ];
14956
			val = this._trimAlignValue( val );
14957
 
14958
			return val;
14959
		} else if ( this._hasMultipleValues() ) {
14960
 
14961
			// .slice() creates a copy of the array
14962
			// this copy gets trimmed by min and max and then returned
14963
			vals = this.options.values.slice();
14964
			for ( i = 0; i < vals.length; i += 1 ) {
14965
				vals[ i ] = this._trimAlignValue( vals[ i ] );
14966
			}
14967
 
14968
			return vals;
14969
		} else {
14970
			return [];
14971
		}
14972
	},
14973
 
14974
	// Returns the step-aligned value that val is closest to, between (inclusive) min and max
14975
	_trimAlignValue: function( val ) {
14976
		if ( val <= this._valueMin() ) {
14977
			return this._valueMin();
14978
		}
14979
		if ( val >= this._valueMax() ) {
14980
			return this._valueMax();
14981
		}
14982
		var step = ( this.options.step > 0 ) ? this.options.step : 1,
14983
			valModStep = ( val - this._valueMin() ) % step,
14984
			alignValue = val - valModStep;
14985
 
14986
		if ( Math.abs( valModStep ) * 2 >= step ) {
14987
			alignValue += ( valModStep > 0 ) ? step : ( -step );
14988
		}
14989
 
14990
		// Since JavaScript has problems with large floats, round
14991
		// the final value to 5 digits after the decimal point (see #4124)
14992
		return parseFloat( alignValue.toFixed( 5 ) );
14993
	},
14994
 
14995
	_calculateNewMax: function() {
14996
		var max = this.options.max,
14997
			min = this._valueMin(),
14998
			step = this.options.step,
14999
			aboveMin = Math.round( ( max - min ) / step ) * step;
15000
		max = aboveMin + min;
15001
		if ( max > this.options.max ) {
15002
 
15003
			//If max is not divisible by step, rounding off may increase its value
15004
			max -= step;
15005
		}
15006
		this.max = parseFloat( max.toFixed( this._precision() ) );
15007
	},
15008
 
15009
	_precision: function() {
15010
		var precision = this._precisionOf( this.options.step );
15011
		if ( this.options.min !== null ) {
15012
			precision = Math.max( precision, this._precisionOf( this.options.min ) );
15013
		}
15014
		return precision;
15015
	},
15016
 
15017
	_precisionOf: function( num ) {
15018
		var str = num.toString(),
15019
			decimal = str.indexOf( "." );
15020
		return decimal === -1 ? 0 : str.length - decimal - 1;
15021
	},
15022
 
15023
	_valueMin: function() {
15024
		return this.options.min;
15025
	},
15026
 
15027
	_valueMax: function() {
15028
		return this.max;
15029
	},
15030
 
15031
	_refreshRange: function( orientation ) {
15032
		if ( orientation === "vertical" ) {
15033
			this.range.css( { "width": "", "left": "" } );
15034
		}
15035
		if ( orientation === "horizontal" ) {
15036
			this.range.css( { "height": "", "bottom": "" } );
15037
		}
15038
	},
15039
 
15040
	_refreshValue: function() {
15041
		var lastValPercent, valPercent, value, valueMin, valueMax,
15042
			oRange = this.options.range,
15043
			o = this.options,
15044
			that = this,
15045
			animate = ( !this._animateOff ) ? o.animate : false,
15046
			_set = {};
15047
 
15048
		if ( this._hasMultipleValues() ) {
15049
			this.handles.each( function( i ) {
15050
				valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() -
15051
					that._valueMin() ) * 100;
15052
				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
15053
				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
15054
				if ( that.options.range === true ) {
15055
					if ( that.orientation === "horizontal" ) {
15056
						if ( i === 0 ) {
15057
							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15058
								left: valPercent + "%"
15059
							}, o.animate );
15060
						}
15061
						if ( i === 1 ) {
15062
							that.range[ animate ? "animate" : "css" ]( {
15063
								width: ( valPercent - lastValPercent ) + "%"
15064
							}, {
15065
								queue: false,
15066
								duration: o.animate
15067
							} );
15068
						}
15069
					} else {
15070
						if ( i === 0 ) {
15071
							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15072
								bottom: ( valPercent ) + "%"
15073
							}, o.animate );
15074
						}
15075
						if ( i === 1 ) {
15076
							that.range[ animate ? "animate" : "css" ]( {
15077
								height: ( valPercent - lastValPercent ) + "%"
15078
							}, {
15079
								queue: false,
15080
								duration: o.animate
15081
							} );
15082
						}
15083
					}
15084
				}
15085
				lastValPercent = valPercent;
15086
			} );
15087
		} else {
15088
			value = this.value();
15089
			valueMin = this._valueMin();
15090
			valueMax = this._valueMax();
15091
			valPercent = ( valueMax !== valueMin ) ?
15092
					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
15093
					0;
15094
			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
15095
			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
15096
 
15097
			if ( oRange === "min" && this.orientation === "horizontal" ) {
15098
				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15099
					width: valPercent + "%"
15100
				}, o.animate );
15101
			}
15102
			if ( oRange === "max" && this.orientation === "horizontal" ) {
15103
				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15104
					width: ( 100 - valPercent ) + "%"
15105
				}, o.animate );
15106
			}
15107
			if ( oRange === "min" && this.orientation === "vertical" ) {
15108
				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15109
					height: valPercent + "%"
15110
				}, o.animate );
15111
			}
15112
			if ( oRange === "max" && this.orientation === "vertical" ) {
15113
				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15114
					height: ( 100 - valPercent ) + "%"
15115
				}, o.animate );
15116
			}
15117
		}
15118
	},
15119
 
15120
	_handleEvents: {
15121
		keydown: function( event ) {
15122
			var allowed, curVal, newVal, step,
15123
				index = $( event.target ).data( "ui-slider-handle-index" );
15124
 
15125
			switch ( event.keyCode ) {
15126
				case $.ui.keyCode.HOME:
15127
				case $.ui.keyCode.END:
15128
				case $.ui.keyCode.PAGE_UP:
15129
				case $.ui.keyCode.PAGE_DOWN:
15130
				case $.ui.keyCode.UP:
15131
				case $.ui.keyCode.RIGHT:
15132
				case $.ui.keyCode.DOWN:
15133
				case $.ui.keyCode.LEFT:
15134
					event.preventDefault();
15135
					if ( !this._keySliding ) {
15136
						this._keySliding = true;
15137
						this._addClass( $( event.target ), null, "ui-state-active" );
15138
						allowed = this._start( event, index );
15139
						if ( allowed === false ) {
15140
							return;
15141
						}
15142
					}
15143
					break;
15144
			}
15145
 
15146
			step = this.options.step;
15147
			if ( this._hasMultipleValues() ) {
15148
				curVal = newVal = this.values( index );
15149
			} else {
15150
				curVal = newVal = this.value();
15151
			}
15152
 
15153
			switch ( event.keyCode ) {
15154
				case $.ui.keyCode.HOME:
15155
					newVal = this._valueMin();
15156
					break;
15157
				case $.ui.keyCode.END:
15158
					newVal = this._valueMax();
15159
					break;
15160
				case $.ui.keyCode.PAGE_UP:
15161
					newVal = this._trimAlignValue(
15162
						curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
15163
					);
15164
					break;
15165
				case $.ui.keyCode.PAGE_DOWN:
15166
					newVal = this._trimAlignValue(
15167
						curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) );
15168
					break;
15169
				case $.ui.keyCode.UP:
15170
				case $.ui.keyCode.RIGHT:
15171
					if ( curVal === this._valueMax() ) {
15172
						return;
15173
					}
15174
					newVal = this._trimAlignValue( curVal + step );
15175
					break;
15176
				case $.ui.keyCode.DOWN:
15177
				case $.ui.keyCode.LEFT:
15178
					if ( curVal === this._valueMin() ) {
15179
						return;
15180
					}
15181
					newVal = this._trimAlignValue( curVal - step );
15182
					break;
15183
			}
15184
 
15185
			this._slide( event, index, newVal );
15186
		},
15187
		keyup: function( event ) {
15188
			var index = $( event.target ).data( "ui-slider-handle-index" );
15189
 
15190
			if ( this._keySliding ) {
15191
				this._keySliding = false;
15192
				this._stop( event, index );
15193
				this._change( event, index );
15194
				this._removeClass( $( event.target ), null, "ui-state-active" );
15195
			}
15196
		}
15197
	}
15198
} );
15199
 
15200
 
15201
/*!
15202
 * jQuery UI Sortable 1.12.1
15203
 * http://jqueryui.com
15204
 *
15205
 * Copyright jQuery Foundation and other contributors
15206
 * Released under the MIT license.
15207
 * http://jquery.org/license
15208
 */
15209
 
15210
//>>label: Sortable
15211
//>>group: Interactions
15212
//>>description: Enables items in a list to be sorted using the mouse.
15213
//>>docs: http://api.jqueryui.com/sortable/
15214
//>>demos: http://jqueryui.com/sortable/
15215
//>>css.structure: ../../themes/base/sortable.css
15216
 
15217
 
15218
 
15219
var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, {
15220
	version: "1.12.1",
15221
	widgetEventPrefix: "sort",
15222
	ready: false,
15223
	options: {
15224
		appendTo: "parent",
15225
		axis: false,
15226
		connectWith: false,
15227
		containment: false,
15228
		cursor: "auto",
15229
		cursorAt: false,
15230
		dropOnEmpty: true,
15231
		forcePlaceholderSize: false,
15232
		forceHelperSize: false,
15233
		grid: false,
15234
		handle: false,
15235
		helper: "original",
15236
		items: "> *",
15237
		opacity: false,
15238
		placeholder: false,
15239
		revert: false,
15240
		scroll: true,
15241
		scrollSensitivity: 20,
15242
		scrollSpeed: 20,
15243
		scope: "default",
15244
		tolerance: "intersect",
15245
		zIndex: 1000,
15246
 
15247
		// Callbacks
15248
		activate: null,
15249
		beforeStop: null,
15250
		change: null,
15251
		deactivate: null,
15252
		out: null,
15253
		over: null,
15254
		receive: null,
15255
		remove: null,
15256
		sort: null,
15257
		start: null,
15258
		stop: null,
15259
		update: null
15260
	},
15261
 
15262
	_isOverAxis: function( x, reference, size ) {
15263
		return ( x >= reference ) && ( x < ( reference + size ) );
15264
	},
15265
 
15266
	_isFloating: function( item ) {
15267
		return ( /left|right/ ).test( item.css( "float" ) ) ||
15268
			( /inline|table-cell/ ).test( item.css( "display" ) );
15269
	},
15270
 
15271
	_create: function() {
15272
		this.containerCache = {};
15273
		this._addClass( "ui-sortable" );
15274
 
15275
		//Get the items
15276
		this.refresh();
15277
 
15278
		//Let's determine the parent's offset
15279
		this.offset = this.element.offset();
15280
 
15281
		//Initialize mouse events for interaction
15282
		this._mouseInit();
15283
 
15284
		this._setHandleClassName();
15285
 
15286
		//We're ready to go
15287
		this.ready = true;
15288
 
15289
	},
15290
 
15291
	_setOption: function( key, value ) {
15292
		this._super( key, value );
15293
 
15294
		if ( key === "handle" ) {
15295
			this._setHandleClassName();
15296
		}
15297
	},
15298
 
15299
	_setHandleClassName: function() {
15300
		var that = this;
15301
		this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" );
15302
		$.each( this.items, function() {
15303
			that._addClass(
15304
				this.instance.options.handle ?
15305
					this.item.find( this.instance.options.handle ) :
15306
					this.item,
15307
				"ui-sortable-handle"
15308
			);
15309
		} );
15310
	},
15311
 
15312
	_destroy: function() {
15313
		this._mouseDestroy();
15314
 
15315
		for ( var i = this.items.length - 1; i >= 0; i-- ) {
15316
			this.items[ i ].item.removeData( this.widgetName + "-item" );
15317
		}
15318
 
15319
		return this;
15320
	},
15321
 
15322
	_mouseCapture: function( event, overrideHandle ) {
15323
		var currentItem = null,
15324
			validHandle = false,
15325
			that = this;
15326
 
15327
		if ( this.reverting ) {
15328
			return false;
15329
		}
15330
 
15331
		if ( this.options.disabled || this.options.type === "static" ) {
15332
			return false;
15333
		}
15334
 
15335
		//We have to refresh the items data once first
15336
		this._refreshItems( event );
15337
 
15338
		//Find out if the clicked node (or one of its parents) is a actual item in this.items
15339
		$( event.target ).parents().each( function() {
15340
			if ( $.data( this, that.widgetName + "-item" ) === that ) {
15341
				currentItem = $( this );
15342
				return false;
15343
			}
15344
		} );
15345
		if ( $.data( event.target, that.widgetName + "-item" ) === that ) {
15346
			currentItem = $( event.target );
15347
		}
15348
 
15349
		if ( !currentItem ) {
15350
			return false;
15351
		}
15352
		if ( this.options.handle && !overrideHandle ) {
15353
			$( this.options.handle, currentItem ).find( "*" ).addBack().each( function() {
15354
				if ( this === event.target ) {
15355
					validHandle = true;
15356
				}
15357
			} );
15358
			if ( !validHandle ) {
15359
				return false;
15360
			}
15361
		}
15362
 
15363
		this.currentItem = currentItem;
15364
		this._removeCurrentsFromItems();
15365
		return true;
15366
 
15367
	},
15368
 
15369
	_mouseStart: function( event, overrideHandle, noActivation ) {
15370
 
15371
		var i, body,
15372
			o = this.options;
15373
 
15374
		this.currentContainer = this;
15375
 
15376
		//We only need to call refreshPositions, because the refreshItems call has been moved to
15377
		// mouseCapture
15378
		this.refreshPositions();
15379
 
15380
		//Create and append the visible helper
15381
		this.helper = this._createHelper( event );
15382
 
15383
		//Cache the helper size
15384
		this._cacheHelperProportions();
15385
 
15386
		/*
15387
		 * - Position generation -
15388
		 * This block generates everything position related - it's the core of draggables.
15389
		 */
15390
 
15391
		//Cache the margins of the original element
15392
		this._cacheMargins();
15393
 
15394
		//Get the next scrolling parent
15395
		this.scrollParent = this.helper.scrollParent();
15396
 
15397
		//The element's absolute position on the page minus margins
15398
		this.offset = this.currentItem.offset();
15399
		this.offset = {
15400
			top: this.offset.top - this.margins.top,
15401
			left: this.offset.left - this.margins.left
15402
		};
15403
 
15404
		$.extend( this.offset, {
15405
			click: { //Where the click happened, relative to the element
15406
				left: event.pageX - this.offset.left,
15407
				top: event.pageY - this.offset.top
15408
			},
15409
			parent: this._getParentOffset(),
15410
 
15411
			// This is a relative to absolute position minus the actual position calculation -
15412
			// only used for relative positioned helper
15413
			relative: this._getRelativeOffset()
15414
		} );
15415
 
15416
		// Only after we got the offset, we can change the helper's position to absolute
15417
		// TODO: Still need to figure out a way to make relative sorting possible
15418
		this.helper.css( "position", "absolute" );
15419
		this.cssPosition = this.helper.css( "position" );
15420
 
15421
		//Generate the original position
15422
		this.originalPosition = this._generatePosition( event );
15423
		this.originalPageX = event.pageX;
15424
		this.originalPageY = event.pageY;
15425
 
15426
		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
15427
		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
15428
 
15429
		//Cache the former DOM position
15430
		this.domPosition = {
15431
			prev: this.currentItem.prev()[ 0 ],
15432
			parent: this.currentItem.parent()[ 0 ]
15433
		};
15434
 
15435
		// If the helper is not the original, hide the original so it's not playing any role during
15436
		// the drag, won't cause anything bad this way
15437
		if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
15438
			this.currentItem.hide();
15439
		}
15440
 
15441
		//Create the placeholder
15442
		this._createPlaceholder();
15443
 
15444
		//Set a containment if given in the options
15445
		if ( o.containment ) {
15446
			this._setContainment();
15447
		}
15448
 
15449
		if ( o.cursor && o.cursor !== "auto" ) { // cursor option
15450
			body = this.document.find( "body" );
15451
 
15452
			// Support: IE
15453
			this.storedCursor = body.css( "cursor" );
15454
			body.css( "cursor", o.cursor );
15455
 
15456
			this.storedStylesheet =
15457
				$( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body );
15458
		}
15459
 
15460
		if ( o.opacity ) { // opacity option
15461
			if ( this.helper.css( "opacity" ) ) {
15462
				this._storedOpacity = this.helper.css( "opacity" );
15463
			}
15464
			this.helper.css( "opacity", o.opacity );
15465
		}
15466
 
15467
		if ( o.zIndex ) { // zIndex option
15468
			if ( this.helper.css( "zIndex" ) ) {
15469
				this._storedZIndex = this.helper.css( "zIndex" );
15470
			}
15471
			this.helper.css( "zIndex", o.zIndex );
15472
		}
15473
 
15474
		//Prepare scrolling
15475
		if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
15476
				this.scrollParent[ 0 ].tagName !== "HTML" ) {
15477
			this.overflowOffset = this.scrollParent.offset();
15478
		}
15479
 
15480
		//Call callbacks
15481
		this._trigger( "start", event, this._uiHash() );
15482
 
15483
		//Recache the helper size
15484
		if ( !this._preserveHelperProportions ) {
15485
			this._cacheHelperProportions();
15486
		}
15487
 
15488
		//Post "activate" events to possible containers
15489
		if ( !noActivation ) {
15490
			for ( i = this.containers.length - 1; i >= 0; i-- ) {
15491
				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
15492
			}
15493
		}
15494
 
15495
		//Prepare possible droppables
15496
		if ( $.ui.ddmanager ) {
15497
			$.ui.ddmanager.current = this;
15498
		}
15499
 
15500
		if ( $.ui.ddmanager && !o.dropBehaviour ) {
15501
			$.ui.ddmanager.prepareOffsets( this, event );
15502
		}
15503
 
15504
		this.dragging = true;
15505
 
15506
		this._addClass( this.helper, "ui-sortable-helper" );
15507
 
15508
		// Execute the drag once - this causes the helper not to be visiblebefore getting its
15509
		// correct position
15510
		this._mouseDrag( event );
15511
		return true;
15512
 
15513
	},
15514
 
15515
	_mouseDrag: function( event ) {
15516
		var i, item, itemElement, intersection,
15517
			o = this.options,
15518
			scrolled = false;
15519
 
15520
		//Compute the helpers position
15521
		this.position = this._generatePosition( event );
15522
		this.positionAbs = this._convertPositionTo( "absolute" );
15523
 
15524
		if ( !this.lastPositionAbs ) {
15525
			this.lastPositionAbs = this.positionAbs;
15526
		}
15527
 
15528
		//Do scrolling
15529
		if ( this.options.scroll ) {
15530
			if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
15531
					this.scrollParent[ 0 ].tagName !== "HTML" ) {
15532
 
15533
				if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -
15534
						event.pageY < o.scrollSensitivity ) {
15535
					this.scrollParent[ 0 ].scrollTop =
15536
						scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;
15537
				} else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {
15538
					this.scrollParent[ 0 ].scrollTop =
15539
						scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;
15540
				}
15541
 
15542
				if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -
15543
						event.pageX < o.scrollSensitivity ) {
15544
					this.scrollParent[ 0 ].scrollLeft = scrolled =
15545
						this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;
15546
				} else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {
15547
					this.scrollParent[ 0 ].scrollLeft = scrolled =
15548
						this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;
15549
				}
15550
 
15551
			} else {
15552
 
15553
				if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {
15554
					scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );
15555
				} else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <
15556
						o.scrollSensitivity ) {
15557
					scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );
15558
				}
15559
 
15560
				if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {
15561
					scrolled = this.document.scrollLeft(
15562
						this.document.scrollLeft() - o.scrollSpeed
15563
					);
15564
				} else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <
15565
						o.scrollSensitivity ) {
15566
					scrolled = this.document.scrollLeft(
15567
						this.document.scrollLeft() + o.scrollSpeed
15568
					);
15569
				}
15570
 
15571
			}
15572
 
15573
			if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
15574
				$.ui.ddmanager.prepareOffsets( this, event );
15575
			}
15576
		}
15577
 
15578
		//Regenerate the absolute position used for position checks
15579
		this.positionAbs = this._convertPositionTo( "absolute" );
15580
 
15581
		//Set the helper position
15582
		if ( !this.options.axis || this.options.axis !== "y" ) {
15583
			this.helper[ 0 ].style.left = this.position.left + "px";
15584
		}
15585
		if ( !this.options.axis || this.options.axis !== "x" ) {
15586
			this.helper[ 0 ].style.top = this.position.top + "px";
15587
		}
15588
 
15589
		//Rearrange
15590
		for ( i = this.items.length - 1; i >= 0; i-- ) {
15591
 
15592
			//Cache variables and intersection, continue if no intersection
15593
			item = this.items[ i ];
15594
			itemElement = item.item[ 0 ];
15595
			intersection = this._intersectsWithPointer( item );
15596
			if ( !intersection ) {
15597
				continue;
15598
			}
15599
 
15600
			// Only put the placeholder inside the current Container, skip all
15601
			// items from other containers. This works because when moving
15602
			// an item from one container to another the
15603
			// currentContainer is switched before the placeholder is moved.
15604
			//
15605
			// Without this, moving items in "sub-sortables" can cause
15606
			// the placeholder to jitter between the outer and inner container.
15607
			if ( item.instance !== this.currentContainer ) {
15608
				continue;
15609
			}
15610
 
15611
			// Cannot intersect with itself
15612
			// no useless actions that have been done before
15613
			// no action if the item moved is the parent of the item checked
15614
			if ( itemElement !== this.currentItem[ 0 ] &&
15615
				this.placeholder[ intersection === 1 ? "next" : "prev" ]()[ 0 ] !== itemElement &&
15616
				!$.contains( this.placeholder[ 0 ], itemElement ) &&
15617
				( this.options.type === "semi-dynamic" ?
15618
					!$.contains( this.element[ 0 ], itemElement ) :
15619
					true
15620
				)
15621
			) {
15622
 
15623
				this.direction = intersection === 1 ? "down" : "up";
15624
 
15625
				if ( this.options.tolerance === "pointer" || this._intersectsWithSides( item ) ) {
15626
					this._rearrange( event, item );
15627
				} else {
15628
					break;
15629
				}
15630
 
15631
				this._trigger( "change", event, this._uiHash() );
15632
				break;
15633
			}
15634
		}
15635
 
15636
		//Post events to containers
15637
		this._contactContainers( event );
15638
 
15639
		//Interconnect with droppables
15640
		if ( $.ui.ddmanager ) {
15641
			$.ui.ddmanager.drag( this, event );
15642
		}
15643
 
15644
		//Call callbacks
15645
		this._trigger( "sort", event, this._uiHash() );
15646
 
15647
		this.lastPositionAbs = this.positionAbs;
15648
		return false;
15649
 
15650
	},
15651
 
15652
	_mouseStop: function( event, noPropagation ) {
15653
 
15654
		if ( !event ) {
15655
			return;
15656
		}
15657
 
15658
		//If we are using droppables, inform the manager about the drop
15659
		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
15660
			$.ui.ddmanager.drop( this, event );
15661
		}
15662
 
15663
		if ( this.options.revert ) {
15664
			var that = this,
15665
				cur = this.placeholder.offset(),
15666
				axis = this.options.axis,
15667
				animation = {};
15668
 
15669
			if ( !axis || axis === "x" ) {
15670
				animation.left = cur.left - this.offset.parent.left - this.margins.left +
15671
					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
15672
 
15673
						this.offsetParent[ 0 ].scrollLeft
15674
					);
15675
			}
15676
			if ( !axis || axis === "y" ) {
15677
				animation.top = cur.top - this.offset.parent.top - this.margins.top +
15678
					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
15679
 
15680
						this.offsetParent[ 0 ].scrollTop
15681
					);
15682
			}
15683
			this.reverting = true;
15684
			$( this.helper ).animate(
15685
				animation,
15686
				parseInt( this.options.revert, 10 ) || 500,
15687
				function() {
15688
					that._clear( event );
15689
				}
15690
			);
15691
		} else {
15692
			this._clear( event, noPropagation );
15693
		}
15694
 
15695
		return false;
15696
 
15697
	},
15698
 
15699
	cancel: function() {
15700
 
15701
		if ( this.dragging ) {
15702
 
15703
			this._mouseUp( new $.Event( "mouseup", { target: null } ) );
15704
 
15705
			if ( this.options.helper === "original" ) {
15706
				this.currentItem.css( this._storedCSS );
15707
				this._removeClass( this.currentItem, "ui-sortable-helper" );
15708
			} else {
15709
				this.currentItem.show();
15710
			}
15711
 
15712
			//Post deactivating events to containers
15713
			for ( var i = this.containers.length - 1; i >= 0; i-- ) {
15714
				this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) );
15715
				if ( this.containers[ i ].containerCache.over ) {
15716
					this.containers[ i ]._trigger( "out", null, this._uiHash( this ) );
15717
					this.containers[ i ].containerCache.over = 0;
15718
				}
15719
			}
15720
 
15721
		}
15722
 
15723
		if ( this.placeholder ) {
15724
 
15725
			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
15726
			// it unbinds ALL events from the original node!
15727
			if ( this.placeholder[ 0 ].parentNode ) {
15728
				this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
15729
			}
15730
			if ( this.options.helper !== "original" && this.helper &&
15731
					this.helper[ 0 ].parentNode ) {
15732
				this.helper.remove();
15733
			}
15734
 
15735
			$.extend( this, {
15736
				helper: null,
15737
				dragging: false,
15738
				reverting: false,
15739
				_noFinalSort: null
15740
			} );
15741
 
15742
			if ( this.domPosition.prev ) {
15743
				$( this.domPosition.prev ).after( this.currentItem );
15744
			} else {
15745
				$( this.domPosition.parent ).prepend( this.currentItem );
15746
			}
15747
		}
15748
 
15749
		return this;
15750
 
15751
	},
15752
 
15753
	serialize: function( o ) {
15754
 
15755
		var items = this._getItemsAsjQuery( o && o.connected ),
15756
			str = [];
15757
		o = o || {};
15758
 
15759
		$( items ).each( function() {
15760
			var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" )
15761
				.match( o.expression || ( /(.+)[\-=_](.+)/ ) );
15762
			if ( res ) {
15763
				str.push(
15764
					( o.key || res[ 1 ] + "[]" ) +
15765
					"=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );
15766
			}
15767
		} );
15768
 
15769
		if ( !str.length && o.key ) {
15770
			str.push( o.key + "=" );
15771
		}
15772
 
15773
		return str.join( "&" );
15774
 
15775
	},
15776
 
15777
	toArray: function( o ) {
15778
 
15779
		var items = this._getItemsAsjQuery( o && o.connected ),
15780
			ret = [];
15781
 
15782
		o = o || {};
15783
 
15784
		items.each( function() {
15785
			ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" );
15786
		} );
15787
		return ret;
15788
 
15789
	},
15790
 
15791
	/* Be careful with the following core functions */
15792
	_intersectsWith: function( item ) {
15793
 
15794
		var x1 = this.positionAbs.left,
15795
			x2 = x1 + this.helperProportions.width,
15796
			y1 = this.positionAbs.top,
15797
			y2 = y1 + this.helperProportions.height,
15798
			l = item.left,
15799
			r = l + item.width,
15800
			t = item.top,
15801
			b = t + item.height,
15802
			dyClick = this.offset.click.top,
15803
			dxClick = this.offset.click.left,
15804
			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t &&
15805
				( y1 + dyClick ) < b ),
15806
			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l &&
15807
				( x1 + dxClick ) < r ),
15808
			isOverElement = isOverElementHeight && isOverElementWidth;
15809
 
15810
		if ( this.options.tolerance === "pointer" ||
15811
			this.options.forcePointerForContainers ||
15812
			( this.options.tolerance !== "pointer" &&
15813
				this.helperProportions[ this.floating ? "width" : "height" ] >
15814
				item[ this.floating ? "width" : "height" ] )
15815
		) {
15816
			return isOverElement;
15817
		} else {
15818
 
15819
			return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half
15820
				x2 - ( this.helperProportions.width / 2 ) < r && // Left Half
15821
				t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half
15822
				y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half
15823
 
15824
		}
15825
	},
15826
 
15827
	_intersectsWithPointer: function( item ) {
15828
		var verticalDirection, horizontalDirection,
15829
			isOverElementHeight = ( this.options.axis === "x" ) ||
15830
				this._isOverAxis(
15831
					this.positionAbs.top + this.offset.click.top, item.top, item.height ),
15832
			isOverElementWidth = ( this.options.axis === "y" ) ||
15833
				this._isOverAxis(
15834
					this.positionAbs.left + this.offset.click.left, item.left, item.width ),
15835
			isOverElement = isOverElementHeight && isOverElementWidth;
15836
 
15837
		if ( !isOverElement ) {
15838
			return false;
15839
		}
15840
 
15841
		verticalDirection = this._getDragVerticalDirection();
15842
		horizontalDirection = this._getDragHorizontalDirection();
15843
 
15844
		return this.floating ?
15845
			( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 )
15846
			: ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) );
15847
 
15848
	},
15849
 
15850
	_intersectsWithSides: function( item ) {
15851
 
15852
		var isOverBottomHalf = this._isOverAxis( this.positionAbs.top +
15853
				this.offset.click.top, item.top + ( item.height / 2 ), item.height ),
15854
			isOverRightHalf = this._isOverAxis( this.positionAbs.left +
15855
				this.offset.click.left, item.left + ( item.width / 2 ), item.width ),
15856
			verticalDirection = this._getDragVerticalDirection(),
15857
			horizontalDirection = this._getDragHorizontalDirection();
15858
 
15859
		if ( this.floating && horizontalDirection ) {
15860
			return ( ( horizontalDirection === "right" && isOverRightHalf ) ||
15861
				( horizontalDirection === "left" && !isOverRightHalf ) );
15862
		} else {
15863
			return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) ||
15864
				( verticalDirection === "up" && !isOverBottomHalf ) );
15865
		}
15866
 
15867
	},
15868
 
15869
	_getDragVerticalDirection: function() {
15870
		var delta = this.positionAbs.top - this.lastPositionAbs.top;
15871
		return delta !== 0 && ( delta > 0 ? "down" : "up" );
15872
	},
15873
 
15874
	_getDragHorizontalDirection: function() {
15875
		var delta = this.positionAbs.left - this.lastPositionAbs.left;
15876
		return delta !== 0 && ( delta > 0 ? "right" : "left" );
15877
	},
15878
 
15879
	refresh: function( event ) {
15880
		this._refreshItems( event );
15881
		this._setHandleClassName();
15882
		this.refreshPositions();
15883
		return this;
15884
	},
15885
 
15886
	_connectWith: function() {
15887
		var options = this.options;
15888
		return options.connectWith.constructor === String ?
15889
			[ options.connectWith ] :
15890
			options.connectWith;
15891
	},
15892
 
15893
	_getItemsAsjQuery: function( connected ) {
15894
 
15895
		var i, j, cur, inst,
15896
			items = [],
15897
			queries = [],
15898
			connectWith = this._connectWith();
15899
 
15900
		if ( connectWith && connected ) {
15901
			for ( i = connectWith.length - 1; i >= 0; i-- ) {
15902
				cur = $( connectWith[ i ], this.document[ 0 ] );
15903
				for ( j = cur.length - 1; j >= 0; j-- ) {
15904
					inst = $.data( cur[ j ], this.widgetFullName );
15905
					if ( inst && inst !== this && !inst.options.disabled ) {
15906
						queries.push( [ $.isFunction( inst.options.items ) ?
15907
							inst.options.items.call( inst.element ) :
15908
							$( inst.options.items, inst.element )
15909
								.not( ".ui-sortable-helper" )
15910
								.not( ".ui-sortable-placeholder" ), inst ] );
15911
					}
15912
				}
15913
			}
15914
		}
15915
 
15916
		queries.push( [ $.isFunction( this.options.items ) ?
15917
			this.options.items
15918
				.call( this.element, null, { options: this.options, item: this.currentItem } ) :
15919
			$( this.options.items, this.element )
15920
				.not( ".ui-sortable-helper" )
15921
				.not( ".ui-sortable-placeholder" ), this ] );
15922
 
15923
		function addItems() {
15924
			items.push( this );
15925
		}
15926
		for ( i = queries.length - 1; i >= 0; i-- ) {
15927
			queries[ i ][ 0 ].each( addItems );
15928
		}
15929
 
15930
		return $( items );
15931
 
15932
	},
15933
 
15934
	_removeCurrentsFromItems: function() {
15935
 
15936
		var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" );
15937
 
15938
		this.items = $.grep( this.items, function( item ) {
15939
			for ( var j = 0; j < list.length; j++ ) {
15940
				if ( list[ j ] === item.item[ 0 ] ) {
15941
					return false;
15942
				}
15943
			}
15944
			return true;
15945
		} );
15946
 
15947
	},
15948
 
15949
	_refreshItems: function( event ) {
15950
 
15951
		this.items = [];
15952
		this.containers = [ this ];
15953
 
15954
		var i, j, cur, inst, targetData, _queries, item, queriesLength,
15955
			items = this.items,
15956
			queries = [ [ $.isFunction( this.options.items ) ?
15957
				this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :
15958
				$( this.options.items, this.element ), this ] ],
15959
			connectWith = this._connectWith();
15960
 
15961
		//Shouldn't be run the first time through due to massive slow-down
15962
		if ( connectWith && this.ready ) {
15963
			for ( i = connectWith.length - 1; i >= 0; i-- ) {
15964
				cur = $( connectWith[ i ], this.document[ 0 ] );
15965
				for ( j = cur.length - 1; j >= 0; j-- ) {
15966
					inst = $.data( cur[ j ], this.widgetFullName );
15967
					if ( inst && inst !== this && !inst.options.disabled ) {
15968
						queries.push( [ $.isFunction( inst.options.items ) ?
15969
							inst.options.items
15970
								.call( inst.element[ 0 ], event, { item: this.currentItem } ) :
15971
							$( inst.options.items, inst.element ), inst ] );
15972
						this.containers.push( inst );
15973
					}
15974
				}
15975
			}
15976
		}
15977
 
15978
		for ( i = queries.length - 1; i >= 0; i-- ) {
15979
			targetData = queries[ i ][ 1 ];
15980
			_queries = queries[ i ][ 0 ];
15981
 
15982
			for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {
15983
				item = $( _queries[ j ] );
15984
 
15985
				// Data for target checking (mouse manager)
15986
				item.data( this.widgetName + "-item", targetData );
15987
 
15988
				items.push( {
15989
					item: item,
15990
					instance: targetData,
15991
					width: 0, height: 0,
15992
					left: 0, top: 0
15993
				} );
15994
			}
15995
		}
15996
 
15997
	},
15998
 
15999
	refreshPositions: function( fast ) {
16000
 
16001
		// Determine whether items are being displayed horizontally
16002
		this.floating = this.items.length ?
16003
			this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
16004
			false;
16005
 
16006
		//This has to be redone because due to the item being moved out/into the offsetParent,
16007
		// the offsetParent's position will change
16008
		if ( this.offsetParent && this.helper ) {
16009
			this.offset.parent = this._getParentOffset();
16010
		}
16011
 
16012
		var i, item, t, p;
16013
 
16014
		for ( i = this.items.length - 1; i >= 0; i-- ) {
16015
			item = this.items[ i ];
16016
 
16017
			//We ignore calculating positions of all connected containers when we're not over them
16018
			if ( item.instance !== this.currentContainer && this.currentContainer &&
16019
					item.item[ 0 ] !== this.currentItem[ 0 ] ) {
16020
				continue;
16021
			}
16022
 
16023
			t = this.options.toleranceElement ?
16024
				$( this.options.toleranceElement, item.item ) :
16025
				item.item;
16026
 
16027
			if ( !fast ) {
16028
				item.width = t.outerWidth();
16029
				item.height = t.outerHeight();
16030
			}
16031
 
16032
			p = t.offset();
16033
			item.left = p.left;
16034
			item.top = p.top;
16035
		}
16036
 
16037
		if ( this.options.custom && this.options.custom.refreshContainers ) {
16038
			this.options.custom.refreshContainers.call( this );
16039
		} else {
16040
			for ( i = this.containers.length - 1; i >= 0; i-- ) {
16041
				p = this.containers[ i ].element.offset();
16042
				this.containers[ i ].containerCache.left = p.left;
16043
				this.containers[ i ].containerCache.top = p.top;
16044
				this.containers[ i ].containerCache.width =
16045
					this.containers[ i ].element.outerWidth();
16046
				this.containers[ i ].containerCache.height =
16047
					this.containers[ i ].element.outerHeight();
16048
			}
16049
		}
16050
 
16051
		return this;
16052
	},
16053
 
16054
	_createPlaceholder: function( that ) {
16055
		that = that || this;
16056
		var className,
16057
			o = that.options;
16058
 
16059
		if ( !o.placeholder || o.placeholder.constructor === String ) {
16060
			className = o.placeholder;
16061
			o.placeholder = {
16062
				element: function() {
16063
 
16064
					var nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(),
16065
						element = $( "<" + nodeName + ">", that.document[ 0 ] );
16066
 
16067
						that._addClass( element, "ui-sortable-placeholder",
16068
								className || that.currentItem[ 0 ].className )
16069
							._removeClass( element, "ui-sortable-helper" );
16070
 
16071
					if ( nodeName === "tbody" ) {
16072
						that._createTrPlaceholder(
16073
							that.currentItem.find( "tr" ).eq( 0 ),
16074
							$( "<tr>", that.document[ 0 ] ).appendTo( element )
16075
						);
16076
					} else if ( nodeName === "tr" ) {
16077
						that._createTrPlaceholder( that.currentItem, element );
16078
					} else if ( nodeName === "img" ) {
16079
						element.attr( "src", that.currentItem.attr( "src" ) );
16080
					}
16081
 
16082
					if ( !className ) {
16083
						element.css( "visibility", "hidden" );
16084
					}
16085
 
16086
					return element;
16087
				},
16088
				update: function( container, p ) {
16089
 
16090
					// 1. If a className is set as 'placeholder option, we don't force sizes -
16091
					// the class is responsible for that
16092
					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a
16093
					// class name is specified
16094
					if ( className && !o.forcePlaceholderSize ) {
16095
						return;
16096
					}
16097
 
16098
					//If the element doesn't have a actual height by itself (without styles coming
16099
					// from a stylesheet), it receives the inline height from the dragged item
16100
					if ( !p.height() ) {
16101
						p.height(
16102
							that.currentItem.innerHeight() -
16103
							parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) -
16104
							parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) );
16105
					}
16106
					if ( !p.width() ) {
16107
						p.width(
16108
							that.currentItem.innerWidth() -
16109
							parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) -
16110
							parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) );
16111
					}
16112
				}
16113
			};
16114
		}
16115
 
16116
		//Create the placeholder
16117
		that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );
16118
 
16119
		//Append it after the actual current item
16120
		that.currentItem.after( that.placeholder );
16121
 
16122
		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
16123
		o.placeholder.update( that, that.placeholder );
16124
 
16125
	},
16126
 
16127
	_createTrPlaceholder: function( sourceTr, targetTr ) {
16128
		var that = this;
16129
 
16130
		sourceTr.children().each( function() {
16131
			$( "<td>&#160;</td>", that.document[ 0 ] )
16132
				.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
16133
				.appendTo( targetTr );
16134
		} );
16135
	},
16136
 
16137
	_contactContainers: function( event ) {
16138
		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
16139
			floating, axis,
16140
			innermostContainer = null,
16141
			innermostIndex = null;
16142
 
16143
		// Get innermost container that intersects with item
16144
		for ( i = this.containers.length - 1; i >= 0; i-- ) {
16145
 
16146
			// Never consider a container that's located within the item itself
16147
			if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {
16148
				continue;
16149
			}
16150
 
16151
			if ( this._intersectsWith( this.containers[ i ].containerCache ) ) {
16152
 
16153
				// If we've already found a container and it's more "inner" than this, then continue
16154
				if ( innermostContainer &&
16155
						$.contains(
16156
							this.containers[ i ].element[ 0 ],
16157
							innermostContainer.element[ 0 ] ) ) {
16158
					continue;
16159
				}
16160
 
16161
				innermostContainer = this.containers[ i ];
16162
				innermostIndex = i;
16163
 
16164
			} else {
16165
 
16166
				// container doesn't intersect. trigger "out" event if necessary
16167
				if ( this.containers[ i ].containerCache.over ) {
16168
					this.containers[ i ]._trigger( "out", event, this._uiHash( this ) );
16169
					this.containers[ i ].containerCache.over = 0;
16170
				}
16171
			}
16172
 
16173
		}
16174
 
16175
		// If no intersecting containers found, return
16176
		if ( !innermostContainer ) {
16177
			return;
16178
		}
16179
 
16180
		// Move the item into the container if it's not there already
16181
		if ( this.containers.length === 1 ) {
16182
			if ( !this.containers[ innermostIndex ].containerCache.over ) {
16183
				this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
16184
				this.containers[ innermostIndex ].containerCache.over = 1;
16185
			}
16186
		} else {
16187
 
16188
			// When entering a new container, we will find the item with the least distance and
16189
			// append our item near it
16190
			dist = 10000;
16191
			itemWithLeastDistance = null;
16192
			floating = innermostContainer.floating || this._isFloating( this.currentItem );
16193
			posProperty = floating ? "left" : "top";
16194
			sizeProperty = floating ? "width" : "height";
16195
			axis = floating ? "pageX" : "pageY";
16196
 
16197
			for ( j = this.items.length - 1; j >= 0; j-- ) {
16198
				if ( !$.contains(
16199
						this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )
16200
				) {
16201
					continue;
16202
				}
16203
				if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {
16204
					continue;
16205
				}
16206
 
16207
				cur = this.items[ j ].item.offset()[ posProperty ];
16208
				nearBottom = false;
16209
				if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
16210
					nearBottom = true;
16211
				}
16212
 
16213
				if ( Math.abs( event[ axis ] - cur ) < dist ) {
16214
					dist = Math.abs( event[ axis ] - cur );
16215
					itemWithLeastDistance = this.items[ j ];
16216
					this.direction = nearBottom ? "up" : "down";
16217
				}
16218
			}
16219
 
16220
			//Check if dropOnEmpty is enabled
16221
			if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {
16222
				return;
16223
			}
16224
 
16225
			if ( this.currentContainer === this.containers[ innermostIndex ] ) {
16226
				if ( !this.currentContainer.containerCache.over ) {
16227
					this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
16228
					this.currentContainer.containerCache.over = 1;
16229
				}
16230
				return;
16231
			}
16232
 
16233
			itemWithLeastDistance ?
16234
				this._rearrange( event, itemWithLeastDistance, null, true ) :
16235
				this._rearrange( event, null, this.containers[ innermostIndex ].element, true );
16236
			this._trigger( "change", event, this._uiHash() );
16237
			this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) );
16238
			this.currentContainer = this.containers[ innermostIndex ];
16239
 
16240
			//Update the placeholder
16241
			this.options.placeholder.update( this.currentContainer, this.placeholder );
16242
 
16243
			this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
16244
			this.containers[ innermostIndex ].containerCache.over = 1;
16245
		}
16246
 
16247
	},
16248
 
16249
	_createHelper: function( event ) {
16250
 
16251
		var o = this.options,
16252
			helper = $.isFunction( o.helper ) ?
16253
				$( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :
16254
				( o.helper === "clone" ? this.currentItem.clone() : this.currentItem );
16255
 
16256
		//Add the helper to the DOM if that didn't happen already
16257
		if ( !helper.parents( "body" ).length ) {
16258
			$( o.appendTo !== "parent" ?
16259
				o.appendTo :
16260
				this.currentItem[ 0 ].parentNode )[ 0 ].appendChild( helper[ 0 ] );
16261
		}
16262
 
16263
		if ( helper[ 0 ] === this.currentItem[ 0 ] ) {
16264
			this._storedCSS = {
16265
				width: this.currentItem[ 0 ].style.width,
16266
				height: this.currentItem[ 0 ].style.height,
16267
				position: this.currentItem.css( "position" ),
16268
				top: this.currentItem.css( "top" ),
16269
				left: this.currentItem.css( "left" )
16270
			};
16271
		}
16272
 
16273
		if ( !helper[ 0 ].style.width || o.forceHelperSize ) {
16274
			helper.width( this.currentItem.width() );
16275
		}
16276
		if ( !helper[ 0 ].style.height || o.forceHelperSize ) {
16277
			helper.height( this.currentItem.height() );
16278
		}
16279
 
16280
		return helper;
16281
 
16282
	},
16283
 
16284
	_adjustOffsetFromHelper: function( obj ) {
16285
		if ( typeof obj === "string" ) {
16286
			obj = obj.split( " " );
16287
		}
16288
		if ( $.isArray( obj ) ) {
16289
			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
16290
		}
16291
		if ( "left" in obj ) {
16292
			this.offset.click.left = obj.left + this.margins.left;
16293
		}
16294
		if ( "right" in obj ) {
16295
			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
16296
		}
16297
		if ( "top" in obj ) {
16298
			this.offset.click.top = obj.top + this.margins.top;
16299
		}
16300
		if ( "bottom" in obj ) {
16301
			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
16302
		}
16303
	},
16304
 
16305
	_getParentOffset: function() {
16306
 
16307
		//Get the offsetParent and cache its position
16308
		this.offsetParent = this.helper.offsetParent();
16309
		var po = this.offsetParent.offset();
16310
 
16311
		// This is a special case where we need to modify a offset calculated on start, since the
16312
		// following happened:
16313
		// 1. The position of the helper is absolute, so it's position is calculated based on the
16314
		// next positioned parent
16315
		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
16316
		// the document, which means that the scroll is included in the initial calculation of the
16317
		// offset of the parent, and never recalculated upon drag
16318
		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16319
				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
16320
			po.left += this.scrollParent.scrollLeft();
16321
			po.top += this.scrollParent.scrollTop();
16322
		}
16323
 
16324
		// This needs to be actually done for all browsers, since pageX/pageY includes this
16325
		// information with an ugly IE fix
16326
		if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ||
16327
				( this.offsetParent[ 0 ].tagName &&
16328
				this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) {
16329
			po = { top: 0, left: 0 };
16330
		}
16331
 
16332
		return {
16333
			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
16334
			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
16335
		};
16336
 
16337
	},
16338
 
16339
	_getRelativeOffset: function() {
16340
 
16341
		if ( this.cssPosition === "relative" ) {
16342
			var p = this.currentItem.position();
16343
			return {
16344
				top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
16345
					this.scrollParent.scrollTop(),
16346
				left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
16347
					this.scrollParent.scrollLeft()
16348
			};
16349
		} else {
16350
			return { top: 0, left: 0 };
16351
		}
16352
 
16353
	},
16354
 
16355
	_cacheMargins: function() {
16356
		this.margins = {
16357
			left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ),
16358
			top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 )
16359
		};
16360
	},
16361
 
16362
	_cacheHelperProportions: function() {
16363
		this.helperProportions = {
16364
			width: this.helper.outerWidth(),
16365
			height: this.helper.outerHeight()
16366
		};
16367
	},
16368
 
16369
	_setContainment: function() {
16370
 
16371
		var ce, co, over,
16372
			o = this.options;
16373
		if ( o.containment === "parent" ) {
16374
			o.containment = this.helper[ 0 ].parentNode;
16375
		}
16376
		if ( o.containment === "document" || o.containment === "window" ) {
16377
			this.containment = [
16378
 
16379
 
16380
				o.containment === "document" ?
16381
					this.document.width() :
16382
					this.window.width() - this.helperProportions.width - this.margins.left,
16383
				( o.containment === "document" ?
16384
					( this.document.height() || document.body.parentNode.scrollHeight ) :
16385
					this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight
16386
				) - this.helperProportions.height - this.margins.top
16387
			];
16388
		}
16389
 
16390
		if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {
16391
			ce = $( o.containment )[ 0 ];
16392
			co = $( o.containment ).offset();
16393
			over = ( $( ce ).css( "overflow" ) !== "hidden" );
16394
 
16395
			this.containment = [
16396
				co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) +
16397
					( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left,
16398
				co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) +
16399
					( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top,
16400
				co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
16401
					( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) -
16402
					( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) -
16403
					this.helperProportions.width - this.margins.left,
16404
				co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
16405
					( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) -
16406
					( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) -
16407
					this.helperProportions.height - this.margins.top
16408
			];
16409
		}
16410
 
16411
	},
16412
 
16413
	_convertPositionTo: function( d, pos ) {
16414
 
16415
		if ( !pos ) {
16416
			pos = this.position;
16417
		}
16418
		var mod = d === "absolute" ? 1 : -1,
16419
			scroll = this.cssPosition === "absolute" &&
16420
				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16421
				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
16422
					this.offsetParent :
16423
					this.scrollParent,
16424
			scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
16425
 
16426
		return {
16427
			top: (
16428
 
16429
				// The absolute mouse position
16430
				pos.top	+
16431
 
16432
				// Only for relative positioned nodes: Relative offset from element to offset parent
16433
				this.offset.relative.top * mod +
16434
 
16435
				// The offsetParent's offset without borders (offset + border)
16436
				this.offset.parent.top * mod -
16437
				( ( this.cssPosition === "fixed" ?
16438
					-this.scrollParent.scrollTop() :
16439
					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )
16440
			),
16441
			left: (
16442
 
16443
				// The absolute mouse position
16444
				pos.left +
16445
 
16446
				// Only for relative positioned nodes: Relative offset from element to offset parent
16447
				this.offset.relative.left * mod +
16448
 
16449
				// The offsetParent's offset without borders (offset + border)
16450
				this.offset.parent.left * mod	-
16451
				( ( this.cssPosition === "fixed" ?
16452
					-this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
16453
					scroll.scrollLeft() ) * mod )
16454
			)
16455
		};
16456
 
16457
	},
16458
 
16459
	_generatePosition: function( event ) {
16460
 
16461
		var top, left,
16462
			o = this.options,
16463
			pageX = event.pageX,
16464
			pageY = event.pageY,
16465
			scroll = this.cssPosition === "absolute" &&
16466
				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16467
				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
16468
					this.offsetParent :
16469
					this.scrollParent,
16470
				scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
16471
 
16472
		// This is another very weird special case that only happens for relative elements:
16473
		// 1. If the css position is relative
16474
		// 2. and the scroll parent is the document or similar to the offset parent
16475
		// we have to refresh the relative offset during the scroll so there are no jumps
16476
		if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16477
				this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {
16478
			this.offset.relative = this._getRelativeOffset();
16479
		}
16480
 
16481
		/*
16482
		 * - Position constraining -
16483
		 * Constrain the position to a mix of grid, containment.
16484
		 */
16485
 
16486
		if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options
16487
 
16488
			if ( this.containment ) {
16489
				if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {
16490
					pageX = this.containment[ 0 ] + this.offset.click.left;
16491
				}
16492
				if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {
16493
					pageY = this.containment[ 1 ] + this.offset.click.top;
16494
				}
16495
				if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {
16496
					pageX = this.containment[ 2 ] + this.offset.click.left;
16497
				}
16498
				if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {
16499
					pageY = this.containment[ 3 ] + this.offset.click.top;
16500
				}
16501
			}
16502
 
16503
			if ( o.grid ) {
16504
				top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /
16505
					o.grid[ 1 ] ) * o.grid[ 1 ];
16506
				pageY = this.containment ?
16507
					( ( top - this.offset.click.top >= this.containment[ 1 ] &&
16508
						top - this.offset.click.top <= this.containment[ 3 ] ) ?
16509
							top :
16510
							( ( top - this.offset.click.top >= this.containment[ 1 ] ) ?
16511
								top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) :
16512
								top;
16513
 
16514
				left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /
16515
					o.grid[ 0 ] ) * o.grid[ 0 ];
16516
				pageX = this.containment ?
16517
					( ( left - this.offset.click.left >= this.containment[ 0 ] &&
16518
						left - this.offset.click.left <= this.containment[ 2 ] ) ?
16519
							left :
16520
							( ( left - this.offset.click.left >= this.containment[ 0 ] ) ?
16521
								left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) :
16522
								left;
16523
			}
16524
 
16525
		}
16526
 
16527
		return {
16528
			top: (
16529
 
16530
				// The absolute mouse position
16531
				pageY -
16532
 
16533
				// Click offset (relative to the element)
16534
				this.offset.click.top -
16535
 
16536
				// Only for relative positioned nodes: Relative offset from element to offset parent
16537
				this.offset.relative.top -
16538
 
16539
				// The offsetParent's offset without borders (offset + border)
16540
				this.offset.parent.top +
16541
				( ( this.cssPosition === "fixed" ?
16542
					-this.scrollParent.scrollTop() :
16543
					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )
16544
			),
16545
			left: (
16546
 
16547
				// The absolute mouse position
16548
				pageX -
16549
 
16550
				// Click offset (relative to the element)
16551
				this.offset.click.left -
16552
 
16553
				// Only for relative positioned nodes: Relative offset from element to offset parent
16554
				this.offset.relative.left -
16555
 
16556
				// The offsetParent's offset without borders (offset + border)
16557
				this.offset.parent.left +
16558
				( ( this.cssPosition === "fixed" ?
16559
					-this.scrollParent.scrollLeft() :
16560
					scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
16561
			)
16562
		};
16563
 
16564
	},
16565
 
16566
	_rearrange: function( event, i, a, hardRefresh ) {
16567
 
16568
		a ? a[ 0 ].appendChild( this.placeholder[ 0 ] ) :
16569
			i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ],
16570
				( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) );
16571
 
16572
		//Various things done here to improve the performance:
16573
		// 1. we create a setTimeout, that calls refreshPositions
16574
		// 2. on the instance, we have a counter variable, that get's higher after every append
16575
		// 3. on the local scope, we copy the counter variable, and check in the timeout,
16576
		// if it's still the same
16577
		// 4. this lets only the last addition to the timeout stack through
16578
		this.counter = this.counter ? ++this.counter : 1;
16579
		var counter = this.counter;
16580
 
16581
		this._delay( function() {
16582
			if ( counter === this.counter ) {
16583
 
16584
				//Precompute after each DOM insertion, NOT on mousemove
16585
				this.refreshPositions( !hardRefresh );
16586
			}
16587
		} );
16588
 
16589
	},
16590
 
16591
	_clear: function( event, noPropagation ) {
16592
 
16593
		this.reverting = false;
16594
 
16595
		// We delay all events that have to be triggered to after the point where the placeholder
16596
		// has been removed and everything else normalized again
16597
		var i,
16598
			delayedTriggers = [];
16599
 
16600
		// We first have to update the dom position of the actual currentItem
16601
		// Note: don't do it if the current item is already removed (by a user), or it gets
16602
		// reappended (see #4088)
16603
		if ( !this._noFinalSort && this.currentItem.parent().length ) {
16604
			this.placeholder.before( this.currentItem );
16605
		}
16606
		this._noFinalSort = null;
16607
 
16608
		if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {
16609
			for ( i in this._storedCSS ) {
16610
				if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) {
16611
					this._storedCSS[ i ] = "";
16612
				}
16613
			}
16614
			this.currentItem.css( this._storedCSS );
16615
			this._removeClass( this.currentItem, "ui-sortable-helper" );
16616
		} else {
16617
			this.currentItem.show();
16618
		}
16619
 
16620
		if ( this.fromOutside && !noPropagation ) {
16621
			delayedTriggers.push( function( event ) {
16622
				this._trigger( "receive", event, this._uiHash( this.fromOutside ) );
16623
			} );
16624
		}
16625
		if ( ( this.fromOutside ||
16626
				this.domPosition.prev !==
16627
				this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] ||
16628
				this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {
16629
 
16630
			// Trigger update callback if the DOM position has changed
16631
			delayedTriggers.push( function( event ) {
16632
				this._trigger( "update", event, this._uiHash() );
16633
			} );
16634
		}
16635
 
16636
		// Check if the items Container has Changed and trigger appropriate
16637
		// events.
16638
		if ( this !== this.currentContainer ) {
16639
			if ( !noPropagation ) {
16640
				delayedTriggers.push( function( event ) {
16641
					this._trigger( "remove", event, this._uiHash() );
16642
				} );
16643
				delayedTriggers.push( ( function( c ) {
16644
					return function( event ) {
16645
						c._trigger( "receive", event, this._uiHash( this ) );
16646
					};
16647
				} ).call( this, this.currentContainer ) );
16648
				delayedTriggers.push( ( function( c ) {
16649
					return function( event ) {
16650
						c._trigger( "update", event, this._uiHash( this ) );
16651
					};
16652
				} ).call( this, this.currentContainer ) );
16653
			}
16654
		}
16655
 
16656
		//Post events to containers
16657
		function delayEvent( type, instance, container ) {
16658
			return function( event ) {
16659
				container._trigger( type, event, instance._uiHash( instance ) );
16660
			};
16661
		}
16662
		for ( i = this.containers.length - 1; i >= 0; i-- ) {
16663
			if ( !noPropagation ) {
16664
				delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
16665
			}
16666
			if ( this.containers[ i ].containerCache.over ) {
16667
				delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
16668
				this.containers[ i ].containerCache.over = 0;
16669
			}
16670
		}
16671
 
16672
		//Do what was originally in plugins
16673
		if ( this.storedCursor ) {
16674
			this.document.find( "body" ).css( "cursor", this.storedCursor );
16675
			this.storedStylesheet.remove();
16676
		}
16677
		if ( this._storedOpacity ) {
16678
			this.helper.css( "opacity", this._storedOpacity );
16679
		}
16680
		if ( this._storedZIndex ) {
16681
			this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex );
16682
		}
16683
 
16684
		this.dragging = false;
16685
 
16686
		if ( !noPropagation ) {
16687
			this._trigger( "beforeStop", event, this._uiHash() );
16688
		}
16689
 
16690
		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
16691
		// it unbinds ALL events from the original node!
16692
		this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
16693
 
16694
		if ( !this.cancelHelperRemoval ) {
16695
			if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
16696
				this.helper.remove();
16697
			}
16698
			this.helper = null;
16699
		}
16700
 
16701
		if ( !noPropagation ) {
16702
			for ( i = 0; i < delayedTriggers.length; i++ ) {
16703
 
16704
				// Trigger all delayed events
16705
				delayedTriggers[ i ].call( this, event );
16706
			}
16707
			this._trigger( "stop", event, this._uiHash() );
16708
		}
16709
 
16710
		this.fromOutside = false;
16711
		return !this.cancelHelperRemoval;
16712
 
16713
	},
16714
 
16715
	_trigger: function() {
16716
		if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {
16717
			this.cancel();
16718
		}
16719
	},
16720
 
16721
	_uiHash: function( _inst ) {
16722
		var inst = _inst || this;
16723
		return {
16724
			helper: inst.helper,
16725
			placeholder: inst.placeholder || $( [] ),
16726
			position: inst.position,
16727
			originalPosition: inst.originalPosition,
16728
			offset: inst.positionAbs,
16729
			item: inst.currentItem,
16730
			sender: _inst ? _inst.element : null
16731
		};
16732
	}
16733
 
16734
} );
16735
 
16736
 
16737
/*!
16738
 * jQuery UI Spinner 1.12.1
16739
 * http://jqueryui.com
16740
 *
16741
 * Copyright jQuery Foundation and other contributors
16742
 * Released under the MIT license.
16743
 * http://jquery.org/license
16744
 */
16745
 
16746
//>>label: Spinner
16747
//>>group: Widgets
16748
//>>description: Displays buttons to easily input numbers via the keyboard or mouse.
16749
//>>docs: http://api.jqueryui.com/spinner/
16750
//>>demos: http://jqueryui.com/spinner/
16751
//>>css.structure: ../../themes/base/core.css
16752
//>>css.structure: ../../themes/base/spinner.css
16753
//>>css.theme: ../../themes/base/theme.css
16754
 
16755
 
16756
 
16757
function spinnerModifer( fn ) {
16758
	return function() {
16759
		var previous = this.element.val();
16760
		fn.apply( this, arguments );
16761
		this._refresh();
16762
		if ( previous !== this.element.val() ) {
16763
			this._trigger( "change" );
16764
		}
16765
	};
16766
}
16767
 
16768
$.widget( "ui.spinner", {
16769
	version: "1.12.1",
16770
	defaultElement: "<input>",
16771
	widgetEventPrefix: "spin",
16772
	options: {
16773
		classes: {
16774
			"ui-spinner": "ui-corner-all",
16775
			"ui-spinner-down": "ui-corner-br",
16776
			"ui-spinner-up": "ui-corner-tr"
16777
		},
16778
		culture: null,
16779
		icons: {
16780
			down: "ui-icon-triangle-1-s",
16781
			up: "ui-icon-triangle-1-n"
16782
		},
16783
		incremental: true,
16784
		max: null,
16785
		min: null,
16786
		numberFormat: null,
16787
		page: 10,
16788
		step: 1,
16789
 
16790
		change: null,
16791
		spin: null,
16792
		start: null,
16793
		stop: null
16794
	},
16795
 
16796
	_create: function() {
16797
 
16798
		// handle string values that need to be parsed
16799
		this._setOption( "max", this.options.max );
16800
		this._setOption( "min", this.options.min );
16801
		this._setOption( "step", this.options.step );
16802
 
16803
		// Only format if there is a value, prevents the field from being marked
16804
		// as invalid in Firefox, see #9573.
16805
		if ( this.value() !== "" ) {
16806
 
16807
			// Format the value, but don't constrain.
16808
			this._value( this.element.val(), true );
16809
		}
16810
 
16811
		this._draw();
16812
		this._on( this._events );
16813
		this._refresh();
16814
 
16815
		// Turning off autocomplete prevents the browser from remembering the
16816
		// value when navigating through history, so we re-enable autocomplete
16817
		// if the page is unloaded before the widget is destroyed. #7790
16818
		this._on( this.window, {
16819
			beforeunload: function() {
16820
				this.element.removeAttr( "autocomplete" );
16821
			}
16822
		} );
16823
	},
16824
 
16825
	_getCreateOptions: function() {
16826
		var options = this._super();
16827
		var element = this.element;
16828
 
16829
		$.each( [ "min", "max", "step" ], function( i, option ) {
16830
			var value = element.attr( option );
16831
			if ( value != null && value.length ) {
16832
				options[ option ] = value;
16833
			}
16834
		} );
16835
 
16836
		return options;
16837
	},
16838
 
16839
	_events: {
16840
		keydown: function( event ) {
16841
			if ( this._start( event ) && this._keydown( event ) ) {
16842
				event.preventDefault();
16843
			}
16844
		},
16845
		keyup: "_stop",
16846
		focus: function() {
16847
			this.previous = this.element.val();
16848
		},
16849
		blur: function( event ) {
16850
			if ( this.cancelBlur ) {
16851
				delete this.cancelBlur;
16852
				return;
16853
			}
16854
 
16855
			this._stop();
16856
			this._refresh();
16857
			if ( this.previous !== this.element.val() ) {
16858
				this._trigger( "change", event );
16859
			}
16860
		},
16861
		mousewheel: function( event, delta ) {
16862
			if ( !delta ) {
16863
				return;
16864
			}
16865
			if ( !this.spinning && !this._start( event ) ) {
16866
				return false;
16867
			}
16868
 
16869
			this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event );
16870
			clearTimeout( this.mousewheelTimer );
16871
			this.mousewheelTimer = this._delay( function() {
16872
				if ( this.spinning ) {
16873
					this._stop( event );
16874
				}
16875
			}, 100 );
16876
			event.preventDefault();
16877
		},
16878
		"mousedown .ui-spinner-button": function( event ) {
16879
			var previous;
16880
 
16881
			// We never want the buttons to have focus; whenever the user is
16882
			// interacting with the spinner, the focus should be on the input.
16883
			// If the input is focused then this.previous is properly set from
16884
			// when the input first received focus. If the input is not focused
16885
			// then we need to set this.previous based on the value before spinning.
16886
			previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ?
16887
				this.previous : this.element.val();
16888
			function checkFocus() {
16889
				var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] );
16890
				if ( !isActive ) {
16891
					this.element.trigger( "focus" );
16892
					this.previous = previous;
16893
 
16894
					// support: IE
16895
					// IE sets focus asynchronously, so we need to check if focus
16896
					// moved off of the input because the user clicked on the button.
16897
					this._delay( function() {
16898
						this.previous = previous;
16899
					} );
16900
				}
16901
			}
16902
 
16903
			// Ensure focus is on (or stays on) the text field
16904
			event.preventDefault();
16905
			checkFocus.call( this );
16906
 
16907
			// Support: IE
16908
			// IE doesn't prevent moving focus even with event.preventDefault()
16909
			// so we set a flag to know when we should ignore the blur event
16910
			// and check (again) if focus moved off of the input.
16911
			this.cancelBlur = true;
16912
			this._delay( function() {
16913
				delete this.cancelBlur;
16914
				checkFocus.call( this );
16915
			} );
16916
 
16917
			if ( this._start( event ) === false ) {
16918
				return;
16919
			}
16920
 
16921
			this._repeat( null, $( event.currentTarget )
16922
				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
16923
		},
16924
		"mouseup .ui-spinner-button": "_stop",
16925
		"mouseenter .ui-spinner-button": function( event ) {
16926
 
16927
			// button will add ui-state-active if mouse was down while mouseleave and kept down
16928
			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
16929
				return;
16930
			}
16931
 
16932
			if ( this._start( event ) === false ) {
16933
				return false;
16934
			}
16935
			this._repeat( null, $( event.currentTarget )
16936
				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
16937
		},
16938
 
16939
		// TODO: do we really want to consider this a stop?
16940
		// shouldn't we just stop the repeater and wait until mouseup before
16941
		// we trigger the stop event?
16942
		"mouseleave .ui-spinner-button": "_stop"
16943
	},
16944
 
16945
	// Support mobile enhanced option and make backcompat more sane
16946
	_enhance: function() {
16947
		this.uiSpinner = this.element
16948
			.attr( "autocomplete", "off" )
16949
			.wrap( "<span>" )
16950
			.parent()
16951
 
16952
				// Add buttons
16953
				.append(
16954
					"<a></a><a></a>"
16955
				);
16956
	},
16957
 
16958
	_draw: function() {
16959
		this._enhance();
16960
 
16961
		this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" );
16962
		this._addClass( "ui-spinner-input" );
16963
 
16964
		this.element.attr( "role", "spinbutton" );
16965
 
16966
		// Button bindings
16967
		this.buttons = this.uiSpinner.children( "a" )
16968
			.attr( "tabIndex", -1 )
16969
			.attr( "aria-hidden", true )
16970
			.button( {
16971
				classes: {
16972
					"ui-button": ""
16973
				}
16974
			} );
16975
 
16976
		// TODO: Right now button does not support classes this is already updated in button PR
16977
		this._removeClass( this.buttons, "ui-corner-all" );
16978
 
16979
		this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" );
16980
		this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" );
16981
		this.buttons.first().button( {
16982
			"icon": this.options.icons.up,
16983
			"showLabel": false
16984
		} );
16985
		this.buttons.last().button( {
16986
			"icon": this.options.icons.down,
16987
			"showLabel": false
16988
		} );
16989
 
16990
		// IE 6 doesn't understand height: 50% for the buttons
16991
		// unless the wrapper has an explicit height
16992
		if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) &&
16993
				this.uiSpinner.height() > 0 ) {
16994
			this.uiSpinner.height( this.uiSpinner.height() );
16995
		}
16996
	},
16997
 
16998
	_keydown: function( event ) {
16999
		var options = this.options,
17000
			keyCode = $.ui.keyCode;
17001
 
17002
		switch ( event.keyCode ) {
17003
		case keyCode.UP:
17004
			this._repeat( null, 1, event );
17005
			return true;
17006
		case keyCode.DOWN:
17007
			this._repeat( null, -1, event );
17008
			return true;
17009
		case keyCode.PAGE_UP:
17010
			this._repeat( null, options.page, event );
17011
			return true;
17012
		case keyCode.PAGE_DOWN:
17013
			this._repeat( null, -options.page, event );
17014
			return true;
17015
		}
17016
 
17017
		return false;
17018
	},
17019
 
17020
	_start: function( event ) {
17021
		if ( !this.spinning && this._trigger( "start", event ) === false ) {
17022
			return false;
17023
		}
17024
 
17025
		if ( !this.counter ) {
17026
			this.counter = 1;
17027
		}
17028
		this.spinning = true;
17029
		return true;
17030
	},
17031
 
17032
	_repeat: function( i, steps, event ) {
17033
		i = i || 500;
17034
 
17035
		clearTimeout( this.timer );
17036
		this.timer = this._delay( function() {
17037
			this._repeat( 40, steps, event );
17038
		}, i );
17039
 
17040
		this._spin( steps * this.options.step, event );
17041
	},
17042
 
17043
	_spin: function( step, event ) {
17044
		var value = this.value() || 0;
17045
 
17046
		if ( !this.counter ) {
17047
			this.counter = 1;
17048
		}
17049
 
17050
		value = this._adjustValue( value + step * this._increment( this.counter ) );
17051
 
17052
		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) {
17053
			this._value( value );
17054
			this.counter++;
17055
		}
17056
	},
17057
 
17058
	_increment: function( i ) {
17059
		var incremental = this.options.incremental;
17060
 
17061
		if ( incremental ) {
17062
			return $.isFunction( incremental ) ?
17063
				incremental( i ) :
17064
				Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
17065
		}
17066
 
17067
		return 1;
17068
	},
17069
 
17070
	_precision: function() {
17071
		var precision = this._precisionOf( this.options.step );
17072
		if ( this.options.min !== null ) {
17073
			precision = Math.max( precision, this._precisionOf( this.options.min ) );
17074
		}
17075
		return precision;
17076
	},
17077
 
17078
	_precisionOf: function( num ) {
17079
		var str = num.toString(),
17080
			decimal = str.indexOf( "." );
17081
		return decimal === -1 ? 0 : str.length - decimal - 1;
17082
	},
17083
 
17084
	_adjustValue: function( value ) {
17085
		var base, aboveMin,
17086
			options = this.options;
17087
 
17088
		// Make sure we're at a valid step
17089
		// - find out where we are relative to the base (min or 0)
17090
		base = options.min !== null ? options.min : 0;
17091
		aboveMin = value - base;
17092
 
17093
		// - round to the nearest step
17094
		aboveMin = Math.round( aboveMin / options.step ) * options.step;
17095
 
17096
		// - rounding is based on 0, so adjust back to our base
17097
		value = base + aboveMin;
17098
 
17099
		// Fix precision from bad JS floating point math
17100
		value = parseFloat( value.toFixed( this._precision() ) );
17101
 
17102
		// Clamp the value
17103
		if ( options.max !== null && value > options.max ) {
17104
			return options.max;
17105
		}
17106
		if ( options.min !== null && value < options.min ) {
17107
			return options.min;
17108
		}
17109
 
17110
		return value;
17111
	},
17112
 
17113
	_stop: function( event ) {
17114
		if ( !this.spinning ) {
17115
			return;
17116
		}
17117
 
17118
		clearTimeout( this.timer );
17119
		clearTimeout( this.mousewheelTimer );
17120
		this.counter = 0;
17121
		this.spinning = false;
17122
		this._trigger( "stop", event );
17123
	},
17124
 
17125
	_setOption: function( key, value ) {
17126
		var prevValue, first, last;
17127
 
17128
		if ( key === "culture" || key === "numberFormat" ) {
17129
			prevValue = this._parse( this.element.val() );
17130
			this.options[ key ] = value;
17131
			this.element.val( this._format( prevValue ) );
17132
			return;
17133
		}
17134
 
17135
		if ( key === "max" || key === "min" || key === "step" ) {
17136
			if ( typeof value === "string" ) {
17137
				value = this._parse( value );
17138
			}
17139
		}
17140
		if ( key === "icons" ) {
17141
			first = this.buttons.first().find( ".ui-icon" );
17142
			this._removeClass( first, null, this.options.icons.up );
17143
			this._addClass( first, null, value.up );
17144
			last = this.buttons.last().find( ".ui-icon" );
17145
			this._removeClass( last, null, this.options.icons.down );
17146
			this._addClass( last, null, value.down );
17147
		}
17148
 
17149
		this._super( key, value );
17150
	},
17151
 
17152
	_setOptionDisabled: function( value ) {
17153
		this._super( value );
17154
 
17155
		this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value );
17156
		this.element.prop( "disabled", !!value );
17157
		this.buttons.button( value ? "disable" : "enable" );
17158
	},
17159
 
17160
	_setOptions: spinnerModifer( function( options ) {
17161
		this._super( options );
17162
	} ),
17163
 
17164
	_parse: function( val ) {
17165
		if ( typeof val === "string" && val !== "" ) {
17166
			val = window.Globalize && this.options.numberFormat ?
17167
				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
17168
		}
17169
		return val === "" || isNaN( val ) ? null : val;
17170
	},
17171
 
17172
	_format: function( value ) {
17173
		if ( value === "" ) {
17174
			return "";
17175
		}
17176
		return window.Globalize && this.options.numberFormat ?
17177
			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
17178
			value;
17179
	},
17180
 
17181
	_refresh: function() {
17182
		this.element.attr( {
17183
			"aria-valuemin": this.options.min,
17184
			"aria-valuemax": this.options.max,
17185
 
17186
			// TODO: what should we do with values that can't be parsed?
17187
			"aria-valuenow": this._parse( this.element.val() )
17188
		} );
17189
	},
17190
 
17191
	isValid: function() {
17192
		var value = this.value();
17193
 
17194
		// Null is invalid
17195
		if ( value === null ) {
17196
			return false;
17197
		}
17198
 
17199
		// If value gets adjusted, it's invalid
17200
		return value === this._adjustValue( value );
17201
	},
17202
 
17203
	// Update the value without triggering change
17204
	_value: function( value, allowAny ) {
17205
		var parsed;
17206
		if ( value !== "" ) {
17207
			parsed = this._parse( value );
17208
			if ( parsed !== null ) {
17209
				if ( !allowAny ) {
17210
					parsed = this._adjustValue( parsed );
17211
				}
17212
				value = this._format( parsed );
17213
			}
17214
		}
17215
		this.element.val( value );
17216
		this._refresh();
17217
	},
17218
 
17219
	_destroy: function() {
17220
		this.element
17221
			.prop( "disabled", false )
17222
			.removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" );
17223
 
17224
		this.uiSpinner.replaceWith( this.element );
17225
	},
17226
 
17227
	stepUp: spinnerModifer( function( steps ) {
17228
		this._stepUp( steps );
17229
	} ),
17230
	_stepUp: function( steps ) {
17231
		if ( this._start() ) {
17232
			this._spin( ( steps || 1 ) * this.options.step );
17233
			this._stop();
17234
		}
17235
	},
17236
 
17237
	stepDown: spinnerModifer( function( steps ) {
17238
		this._stepDown( steps );
17239
	} ),
17240
	_stepDown: function( steps ) {
17241
		if ( this._start() ) {
17242
			this._spin( ( steps || 1 ) * -this.options.step );
17243
			this._stop();
17244
		}
17245
	},
17246
 
17247
	pageUp: spinnerModifer( function( pages ) {
17248
		this._stepUp( ( pages || 1 ) * this.options.page );
17249
	} ),
17250
 
17251
	pageDown: spinnerModifer( function( pages ) {
17252
		this._stepDown( ( pages || 1 ) * this.options.page );
17253
	} ),
17254
 
17255
	value: function( newVal ) {
17256
		if ( !arguments.length ) {
17257
			return this._parse( this.element.val() );
17258
		}
17259
		spinnerModifer( this._value ).call( this, newVal );
17260
	},
17261
 
17262
	widget: function() {
17263
		return this.uiSpinner;
17264
	}
17265
} );
17266
 
17267
// DEPRECATED
17268
// TODO: switch return back to widget declaration at top of file when this is removed
17269
if ( $.uiBackCompat !== false ) {
17270
 
17271
	// Backcompat for spinner html extension points
17272
	$.widget( "ui.spinner", $.ui.spinner, {
17273
		_enhance: function() {
17274
			this.uiSpinner = this.element
17275
				.attr( "autocomplete", "off" )
17276
				.wrap( this._uiSpinnerHtml() )
17277
				.parent()
17278
 
17279
					// Add buttons
17280
					.append( this._buttonHtml() );
17281
		},
17282
		_uiSpinnerHtml: function() {
17283
			return "<span>";
17284
		},
17285
 
17286
		_buttonHtml: function() {
17287
			return "<a></a><a></a>";
17288
		}
17289
	} );
17290
}
17291
 
17292
var widgetsSpinner = $.ui.spinner;
17293
 
17294
 
17295
/*!
17296
 * jQuery UI Tabs 1.12.1
17297
 * http://jqueryui.com
17298
 *
17299
 * Copyright jQuery Foundation and other contributors
17300
 * Released under the MIT license.
17301
 * http://jquery.org/license
17302
 */
17303
 
17304
//>>label: Tabs
17305
//>>group: Widgets
17306
//>>description: Transforms a set of container elements into a tab structure.
17307
//>>docs: http://api.jqueryui.com/tabs/
17308
//>>demos: http://jqueryui.com/tabs/
17309
//>>css.structure: ../../themes/base/core.css
17310
//>>css.structure: ../../themes/base/tabs.css
17311
//>>css.theme: ../../themes/base/theme.css
17312
 
17313
 
17314
 
17315
$.widget( "ui.tabs", {
17316
	version: "1.12.1",
17317
	delay: 300,
17318
	options: {
17319
		active: null,
17320
		classes: {
17321
			"ui-tabs": "ui-corner-all",
17322
			"ui-tabs-nav": "ui-corner-all",
17323
			"ui-tabs-panel": "ui-corner-bottom",
17324
			"ui-tabs-tab": "ui-corner-top"
17325
		},
17326
		collapsible: false,
17327
		event: "click",
17328
		heightStyle: "content",
17329
		hide: null,
17330
		show: null,
17331
 
17332
		// Callbacks
17333
		activate: null,
17334
		beforeActivate: null,
17335
		beforeLoad: null,
17336
		load: null
17337
	},
17338
 
17339
	_isLocal: ( function() {
17340
		var rhash = /#.*$/;
17341
 
17342
		return function( anchor ) {
17343
			var anchorUrl, locationUrl;
17344
 
17345
			anchorUrl = anchor.href.replace( rhash, "" );
17346
			locationUrl = location.href.replace( rhash, "" );
17347
 
17348
			// Decoding may throw an error if the URL isn't UTF-8 (#9518)
17349
			try {
17350
				anchorUrl = decodeURIComponent( anchorUrl );
17351
			} catch ( error ) {}
17352
			try {
17353
				locationUrl = decodeURIComponent( locationUrl );
17354
			} catch ( error ) {}
17355
 
17356
			return anchor.hash.length > 1 && anchorUrl === locationUrl;
17357
		};
17358
	} )(),
17359
 
17360
	_create: function() {
17361
		var that = this,
17362
			options = this.options;
17363
 
17364
		this.running = false;
17365
 
17366
		this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
17367
		this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
17368
 
17369
		this._processTabs();
17370
		options.active = this._initialActive();
17371
 
17372
		// Take disabling tabs via class attribute from HTML
17373
		// into account and update option properly.
17374
		if ( $.isArray( options.disabled ) ) {
17375
			options.disabled = $.unique( options.disabled.concat(
17376
				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
17377
					return that.tabs.index( li );
17378
				} )
17379
			) ).sort();
17380
		}
17381
 
17382
		// Check for length avoids error when initializing empty list
17383
		if ( this.options.active !== false && this.anchors.length ) {
17384
			this.active = this._findActive( options.active );
17385
		} else {
17386
			this.active = $();
17387
		}
17388
 
17389
		this._refresh();
17390
 
17391
		if ( this.active.length ) {
17392
			this.load( options.active );
17393
		}
17394
	},
17395
 
17396
	_initialActive: function() {
17397
		var active = this.options.active,
17398
			collapsible = this.options.collapsible,
17399
			locationHash = location.hash.substring( 1 );
17400
 
17401
		if ( active === null ) {
17402
 
17403
			// check the fragment identifier in the URL
17404
			if ( locationHash ) {
17405
				this.tabs.each( function( i, tab ) {
17406
					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
17407
						active = i;
17408
						return false;
17409
					}
17410
				} );
17411
			}
17412
 
17413
			// Check for a tab marked active via a class
17414
			if ( active === null ) {
17415
				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
17416
			}
17417
 
17418
			// No active tab, set to false
17419
			if ( active === null || active === -1 ) {
17420
				active = this.tabs.length ? 0 : false;
17421
			}
17422
		}
17423
 
17424
		// Handle numbers: negative, out of range
17425
		if ( active !== false ) {
17426
			active = this.tabs.index( this.tabs.eq( active ) );
17427
			if ( active === -1 ) {
17428
				active = collapsible ? false : 0;
17429
			}
17430
		}
17431
 
17432
		// Don't allow collapsible: false and active: false
17433
		if ( !collapsible && active === false && this.anchors.length ) {
17434
			active = 0;
17435
		}
17436
 
17437
		return active;
17438
	},
17439
 
17440
	_getCreateEventData: function() {
17441
		return {
17442
			tab: this.active,
17443
			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
17444
		};
17445
	},
17446
 
17447
	_tabKeydown: function( event ) {
17448
		var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ),
17449
			selectedIndex = this.tabs.index( focusedTab ),
17450
			goingForward = true;
17451
 
17452
		if ( this._handlePageNav( event ) ) {
17453
			return;
17454
		}
17455
 
17456
		switch ( event.keyCode ) {
17457
		case $.ui.keyCode.RIGHT:
17458
		case $.ui.keyCode.DOWN:
17459
			selectedIndex++;
17460
			break;
17461
		case $.ui.keyCode.UP:
17462
		case $.ui.keyCode.LEFT:
17463
			goingForward = false;
17464
			selectedIndex--;
17465
			break;
17466
		case $.ui.keyCode.END:
17467
			selectedIndex = this.anchors.length - 1;
17468
			break;
17469
		case $.ui.keyCode.HOME:
17470
			selectedIndex = 0;
17471
			break;
17472
		case $.ui.keyCode.SPACE:
17473
 
17474
			// Activate only, no collapsing
17475
			event.preventDefault();
17476
			clearTimeout( this.activating );
17477
			this._activate( selectedIndex );
17478
			return;
17479
		case $.ui.keyCode.ENTER:
17480
 
17481
			// Toggle (cancel delayed activation, allow collapsing)
17482
			event.preventDefault();
17483
			clearTimeout( this.activating );
17484
 
17485
			// Determine if we should collapse or activate
17486
			this._activate( selectedIndex === this.options.active ? false : selectedIndex );
17487
			return;
17488
		default:
17489
			return;
17490
		}
17491
 
17492
		// Focus the appropriate tab, based on which key was pressed
17493
		event.preventDefault();
17494
		clearTimeout( this.activating );
17495
		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
17496
 
17497
		// Navigating with control/command key will prevent automatic activation
17498
		if ( !event.ctrlKey && !event.metaKey ) {
17499
 
17500
			// Update aria-selected immediately so that AT think the tab is already selected.
17501
			// Otherwise AT may confuse the user by stating that they need to activate the tab,
17502
			// but the tab will already be activated by the time the announcement finishes.
17503
			focusedTab.attr( "aria-selected", "false" );
17504
			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
17505
 
17506
			this.activating = this._delay( function() {
17507
				this.option( "active", selectedIndex );
17508
			}, this.delay );
17509
		}
17510
	},
17511
 
17512
	_panelKeydown: function( event ) {
17513
		if ( this._handlePageNav( event ) ) {
17514
			return;
17515
		}
17516
 
17517
		// Ctrl+up moves focus to the current tab
17518
		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
17519
			event.preventDefault();
17520
			this.active.trigger( "focus" );
17521
		}
17522
	},
17523
 
17524
	// Alt+page up/down moves focus to the previous/next tab (and activates)
17525
	_handlePageNav: function( event ) {
17526
		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
17527
			this._activate( this._focusNextTab( this.options.active - 1, false ) );
17528
			return true;
17529
		}
17530
		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
17531
			this._activate( this._focusNextTab( this.options.active + 1, true ) );
17532
			return true;
17533
		}
17534
	},
17535
 
17536
	_findNextTab: function( index, goingForward ) {
17537
		var lastTabIndex = this.tabs.length - 1;
17538
 
17539
		function constrain() {
17540
			if ( index > lastTabIndex ) {
17541
				index = 0;
17542
			}
17543
			if ( index < 0 ) {
17544
				index = lastTabIndex;
17545
			}
17546
			return index;
17547
		}
17548
 
17549
		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
17550
			index = goingForward ? index + 1 : index - 1;
17551
		}
17552
 
17553
		return index;
17554
	},
17555
 
17556
	_focusNextTab: function( index, goingForward ) {
17557
		index = this._findNextTab( index, goingForward );
17558
		this.tabs.eq( index ).trigger( "focus" );
17559
		return index;
17560
	},
17561
 
17562
	_setOption: function( key, value ) {
17563
		if ( key === "active" ) {
17564
 
17565
			// _activate() will handle invalid values and update this.options
17566
			this._activate( value );
17567
			return;
17568
		}
17569
 
17570
		this._super( key, value );
17571
 
17572
		if ( key === "collapsible" ) {
17573
			this._toggleClass( "ui-tabs-collapsible", null, value );
17574
 
17575
			// Setting collapsible: false while collapsed; open first panel
17576
			if ( !value && this.options.active === false ) {
17577
				this._activate( 0 );
17578
			}
17579
		}
17580
 
17581
		if ( key === "event" ) {
17582
			this._setupEvents( value );
17583
		}
17584
 
17585
		if ( key === "heightStyle" ) {
17586
			this._setupHeightStyle( value );
17587
		}
17588
	},
17589
 
17590
	_sanitizeSelector: function( hash ) {
17591
		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
17592
	},
17593
 
17594
	refresh: function() {
17595
		var options = this.options,
17596
			lis = this.tablist.children( ":has(a[href])" );
17597
 
17598
		// Get disabled tabs from class attribute from HTML
17599
		// this will get converted to a boolean if needed in _refresh()
17600
		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
17601
			return lis.index( tab );
17602
		} );
17603
 
17604
		this._processTabs();
17605
 
17606
		// Was collapsed or no tabs
17607
		if ( options.active === false || !this.anchors.length ) {
17608
			options.active = false;
17609
			this.active = $();
17610
 
17611
		// was active, but active tab is gone
17612
		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
17613
 
17614
			// all remaining tabs are disabled
17615
			if ( this.tabs.length === options.disabled.length ) {
17616
				options.active = false;
17617
				this.active = $();
17618
 
17619
			// activate previous tab
17620
			} else {
17621
				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
17622
			}
17623
 
17624
		// was active, active tab still exists
17625
		} else {
17626
 
17627
			// make sure active index is correct
17628
			options.active = this.tabs.index( this.active );
17629
		}
17630
 
17631
		this._refresh();
17632
	},
17633
 
17634
	_refresh: function() {
17635
		this._setOptionDisabled( this.options.disabled );
17636
		this._setupEvents( this.options.event );
17637
		this._setupHeightStyle( this.options.heightStyle );
17638
 
17639
		this.tabs.not( this.active ).attr( {
17640
			"aria-selected": "false",
17641
			"aria-expanded": "false",
17642
			tabIndex: -1
17643
		} );
17644
		this.panels.not( this._getPanelForTab( this.active ) )
17645
			.hide()
17646
			.attr( {
17647
				"aria-hidden": "true"
17648
			} );
17649
 
17650
		// Make sure one tab is in the tab order
17651
		if ( !this.active.length ) {
17652
			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
17653
		} else {
17654
			this.active
17655
				.attr( {
17656
					"aria-selected": "true",
17657
					"aria-expanded": "true",
17658
					tabIndex: 0
17659
				} );
17660
			this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
17661
			this._getPanelForTab( this.active )
17662
				.show()
17663
				.attr( {
17664
					"aria-hidden": "false"
17665
				} );
17666
		}
17667
	},
17668
 
17669
	_processTabs: function() {
17670
		var that = this,
17671
			prevTabs = this.tabs,
17672
			prevAnchors = this.anchors,
17673
			prevPanels = this.panels;
17674
 
17675
		this.tablist = this._getList().attr( "role", "tablist" );
17676
		this._addClass( this.tablist, "ui-tabs-nav",
17677
			"ui-helper-reset ui-helper-clearfix ui-widget-header" );
17678
 
17679
		// Prevent users from focusing disabled tabs via click
17680
		this.tablist
17681
			.on( "mousedown" + this.eventNamespace, "> li", function( event ) {
17682
				if ( $( this ).is( ".ui-state-disabled" ) ) {
17683
					event.preventDefault();
17684
				}
17685
			} )
17686
 
17687
			// Support: IE <9
17688
			// Preventing the default action in mousedown doesn't prevent IE
17689
			// from focusing the element, so if the anchor gets focused, blur.
17690
			// We don't have to worry about focusing the previously focused
17691
			// element since clicking on a non-focusable element should focus
17692
			// the body anyway.
17693
			.on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() {
17694
				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
17695
					this.blur();
17696
				}
17697
			} );
17698
 
17699
		this.tabs = this.tablist.find( "> li:has(a[href])" )
17700
			.attr( {
17701
				role: "tab",
17702
				tabIndex: -1
17703
			} );
17704
		this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" );
17705
 
17706
		this.anchors = this.tabs.map( function() {
17707
			return $( "a", this )[ 0 ];
17708
		} )
17709
			.attr( {
17710
				role: "presentation",
17711
				tabIndex: -1
17712
			} );
17713
		this._addClass( this.anchors, "ui-tabs-anchor" );
17714
 
17715
		this.panels = $();
17716
 
17717
		this.anchors.each( function( i, anchor ) {
17718
			var selector, panel, panelId,
17719
				anchorId = $( anchor ).uniqueId().attr( "id" ),
17720
				tab = $( anchor ).closest( "li" ),
17721
				originalAriaControls = tab.attr( "aria-controls" );
17722
 
17723
			// Inline tab
17724
			if ( that._isLocal( anchor ) ) {
17725
				selector = anchor.hash;
17726
				panelId = selector.substring( 1 );
17727
				panel = that.element.find( that._sanitizeSelector( selector ) );
17728
 
17729
			// remote tab
17730
			} else {
17731
 
17732
				// If the tab doesn't already have aria-controls,
17733
				// generate an id by using a throw-away element
17734
				panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
17735
				selector = "#" + panelId;
17736
				panel = that.element.find( selector );
17737
				if ( !panel.length ) {
17738
					panel = that._createPanel( panelId );
17739
					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
17740
				}
17741
				panel.attr( "aria-live", "polite" );
17742
			}
17743
 
17744
			if ( panel.length ) {
17745
				that.panels = that.panels.add( panel );
17746
			}
17747
			if ( originalAriaControls ) {
17748
				tab.data( "ui-tabs-aria-controls", originalAriaControls );
17749
			}
17750
			tab.attr( {
17751
				"aria-controls": panelId,
17752
				"aria-labelledby": anchorId
17753
			} );
17754
			panel.attr( "aria-labelledby", anchorId );
17755
		} );
17756
 
17757
		this.panels.attr( "role", "tabpanel" );
17758
		this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
17759
 
17760
		// Avoid memory leaks (#10056)
17761
		if ( prevTabs ) {
17762
			this._off( prevTabs.not( this.tabs ) );
17763
			this._off( prevAnchors.not( this.anchors ) );
17764
			this._off( prevPanels.not( this.panels ) );
17765
		}
17766
	},
17767
 
17768
	// Allow overriding how to find the list for rare usage scenarios (#7715)
17769
	_getList: function() {
17770
		return this.tablist || this.element.find( "ol, ul" ).eq( 0 );
17771
	},
17772
 
17773
	_createPanel: function( id ) {
17774
		return $( "<div>" )
17775
			.attr( "id", id )
17776
			.data( "ui-tabs-destroy", true );
17777
	},
17778
 
17779
	_setOptionDisabled: function( disabled ) {
17780
		var currentItem, li, i;
17781
 
17782
		if ( $.isArray( disabled ) ) {
17783
			if ( !disabled.length ) {
17784
				disabled = false;
17785
			} else if ( disabled.length === this.anchors.length ) {
17786
				disabled = true;
17787
			}
17788
		}
17789
 
17790
		// Disable tabs
17791
		for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
17792
			currentItem = $( li );
17793
			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
17794
				currentItem.attr( "aria-disabled", "true" );
17795
				this._addClass( currentItem, null, "ui-state-disabled" );
17796
			} else {
17797
				currentItem.removeAttr( "aria-disabled" );
17798
				this._removeClass( currentItem, null, "ui-state-disabled" );
17799
			}
17800
		}
17801
 
17802
		this.options.disabled = disabled;
17803
 
17804
		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null,
17805
			disabled === true );
17806
	},
17807
 
17808
	_setupEvents: function( event ) {
17809
		var events = {};
17810
		if ( event ) {
17811
			$.each( event.split( " " ), function( index, eventName ) {
17812
				events[ eventName ] = "_eventHandler";
17813
			} );
17814
		}
17815
 
17816
		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
17817
 
17818
		// Always prevent the default action, even when disabled
17819
		this._on( true, this.anchors, {
17820
			click: function( event ) {
17821
				event.preventDefault();
17822
			}
17823
		} );
17824
		this._on( this.anchors, events );
17825
		this._on( this.tabs, { keydown: "_tabKeydown" } );
17826
		this._on( this.panels, { keydown: "_panelKeydown" } );
17827
 
17828
		this._focusable( this.tabs );
17829
		this._hoverable( this.tabs );
17830
	},
17831
 
17832
	_setupHeightStyle: function( heightStyle ) {
17833
		var maxHeight,
17834
			parent = this.element.parent();
17835
 
17836
		if ( heightStyle === "fill" ) {
17837
			maxHeight = parent.height();
17838
			maxHeight -= this.element.outerHeight() - this.element.height();
17839
 
17840
			this.element.siblings( ":visible" ).each( function() {
17841
				var elem = $( this ),
17842
					position = elem.css( "position" );
17843
 
17844
				if ( position === "absolute" || position === "fixed" ) {
17845
					return;
17846
				}
17847
				maxHeight -= elem.outerHeight( true );
17848
			} );
17849
 
17850
			this.element.children().not( this.panels ).each( function() {
17851
				maxHeight -= $( this ).outerHeight( true );
17852
			} );
17853
 
17854
			this.panels.each( function() {
17855
				$( this ).height( Math.max( 0, maxHeight -
17856
					$( this ).innerHeight() + $( this ).height() ) );
17857
			} )
17858
				.css( "overflow", "auto" );
17859
		} else if ( heightStyle === "auto" ) {
17860
			maxHeight = 0;
17861
			this.panels.each( function() {
17862
				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
17863
			} ).height( maxHeight );
17864
		}
17865
	},
17866
 
17867
	_eventHandler: function( event ) {
17868
		var options = this.options,
17869
			active = this.active,
17870
			anchor = $( event.currentTarget ),
17871
			tab = anchor.closest( "li" ),
17872
			clickedIsActive = tab[ 0 ] === active[ 0 ],
17873
			collapsing = clickedIsActive && options.collapsible,
17874
			toShow = collapsing ? $() : this._getPanelForTab( tab ),
17875
			toHide = !active.length ? $() : this._getPanelForTab( active ),
17876
			eventData = {
17877
				oldTab: active,
17878
				oldPanel: toHide,
17879
				newTab: collapsing ? $() : tab,
17880
				newPanel: toShow
17881
			};
17882
 
17883
		event.preventDefault();
17884
 
17885
		if ( tab.hasClass( "ui-state-disabled" ) ||
17886
 
17887
				// tab is already loading
17888
				tab.hasClass( "ui-tabs-loading" ) ||
17889
 
17890
				// can't switch durning an animation
17891
				this.running ||
17892
 
17893
				// click on active header, but not collapsible
17894
				( clickedIsActive && !options.collapsible ) ||
17895
 
17896
				// allow canceling activation
17897
				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
17898
			return;
17899
		}
17900
 
17901
		options.active = collapsing ? false : this.tabs.index( tab );
17902
 
17903
		this.active = clickedIsActive ? $() : tab;
17904
		if ( this.xhr ) {
17905
			this.xhr.abort();
17906
		}
17907
 
17908
		if ( !toHide.length && !toShow.length ) {
17909
			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
17910
		}
17911
 
17912
		if ( toShow.length ) {
17913
			this.load( this.tabs.index( tab ), event );
17914
		}
17915
		this._toggle( event, eventData );
17916
	},
17917
 
17918
	// Handles show/hide for selecting tabs
17919
	_toggle: function( event, eventData ) {
17920
		var that = this,
17921
			toShow = eventData.newPanel,
17922
			toHide = eventData.oldPanel;
17923
 
17924
		this.running = true;
17925
 
17926
		function complete() {
17927
			that.running = false;
17928
			that._trigger( "activate", event, eventData );
17929
		}
17930
 
17931
		function show() {
17932
			that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
17933
 
17934
			if ( toShow.length && that.options.show ) {
17935
				that._show( toShow, that.options.show, complete );
17936
			} else {
17937
				toShow.show();
17938
				complete();
17939
			}
17940
		}
17941
 
17942
		// Start out by hiding, then showing, then completing
17943
		if ( toHide.length && this.options.hide ) {
17944
			this._hide( toHide, this.options.hide, function() {
17945
				that._removeClass( eventData.oldTab.closest( "li" ),
17946
					"ui-tabs-active", "ui-state-active" );
17947
				show();
17948
			} );
17949
		} else {
17950
			this._removeClass( eventData.oldTab.closest( "li" ),
17951
				"ui-tabs-active", "ui-state-active" );
17952
			toHide.hide();
17953
			show();
17954
		}
17955
 
17956
		toHide.attr( "aria-hidden", "true" );
17957
		eventData.oldTab.attr( {
17958
			"aria-selected": "false",
17959
			"aria-expanded": "false"
17960
		} );
17961
 
17962
		// If we're switching tabs, remove the old tab from the tab order.
17963
		// If we're opening from collapsed state, remove the previous tab from the tab order.
17964
		// If we're collapsing, then keep the collapsing tab in the tab order.
17965
		if ( toShow.length && toHide.length ) {
17966
			eventData.oldTab.attr( "tabIndex", -1 );
17967
		} else if ( toShow.length ) {
17968
			this.tabs.filter( function() {
17969
				return $( this ).attr( "tabIndex" ) === 0;
17970
			} )
17971
				.attr( "tabIndex", -1 );
17972
		}
17973
 
17974
		toShow.attr( "aria-hidden", "false" );
17975
		eventData.newTab.attr( {
17976
			"aria-selected": "true",
17977
			"aria-expanded": "true",
17978
			tabIndex: 0
17979
		} );
17980
	},
17981
 
17982
	_activate: function( index ) {
17983
		var anchor,
17984
			active = this._findActive( index );
17985
 
17986
		// Trying to activate the already active panel
17987
		if ( active[ 0 ] === this.active[ 0 ] ) {
17988
			return;
17989
		}
17990
 
17991
		// Trying to collapse, simulate a click on the current active header
17992
		if ( !active.length ) {
17993
			active = this.active;
17994
		}
17995
 
17996
		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
17997
		this._eventHandler( {
17998
			target: anchor,
17999
			currentTarget: anchor,
18000
			preventDefault: $.noop
18001
		} );
18002
	},
18003
 
18004
	_findActive: function( index ) {
18005
		return index === false ? $() : this.tabs.eq( index );
18006
	},
18007
 
18008
	_getIndex: function( index ) {
18009
 
18010
		// meta-function to give users option to provide a href string instead of a numerical index.
18011
		if ( typeof index === "string" ) {
18012
			index = this.anchors.index( this.anchors.filter( "[href$='" +
18013
				$.ui.escapeSelector( index ) + "']" ) );
18014
		}
18015
 
18016
		return index;
18017
	},
18018
 
18019
	_destroy: function() {
18020
		if ( this.xhr ) {
18021
			this.xhr.abort();
18022
		}
18023
 
18024
		this.tablist
18025
			.removeAttr( "role" )
18026
			.off( this.eventNamespace );
18027
 
18028
		this.anchors
18029
			.removeAttr( "role tabIndex" )
18030
			.removeUniqueId();
18031
 
18032
		this.tabs.add( this.panels ).each( function() {
18033
			if ( $.data( this, "ui-tabs-destroy" ) ) {
18034
				$( this ).remove();
18035
			} else {
18036
				$( this ).removeAttr( "role tabIndex " +
18037
					"aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" );
18038
			}
18039
		} );
18040
 
18041
		this.tabs.each( function() {
18042
			var li = $( this ),
18043
				prev = li.data( "ui-tabs-aria-controls" );
18044
			if ( prev ) {
18045
				li
18046
					.attr( "aria-controls", prev )
18047
					.removeData( "ui-tabs-aria-controls" );
18048
			} else {
18049
				li.removeAttr( "aria-controls" );
18050
			}
18051
		} );
18052
 
18053
		this.panels.show();
18054
 
18055
		if ( this.options.heightStyle !== "content" ) {
18056
			this.panels.css( "height", "" );
18057
		}
18058
	},
18059
 
18060
	enable: function( index ) {
18061
		var disabled = this.options.disabled;
18062
		if ( disabled === false ) {
18063
			return;
18064
		}
18065
 
18066
		if ( index === undefined ) {
18067
			disabled = false;
18068
		} else {
18069
			index = this._getIndex( index );
18070
			if ( $.isArray( disabled ) ) {
18071
				disabled = $.map( disabled, function( num ) {
18072
					return num !== index ? num : null;
18073
				} );
18074
			} else {
18075
				disabled = $.map( this.tabs, function( li, num ) {
18076
					return num !== index ? num : null;
18077
				} );
18078
			}
18079
		}
18080
		this._setOptionDisabled( disabled );
18081
	},
18082
 
18083
	disable: function( index ) {
18084
		var disabled = this.options.disabled;
18085
		if ( disabled === true ) {
18086
			return;
18087
		}
18088
 
18089
		if ( index === undefined ) {
18090
			disabled = true;
18091
		} else {
18092
			index = this._getIndex( index );
18093
			if ( $.inArray( index, disabled ) !== -1 ) {
18094
				return;
18095
			}
18096
			if ( $.isArray( disabled ) ) {
18097
				disabled = $.merge( [ index ], disabled ).sort();
18098
			} else {
18099
				disabled = [ index ];
18100
			}
18101
		}
18102
		this._setOptionDisabled( disabled );
18103
	},
18104
 
18105
	load: function( index, event ) {
18106
		index = this._getIndex( index );
18107
		var that = this,
18108
			tab = this.tabs.eq( index ),
18109
			anchor = tab.find( ".ui-tabs-anchor" ),
18110
			panel = this._getPanelForTab( tab ),
18111
			eventData = {
18112
				tab: tab,
18113
				panel: panel
18114
			},
18115
			complete = function( jqXHR, status ) {
18116
				if ( status === "abort" ) {
18117
					that.panels.stop( false, true );
18118
				}
18119
 
18120
				that._removeClass( tab, "ui-tabs-loading" );
18121
				panel.removeAttr( "aria-busy" );
18122
 
18123
				if ( jqXHR === that.xhr ) {
18124
					delete that.xhr;
18125
				}
18126
			};
18127
 
18128
		// Not remote
18129
		if ( this._isLocal( anchor[ 0 ] ) ) {
18130
			return;
18131
		}
18132
 
18133
		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
18134
 
18135
		// Support: jQuery <1.8
18136
		// jQuery <1.8 returns false if the request is canceled in beforeSend,
18137
		// but as of 1.8, $.ajax() always returns a jqXHR object.
18138
		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
18139
			this._addClass( tab, "ui-tabs-loading" );
18140
			panel.attr( "aria-busy", "true" );
18141
 
18142
			this.xhr
18143
				.done( function( response, status, jqXHR ) {
18144
 
18145
					// support: jQuery <1.8
18146
					// http://bugs.jquery.com/ticket/11778
18147
					setTimeout( function() {
18148
						panel.html( response );
18149
						that._trigger( "load", event, eventData );
18150
 
18151
						complete( jqXHR, status );
18152
					}, 1 );
18153
				} )
18154
				.fail( function( jqXHR, status ) {
18155
 
18156
					// support: jQuery <1.8
18157
					// http://bugs.jquery.com/ticket/11778
18158
					setTimeout( function() {
18159
						complete( jqXHR, status );
18160
					}, 1 );
18161
				} );
18162
		}
18163
	},
18164
 
18165
	_ajaxSettings: function( anchor, event, eventData ) {
18166
		var that = this;
18167
		return {
18168
 
18169
			// Support: IE <11 only
18170
			// Strip any hash that exists to prevent errors with the Ajax request
18171
			url: anchor.attr( "href" ).replace( /#.*$/, "" ),
18172
			beforeSend: function( jqXHR, settings ) {
18173
				return that._trigger( "beforeLoad", event,
18174
					$.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
18175
			}
18176
		};
18177
	},
18178
 
18179
	_getPanelForTab: function( tab ) {
18180
		var id = $( tab ).attr( "aria-controls" );
18181
		return this.element.find( this._sanitizeSelector( "#" + id ) );
18182
	}
18183
} );
18184
 
18185
// DEPRECATED
18186
// TODO: Switch return back to widget declaration at top of file when this is removed
18187
if ( $.uiBackCompat !== false ) {
18188
 
18189
	// Backcompat for ui-tab class (now ui-tabs-tab)
18190
	$.widget( "ui.tabs", $.ui.tabs, {
18191
		_processTabs: function() {
18192
			this._superApply( arguments );
18193
			this._addClass( this.tabs, "ui-tab" );
18194
		}
18195
	} );
18196
}
18197
 
18198
var widgetsTabs = $.ui.tabs;
18199
 
18200
 
18201
/*!
18202
 * jQuery UI Tooltip 1.12.1
18203
 * http://jqueryui.com
18204
 *
18205
 * Copyright jQuery Foundation and other contributors
18206
 * Released under the MIT license.
18207
 * http://jquery.org/license
18208
 */
18209
 
18210
//>>label: Tooltip
18211
//>>group: Widgets
18212
//>>description: Shows additional information for any element on hover or focus.
18213
//>>docs: http://api.jqueryui.com/tooltip/
18214
//>>demos: http://jqueryui.com/tooltip/
18215
//>>css.structure: ../../themes/base/core.css
18216
//>>css.structure: ../../themes/base/tooltip.css
18217
//>>css.theme: ../../themes/base/theme.css
18218
 
18219
 
18220
 
18221
$.widget( "ui.tooltip", {
18222
	version: "1.12.1",
18223
	options: {
18224
		classes: {
18225
			"ui-tooltip": "ui-corner-all ui-widget-shadow"
18226
		},
18227
		content: function() {
18228
 
18229
			// support: IE<9, Opera in jQuery <1.7
18230
			// .text() can't accept undefined, so coerce to a string
18231
			var title = $( this ).attr( "title" ) || "";
18232
 
18233
			// Escape title, since we're going from an attribute to raw HTML
18234
			return $( "<a>" ).text( title ).html();
18235
		},
18236
		hide: true,
18237
 
18238
		// Disabled elements have inconsistent behavior across browsers (#8661)
18239
		items: "[title]:not([disabled])",
18240
		position: {
18241
			my: "left top+15",
18242
			at: "left bottom",
18243
			collision: "flipfit flip"
18244
		},
18245
		show: true,
18246
		track: false,
18247
 
18248
		// Callbacks
18249
		close: null,
18250
		open: null
18251
	},
18252
 
18253
	_addDescribedBy: function( elem, id ) {
18254
		var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ );
18255
		describedby.push( id );
18256
		elem
18257
			.data( "ui-tooltip-id", id )
18258
			.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
18259
	},
18260
 
18261
	_removeDescribedBy: function( elem ) {
18262
		var id = elem.data( "ui-tooltip-id" ),
18263
			describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ),
18264
			index = $.inArray( id, describedby );
18265
 
18266
		if ( index !== -1 ) {
18267
			describedby.splice( index, 1 );
18268
		}
18269
 
18270
		elem.removeData( "ui-tooltip-id" );
18271
		describedby = $.trim( describedby.join( " " ) );
18272
		if ( describedby ) {
18273
			elem.attr( "aria-describedby", describedby );
18274
		} else {
18275
			elem.removeAttr( "aria-describedby" );
18276
		}
18277
	},
18278
 
18279
	_create: function() {
18280
		this._on( {
18281
			mouseover: "open",
18282
			focusin: "open"
18283
		} );
18284
 
18285
		// IDs of generated tooltips, needed for destroy
18286
		this.tooltips = {};
18287
 
18288
		// IDs of parent tooltips where we removed the title attribute
18289
		this.parents = {};
18290
 
18291
		// Append the aria-live region so tooltips announce correctly
18292
		this.liveRegion = $( "<div>" )
18293
			.attr( {
18294
				role: "log",
18295
				"aria-live": "assertive",
18296
				"aria-relevant": "additions"
18297
			} )
18298
			.appendTo( this.document[ 0 ].body );
18299
		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
18300
 
18301
		this.disabledTitles = $( [] );
18302
	},
18303
 
18304
	_setOption: function( key, value ) {
18305
		var that = this;
18306
 
18307
		this._super( key, value );
18308
 
18309
		if ( key === "content" ) {
18310
			$.each( this.tooltips, function( id, tooltipData ) {
18311
				that._updateContent( tooltipData.element );
18312
			} );
18313
		}
18314
	},
18315
 
18316
	_setOptionDisabled: function( value ) {
18317
		this[ value ? "_disable" : "_enable" ]();
18318
	},
18319
 
18320
	_disable: function() {
18321
		var that = this;
18322
 
18323
		// Close open tooltips
18324
		$.each( this.tooltips, function( id, tooltipData ) {
18325
			var event = $.Event( "blur" );
18326
			event.target = event.currentTarget = tooltipData.element[ 0 ];
18327
			that.close( event, true );
18328
		} );
18329
 
18330
		// Remove title attributes to prevent native tooltips
18331
		this.disabledTitles = this.disabledTitles.add(
18332
			this.element.find( this.options.items ).addBack()
18333
				.filter( function() {
18334
					var element = $( this );
18335
					if ( element.is( "[title]" ) ) {
18336
						return element
18337
							.data( "ui-tooltip-title", element.attr( "title" ) )
18338
							.removeAttr( "title" );
18339
					}
18340
				} )
18341
		);
18342
	},
18343
 
18344
	_enable: function() {
18345
 
18346
		// restore title attributes
18347
		this.disabledTitles.each( function() {
18348
			var element = $( this );
18349
			if ( element.data( "ui-tooltip-title" ) ) {
18350
				element.attr( "title", element.data( "ui-tooltip-title" ) );
18351
			}
18352
		} );
18353
		this.disabledTitles = $( [] );
18354
	},
18355
 
18356
	open: function( event ) {
18357
		var that = this,
18358
			target = $( event ? event.target : this.element )
18359
 
18360
				// we need closest here due to mouseover bubbling,
18361
				// but always pointing at the same event target
18362
				.closest( this.options.items );
18363
 
18364
		// No element to show a tooltip for or the tooltip is already open
18365
		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
18366
			return;
18367
		}
18368
 
18369
		if ( target.attr( "title" ) ) {
18370
			target.data( "ui-tooltip-title", target.attr( "title" ) );
18371
		}
18372
 
18373
		target.data( "ui-tooltip-open", true );
18374
 
18375
		// Kill parent tooltips, custom or native, for hover
18376
		if ( event && event.type === "mouseover" ) {
18377
			target.parents().each( function() {
18378
				var parent = $( this ),
18379
					blurEvent;
18380
				if ( parent.data( "ui-tooltip-open" ) ) {
18381
					blurEvent = $.Event( "blur" );
18382
					blurEvent.target = blurEvent.currentTarget = this;
18383
					that.close( blurEvent, true );
18384
				}
18385
				if ( parent.attr( "title" ) ) {
18386
					parent.uniqueId();
18387
					that.parents[ this.id ] = {
18388
						element: this,
18389
						title: parent.attr( "title" )
18390
					};
18391
					parent.attr( "title", "" );
18392
				}
18393
			} );
18394
		}
18395
 
18396
		this._registerCloseHandlers( event, target );
18397
		this._updateContent( target, event );
18398
	},
18399
 
18400
	_updateContent: function( target, event ) {
18401
		var content,
18402
			contentOption = this.options.content,
18403
			that = this,
18404
			eventType = event ? event.type : null;
18405
 
18406
		if ( typeof contentOption === "string" || contentOption.nodeType ||
18407
				contentOption.jquery ) {
18408
			return this._open( event, target, contentOption );
18409
		}
18410
 
18411
		content = contentOption.call( target[ 0 ], function( response ) {
18412
 
18413
			// IE may instantly serve a cached response for ajax requests
18414
			// delay this call to _open so the other call to _open runs first
18415
			that._delay( function() {
18416
 
18417
				// Ignore async response if tooltip was closed already
18418
				if ( !target.data( "ui-tooltip-open" ) ) {
18419
					return;
18420
				}
18421
 
18422
				// JQuery creates a special event for focusin when it doesn't
18423
				// exist natively. To improve performance, the native event
18424
				// object is reused and the type is changed. Therefore, we can't
18425
				// rely on the type being correct after the event finished
18426
				// bubbling, so we set it back to the previous value. (#8740)
18427
				if ( event ) {
18428
					event.type = eventType;
18429
				}
18430
				this._open( event, target, response );
18431
			} );
18432
		} );
18433
		if ( content ) {
18434
			this._open( event, target, content );
18435
		}
18436
	},
18437
 
18438
	_open: function( event, target, content ) {
18439
		var tooltipData, tooltip, delayedShow, a11yContent,
18440
			positionOption = $.extend( {}, this.options.position );
18441
 
18442
		if ( !content ) {
18443
			return;
18444
		}
18445
 
18446
		// Content can be updated multiple times. If the tooltip already
18447
		// exists, then just update the content and bail.
18448
		tooltipData = this._find( target );
18449
		if ( tooltipData ) {
18450
			tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
18451
			return;
18452
		}
18453
 
18454
		// If we have a title, clear it to prevent the native tooltip
18455
		// we have to check first to avoid defining a title if none exists
18456
		// (we don't want to cause an element to start matching [title])
18457
		//
18458
		// We use removeAttr only for key events, to allow IE to export the correct
18459
		// accessible attributes. For mouse events, set to empty string to avoid
18460
		// native tooltip showing up (happens only when removing inside mouseover).
18461
		if ( target.is( "[title]" ) ) {
18462
			if ( event && event.type === "mouseover" ) {
18463
				target.attr( "title", "" );
18464
			} else {
18465
				target.removeAttr( "title" );
18466
			}
18467
		}
18468
 
18469
		tooltipData = this._tooltip( target );
18470
		tooltip = tooltipData.tooltip;
18471
		this._addDescribedBy( target, tooltip.attr( "id" ) );
18472
		tooltip.find( ".ui-tooltip-content" ).html( content );
18473
 
18474
		// Support: Voiceover on OS X, JAWS on IE <= 9
18475
		// JAWS announces deletions even when aria-relevant="additions"
18476
		// Voiceover will sometimes re-read the entire log region's contents from the beginning
18477
		this.liveRegion.children().hide();
18478
		a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() );
18479
		a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" );
18480
		a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
18481
		a11yContent.appendTo( this.liveRegion );
18482
 
18483
		function position( event ) {
18484
			positionOption.of = event;
18485
			if ( tooltip.is( ":hidden" ) ) {
18486
				return;
18487
			}
18488
			tooltip.position( positionOption );
18489
		}
18490
		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
18491
			this._on( this.document, {
18492
				mousemove: position
18493
			} );
18494
 
18495
			// trigger once to override element-relative positioning
18496
			position( event );
18497
		} else {
18498
			tooltip.position( $.extend( {
18499
				of: target
18500
			}, this.options.position ) );
18501
		}
18502
 
18503
		tooltip.hide();
18504
 
18505
		this._show( tooltip, this.options.show );
18506
 
18507
		// Handle tracking tooltips that are shown with a delay (#8644). As soon
18508
		// as the tooltip is visible, position the tooltip using the most recent
18509
		// event.
18510
		// Adds the check to add the timers only when both delay and track options are set (#14682)
18511
		if ( this.options.track && this.options.show && this.options.show.delay ) {
18512
			delayedShow = this.delayedShow = setInterval( function() {
18513
				if ( tooltip.is( ":visible" ) ) {
18514
					position( positionOption.of );
18515
					clearInterval( delayedShow );
18516
				}
18517
			}, $.fx.interval );
18518
		}
18519
 
18520
		this._trigger( "open", event, { tooltip: tooltip } );
18521
	},
18522
 
18523
	_registerCloseHandlers: function( event, target ) {
18524
		var events = {
18525
			keyup: function( event ) {
18526
				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
18527
					var fakeEvent = $.Event( event );
18528
					fakeEvent.currentTarget = target[ 0 ];
18529
					this.close( fakeEvent, true );
18530
				}
18531
			}
18532
		};
18533
 
18534
		// Only bind remove handler for delegated targets. Non-delegated
18535
		// tooltips will handle this in destroy.
18536
		if ( target[ 0 ] !== this.element[ 0 ] ) {
18537
			events.remove = function() {
18538
				this._removeTooltip( this._find( target ).tooltip );
18539
			};
18540
		}
18541
 
18542
		if ( !event || event.type === "mouseover" ) {
18543
			events.mouseleave = "close";
18544
		}
18545
		if ( !event || event.type === "focusin" ) {
18546
			events.focusout = "close";
18547
		}
18548
		this._on( true, target, events );
18549
	},
18550
 
18551
	close: function( event ) {
18552
		var tooltip,
18553
			that = this,
18554
			target = $( event ? event.currentTarget : this.element ),
18555
			tooltipData = this._find( target );
18556
 
18557
		// The tooltip may already be closed
18558
		if ( !tooltipData ) {
18559
 
18560
			// We set ui-tooltip-open immediately upon open (in open()), but only set the
18561
			// additional data once there's actually content to show (in _open()). So even if the
18562
			// tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
18563
			// the period between open() and _open().
18564
			target.removeData( "ui-tooltip-open" );
18565
			return;
18566
		}
18567
 
18568
		tooltip = tooltipData.tooltip;
18569
 
18570
		// Disabling closes the tooltip, so we need to track when we're closing
18571
		// to avoid an infinite loop in case the tooltip becomes disabled on close
18572
		if ( tooltipData.closing ) {
18573
			return;
18574
		}
18575
 
18576
		// Clear the interval for delayed tracking tooltips
18577
		clearInterval( this.delayedShow );
18578
 
18579
		// Only set title if we had one before (see comment in _open())
18580
		// If the title attribute has changed since open(), don't restore
18581
		if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
18582
			target.attr( "title", target.data( "ui-tooltip-title" ) );
18583
		}
18584
 
18585
		this._removeDescribedBy( target );
18586
 
18587
		tooltipData.hiding = true;
18588
		tooltip.stop( true );
18589
		this._hide( tooltip, this.options.hide, function() {
18590
			that._removeTooltip( $( this ) );
18591
		} );
18592
 
18593
		target.removeData( "ui-tooltip-open" );
18594
		this._off( target, "mouseleave focusout keyup" );
18595
 
18596
		// Remove 'remove' binding only on delegated targets
18597
		if ( target[ 0 ] !== this.element[ 0 ] ) {
18598
			this._off( target, "remove" );
18599
		}
18600
		this._off( this.document, "mousemove" );
18601
 
18602
		if ( event && event.type === "mouseleave" ) {
18603
			$.each( this.parents, function( id, parent ) {
18604
				$( parent.element ).attr( "title", parent.title );
18605
				delete that.parents[ id ];
18606
			} );
18607
		}
18608
 
18609
		tooltipData.closing = true;
18610
		this._trigger( "close", event, { tooltip: tooltip } );
18611
		if ( !tooltipData.hiding ) {
18612
			tooltipData.closing = false;
18613
		}
18614
	},
18615
 
18616
	_tooltip: function( element ) {
18617
		var tooltip = $( "<div>" ).attr( "role", "tooltip" ),
18618
			content = $( "<div>" ).appendTo( tooltip ),
18619
			id = tooltip.uniqueId().attr( "id" );
18620
 
18621
		this._addClass( content, "ui-tooltip-content" );
18622
		this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" );
18623
 
18624
		tooltip.appendTo( this._appendTo( element ) );
18625
 
18626
		return this.tooltips[ id ] = {
18627
			element: element,
18628
			tooltip: tooltip
18629
		};
18630
	},
18631
 
18632
	_find: function( target ) {
18633
		var id = target.data( "ui-tooltip-id" );
18634
		return id ? this.tooltips[ id ] : null;
18635
	},
18636
 
18637
	_removeTooltip: function( tooltip ) {
18638
		tooltip.remove();
18639
		delete this.tooltips[ tooltip.attr( "id" ) ];
18640
	},
18641
 
18642
	_appendTo: function( target ) {
18643
		var element = target.closest( ".ui-front, dialog" );
18644
 
18645
		if ( !element.length ) {
18646
			element = this.document[ 0 ].body;
18647
		}
18648
 
18649
		return element;
18650
	},
18651
 
18652
	_destroy: function() {
18653
		var that = this;
18654
 
18655
		// Close open tooltips
18656
		$.each( this.tooltips, function( id, tooltipData ) {
18657
 
18658
			// Delegate to close method to handle common cleanup
18659
			var event = $.Event( "blur" ),
18660
				element = tooltipData.element;
18661
			event.target = event.currentTarget = element[ 0 ];
18662
			that.close( event, true );
18663
 
18664
			// Remove immediately; destroying an open tooltip doesn't use the
18665
			// hide animation
18666
			$( "#" + id ).remove();
18667
 
18668
			// Restore the title
18669
			if ( element.data( "ui-tooltip-title" ) ) {
18670
 
18671
				// If the title attribute has changed since open(), don't restore
18672
				if ( !element.attr( "title" ) ) {
18673
					element.attr( "title", element.data( "ui-tooltip-title" ) );
18674
				}
18675
				element.removeData( "ui-tooltip-title" );
18676
			}
18677
		} );
18678
		this.liveRegion.remove();
18679
	}
18680
} );
18681
 
18682
// DEPRECATED
18683
// TODO: Switch return back to widget declaration at top of file when this is removed
18684
if ( $.uiBackCompat !== false ) {
18685
 
18686
	// Backcompat for tooltipClass option
18687
	$.widget( "ui.tooltip", $.ui.tooltip, {
18688
		options: {
18689
			tooltipClass: null
18690
		},
18691
		_tooltip: function() {
18692
			var tooltipData = this._superApply( arguments );
18693
			if ( this.options.tooltipClass ) {
18694
				tooltipData.tooltip.addClass( this.options.tooltipClass );
18695
			}
18696
			return tooltipData;
18697
		}
18698
	} );
18699
}
18700
 
18701
var widgetsTooltip = $.ui.tooltip;
18702
 
18703
 
18704
 
18705
 
18706
}));