Subversion-Projekte lars-tiefland.cienc

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
8 lars 1
/*! jQuery UI - v1.11.4 - 2016-03-17
2
* http://jqueryui.com
3
* Includes: core.js, widget.js, mouse.js, position.js, draggable.js, droppable.js, resizable.js, selectable.js, sortable.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, menu.js, progressbar.js, selectmenu.js, slider.js, spinner.js, tabs.js, tooltip.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js
4
* Copyright jQuery Foundation and other contributors; Licensed MIT */
5
 
6
(function( factory ) {
7
	if ( typeof define === "function" && define.amd ) {
8
 
9
		// AMD. Register as an anonymous module.
10
		define([ "jquery" ], factory );
11
	} else {
12
 
13
		// Browser globals
14
		factory( jQuery );
15
	}
16
}(function( $ ) {
17
/*!
18
 * jQuery UI Core 1.11.4
19
 * http://jqueryui.com
20
 *
21
 * Copyright jQuery Foundation and other contributors
22
 * Released under the MIT license.
23
 * http://jquery.org/license
24
 *
25
 * http://api.jqueryui.com/category/ui-core/
26
 */
27
 
28
 
29
// $.ui might exist from components with no dependencies, e.g., $.ui.position
30
$.ui = $.ui || {};
31
 
32
$.extend( $.ui, {
33
	version: "1.11.4",
34
 
35
	keyCode: {
36
		BACKSPACE: 8,
37
		COMMA: 188,
38
		DELETE: 46,
39
		DOWN: 40,
40
		END: 35,
41
		ENTER: 13,
42
		ESCAPE: 27,
43
		HOME: 36,
44
		LEFT: 37,
45
		PAGE_DOWN: 34,
46
		PAGE_UP: 33,
47
		PERIOD: 190,
48
		RIGHT: 39,
49
		SPACE: 32,
50
		TAB: 9,
51
		UP: 38
52
	}
53
});
54
 
55
// plugins
56
$.fn.extend({
57
	scrollParent: function( includeHidden ) {
58
		var position = this.css( "position" ),
59
			excludeStaticParent = position === "absolute",
60
			overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
61
			scrollParent = this.parents().filter( function() {
62
				var parent = $( this );
63
				if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
64
					return false;
65
				}
66
				return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) );
67
			}).eq( 0 );
68
 
69
		return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent;
70
	},
71
 
72
	uniqueId: (function() {
73
		var uuid = 0;
74
 
75
		return function() {
76
			return this.each(function() {
77
				if ( !this.id ) {
78
					this.id = "ui-id-" + ( ++uuid );
79
				}
80
			});
81
		};
82
	})(),
83
 
84
	removeUniqueId: function() {
85
		return this.each(function() {
86
			if ( /^ui-id-\d+$/.test( this.id ) ) {
87
				$( this ).removeAttr( "id" );
88
			}
89
		});
90
	}
91
});
92
 
93
// selectors
94
function focusable( element, isTabIndexNotNaN ) {
95
	var map, mapName, img,
96
		nodeName = element.nodeName.toLowerCase();
97
	if ( "area" === nodeName ) {
98
		map = element.parentNode;
99
		mapName = map.name;
100
		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
101
			return false;
102
		}
103
		img = $( "img[usemap='#" + mapName + "']" )[ 0 ];
104
		return !!img && visible( img );
105
	}
106
	return ( /^(input|select|textarea|button|object)$/.test( nodeName ) ?
107
		!element.disabled :
108
		"a" === nodeName ?
109
			element.href || isTabIndexNotNaN :
110
			isTabIndexNotNaN) &&
111
		// the element and all of its ancestors must be visible
112
		visible( element );
113
}
114
 
115
function visible( element ) {
116
	return $.expr.filters.visible( element ) &&
117
		!$( element ).parents().addBack().filter(function() {
118
			return $.css( this, "visibility" ) === "hidden";
119
		}).length;
120
}
121
 
122
$.extend( $.expr[ ":" ], {
123
	data: $.expr.createPseudo ?
124
		$.expr.createPseudo(function( dataName ) {
125
			return function( elem ) {
126
				return !!$.data( elem, dataName );
127
			};
128
		}) :
129
		// support: jQuery <1.8
130
		function( elem, i, match ) {
131
			return !!$.data( elem, match[ 3 ] );
132
		},
133
 
134
	focusable: function( element ) {
135
		return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
136
	},
137
 
138
	tabbable: function( element ) {
139
		var tabIndex = $.attr( element, "tabindex" ),
140
			isTabIndexNaN = isNaN( tabIndex );
141
		return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
142
	}
143
});
144
 
145
// support: jQuery <1.8
146
if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
147
	$.each( [ "Width", "Height" ], function( i, name ) {
148
		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
149
			type = name.toLowerCase(),
150
			orig = {
151
				innerWidth: $.fn.innerWidth,
152
				innerHeight: $.fn.innerHeight,
153
				outerWidth: $.fn.outerWidth,
154
				outerHeight: $.fn.outerHeight
155
			};
156
 
157
		function reduce( elem, size, border, margin ) {
158
			$.each( side, function() {
159
				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
160
				if ( border ) {
161
					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
162
				}
163
				if ( margin ) {
164
					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
165
				}
166
			});
167
			return size;
168
		}
169
 
170
		$.fn[ "inner" + name ] = function( size ) {
171
			if ( size === undefined ) {
172
				return orig[ "inner" + name ].call( this );
173
			}
174
 
175
			return this.each(function() {
176
				$( this ).css( type, reduce( this, size ) + "px" );
177
			});
178
		};
179
 
180
		$.fn[ "outer" + name] = function( size, margin ) {
181
			if ( typeof size !== "number" ) {
182
				return orig[ "outer" + name ].call( this, size );
183
			}
184
 
185
			return this.each(function() {
186
				$( this).css( type, reduce( this, size, true, margin ) + "px" );
187
			});
188
		};
189
	});
190
}
191
 
192
// support: jQuery <1.8
193
if ( !$.fn.addBack ) {
194
	$.fn.addBack = function( selector ) {
195
		return this.add( selector == null ?
196
			this.prevObject : this.prevObject.filter( selector )
197
		);
198
	};
199
}
200
 
201
// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
202
if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
203
	$.fn.removeData = (function( removeData ) {
204
		return function( key ) {
205
			if ( arguments.length ) {
206
				return removeData.call( this, $.camelCase( key ) );
207
			} else {
208
				return removeData.call( this );
209
			}
210
		};
211
	})( $.fn.removeData );
212
}
213
 
214
// deprecated
215
$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
216
 
217
$.fn.extend({
218
	focus: (function( orig ) {
219
		return function( delay, fn ) {
220
			return typeof delay === "number" ?
221
				this.each(function() {
222
					var elem = this;
223
					setTimeout(function() {
224
						$( elem ).focus();
225
						if ( fn ) {
226
							fn.call( elem );
227
						}
228
					}, delay );
229
				}) :
230
				orig.apply( this, arguments );
231
		};
232
	})( $.fn.focus ),
233
 
234
	disableSelection: (function() {
235
		var eventType = "onselectstart" in document.createElement( "div" ) ?
236
			"selectstart" :
237
			"mousedown";
238
 
239
		return function() {
240
			return this.bind( eventType + ".ui-disableSelection", function( event ) {
241
				event.preventDefault();
242
			});
243
		};
244
	})(),
245
 
246
	enableSelection: function() {
247
		return this.unbind( ".ui-disableSelection" );
248
	},
249
 
250
	zIndex: function( zIndex ) {
251
		if ( zIndex !== undefined ) {
252
			return this.css( "zIndex", zIndex );
253
		}
254
 
255
		if ( this.length ) {
256
			var elem = $( this[ 0 ] ), position, value;
257
			while ( elem.length && elem[ 0 ] !== document ) {
258
				// Ignore z-index if position is set to a value where z-index is ignored by the browser
259
				// This makes behavior of this function consistent across browsers
260
				// WebKit always returns auto if the element is positioned
261
				position = elem.css( "position" );
262
				if ( position === "absolute" || position === "relative" || position === "fixed" ) {
263
					// IE returns 0 when zIndex is not specified
264
					// other browsers return a string
265
					// we ignore the case of nested elements with an explicit value of 0
266
					// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
267
					value = parseInt( elem.css( "zIndex" ), 10 );
268
					if ( !isNaN( value ) && value !== 0 ) {
269
						return value;
270
					}
271
				}
272
				elem = elem.parent();
273
			}
274
		}
275
 
276
		return 0;
277
	}
278
});
279
 
280
// $.ui.plugin is deprecated. Use $.widget() extensions instead.
281
$.ui.plugin = {
282
	add: function( module, option, set ) {
283
		var i,
284
			proto = $.ui[ module ].prototype;
285
		for ( i in set ) {
286
			proto.plugins[ i ] = proto.plugins[ i ] || [];
287
			proto.plugins[ i ].push( [ option, set[ i ] ] );
288
		}
289
	},
290
	call: function( instance, name, args, allowDisconnected ) {
291
		var i,
292
			set = instance.plugins[ name ];
293
 
294
		if ( !set ) {
295
			return;
296
		}
297
 
298
		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
299
			return;
300
		}
301
 
302
		for ( i = 0; i < set.length; i++ ) {
303
			if ( instance.options[ set[ i ][ 0 ] ] ) {
304
				set[ i ][ 1 ].apply( instance.element, args );
305
			}
306
		}
307
	}
308
};
309
 
310
 
311
/*!
312
 * jQuery UI Widget 1.11.4
313
 * http://jqueryui.com
314
 *
315
 * Copyright jQuery Foundation and other contributors
316
 * Released under the MIT license.
317
 * http://jquery.org/license
318
 *
319
 * http://api.jqueryui.com/jQuery.widget/
320
 */
321
 
322
 
323
var widget_uuid = 0,
324
	widget_slice = Array.prototype.slice;
325
 
326
$.cleanData = (function( orig ) {
327
	return function( elems ) {
328
		var events, elem, i;
329
		for ( i = 0; (elem = elems[i]) != null; i++ ) {
330
			try {
331
 
332
				// Only trigger remove when necessary to save time
333
				events = $._data( elem, "events" );
334
				if ( events && events.remove ) {
335
					$( elem ).triggerHandler( "remove" );
336
				}
337
 
338
			// http://bugs.jquery.com/ticket/8235
339
			} catch ( e ) {}
340
		}
341
		orig( elems );
342
	};
343
})( $.cleanData );
344
 
345
$.widget = function( name, base, prototype ) {
346
	var fullName, existingConstructor, constructor, basePrototype,
347
		// proxiedPrototype allows the provided prototype to remain unmodified
348
		// so that it can be used as a mixin for multiple widgets (#8876)
349
		proxiedPrototype = {},
350
		namespace = name.split( "." )[ 0 ];
351
 
352
	name = name.split( "." )[ 1 ];
353
	fullName = namespace + "-" + name;
354
 
355
	if ( !prototype ) {
356
		prototype = base;
357
		base = $.Widget;
358
	}
359
 
360
	// create selector for plugin
361
	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
362
		return !!$.data( elem, fullName );
363
	};
364
 
365
	$[ namespace ] = $[ namespace ] || {};
366
	existingConstructor = $[ namespace ][ name ];
367
	constructor = $[ namespace ][ name ] = function( options, element ) {
368
		// allow instantiation without "new" keyword
369
		if ( !this._createWidget ) {
370
			return new constructor( options, element );
371
		}
372
 
373
		// allow instantiation without initializing for simple inheritance
374
		// must use "new" keyword (the code above always passes args)
375
		if ( arguments.length ) {
376
			this._createWidget( options, element );
377
		}
378
	};
379
	// extend with the existing constructor to carry over any static properties
380
	$.extend( constructor, existingConstructor, {
381
		version: prototype.version,
382
		// copy the object used to create the prototype in case we need to
383
		// redefine the widget later
384
		_proto: $.extend( {}, prototype ),
385
		// track widgets that inherit from this widget in case this widget is
386
		// redefined after a widget inherits from it
387
		_childConstructors: []
388
	});
389
 
390
	basePrototype = new base();
391
	// we need to make the options hash a property directly on the new instance
392
	// otherwise we'll modify the options hash on the prototype that we're
393
	// inheriting from
394
	basePrototype.options = $.widget.extend( {}, basePrototype.options );
395
	$.each( prototype, function( prop, value ) {
396
		if ( !$.isFunction( value ) ) {
397
			proxiedPrototype[ prop ] = value;
398
			return;
399
		}
400
		proxiedPrototype[ prop ] = (function() {
401
			var _super = function() {
402
					return base.prototype[ prop ].apply( this, arguments );
403
				},
404
				_superApply = function( args ) {
405
					return base.prototype[ prop ].apply( this, args );
406
				};
407
			return function() {
408
				var __super = this._super,
409
					__superApply = this._superApply,
410
					returnValue;
411
 
412
				this._super = _super;
413
				this._superApply = _superApply;
414
 
415
				returnValue = value.apply( this, arguments );
416
 
417
				this._super = __super;
418
				this._superApply = __superApply;
419
 
420
				return returnValue;
421
			};
422
		})();
423
	});
424
	constructor.prototype = $.widget.extend( basePrototype, {
425
		// TODO: remove support for widgetEventPrefix
426
		// always use the name + a colon as the prefix, e.g., draggable:start
427
		// don't prefix for widgets that aren't DOM-based
428
		widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
429
	}, proxiedPrototype, {
430
		constructor: constructor,
431
		namespace: namespace,
432
		widgetName: name,
433
		widgetFullName: fullName
434
	});
435
 
436
	// If this widget is being redefined then we need to find all widgets that
437
	// are inheriting from it and redefine all of them so that they inherit from
438
	// the new version of this widget. We're essentially trying to replace one
439
	// level in the prototype chain.
440
	if ( existingConstructor ) {
441
		$.each( existingConstructor._childConstructors, function( i, child ) {
442
			var childPrototype = child.prototype;
443
 
444
			// redefine the child widget using the same prototype that was
445
			// originally used, but inherit from the new version of the base
446
			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
447
		});
448
		// remove the list of existing child constructors from the old constructor
449
		// so the old child constructors can be garbage collected
450
		delete existingConstructor._childConstructors;
451
	} else {
452
		base._childConstructors.push( constructor );
453
	}
454
 
455
	$.widget.bridge( name, constructor );
456
 
457
	return constructor;
458
};
459
 
460
$.widget.extend = function( target ) {
461
	var input = widget_slice.call( arguments, 1 ),
462
		inputIndex = 0,
463
		inputLength = input.length,
464
		key,
465
		value;
466
	for ( ; inputIndex < inputLength; inputIndex++ ) {
467
		for ( key in input[ inputIndex ] ) {
468
			value = input[ inputIndex ][ key ];
469
			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
470
				// Clone objects
471
				if ( $.isPlainObject( value ) ) {
472
					target[ key ] = $.isPlainObject( target[ key ] ) ?
473
						$.widget.extend( {}, target[ key ], value ) :
474
						// Don't extend strings, arrays, etc. with objects
475
						$.widget.extend( {}, value );
476
				// Copy everything else by reference
477
				} else {
478
					target[ key ] = value;
479
				}
480
			}
481
		}
482
	}
483
	return target;
484
};
485
 
486
$.widget.bridge = function( name, object ) {
487
	var fullName = object.prototype.widgetFullName || name;
488
	$.fn[ name ] = function( options ) {
489
		var isMethodCall = typeof options === "string",
490
			args = widget_slice.call( arguments, 1 ),
491
			returnValue = this;
492
 
493
		if ( isMethodCall ) {
494
			this.each(function() {
495
				var methodValue,
496
					instance = $.data( this, fullName );
497
				if ( options === "instance" ) {
498
					returnValue = instance;
499
					return false;
500
				}
501
				if ( !instance ) {
502
					return $.error( "cannot call methods on " + name + " prior to initialization; " +
503
						"attempted to call method '" + options + "'" );
504
				}
505
				if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
506
					return $.error( "no such method '" + options + "' for " + name + " widget instance" );
507
				}
508
				methodValue = instance[ options ].apply( instance, args );
509
				if ( methodValue !== instance && methodValue !== undefined ) {
510
					returnValue = methodValue && methodValue.jquery ?
511
						returnValue.pushStack( methodValue.get() ) :
512
						methodValue;
513
					return false;
514
				}
515
			});
516
		} else {
517
 
518
			// Allow multiple hashes to be passed on init
519
			if ( args.length ) {
520
				options = $.widget.extend.apply( null, [ options ].concat(args) );
521
			}
522
 
523
			this.each(function() {
524
				var instance = $.data( this, fullName );
525
				if ( instance ) {
526
					instance.option( options || {} );
527
					if ( instance._init ) {
528
						instance._init();
529
					}
530
				} else {
531
					$.data( this, fullName, new object( options, this ) );
532
				}
533
			});
534
		}
535
 
536
		return returnValue;
537
	};
538
};
539
 
540
$.Widget = function( /* options, element */ ) {};
541
$.Widget._childConstructors = [];
542
 
543
$.Widget.prototype = {
544
	widgetName: "widget",
545
	widgetEventPrefix: "",
546
	defaultElement: "<div>",
547
	options: {
548
		disabled: false,
549
 
550
		// callbacks
551
		create: null
552
	},
553
	_createWidget: function( options, element ) {
554
		element = $( element || this.defaultElement || this )[ 0 ];
555
		this.element = $( element );
556
		this.uuid = widget_uuid++;
557
		this.eventNamespace = "." + this.widgetName + this.uuid;
558
 
559
		this.bindings = $();
560
		this.hoverable = $();
561
		this.focusable = $();
562
 
563
		if ( element !== this ) {
564
			$.data( element, this.widgetFullName, this );
565
			this._on( true, this.element, {
566
				remove: function( event ) {
567
					if ( event.target === element ) {
568
						this.destroy();
569
					}
570
				}
571
			});
572
			this.document = $( element.style ?
573
				// element within the document
574
				element.ownerDocument :
575
				// element is window or document
576
				element.document || element );
577
			this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
578
		}
579
 
580
		this.options = $.widget.extend( {},
581
			this.options,
582
			this._getCreateOptions(),
583
			options );
584
 
585
		this._create();
586
		this._trigger( "create", null, this._getCreateEventData() );
587
		this._init();
588
	},
589
	_getCreateOptions: $.noop,
590
	_getCreateEventData: $.noop,
591
	_create: $.noop,
592
	_init: $.noop,
593
 
594
	destroy: function() {
595
		this._destroy();
596
		// we can probably remove the unbind calls in 2.0
597
		// all event bindings should go through this._on()
598
		this.element
599
			.unbind( this.eventNamespace )
600
			.removeData( this.widgetFullName )
601
			// support: jquery <1.6.3
602
			// http://bugs.jquery.com/ticket/9413
603
			.removeData( $.camelCase( this.widgetFullName ) );
604
		this.widget()
605
			.unbind( this.eventNamespace )
606
			.removeAttr( "aria-disabled" )
607
			.removeClass(
608
				this.widgetFullName + "-disabled " +
609
				"ui-state-disabled" );
610
 
611
		// clean up events and states
612
		this.bindings.unbind( this.eventNamespace );
613
		this.hoverable.removeClass( "ui-state-hover" );
614
		this.focusable.removeClass( "ui-state-focus" );
615
	},
616
	_destroy: $.noop,
617
 
618
	widget: function() {
619
		return this.element;
620
	},
621
 
622
	option: function( key, value ) {
623
		var options = key,
624
			parts,
625
			curOption,
626
			i;
627
 
628
		if ( arguments.length === 0 ) {
629
			// don't return a reference to the internal hash
630
			return $.widget.extend( {}, this.options );
631
		}
632
 
633
		if ( typeof key === "string" ) {
634
			// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
635
			options = {};
636
			parts = key.split( "." );
637
			key = parts.shift();
638
			if ( parts.length ) {
639
				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
640
				for ( i = 0; i < parts.length - 1; i++ ) {
641
					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
642
					curOption = curOption[ parts[ i ] ];
643
				}
644
				key = parts.pop();
645
				if ( arguments.length === 1 ) {
646
					return curOption[ key ] === undefined ? null : curOption[ key ];
647
				}
648
				curOption[ key ] = value;
649
			} else {
650
				if ( arguments.length === 1 ) {
651
					return this.options[ key ] === undefined ? null : this.options[ key ];
652
				}
653
				options[ key ] = value;
654
			}
655
		}
656
 
657
		this._setOptions( options );
658
 
659
		return this;
660
	},
661
	_setOptions: function( options ) {
662
		var key;
663
 
664
		for ( key in options ) {
665
			this._setOption( key, options[ key ] );
666
		}
667
 
668
		return this;
669
	},
670
	_setOption: function( key, value ) {
671
		this.options[ key ] = value;
672
 
673
		if ( key === "disabled" ) {
674
			this.widget()
675
				.toggleClass( this.widgetFullName + "-disabled", !!value );
676
 
677
			// If the widget is becoming disabled, then nothing is interactive
678
			if ( value ) {
679
				this.hoverable.removeClass( "ui-state-hover" );
680
				this.focusable.removeClass( "ui-state-focus" );
681
			}
682
		}
683
 
684
		return this;
685
	},
686
 
687
	enable: function() {
688
		return this._setOptions({ disabled: false });
689
	},
690
	disable: function() {
691
		return this._setOptions({ disabled: true });
692
	},
693
 
694
	_on: function( suppressDisabledCheck, element, handlers ) {
695
		var delegateElement,
696
			instance = this;
697
 
698
		// no suppressDisabledCheck flag, shuffle arguments
699
		if ( typeof suppressDisabledCheck !== "boolean" ) {
700
			handlers = element;
701
			element = suppressDisabledCheck;
702
			suppressDisabledCheck = false;
703
		}
704
 
705
		// no element argument, shuffle and use this.element
706
		if ( !handlers ) {
707
			handlers = element;
708
			element = this.element;
709
			delegateElement = this.widget();
710
		} else {
711
			element = delegateElement = $( element );
712
			this.bindings = this.bindings.add( element );
713
		}
714
 
715
		$.each( handlers, function( event, handler ) {
716
			function handlerProxy() {
717
				// allow widgets to customize the disabled handling
718
				// - disabled as an array instead of boolean
719
				// - disabled class as method for disabling individual parts
720
				if ( !suppressDisabledCheck &&
721
						( instance.options.disabled === true ||
722
							$( this ).hasClass( "ui-state-disabled" ) ) ) {
723
					return;
724
				}
725
				return ( typeof handler === "string" ? instance[ handler ] : handler )
726
					.apply( instance, arguments );
727
			}
728
 
729
			// copy the guid so direct unbinding works
730
			if ( typeof handler !== "string" ) {
731
				handlerProxy.guid = handler.guid =
732
					handler.guid || handlerProxy.guid || $.guid++;
733
			}
734
 
735
			var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
736
				eventName = match[1] + instance.eventNamespace,
737
				selector = match[2];
738
			if ( selector ) {
739
				delegateElement.delegate( selector, eventName, handlerProxy );
740
			} else {
741
				element.bind( eventName, handlerProxy );
742
			}
743
		});
744
	},
745
 
746
	_off: function( element, eventName ) {
747
		eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
748
			this.eventNamespace;
749
		element.unbind( eventName ).undelegate( eventName );
750
 
751
		// Clear the stack to avoid memory leaks (#10056)
752
		this.bindings = $( this.bindings.not( element ).get() );
753
		this.focusable = $( this.focusable.not( element ).get() );
754
		this.hoverable = $( this.hoverable.not( element ).get() );
755
	},
756
 
757
	_delay: function( handler, delay ) {
758
		function handlerProxy() {
759
			return ( typeof handler === "string" ? instance[ handler ] : handler )
760
				.apply( instance, arguments );
761
		}
762
		var instance = this;
763
		return setTimeout( handlerProxy, delay || 0 );
764
	},
765
 
766
	_hoverable: function( element ) {
767
		this.hoverable = this.hoverable.add( element );
768
		this._on( element, {
769
			mouseenter: function( event ) {
770
				$( event.currentTarget ).addClass( "ui-state-hover" );
771
			},
772
			mouseleave: function( event ) {
773
				$( event.currentTarget ).removeClass( "ui-state-hover" );
774
			}
775
		});
776
	},
777
 
778
	_focusable: function( element ) {
779
		this.focusable = this.focusable.add( element );
780
		this._on( element, {
781
			focusin: function( event ) {
782
				$( event.currentTarget ).addClass( "ui-state-focus" );
783
			},
784
			focusout: function( event ) {
785
				$( event.currentTarget ).removeClass( "ui-state-focus" );
786
			}
787
		});
788
	},
789
 
790
	_trigger: function( type, event, data ) {
791
		var prop, orig,
792
			callback = this.options[ type ];
793
 
794
		data = data || {};
795
		event = $.Event( event );
796
		event.type = ( type === this.widgetEventPrefix ?
797
			type :
798
			this.widgetEventPrefix + type ).toLowerCase();
799
		// the original event may come from any element
800
		// so we need to reset the target on the new event
801
		event.target = this.element[ 0 ];
802
 
803
		// copy original event properties over to the new event
804
		orig = event.originalEvent;
805
		if ( orig ) {
806
			for ( prop in orig ) {
807
				if ( !( prop in event ) ) {
808
					event[ prop ] = orig[ prop ];
809
				}
810
			}
811
		}
812
 
813
		this.element.trigger( event, data );
814
		return !( $.isFunction( callback ) &&
815
			callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
816
			event.isDefaultPrevented() );
817
	}
818
};
819
 
820
$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
821
	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
822
		if ( typeof options === "string" ) {
823
			options = { effect: options };
824
		}
825
		var hasOptions,
826
			effectName = !options ?
827
				method :
828
				options === true || typeof options === "number" ?
829
					defaultEffect :
830
					options.effect || defaultEffect;
831
		options = options || {};
832
		if ( typeof options === "number" ) {
833
			options = { duration: options };
834
		}
835
		hasOptions = !$.isEmptyObject( options );
836
		options.complete = callback;
837
		if ( options.delay ) {
838
			element.delay( options.delay );
839
		}
840
		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
841
			element[ method ]( options );
842
		} else if ( effectName !== method && element[ effectName ] ) {
843
			element[ effectName ]( options.duration, options.easing, callback );
844
		} else {
845
			element.queue(function( next ) {
846
				$( this )[ method ]();
847
				if ( callback ) {
848
					callback.call( element[ 0 ] );
849
				}
850
				next();
851
			});
852
		}
853
	};
854
});
855
 
856
var widget = $.widget;
857
 
858
 
859
/*!
860
 * jQuery UI Mouse 1.11.4
861
 * http://jqueryui.com
862
 *
863
 * Copyright jQuery Foundation and other contributors
864
 * Released under the MIT license.
865
 * http://jquery.org/license
866
 *
867
 * http://api.jqueryui.com/mouse/
868
 */
869
 
870
 
871
var mouseHandled = false;
872
$( document ).mouseup( function() {
873
	mouseHandled = false;
874
});
875
 
876
var mouse = $.widget("ui.mouse", {
877
	version: "1.11.4",
878
	options: {
879
		cancel: "input,textarea,button,select,option",
880
		distance: 1,
881
		delay: 0
882
	},
883
	_mouseInit: function() {
884
		var that = this;
885
 
886
		this.element
887
			.bind("mousedown." + this.widgetName, function(event) {
888
				return that._mouseDown(event);
889
			})
890
			.bind("click." + this.widgetName, function(event) {
891
				if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
892
					$.removeData(event.target, that.widgetName + ".preventClickEvent");
893
					event.stopImmediatePropagation();
894
					return false;
895
				}
896
			});
897
 
898
		this.started = false;
899
	},
900
 
901
	// TODO: make sure destroying one instance of mouse doesn't mess with
902
	// other instances of mouse
903
	_mouseDestroy: function() {
904
		this.element.unbind("." + this.widgetName);
905
		if ( this._mouseMoveDelegate ) {
906
			this.document
907
				.unbind("mousemove." + this.widgetName, this._mouseMoveDelegate)
908
				.unbind("mouseup." + this.widgetName, this._mouseUpDelegate);
909
		}
910
	},
911
 
912
	_mouseDown: function(event) {
913
		// don't let more than one widget handle mouseStart
914
		if ( mouseHandled ) {
915
			return;
916
		}
917
 
918
		this._mouseMoved = false;
919
 
920
		// we may have missed mouseup (out of window)
921
		(this._mouseStarted && this._mouseUp(event));
922
 
923
		this._mouseDownEvent = event;
924
 
925
		var that = this,
926
			btnIsLeft = (event.which === 1),
927
			// event.target.nodeName works around a bug in IE 8 with
928
			// disabled inputs (#7620)
929
			elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
930
		if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
931
			return true;
932
		}
933
 
934
		this.mouseDelayMet = !this.options.delay;
935
		if (!this.mouseDelayMet) {
936
			this._mouseDelayTimer = setTimeout(function() {
937
				that.mouseDelayMet = true;
938
			}, this.options.delay);
939
		}
940
 
941
		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
942
			this._mouseStarted = (this._mouseStart(event) !== false);
943
			if (!this._mouseStarted) {
944
				event.preventDefault();
945
				return true;
946
			}
947
		}
948
 
949
		// Click event may never have fired (Gecko & Opera)
950
		if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
951
			$.removeData(event.target, this.widgetName + ".preventClickEvent");
952
		}
953
 
954
		// these delegates are required to keep context
955
		this._mouseMoveDelegate = function(event) {
956
			return that._mouseMove(event);
957
		};
958
		this._mouseUpDelegate = function(event) {
959
			return that._mouseUp(event);
960
		};
961
 
962
		this.document
963
			.bind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
964
			.bind( "mouseup." + this.widgetName, this._mouseUpDelegate );
965
 
966
		event.preventDefault();
967
 
968
		mouseHandled = true;
969
		return true;
970
	},
971
 
972
	_mouseMove: function(event) {
973
		// Only check for mouseups outside the document if you've moved inside the document
974
		// at least once. This prevents the firing of mouseup in the case of IE<9, which will
975
		// fire a mousemove event if content is placed under the cursor. See #7778
976
		// Support: IE <9
977
		if ( this._mouseMoved ) {
978
			// IE mouseup check - mouseup happened when mouse was out of window
979
			if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
980
				return this._mouseUp(event);
981
 
982
			// Iframe mouseup check - mouseup occurred in another document
983
			} else if ( !event.which ) {
984
				return this._mouseUp( event );
985
			}
986
		}
987
 
988
		if ( event.which || event.button ) {
989
			this._mouseMoved = true;
990
		}
991
 
992
		if (this._mouseStarted) {
993
			this._mouseDrag(event);
994
			return event.preventDefault();
995
		}
996
 
997
		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
998
			this._mouseStarted =
999
				(this._mouseStart(this._mouseDownEvent, event) !== false);
1000
			(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
1001
		}
1002
 
1003
		return !this._mouseStarted;
1004
	},
1005
 
1006
	_mouseUp: function(event) {
1007
		this.document
1008
			.unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
1009
			.unbind( "mouseup." + this.widgetName, this._mouseUpDelegate );
1010
 
1011
		if (this._mouseStarted) {
1012
			this._mouseStarted = false;
1013
 
1014
			if (event.target === this._mouseDownEvent.target) {
1015
				$.data(event.target, this.widgetName + ".preventClickEvent", true);
1016
			}
1017
 
1018
			this._mouseStop(event);
1019
		}
1020
 
1021
		mouseHandled = false;
1022
		return false;
1023
	},
1024
 
1025
	_mouseDistanceMet: function(event) {
1026
		return (Math.max(
1027
				Math.abs(this._mouseDownEvent.pageX - event.pageX),
1028
				Math.abs(this._mouseDownEvent.pageY - event.pageY)
1029
			) >= this.options.distance
1030
		);
1031
	},
1032
 
1033
	_mouseDelayMet: function(/* event */) {
1034
		return this.mouseDelayMet;
1035
	},
1036
 
1037
	// These are placeholder methods, to be overriden by extending plugin
1038
	_mouseStart: function(/* event */) {},
1039
	_mouseDrag: function(/* event */) {},
1040
	_mouseStop: function(/* event */) {},
1041
	_mouseCapture: function(/* event */) { return true; }
1042
});
1043
 
1044
 
1045
/*!
1046
 * jQuery UI Position 1.11.4
1047
 * http://jqueryui.com
1048
 *
1049
 * Copyright jQuery Foundation and other contributors
1050
 * Released under the MIT license.
1051
 * http://jquery.org/license
1052
 *
1053
 * http://api.jqueryui.com/position/
1054
 */
1055
 
1056
(function() {
1057
 
1058
$.ui = $.ui || {};
1059
 
1060
var cachedScrollbarWidth, supportsOffsetFractions,
1061
	max = Math.max,
1062
	abs = Math.abs,
1063
	round = Math.round,
1064
	rhorizontal = /left|center|right/,
1065
	rvertical = /top|center|bottom/,
1066
	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
1067
	rposition = /^\w+/,
1068
	rpercent = /%$/,
1069
	_position = $.fn.position;
1070
 
1071
function getOffsets( offsets, width, height ) {
1072
	return [
1073
		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
1074
		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
1075
	];
1076
}
1077
 
1078
function parseCss( element, property ) {
1079
	return parseInt( $.css( element, property ), 10 ) || 0;
1080
}
1081
 
1082
function getDimensions( elem ) {
1083
	var raw = elem[0];
1084
	if ( raw.nodeType === 9 ) {
1085
		return {
1086
			width: elem.width(),
1087
			height: elem.height(),
1088
			offset: { top: 0, left: 0 }
1089
		};
1090
	}
1091
	if ( $.isWindow( raw ) ) {
1092
		return {
1093
			width: elem.width(),
1094
			height: elem.height(),
1095
			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
1096
		};
1097
	}
1098
	if ( raw.preventDefault ) {
1099
		return {
1100
			width: 0,
1101
			height: 0,
1102
			offset: { top: raw.pageY, left: raw.pageX }
1103
		};
1104
	}
1105
	return {
1106
		width: elem.outerWidth(),
1107
		height: elem.outerHeight(),
1108
		offset: elem.offset()
1109
	};
1110
}
1111
 
1112
$.position = {
1113
	scrollbarWidth: function() {
1114
		if ( cachedScrollbarWidth !== undefined ) {
1115
			return cachedScrollbarWidth;
1116
		}
1117
		var w1, w2,
1118
			div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
1119
			innerDiv = div.children()[0];
1120
 
1121
		$( "body" ).append( div );
1122
		w1 = innerDiv.offsetWidth;
1123
		div.css( "overflow", "scroll" );
1124
 
1125
		w2 = innerDiv.offsetWidth;
1126
 
1127
		if ( w1 === w2 ) {
1128
			w2 = div[0].clientWidth;
1129
		}
1130
 
1131
		div.remove();
1132
 
1133
		return (cachedScrollbarWidth = w1 - w2);
1134
	},
1135
	getScrollInfo: function( within ) {
1136
		var overflowX = within.isWindow || within.isDocument ? "" :
1137
				within.element.css( "overflow-x" ),
1138
			overflowY = within.isWindow || within.isDocument ? "" :
1139
				within.element.css( "overflow-y" ),
1140
			hasOverflowX = overflowX === "scroll" ||
1141
				( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
1142
			hasOverflowY = overflowY === "scroll" ||
1143
				( overflowY === "auto" && within.height < within.element[0].scrollHeight );
1144
		return {
1145
			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
1146
			height: hasOverflowX ? $.position.scrollbarWidth() : 0
1147
		};
1148
	},
1149
	getWithinInfo: function( element ) {
1150
		var withinElement = $( element || window ),
1151
			isWindow = $.isWindow( withinElement[0] ),
1152
			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
1153
		return {
1154
			element: withinElement,
1155
			isWindow: isWindow,
1156
			isDocument: isDocument,
1157
			offset: withinElement.offset() || { left: 0, top: 0 },
1158
			scrollLeft: withinElement.scrollLeft(),
1159
			scrollTop: withinElement.scrollTop(),
1160
 
1161
			// support: jQuery 1.6.x
1162
			// jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows
1163
			width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(),
1164
			height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight()
1165
		};
1166
	}
1167
};
1168
 
1169
$.fn.position = function( options ) {
1170
	if ( !options || !options.of ) {
1171
		return _position.apply( this, arguments );
1172
	}
1173
 
1174
	// make a copy, we don't want to modify arguments
1175
	options = $.extend( {}, options );
1176
 
1177
	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
1178
		target = $( options.of ),
1179
		within = $.position.getWithinInfo( options.within ),
1180
		scrollInfo = $.position.getScrollInfo( within ),
1181
		collision = ( options.collision || "flip" ).split( " " ),
1182
		offsets = {};
1183
 
1184
	dimensions = getDimensions( target );
1185
	if ( target[0].preventDefault ) {
1186
		// force left top to allow flipping
1187
		options.at = "left top";
1188
	}
1189
	targetWidth = dimensions.width;
1190
	targetHeight = dimensions.height;
1191
	targetOffset = dimensions.offset;
1192
	// clone to reuse original targetOffset later
1193
	basePosition = $.extend( {}, targetOffset );
1194
 
1195
	// force my and at to have valid horizontal and vertical positions
1196
	// if a value is missing or invalid, it will be converted to center
1197
	$.each( [ "my", "at" ], function() {
1198
		var pos = ( options[ this ] || "" ).split( " " ),
1199
			horizontalOffset,
1200
			verticalOffset;
1201
 
1202
		if ( pos.length === 1) {
1203
			pos = rhorizontal.test( pos[ 0 ] ) ?
1204
				pos.concat( [ "center" ] ) :
1205
				rvertical.test( pos[ 0 ] ) ?
1206
					[ "center" ].concat( pos ) :
1207
					[ "center", "center" ];
1208
		}
1209
		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
1210
		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
1211
 
1212
		// calculate offsets
1213
		horizontalOffset = roffset.exec( pos[ 0 ] );
1214
		verticalOffset = roffset.exec( pos[ 1 ] );
1215
		offsets[ this ] = [
1216
			horizontalOffset ? horizontalOffset[ 0 ] : 0,
1217
			verticalOffset ? verticalOffset[ 0 ] : 0
1218
		];
1219
 
1220
		// reduce to just the positions without the offsets
1221
		options[ this ] = [
1222
			rposition.exec( pos[ 0 ] )[ 0 ],
1223
			rposition.exec( pos[ 1 ] )[ 0 ]
1224
		];
1225
	});
1226
 
1227
	// normalize collision option
1228
	if ( collision.length === 1 ) {
1229
		collision[ 1 ] = collision[ 0 ];
1230
	}
1231
 
1232
	if ( options.at[ 0 ] === "right" ) {
1233
		basePosition.left += targetWidth;
1234
	} else if ( options.at[ 0 ] === "center" ) {
1235
		basePosition.left += targetWidth / 2;
1236
	}
1237
 
1238
	if ( options.at[ 1 ] === "bottom" ) {
1239
		basePosition.top += targetHeight;
1240
	} else if ( options.at[ 1 ] === "center" ) {
1241
		basePosition.top += targetHeight / 2;
1242
	}
1243
 
1244
	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
1245
	basePosition.left += atOffset[ 0 ];
1246
	basePosition.top += atOffset[ 1 ];
1247
 
1248
	return this.each(function() {
1249
		var collisionPosition, using,
1250
			elem = $( this ),
1251
			elemWidth = elem.outerWidth(),
1252
			elemHeight = elem.outerHeight(),
1253
			marginLeft = parseCss( this, "marginLeft" ),
1254
			marginTop = parseCss( this, "marginTop" ),
1255
			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
1256
			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
1257
			position = $.extend( {}, basePosition ),
1258
			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1259
 
1260
		if ( options.my[ 0 ] === "right" ) {
1261
			position.left -= elemWidth;
1262
		} else if ( options.my[ 0 ] === "center" ) {
1263
			position.left -= elemWidth / 2;
1264
		}
1265
 
1266
		if ( options.my[ 1 ] === "bottom" ) {
1267
			position.top -= elemHeight;
1268
		} else if ( options.my[ 1 ] === "center" ) {
1269
			position.top -= elemHeight / 2;
1270
		}
1271
 
1272
		position.left += myOffset[ 0 ];
1273
		position.top += myOffset[ 1 ];
1274
 
1275
		// if the browser doesn't support fractions, then round for consistent results
1276
		if ( !supportsOffsetFractions ) {
1277
			position.left = round( position.left );
1278
			position.top = round( position.top );
1279
		}
1280
 
1281
		collisionPosition = {
1282
			marginLeft: marginLeft,
1283
			marginTop: marginTop
1284
		};
1285
 
1286
		$.each( [ "left", "top" ], function( i, dir ) {
1287
			if ( $.ui.position[ collision[ i ] ] ) {
1288
				$.ui.position[ collision[ i ] ][ dir ]( position, {
1289
					targetWidth: targetWidth,
1290
					targetHeight: targetHeight,
1291
					elemWidth: elemWidth,
1292
					elemHeight: elemHeight,
1293
					collisionPosition: collisionPosition,
1294
					collisionWidth: collisionWidth,
1295
					collisionHeight: collisionHeight,
1296
					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1297
					my: options.my,
1298
					at: options.at,
1299
					within: within,
1300
					elem: elem
1301
				});
1302
			}
1303
		});
1304
 
1305
		if ( options.using ) {
1306
			// adds feedback as second argument to using callback, if present
1307
			using = function( props ) {
1308
				var left = targetOffset.left - position.left,
1309
					right = left + targetWidth - elemWidth,
1310
					top = targetOffset.top - position.top,
1311
					bottom = top + targetHeight - elemHeight,
1312
					feedback = {
1313
						target: {
1314
							element: target,
1315
							left: targetOffset.left,
1316
							top: targetOffset.top,
1317
							width: targetWidth,
1318
							height: targetHeight
1319
						},
1320
						element: {
1321
							element: elem,
1322
							left: position.left,
1323
							top: position.top,
1324
							width: elemWidth,
1325
							height: elemHeight
1326
						},
1327
						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1328
						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1329
					};
1330
				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1331
					feedback.horizontal = "center";
1332
				}
1333
				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1334
					feedback.vertical = "middle";
1335
				}
1336
				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1337
					feedback.important = "horizontal";
1338
				} else {
1339
					feedback.important = "vertical";
1340
				}
1341
				options.using.call( this, props, feedback );
1342
			};
1343
		}
1344
 
1345
		elem.offset( $.extend( position, { using: using } ) );
1346
	});
1347
};
1348
 
1349
$.ui.position = {
1350
	fit: {
1351
		left: function( position, data ) {
1352
			var within = data.within,
1353
				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1354
				outerWidth = within.width,
1355
				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1356
				overLeft = withinOffset - collisionPosLeft,
1357
				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1358
				newOverRight;
1359
 
1360
			// element is wider than within
1361
			if ( data.collisionWidth > outerWidth ) {
1362
				// element is initially over the left side of within
1363
				if ( overLeft > 0 && overRight <= 0 ) {
1364
					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
1365
					position.left += overLeft - newOverRight;
1366
				// element is initially over right side of within
1367
				} else if ( overRight > 0 && overLeft <= 0 ) {
1368
					position.left = withinOffset;
1369
				// element is initially over both left and right sides of within
1370
				} else {
1371
					if ( overLeft > overRight ) {
1372
						position.left = withinOffset + outerWidth - data.collisionWidth;
1373
					} else {
1374
						position.left = withinOffset;
1375
					}
1376
				}
1377
			// too far left -> align with left edge
1378
			} else if ( overLeft > 0 ) {
1379
				position.left += overLeft;
1380
			// too far right -> align with right edge
1381
			} else if ( overRight > 0 ) {
1382
				position.left -= overRight;
1383
			// adjust based on position and margin
1384
			} else {
1385
				position.left = max( position.left - collisionPosLeft, position.left );
1386
			}
1387
		},
1388
		top: function( position, data ) {
1389
			var within = data.within,
1390
				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1391
				outerHeight = data.within.height,
1392
				collisionPosTop = position.top - data.collisionPosition.marginTop,
1393
				overTop = withinOffset - collisionPosTop,
1394
				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1395
				newOverBottom;
1396
 
1397
			// element is taller than within
1398
			if ( data.collisionHeight > outerHeight ) {
1399
				// element is initially over the top of within
1400
				if ( overTop > 0 && overBottom <= 0 ) {
1401
					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
1402
					position.top += overTop - newOverBottom;
1403
				// element is initially over bottom of within
1404
				} else if ( overBottom > 0 && overTop <= 0 ) {
1405
					position.top = withinOffset;
1406
				// element is initially over both top and bottom of within
1407
				} else {
1408
					if ( overTop > overBottom ) {
1409
						position.top = withinOffset + outerHeight - data.collisionHeight;
1410
					} else {
1411
						position.top = withinOffset;
1412
					}
1413
				}
1414
			// too far up -> align with top
1415
			} else if ( overTop > 0 ) {
1416
				position.top += overTop;
1417
			// too far down -> align with bottom edge
1418
			} else if ( overBottom > 0 ) {
1419
				position.top -= overBottom;
1420
			// adjust based on position and margin
1421
			} else {
1422
				position.top = max( position.top - collisionPosTop, position.top );
1423
			}
1424
		}
1425
	},
1426
	flip: {
1427
		left: function( position, data ) {
1428
			var within = data.within,
1429
				withinOffset = within.offset.left + within.scrollLeft,
1430
				outerWidth = within.width,
1431
				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1432
				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1433
				overLeft = collisionPosLeft - offsetLeft,
1434
				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1435
				myOffset = data.my[ 0 ] === "left" ?
1436
					-data.elemWidth :
1437
					data.my[ 0 ] === "right" ?
1438
						data.elemWidth :
1439
						0,
1440
				atOffset = data.at[ 0 ] === "left" ?
1441
					data.targetWidth :
1442
					data.at[ 0 ] === "right" ?
1443
						-data.targetWidth :
1444
						0,
1445
				offset = -2 * data.offset[ 0 ],
1446
				newOverRight,
1447
				newOverLeft;
1448
 
1449
			if ( overLeft < 0 ) {
1450
				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
1451
				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1452
					position.left += myOffset + atOffset + offset;
1453
				}
1454
			} else if ( overRight > 0 ) {
1455
				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
1456
				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1457
					position.left += myOffset + atOffset + offset;
1458
				}
1459
			}
1460
		},
1461
		top: function( position, data ) {
1462
			var within = data.within,
1463
				withinOffset = within.offset.top + within.scrollTop,
1464
				outerHeight = within.height,
1465
				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1466
				collisionPosTop = position.top - data.collisionPosition.marginTop,
1467
				overTop = collisionPosTop - offsetTop,
1468
				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1469
				top = data.my[ 1 ] === "top",
1470
				myOffset = top ?
1471
					-data.elemHeight :
1472
					data.my[ 1 ] === "bottom" ?
1473
						data.elemHeight :
1474
						0,
1475
				atOffset = data.at[ 1 ] === "top" ?
1476
					data.targetHeight :
1477
					data.at[ 1 ] === "bottom" ?
1478
						-data.targetHeight :
1479
						0,
1480
				offset = -2 * data.offset[ 1 ],
1481
				newOverTop,
1482
				newOverBottom;
1483
			if ( overTop < 0 ) {
1484
				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
1485
				if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
1486
					position.top += myOffset + atOffset + offset;
1487
				}
1488
			} else if ( overBottom > 0 ) {
1489
				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
1490
				if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
1491
					position.top += myOffset + atOffset + offset;
1492
				}
1493
			}
1494
		}
1495
	},
1496
	flipfit: {
1497
		left: function() {
1498
			$.ui.position.flip.left.apply( this, arguments );
1499
			$.ui.position.fit.left.apply( this, arguments );
1500
		},
1501
		top: function() {
1502
			$.ui.position.flip.top.apply( this, arguments );
1503
			$.ui.position.fit.top.apply( this, arguments );
1504
		}
1505
	}
1506
};
1507
 
1508
// fraction support test
1509
(function() {
1510
	var testElement, testElementParent, testElementStyle, offsetLeft, i,
1511
		body = document.getElementsByTagName( "body" )[ 0 ],
1512
		div = document.createElement( "div" );
1513
 
1514
	//Create a "fake body" for testing based on method used in jQuery.support
1515
	testElement = document.createElement( body ? "div" : "body" );
1516
	testElementStyle = {
1517
		visibility: "hidden",
1518
		width: 0,
1519
		height: 0,
1520
		border: 0,
1521
		margin: 0,
1522
		background: "none"
1523
	};
1524
	if ( body ) {
1525
		$.extend( testElementStyle, {
1526
			position: "absolute",
1527
			left: "-1000px",
1528
			top: "-1000px"
1529
		});
1530
	}
1531
	for ( i in testElementStyle ) {
1532
		testElement.style[ i ] = testElementStyle[ i ];
1533
	}
1534
	testElement.appendChild( div );
1535
	testElementParent = body || document.documentElement;
1536
	testElementParent.insertBefore( testElement, testElementParent.firstChild );
1537
 
1538
	div.style.cssText = "position: absolute; left: 10.7432222px;";
1539
 
1540
	offsetLeft = $( div ).offset().left;
1541
	supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11;
1542
 
1543
	testElement.innerHTML = "";
1544
	testElementParent.removeChild( testElement );
1545
})();
1546
 
1547
})();
1548
 
1549
var position = $.ui.position;
1550
 
1551
 
1552
/*!
1553
 * jQuery UI Draggable 1.11.4
1554
 * http://jqueryui.com
1555
 *
1556
 * Copyright jQuery Foundation and other contributors
1557
 * Released under the MIT license.
1558
 * http://jquery.org/license
1559
 *
1560
 * http://api.jqueryui.com/draggable/
1561
 */
1562
 
1563
 
1564
$.widget("ui.draggable", $.ui.mouse, {
1565
	version: "1.11.4",
1566
	widgetEventPrefix: "drag",
1567
	options: {
1568
		addClasses: true,
1569
		appendTo: "parent",
1570
		axis: false,
1571
		connectToSortable: false,
1572
		containment: false,
1573
		cursor: "auto",
1574
		cursorAt: false,
1575
		grid: false,
1576
		handle: false,
1577
		helper: "original",
1578
		iframeFix: false,
1579
		opacity: false,
1580
		refreshPositions: false,
1581
		revert: false,
1582
		revertDuration: 500,
1583
		scope: "default",
1584
		scroll: true,
1585
		scrollSensitivity: 20,
1586
		scrollSpeed: 20,
1587
		snap: false,
1588
		snapMode: "both",
1589
		snapTolerance: 20,
1590
		stack: false,
1591
		zIndex: false,
1592
 
1593
		// callbacks
1594
		drag: null,
1595
		start: null,
1596
		stop: null
1597
	},
1598
	_create: function() {
1599
 
1600
		if ( this.options.helper === "original" ) {
1601
			this._setPositionRelative();
1602
		}
1603
		if (this.options.addClasses){
1604
			this.element.addClass("ui-draggable");
1605
		}
1606
		if (this.options.disabled){
1607
			this.element.addClass("ui-draggable-disabled");
1608
		}
1609
		this._setHandleClassName();
1610
 
1611
		this._mouseInit();
1612
	},
1613
 
1614
	_setOption: function( key, value ) {
1615
		this._super( key, value );
1616
		if ( key === "handle" ) {
1617
			this._removeHandleClassName();
1618
			this._setHandleClassName();
1619
		}
1620
	},
1621
 
1622
	_destroy: function() {
1623
		if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
1624
			this.destroyOnClear = true;
1625
			return;
1626
		}
1627
		this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1628
		this._removeHandleClassName();
1629
		this._mouseDestroy();
1630
	},
1631
 
1632
	_mouseCapture: function(event) {
1633
		var o = this.options;
1634
 
1635
		this._blurActiveElement( event );
1636
 
1637
		// among others, prevent a drag on a resizable-handle
1638
		if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
1639
			return false;
1640
		}
1641
 
1642
		//Quit if we're not on a valid handle
1643
		this.handle = this._getHandle(event);
1644
		if (!this.handle) {
1645
			return false;
1646
		}
1647
 
1648
		this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
1649
 
1650
		return true;
1651
 
1652
	},
1653
 
1654
	_blockFrames: function( selector ) {
1655
		this.iframeBlocks = this.document.find( selector ).map(function() {
1656
			var iframe = $( this );
1657
 
1658
			return $( "<div>" )
1659
				.css( "position", "absolute" )
1660
				.appendTo( iframe.parent() )
1661
				.outerWidth( iframe.outerWidth() )
1662
				.outerHeight( iframe.outerHeight() )
1663
				.offset( iframe.offset() )[ 0 ];
1664
		});
1665
	},
1666
 
1667
	_unblockFrames: function() {
1668
		if ( this.iframeBlocks ) {
1669
			this.iframeBlocks.remove();
1670
			delete this.iframeBlocks;
1671
		}
1672
	},
1673
 
1674
	_blurActiveElement: function( event ) {
1675
		var document = this.document[ 0 ];
1676
 
1677
		// Only need to blur if the event occurred on the draggable itself, see #10527
1678
		if ( !this.handleElement.is( event.target ) ) {
1679
			return;
1680
		}
1681
 
1682
		// support: IE9
1683
		// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
1684
		try {
1685
 
1686
			// Support: IE9, IE10
1687
			// If the <body> is blurred, IE will switch windows, see #9520
1688
			if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) {
1689
 
1690
				// Blur any element that currently has focus, see #4261
1691
				$( document.activeElement ).blur();
1692
			}
1693
		} catch ( error ) {}
1694
	},
1695
 
1696
	_mouseStart: function(event) {
1697
 
1698
		var o = this.options;
1699
 
1700
		//Create and append the visible helper
1701
		this.helper = this._createHelper(event);
1702
 
1703
		this.helper.addClass("ui-draggable-dragging");
1704
 
1705
		//Cache the helper size
1706
		this._cacheHelperProportions();
1707
 
1708
		//If ddmanager is used for droppables, set the global draggable
1709
		if ($.ui.ddmanager) {
1710
			$.ui.ddmanager.current = this;
1711
		}
1712
 
1713
		/*
1714
		 * - Position generation -
1715
		 * This block generates everything position related - it's the core of draggables.
1716
		 */
1717
 
1718
		//Cache the margins of the original element
1719
		this._cacheMargins();
1720
 
1721
		//Store the helper's css position
1722
		this.cssPosition = this.helper.css( "position" );
1723
		this.scrollParent = this.helper.scrollParent( true );
1724
		this.offsetParent = this.helper.offsetParent();
1725
		this.hasFixedAncestor = this.helper.parents().filter(function() {
1726
				return $( this ).css( "position" ) === "fixed";
1727
			}).length > 0;
1728
 
1729
		//The element's absolute position on the page minus margins
1730
		this.positionAbs = this.element.offset();
1731
		this._refreshOffsets( event );
1732
 
1733
		//Generate the original position
1734
		this.originalPosition = this.position = this._generatePosition( event, false );
1735
		this.originalPageX = event.pageX;
1736
		this.originalPageY = event.pageY;
1737
 
1738
		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
1739
		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1740
 
1741
		//Set a containment if given in the options
1742
		this._setContainment();
1743
 
1744
		//Trigger event + callbacks
1745
		if (this._trigger("start", event) === false) {
1746
			this._clear();
1747
			return false;
1748
		}
1749
 
1750
		//Recache the helper size
1751
		this._cacheHelperProportions();
1752
 
1753
		//Prepare the droppable offsets
1754
		if ($.ui.ddmanager && !o.dropBehaviour) {
1755
			$.ui.ddmanager.prepareOffsets(this, event);
1756
		}
1757
 
1758
		// Reset helper's right/bottom css if they're set and set explicit width/height instead
1759
		// as this prevents resizing of elements with right/bottom set (see #7772)
1760
		this._normalizeRightBottom();
1761
 
1762
		this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1763
 
1764
		//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1765
		if ( $.ui.ddmanager ) {
1766
			$.ui.ddmanager.dragStart(this, event);
1767
		}
1768
 
1769
		return true;
1770
	},
1771
 
1772
	_refreshOffsets: function( event ) {
1773
		this.offset = {
1774
			top: this.positionAbs.top - this.margins.top,
1775
			left: this.positionAbs.left - this.margins.left,
1776
			scroll: false,
1777
			parent: this._getParentOffset(),
1778
			relative: this._getRelativeOffset()
1779
		};
1780
 
1781
		this.offset.click = {
1782
			left: event.pageX - this.offset.left,
1783
			top: event.pageY - this.offset.top
1784
		};
1785
	},
1786
 
1787
	_mouseDrag: function(event, noPropagation) {
1788
		// reset any necessary cached properties (see #5009)
1789
		if ( this.hasFixedAncestor ) {
1790
			this.offset.parent = this._getParentOffset();
1791
		}
1792
 
1793
		//Compute the helpers position
1794
		this.position = this._generatePosition( event, true );
1795
		this.positionAbs = this._convertPositionTo("absolute");
1796
 
1797
		//Call plugins and callbacks and use the resulting position if something is returned
1798
		if (!noPropagation) {
1799
			var ui = this._uiHash();
1800
			if (this._trigger("drag", event, ui) === false) {
1801
				this._mouseUp({});
1802
				return false;
1803
			}
1804
			this.position = ui.position;
1805
		}
1806
 
1807
		this.helper[ 0 ].style.left = this.position.left + "px";
1808
		this.helper[ 0 ].style.top = this.position.top + "px";
1809
 
1810
		if ($.ui.ddmanager) {
1811
			$.ui.ddmanager.drag(this, event);
1812
		}
1813
 
1814
		return false;
1815
	},
1816
 
1817
	_mouseStop: function(event) {
1818
 
1819
		//If we are using droppables, inform the manager about the drop
1820
		var that = this,
1821
			dropped = false;
1822
		if ($.ui.ddmanager && !this.options.dropBehaviour) {
1823
			dropped = $.ui.ddmanager.drop(this, event);
1824
		}
1825
 
1826
		//if a drop comes from outside (a sortable)
1827
		if (this.dropped) {
1828
			dropped = this.dropped;
1829
			this.dropped = false;
1830
		}
1831
 
1832
		if ((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
1833
			$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1834
				if (that._trigger("stop", event) !== false) {
1835
					that._clear();
1836
				}
1837
			});
1838
		} else {
1839
			if (this._trigger("stop", event) !== false) {
1840
				this._clear();
1841
			}
1842
		}
1843
 
1844
		return false;
1845
	},
1846
 
1847
	_mouseUp: function( event ) {
1848
		this._unblockFrames();
1849
 
1850
		//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1851
		if ( $.ui.ddmanager ) {
1852
			$.ui.ddmanager.dragStop(this, event);
1853
		}
1854
 
1855
		// Only need to focus if the event occurred on the draggable itself, see #10527
1856
		if ( this.handleElement.is( event.target ) ) {
1857
			// The interaction is over; whether or not the click resulted in a drag, focus the element
1858
			this.element.focus();
1859
		}
1860
 
1861
		return $.ui.mouse.prototype._mouseUp.call(this, event);
1862
	},
1863
 
1864
	cancel: function() {
1865
 
1866
		if (this.helper.is(".ui-draggable-dragging")) {
1867
			this._mouseUp({});
1868
		} else {
1869
			this._clear();
1870
		}
1871
 
1872
		return this;
1873
 
1874
	},
1875
 
1876
	_getHandle: function(event) {
1877
		return this.options.handle ?
1878
			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
1879
			true;
1880
	},
1881
 
1882
	_setHandleClassName: function() {
1883
		this.handleElement = this.options.handle ?
1884
			this.element.find( this.options.handle ) : this.element;
1885
		this.handleElement.addClass( "ui-draggable-handle" );
1886
	},
1887
 
1888
	_removeHandleClassName: function() {
1889
		this.handleElement.removeClass( "ui-draggable-handle" );
1890
	},
1891
 
1892
	_createHelper: function(event) {
1893
 
1894
		var o = this.options,
1895
			helperIsFunction = $.isFunction( o.helper ),
1896
			helper = helperIsFunction ?
1897
				$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
1898
				( o.helper === "clone" ?
1899
					this.element.clone().removeAttr( "id" ) :
1900
					this.element );
1901
 
1902
		if (!helper.parents("body").length) {
1903
			helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
1904
		}
1905
 
1906
		// http://bugs.jqueryui.com/ticket/9446
1907
		// a helper function can return the original element
1908
		// which wouldn't have been set to relative in _create
1909
		if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
1910
			this._setPositionRelative();
1911
		}
1912
 
1913
		if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
1914
			helper.css("position", "absolute");
1915
		}
1916
 
1917
		return helper;
1918
 
1919
	},
1920
 
1921
	_setPositionRelative: function() {
1922
		if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
1923
			this.element[ 0 ].style.position = "relative";
1924
		}
1925
	},
1926
 
1927
	_adjustOffsetFromHelper: function(obj) {
1928
		if (typeof obj === "string") {
1929
			obj = obj.split(" ");
1930
		}
1931
		if ($.isArray(obj)) {
1932
			obj = { left: +obj[0], top: +obj[1] || 0 };
1933
		}
1934
		if ("left" in obj) {
1935
			this.offset.click.left = obj.left + this.margins.left;
1936
		}
1937
		if ("right" in obj) {
1938
			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1939
		}
1940
		if ("top" in obj) {
1941
			this.offset.click.top = obj.top + this.margins.top;
1942
		}
1943
		if ("bottom" in obj) {
1944
			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1945
		}
1946
	},
1947
 
1948
	_isRootNode: function( element ) {
1949
		return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
1950
	},
1951
 
1952
	_getParentOffset: function() {
1953
 
1954
		//Get the offsetParent and cache its position
1955
		var po = this.offsetParent.offset(),
1956
			document = this.document[ 0 ];
1957
 
1958
		// This is a special case where we need to modify a offset calculated on start, since the following happened:
1959
		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1960
		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1961
		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1962
		if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1963
			po.left += this.scrollParent.scrollLeft();
1964
			po.top += this.scrollParent.scrollTop();
1965
		}
1966
 
1967
		if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
1968
			po = { top: 0, left: 0 };
1969
		}
1970
 
1971
		return {
1972
			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0),
1973
			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0)
1974
		};
1975
 
1976
	},
1977
 
1978
	_getRelativeOffset: function() {
1979
		if ( this.cssPosition !== "relative" ) {
1980
			return { top: 0, left: 0 };
1981
		}
1982
 
1983
		var p = this.element.position(),
1984
			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
1985
 
1986
		return {
1987
			top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
1988
			left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
1989
		};
1990
 
1991
	},
1992
 
1993
	_cacheMargins: function() {
1994
		this.margins = {
1995
			left: (parseInt(this.element.css("marginLeft"), 10) || 0),
1996
			top: (parseInt(this.element.css("marginTop"), 10) || 0),
1997
			right: (parseInt(this.element.css("marginRight"), 10) || 0),
1998
			bottom: (parseInt(this.element.css("marginBottom"), 10) || 0)
1999
		};
2000
	},
2001
 
2002
	_cacheHelperProportions: function() {
2003
		this.helperProportions = {
2004
			width: this.helper.outerWidth(),
2005
			height: this.helper.outerHeight()
2006
		};
2007
	},
2008
 
2009
	_setContainment: function() {
2010
 
2011
		var isUserScrollable, c, ce,
2012
			o = this.options,
2013
			document = this.document[ 0 ];
2014
 
2015
		this.relativeContainer = null;
2016
 
2017
		if ( !o.containment ) {
2018
			this.containment = null;
2019
			return;
2020
		}
2021
 
2022
		if ( o.containment === "window" ) {
2023
			this.containment = [
2024
				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
2025
				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
2026
				$( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
2027
				$( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
2028
			];
2029
			return;
2030
		}
2031
 
2032
		if ( o.containment === "document") {
2033
			this.containment = [
2034
				0,
2035
				0,
2036
				$( document ).width() - this.helperProportions.width - this.margins.left,
2037
				( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
2038
			];
2039
			return;
2040
		}
2041
 
2042
		if ( o.containment.constructor === Array ) {
2043
			this.containment = o.containment;
2044
			return;
2045
		}
2046
 
2047
		if ( o.containment === "parent" ) {
2048
			o.containment = this.helper[ 0 ].parentNode;
2049
		}
2050
 
2051
		c = $( o.containment );
2052
		ce = c[ 0 ];
2053
 
2054
		if ( !ce ) {
2055
			return;
2056
		}
2057
 
2058
		isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
2059
 
2060
		this.containment = [
2061
			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
2062
			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
2063
			( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
2064
				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
2065
				( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
2066
				this.helperProportions.width -
2067
				this.margins.left -
2068
				this.margins.right,
2069
			( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
2070
				( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
2071
				( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
2072
				this.helperProportions.height -
2073
				this.margins.top -
2074
				this.margins.bottom
2075
		];
2076
		this.relativeContainer = c;
2077
	},
2078
 
2079
	_convertPositionTo: function(d, pos) {
2080
 
2081
		if (!pos) {
2082
			pos = this.position;
2083
		}
2084
 
2085
		var mod = d === "absolute" ? 1 : -1,
2086
			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
2087
 
2088
		return {
2089
			top: (
2090
				pos.top	+																// The absolute mouse position
2091
				this.offset.relative.top * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
2092
				this.offset.parent.top * mod -										// The offsetParent's offset without borders (offset + border)
2093
				( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)
2094
			),
2095
			left: (
2096
				pos.left +																// The absolute mouse position
2097
				this.offset.relative.left * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
2098
				this.offset.parent.left * mod	-										// The offsetParent's offset without borders (offset + border)
2099
				( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod)
2100
			)
2101
		};
2102
 
2103
	},
2104
 
2105
	_generatePosition: function( event, constrainPosition ) {
2106
 
2107
		var containment, co, top, left,
2108
			o = this.options,
2109
			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
2110
			pageX = event.pageX,
2111
			pageY = event.pageY;
2112
 
2113
		// Cache the scroll
2114
		if ( !scrollIsRootNode || !this.offset.scroll ) {
2115
			this.offset.scroll = {
2116
				top: this.scrollParent.scrollTop(),
2117
				left: this.scrollParent.scrollLeft()
2118
			};
2119
		}
2120
 
2121
		/*
2122
		 * - Position constraining -
2123
		 * Constrain the position to a mix of grid, containment.
2124
		 */
2125
 
2126
		// If we are not dragging yet, we won't check for options
2127
		if ( constrainPosition ) {
2128
			if ( this.containment ) {
2129
				if ( this.relativeContainer ){
2130
					co = this.relativeContainer.offset();
2131
					containment = [
2132
						this.containment[ 0 ] + co.left,
2133
						this.containment[ 1 ] + co.top,
2134
						this.containment[ 2 ] + co.left,
2135
						this.containment[ 3 ] + co.top
2136
					];
2137
				} else {
2138
					containment = this.containment;
2139
				}
2140
 
2141
				if (event.pageX - this.offset.click.left < containment[0]) {
2142
					pageX = containment[0] + this.offset.click.left;
2143
				}
2144
				if (event.pageY - this.offset.click.top < containment[1]) {
2145
					pageY = containment[1] + this.offset.click.top;
2146
				}
2147
				if (event.pageX - this.offset.click.left > containment[2]) {
2148
					pageX = containment[2] + this.offset.click.left;
2149
				}
2150
				if (event.pageY - this.offset.click.top > containment[3]) {
2151
					pageY = containment[3] + this.offset.click.top;
2152
				}
2153
			}
2154
 
2155
			if (o.grid) {
2156
				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
2157
				top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
2158
				pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
2159
 
2160
				left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
2161
				pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
2162
			}
2163
 
2164
			if ( o.axis === "y" ) {
2165
				pageX = this.originalPageX;
2166
			}
2167
 
2168
			if ( o.axis === "x" ) {
2169
				pageY = this.originalPageY;
2170
			}
2171
		}
2172
 
2173
		return {
2174
			top: (
2175
				pageY -																	// The absolute mouse position
2176
				this.offset.click.top	-												// Click offset (relative to the element)
2177
				this.offset.relative.top -												// Only for relative positioned nodes: Relative offset from element to offset parent
2178
				this.offset.parent.top +												// The offsetParent's offset without borders (offset + border)
2179
				( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
2180
			),
2181
			left: (
2182
				pageX -																	// The absolute mouse position
2183
				this.offset.click.left -												// Click offset (relative to the element)
2184
				this.offset.relative.left -												// Only for relative positioned nodes: Relative offset from element to offset parent
2185
				this.offset.parent.left +												// The offsetParent's offset without borders (offset + border)
2186
				( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
2187
			)
2188
		};
2189
 
2190
	},
2191
 
2192
	_clear: function() {
2193
		this.helper.removeClass("ui-draggable-dragging");
2194
		if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
2195
			this.helper.remove();
2196
		}
2197
		this.helper = null;
2198
		this.cancelHelperRemoval = false;
2199
		if ( this.destroyOnClear ) {
2200
			this.destroy();
2201
		}
2202
	},
2203
 
2204
	_normalizeRightBottom: function() {
2205
		if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) {
2206
			this.helper.width( this.helper.width() );
2207
			this.helper.css( "right", "auto" );
2208
		}
2209
		if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) {
2210
			this.helper.height( this.helper.height() );
2211
			this.helper.css( "bottom", "auto" );
2212
		}
2213
	},
2214
 
2215
	// From now on bulk stuff - mainly helpers
2216
 
2217
	_trigger: function( type, event, ui ) {
2218
		ui = ui || this._uiHash();
2219
		$.ui.plugin.call( this, type, [ event, ui, this ], true );
2220
 
2221
		// Absolute position and offset (see #6884 ) have to be recalculated after plugins
2222
		if ( /^(drag|start|stop)/.test( type ) ) {
2223
			this.positionAbs = this._convertPositionTo( "absolute" );
2224
			ui.offset = this.positionAbs;
2225
		}
2226
		return $.Widget.prototype._trigger.call( this, type, event, ui );
2227
	},
2228
 
2229
	plugins: {},
2230
 
2231
	_uiHash: function() {
2232
		return {
2233
			helper: this.helper,
2234
			position: this.position,
2235
			originalPosition: this.originalPosition,
2236
			offset: this.positionAbs
2237
		};
2238
	}
2239
 
2240
});
2241
 
2242
$.ui.plugin.add( "draggable", "connectToSortable", {
2243
	start: function( event, ui, draggable ) {
2244
		var uiSortable = $.extend( {}, ui, {
2245
			item: draggable.element
2246
		});
2247
 
2248
		draggable.sortables = [];
2249
		$( draggable.options.connectToSortable ).each(function() {
2250
			var sortable = $( this ).sortable( "instance" );
2251
 
2252
			if ( sortable && !sortable.options.disabled ) {
2253
				draggable.sortables.push( sortable );
2254
 
2255
				// refreshPositions is called at drag start to refresh the containerCache
2256
				// which is used in drag. This ensures it's initialized and synchronized
2257
				// with any changes that might have happened on the page since initialization.
2258
				sortable.refreshPositions();
2259
				sortable._trigger("activate", event, uiSortable);
2260
			}
2261
		});
2262
	},
2263
	stop: function( event, ui, draggable ) {
2264
		var uiSortable = $.extend( {}, ui, {
2265
			item: draggable.element
2266
		});
2267
 
2268
		draggable.cancelHelperRemoval = false;
2269
 
2270
		$.each( draggable.sortables, function() {
2271
			var sortable = this;
2272
 
2273
			if ( sortable.isOver ) {
2274
				sortable.isOver = 0;
2275
 
2276
				// Allow this sortable to handle removing the helper
2277
				draggable.cancelHelperRemoval = true;
2278
				sortable.cancelHelperRemoval = false;
2279
 
2280
				// Use _storedCSS To restore properties in the sortable,
2281
				// as this also handles revert (#9675) since the draggable
2282
				// may have modified them in unexpected ways (#8809)
2283
				sortable._storedCSS = {
2284
					position: sortable.placeholder.css( "position" ),
2285
					top: sortable.placeholder.css( "top" ),
2286
					left: sortable.placeholder.css( "left" )
2287
				};
2288
 
2289
				sortable._mouseStop(event);
2290
 
2291
				// Once drag has ended, the sortable should return to using
2292
				// its original helper, not the shared helper from draggable
2293
				sortable.options.helper = sortable.options._helper;
2294
			} else {
2295
				// Prevent this Sortable from removing the helper.
2296
				// However, don't set the draggable to remove the helper
2297
				// either as another connected Sortable may yet handle the removal.
2298
				sortable.cancelHelperRemoval = true;
2299
 
2300
				sortable._trigger( "deactivate", event, uiSortable );
2301
			}
2302
		});
2303
	},
2304
	drag: function( event, ui, draggable ) {
2305
		$.each( draggable.sortables, function() {
2306
			var innermostIntersecting = false,
2307
				sortable = this;
2308
 
2309
			// Copy over variables that sortable's _intersectsWith uses
2310
			sortable.positionAbs = draggable.positionAbs;
2311
			sortable.helperProportions = draggable.helperProportions;
2312
			sortable.offset.click = draggable.offset.click;
2313
 
2314
			if ( sortable._intersectsWith( sortable.containerCache ) ) {
2315
				innermostIntersecting = true;
2316
 
2317
				$.each( draggable.sortables, function() {
2318
					// Copy over variables that sortable's _intersectsWith uses
2319
					this.positionAbs = draggable.positionAbs;
2320
					this.helperProportions = draggable.helperProportions;
2321
					this.offset.click = draggable.offset.click;
2322
 
2323
					if ( this !== sortable &&
2324
							this._intersectsWith( this.containerCache ) &&
2325
							$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
2326
						innermostIntersecting = false;
2327
					}
2328
 
2329
					return innermostIntersecting;
2330
				});
2331
			}
2332
 
2333
			if ( innermostIntersecting ) {
2334
				// If it intersects, we use a little isOver variable and set it once,
2335
				// so that the move-in stuff gets fired only once.
2336
				if ( !sortable.isOver ) {
2337
					sortable.isOver = 1;
2338
 
2339
					// Store draggable's parent in case we need to reappend to it later.
2340
					draggable._parent = ui.helper.parent();
2341
 
2342
					sortable.currentItem = ui.helper
2343
						.appendTo( sortable.element )
2344
						.data( "ui-sortable-item", true );
2345
 
2346
					// Store helper option to later restore it
2347
					sortable.options._helper = sortable.options.helper;
2348
 
2349
					sortable.options.helper = function() {
2350
						return ui.helper[ 0 ];
2351
					};
2352
 
2353
					// Fire the start events of the sortable with our passed browser event,
2354
					// and our own helper (so it doesn't create a new one)
2355
					event.target = sortable.currentItem[ 0 ];
2356
					sortable._mouseCapture( event, true );
2357
					sortable._mouseStart( event, true, true );
2358
 
2359
					// Because the browser event is way off the new appended portlet,
2360
					// modify necessary variables to reflect the changes
2361
					sortable.offset.click.top = draggable.offset.click.top;
2362
					sortable.offset.click.left = draggable.offset.click.left;
2363
					sortable.offset.parent.left -= draggable.offset.parent.left -
2364
						sortable.offset.parent.left;
2365
					sortable.offset.parent.top -= draggable.offset.parent.top -
2366
						sortable.offset.parent.top;
2367
 
2368
					draggable._trigger( "toSortable", event );
2369
 
2370
					// Inform draggable that the helper is in a valid drop zone,
2371
					// used solely in the revert option to handle "valid/invalid".
2372
					draggable.dropped = sortable.element;
2373
 
2374
					// Need to refreshPositions of all sortables in the case that
2375
					// adding to one sortable changes the location of the other sortables (#9675)
2376
					$.each( draggable.sortables, function() {
2377
						this.refreshPositions();
2378
					});
2379
 
2380
					// hack so receive/update callbacks work (mostly)
2381
					draggable.currentItem = draggable.element;
2382
					sortable.fromOutside = draggable;
2383
				}
2384
 
2385
				if ( sortable.currentItem ) {
2386
					sortable._mouseDrag( event );
2387
					// Copy the sortable's position because the draggable's can potentially reflect
2388
					// a relative position, while sortable is always absolute, which the dragged
2389
					// element has now become. (#8809)
2390
					ui.position = sortable.position;
2391
				}
2392
			} else {
2393
				// If it doesn't intersect with the sortable, and it intersected before,
2394
				// we fake the drag stop of the sortable, but make sure it doesn't remove
2395
				// the helper by using cancelHelperRemoval.
2396
				if ( sortable.isOver ) {
2397
 
2398
					sortable.isOver = 0;
2399
					sortable.cancelHelperRemoval = true;
2400
 
2401
					// Calling sortable's mouseStop would trigger a revert,
2402
					// so revert must be temporarily false until after mouseStop is called.
2403
					sortable.options._revert = sortable.options.revert;
2404
					sortable.options.revert = false;
2405
 
2406
					sortable._trigger( "out", event, sortable._uiHash( sortable ) );
2407
					sortable._mouseStop( event, true );
2408
 
2409
					// restore sortable behaviors that were modfied
2410
					// when the draggable entered the sortable area (#9481)
2411
					sortable.options.revert = sortable.options._revert;
2412
					sortable.options.helper = sortable.options._helper;
2413
 
2414
					if ( sortable.placeholder ) {
2415
						sortable.placeholder.remove();
2416
					}
2417
 
2418
					// Restore and recalculate the draggable's offset considering the sortable
2419
					// may have modified them in unexpected ways. (#8809, #10669)
2420
					ui.helper.appendTo( draggable._parent );
2421
					draggable._refreshOffsets( event );
2422
					ui.position = draggable._generatePosition( event, true );
2423
 
2424
					draggable._trigger( "fromSortable", event );
2425
 
2426
					// Inform draggable that the helper is no longer in a valid drop zone
2427
					draggable.dropped = false;
2428
 
2429
					// Need to refreshPositions of all sortables just in case removing
2430
					// from one sortable changes the location of other sortables (#9675)
2431
					$.each( draggable.sortables, function() {
2432
						this.refreshPositions();
2433
					});
2434
				}
2435
			}
2436
		});
2437
	}
2438
});
2439
 
2440
$.ui.plugin.add("draggable", "cursor", {
2441
	start: function( event, ui, instance ) {
2442
		var t = $( "body" ),
2443
			o = instance.options;
2444
 
2445
		if (t.css("cursor")) {
2446
			o._cursor = t.css("cursor");
2447
		}
2448
		t.css("cursor", o.cursor);
2449
	},
2450
	stop: function( event, ui, instance ) {
2451
		var o = instance.options;
2452
		if (o._cursor) {
2453
			$("body").css("cursor", o._cursor);
2454
		}
2455
	}
2456
});
2457
 
2458
$.ui.plugin.add("draggable", "opacity", {
2459
	start: function( event, ui, instance ) {
2460
		var t = $( ui.helper ),
2461
			o = instance.options;
2462
		if (t.css("opacity")) {
2463
			o._opacity = t.css("opacity");
2464
		}
2465
		t.css("opacity", o.opacity);
2466
	},
2467
	stop: function( event, ui, instance ) {
2468
		var o = instance.options;
2469
		if (o._opacity) {
2470
			$(ui.helper).css("opacity", o._opacity);
2471
		}
2472
	}
2473
});
2474
 
2475
$.ui.plugin.add("draggable", "scroll", {
2476
	start: function( event, ui, i ) {
2477
		if ( !i.scrollParentNotHidden ) {
2478
			i.scrollParentNotHidden = i.helper.scrollParent( false );
2479
		}
2480
 
2481
		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
2482
			i.overflowOffset = i.scrollParentNotHidden.offset();
2483
		}
2484
	},
2485
	drag: function( event, ui, i  ) {
2486
 
2487
		var o = i.options,
2488
			scrolled = false,
2489
			scrollParent = i.scrollParentNotHidden[ 0 ],
2490
			document = i.document[ 0 ];
2491
 
2492
		if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
2493
			if ( !o.axis || o.axis !== "x" ) {
2494
				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) {
2495
					scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
2496
				} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
2497
					scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
2498
				}
2499
			}
2500
 
2501
			if ( !o.axis || o.axis !== "y" ) {
2502
				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) {
2503
					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
2504
				} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
2505
					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
2506
				}
2507
			}
2508
 
2509
		} else {
2510
 
2511
			if (!o.axis || o.axis !== "x") {
2512
				if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
2513
					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
2514
				} else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
2515
					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
2516
				}
2517
			}
2518
 
2519
			if (!o.axis || o.axis !== "y") {
2520
				if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
2521
					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
2522
				} else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
2523
					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
2524
				}
2525
			}
2526
 
2527
		}
2528
 
2529
		if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
2530
			$.ui.ddmanager.prepareOffsets(i, event);
2531
		}
2532
 
2533
	}
2534
});
2535
 
2536
$.ui.plugin.add("draggable", "snap", {
2537
	start: function( event, ui, i ) {
2538
 
2539
		var o = i.options;
2540
 
2541
		i.snapElements = [];
2542
 
2543
		$(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
2544
			var $t = $(this),
2545
				$o = $t.offset();
2546
			if (this !== i.element[0]) {
2547
				i.snapElements.push({
2548
					item: this,
2549
					width: $t.outerWidth(), height: $t.outerHeight(),
2550
					top: $o.top, left: $o.left
2551
				});
2552
			}
2553
		});
2554
 
2555
	},
2556
	drag: function( event, ui, inst ) {
2557
 
2558
		var ts, bs, ls, rs, l, r, t, b, i, first,
2559
			o = inst.options,
2560
			d = o.snapTolerance,
2561
			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
2562
			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
2563
 
2564
		for (i = inst.snapElements.length - 1; i >= 0; i--){
2565
 
2566
			l = inst.snapElements[i].left - inst.margins.left;
2567
			r = l + inst.snapElements[i].width;
2568
			t = inst.snapElements[i].top - inst.margins.top;
2569
			b = t + inst.snapElements[i].height;
2570
 
2571
			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
2572
				if (inst.snapElements[i].snapping) {
2573
					(inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2574
				}
2575
				inst.snapElements[i].snapping = false;
2576
				continue;
2577
			}
2578
 
2579
			if (o.snapMode !== "inner") {
2580
				ts = Math.abs(t - y2) <= d;
2581
				bs = Math.abs(b - y1) <= d;
2582
				ls = Math.abs(l - x2) <= d;
2583
				rs = Math.abs(r - x1) <= d;
2584
				if (ts) {
2585
					ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top;
2586
				}
2587
				if (bs) {
2588
					ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top;
2589
				}
2590
				if (ls) {
2591
					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left;
2592
				}
2593
				if (rs) {
2594
					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left;
2595
				}
2596
			}
2597
 
2598
			first = (ts || bs || ls || rs);
2599
 
2600
			if (o.snapMode !== "outer") {
2601
				ts = Math.abs(t - y1) <= d;
2602
				bs = Math.abs(b - y2) <= d;
2603
				ls = Math.abs(l - x1) <= d;
2604
				rs = Math.abs(r - x2) <= d;
2605
				if (ts) {
2606
					ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top;
2607
				}
2608
				if (bs) {
2609
					ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top;
2610
				}
2611
				if (ls) {
2612
					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left;
2613
				}
2614
				if (rs) {
2615
					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left;
2616
				}
2617
			}
2618
 
2619
			if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
2620
				(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2621
			}
2622
			inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
2623
 
2624
		}
2625
 
2626
	}
2627
});
2628
 
2629
$.ui.plugin.add("draggable", "stack", {
2630
	start: function( event, ui, instance ) {
2631
		var min,
2632
			o = instance.options,
2633
			group = $.makeArray($(o.stack)).sort(function(a, b) {
2634
				return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0);
2635
			});
2636
 
2637
		if (!group.length) { return; }
2638
 
2639
		min = parseInt($(group[0]).css("zIndex"), 10) || 0;
2640
		$(group).each(function(i) {
2641
			$(this).css("zIndex", min + i);
2642
		});
2643
		this.css("zIndex", (min + group.length));
2644
	}
2645
});
2646
 
2647
$.ui.plugin.add("draggable", "zIndex", {
2648
	start: function( event, ui, instance ) {
2649
		var t = $( ui.helper ),
2650
			o = instance.options;
2651
 
2652
		if (t.css("zIndex")) {
2653
			o._zIndex = t.css("zIndex");
2654
		}
2655
		t.css("zIndex", o.zIndex);
2656
	},
2657
	stop: function( event, ui, instance ) {
2658
		var o = instance.options;
2659
 
2660
		if (o._zIndex) {
2661
			$(ui.helper).css("zIndex", o._zIndex);
2662
		}
2663
	}
2664
});
2665
 
2666
var draggable = $.ui.draggable;
2667
 
2668
 
2669
/*!
2670
 * jQuery UI Droppable 1.11.4
2671
 * http://jqueryui.com
2672
 *
2673
 * Copyright jQuery Foundation and other contributors
2674
 * Released under the MIT license.
2675
 * http://jquery.org/license
2676
 *
2677
 * http://api.jqueryui.com/droppable/
2678
 */
2679
 
2680
 
2681
$.widget( "ui.droppable", {
2682
	version: "1.11.4",
2683
	widgetEventPrefix: "drop",
2684
	options: {
2685
		accept: "*",
2686
		activeClass: false,
2687
		addClasses: true,
2688
		greedy: false,
2689
		hoverClass: false,
2690
		scope: "default",
2691
		tolerance: "intersect",
2692
 
2693
		// callbacks
2694
		activate: null,
2695
		deactivate: null,
2696
		drop: null,
2697
		out: null,
2698
		over: null
2699
	},
2700
	_create: function() {
2701
 
2702
		var proportions,
2703
			o = this.options,
2704
			accept = o.accept;
2705
 
2706
		this.isover = false;
2707
		this.isout = true;
2708
 
2709
		this.accept = $.isFunction( accept ) ? accept : function( d ) {
2710
			return d.is( accept );
2711
		};
2712
 
2713
		this.proportions = function( /* valueToWrite */ ) {
2714
			if ( arguments.length ) {
2715
				// Store the droppable's proportions
2716
				proportions = arguments[ 0 ];
2717
			} else {
2718
				// Retrieve or derive the droppable's proportions
2719
				return proportions ?
2720
					proportions :
2721
					proportions = {
2722
						width: this.element[ 0 ].offsetWidth,
2723
						height: this.element[ 0 ].offsetHeight
2724
					};
2725
			}
2726
		};
2727
 
2728
		this._addToManager( o.scope );
2729
 
2730
		o.addClasses && this.element.addClass( "ui-droppable" );
2731
 
2732
	},
2733
 
2734
	_addToManager: function( scope ) {
2735
		// Add the reference and positions to the manager
2736
		$.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
2737
		$.ui.ddmanager.droppables[ scope ].push( this );
2738
	},
2739
 
2740
	_splice: function( drop ) {
2741
		var i = 0;
2742
		for ( ; i < drop.length; i++ ) {
2743
			if ( drop[ i ] === this ) {
2744
				drop.splice( i, 1 );
2745
			}
2746
		}
2747
	},
2748
 
2749
	_destroy: function() {
2750
		var drop = $.ui.ddmanager.droppables[ this.options.scope ];
2751
 
2752
		this._splice( drop );
2753
 
2754
		this.element.removeClass( "ui-droppable ui-droppable-disabled" );
2755
	},
2756
 
2757
	_setOption: function( key, value ) {
2758
 
2759
		if ( key === "accept" ) {
2760
			this.accept = $.isFunction( value ) ? value : function( d ) {
2761
				return d.is( value );
2762
			};
2763
		} else if ( key === "scope" ) {
2764
			var drop = $.ui.ddmanager.droppables[ this.options.scope ];
2765
 
2766
			this._splice( drop );
2767
			this._addToManager( value );
2768
		}
2769
 
2770
		this._super( key, value );
2771
	},
2772
 
2773
	_activate: function( event ) {
2774
		var draggable = $.ui.ddmanager.current;
2775
		if ( this.options.activeClass ) {
2776
			this.element.addClass( this.options.activeClass );
2777
		}
2778
		if ( draggable ){
2779
			this._trigger( "activate", event, this.ui( draggable ) );
2780
		}
2781
	},
2782
 
2783
	_deactivate: function( event ) {
2784
		var draggable = $.ui.ddmanager.current;
2785
		if ( this.options.activeClass ) {
2786
			this.element.removeClass( this.options.activeClass );
2787
		}
2788
		if ( draggable ){
2789
			this._trigger( "deactivate", event, this.ui( draggable ) );
2790
		}
2791
	},
2792
 
2793
	_over: function( event ) {
2794
 
2795
		var draggable = $.ui.ddmanager.current;
2796
 
2797
		// Bail if draggable and droppable are same element
2798
		if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2799
			return;
2800
		}
2801
 
2802
		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2803
			if ( this.options.hoverClass ) {
2804
				this.element.addClass( this.options.hoverClass );
2805
			}
2806
			this._trigger( "over", event, this.ui( draggable ) );
2807
		}
2808
 
2809
	},
2810
 
2811
	_out: function( event ) {
2812
 
2813
		var draggable = $.ui.ddmanager.current;
2814
 
2815
		// Bail if draggable and droppable are same element
2816
		if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2817
			return;
2818
		}
2819
 
2820
		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2821
			if ( this.options.hoverClass ) {
2822
				this.element.removeClass( this.options.hoverClass );
2823
			}
2824
			this._trigger( "out", event, this.ui( draggable ) );
2825
		}
2826
 
2827
	},
2828
 
2829
	_drop: function( event, custom ) {
2830
 
2831
		var draggable = custom || $.ui.ddmanager.current,
2832
			childrenIntersection = false;
2833
 
2834
		// Bail if draggable and droppable are same element
2835
		if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2836
			return false;
2837
		}
2838
 
2839
		this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() {
2840
			var inst = $( this ).droppable( "instance" );
2841
			if (
2842
				inst.options.greedy &&
2843
				!inst.options.disabled &&
2844
				inst.options.scope === draggable.options.scope &&
2845
				inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) &&
2846
				$.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event )
2847
			) { childrenIntersection = true; return false; }
2848
		});
2849
		if ( childrenIntersection ) {
2850
			return false;
2851
		}
2852
 
2853
		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2854
			if ( this.options.activeClass ) {
2855
				this.element.removeClass( this.options.activeClass );
2856
			}
2857
			if ( this.options.hoverClass ) {
2858
				this.element.removeClass( this.options.hoverClass );
2859
			}
2860
			this._trigger( "drop", event, this.ui( draggable ) );
2861
			return this.element;
2862
		}
2863
 
2864
		return false;
2865
 
2866
	},
2867
 
2868
	ui: function( c ) {
2869
		return {
2870
			draggable: ( c.currentItem || c.element ),
2871
			helper: c.helper,
2872
			position: c.position,
2873
			offset: c.positionAbs
2874
		};
2875
	}
2876
 
2877
});
2878
 
2879
$.ui.intersect = (function() {
2880
	function isOverAxis( x, reference, size ) {
2881
		return ( x >= reference ) && ( x < ( reference + size ) );
2882
	}
2883
 
2884
	return function( draggable, droppable, toleranceMode, event ) {
2885
 
2886
		if ( !droppable.offset ) {
2887
			return false;
2888
		}
2889
 
2890
		var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left,
2891
			y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top,
2892
			x2 = x1 + draggable.helperProportions.width,
2893
			y2 = y1 + draggable.helperProportions.height,
2894
			l = droppable.offset.left,
2895
			t = droppable.offset.top,
2896
			r = l + droppable.proportions().width,
2897
			b = t + droppable.proportions().height;
2898
 
2899
		switch ( toleranceMode ) {
2900
		case "fit":
2901
			return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
2902
		case "intersect":
2903
			return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
2904
				x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
2905
				t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
2906
				y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
2907
		case "pointer":
2908
			return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width );
2909
		case "touch":
2910
			return (
2911
				( y1 >= t && y1 <= b ) || // Top edge touching
2912
				( y2 >= t && y2 <= b ) || // Bottom edge touching
2913
				( y1 < t && y2 > b ) // Surrounded vertically
2914
			) && (
2915
				( x1 >= l && x1 <= r ) || // Left edge touching
2916
				( x2 >= l && x2 <= r ) || // Right edge touching
2917
				( x1 < l && x2 > r ) // Surrounded horizontally
2918
			);
2919
		default:
2920
			return false;
2921
		}
2922
	};
2923
})();
2924
 
2925
/*
2926
	This manager tracks offsets of draggables and droppables
2927
*/
2928
$.ui.ddmanager = {
2929
	current: null,
2930
	droppables: { "default": [] },
2931
	prepareOffsets: function( t, event ) {
2932
 
2933
		var i, j,
2934
			m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
2935
			type = event ? event.type : null, // workaround for #2317
2936
			list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
2937
 
2938
		droppablesLoop: for ( i = 0; i < m.length; i++ ) {
2939
 
2940
			// No disabled and non-accepted
2941
			if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) {
2942
				continue;
2943
			}
2944
 
2945
			// Filter out elements in the current dragged item
2946
			for ( j = 0; j < list.length; j++ ) {
2947
				if ( list[ j ] === m[ i ].element[ 0 ] ) {
2948
					m[ i ].proportions().height = 0;
2949
					continue droppablesLoop;
2950
				}
2951
			}
2952
 
2953
			m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
2954
			if ( !m[ i ].visible ) {
2955
				continue;
2956
			}
2957
 
2958
			// Activate the droppable if used directly from draggables
2959
			if ( type === "mousedown" ) {
2960
				m[ i ]._activate.call( m[ i ], event );
2961
			}
2962
 
2963
			m[ i ].offset = m[ i ].element.offset();
2964
			m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
2965
 
2966
		}
2967
 
2968
	},
2969
	drop: function( draggable, event ) {
2970
 
2971
		var dropped = false;
2972
		// Create a copy of the droppables in case the list changes during the drop (#9116)
2973
		$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
2974
 
2975
			if ( !this.options ) {
2976
				return;
2977
			}
2978
			if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
2979
				dropped = this._drop.call( this, event ) || dropped;
2980
			}
2981
 
2982
			if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2983
				this.isout = true;
2984
				this.isover = false;
2985
				this._deactivate.call( this, event );
2986
			}
2987
 
2988
		});
2989
		return dropped;
2990
 
2991
	},
2992
	dragStart: function( draggable, event ) {
2993
		// Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2994
		draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2995
			if ( !draggable.options.refreshPositions ) {
2996
				$.ui.ddmanager.prepareOffsets( draggable, event );
2997
			}
2998
		});
2999
	},
3000
	drag: function( draggable, event ) {
3001
 
3002
		// If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
3003
		if ( draggable.options.refreshPositions ) {
3004
			$.ui.ddmanager.prepareOffsets( draggable, event );
3005
		}
3006
 
3007
		// Run through all droppables and check their positions based on specific tolerance options
3008
		$.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
3009
 
3010
			if ( this.options.disabled || this.greedyChild || !this.visible ) {
3011
				return;
3012
			}
3013
 
3014
			var parentInstance, scope, parent,
3015
				intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
3016
				c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null );
3017
			if ( !c ) {
3018
				return;
3019
			}
3020
 
3021
			if ( this.options.greedy ) {
3022
				// find droppable parents with same scope
3023
				scope = this.options.scope;
3024
				parent = this.element.parents( ":data(ui-droppable)" ).filter(function() {
3025
					return $( this ).droppable( "instance" ).options.scope === scope;
3026
				});
3027
 
3028
				if ( parent.length ) {
3029
					parentInstance = $( parent[ 0 ] ).droppable( "instance" );
3030
					parentInstance.greedyChild = ( c === "isover" );
3031
				}
3032
			}
3033
 
3034
			// we just moved into a greedy child
3035
			if ( parentInstance && c === "isover" ) {
3036
				parentInstance.isover = false;
3037
				parentInstance.isout = true;
3038
				parentInstance._out.call( parentInstance, event );
3039
			}
3040
 
3041
			this[ c ] = true;
3042
			this[c === "isout" ? "isover" : "isout"] = false;
3043
			this[c === "isover" ? "_over" : "_out"].call( this, event );
3044
 
3045
			// we just moved out of a greedy child
3046
			if ( parentInstance && c === "isout" ) {
3047
				parentInstance.isout = false;
3048
				parentInstance.isover = true;
3049
				parentInstance._over.call( parentInstance, event );
3050
			}
3051
		});
3052
 
3053
	},
3054
	dragStop: function( draggable, event ) {
3055
		draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
3056
		// Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
3057
		if ( !draggable.options.refreshPositions ) {
3058
			$.ui.ddmanager.prepareOffsets( draggable, event );
3059
		}
3060
	}
3061
};
3062
 
3063
var droppable = $.ui.droppable;
3064
 
3065
 
3066
/*!
3067
 * jQuery UI Resizable 1.11.4
3068
 * http://jqueryui.com
3069
 *
3070
 * Copyright jQuery Foundation and other contributors
3071
 * Released under the MIT license.
3072
 * http://jquery.org/license
3073
 *
3074
 * http://api.jqueryui.com/resizable/
3075
 */
3076
 
3077
 
3078
$.widget("ui.resizable", $.ui.mouse, {
3079
	version: "1.11.4",
3080
	widgetEventPrefix: "resize",
3081
	options: {
3082
		alsoResize: false,
3083
		animate: false,
3084
		animateDuration: "slow",
3085
		animateEasing: "swing",
3086
		aspectRatio: false,
3087
		autoHide: false,
3088
		containment: false,
3089
		ghost: false,
3090
		grid: false,
3091
		handles: "e,s,se",
3092
		helper: false,
3093
		maxHeight: null,
3094
		maxWidth: null,
3095
		minHeight: 10,
3096
		minWidth: 10,
3097
		// See #7960
3098
		zIndex: 90,
3099
 
3100
		// callbacks
3101
		resize: null,
3102
		start: null,
3103
		stop: null
3104
	},
3105
 
3106
	_num: function( value ) {
3107
		return parseInt( value, 10 ) || 0;
3108
	},
3109
 
3110
	_isNumber: function( value ) {
3111
		return !isNaN( parseInt( value, 10 ) );
3112
	},
3113
 
3114
	_hasScroll: function( el, a ) {
3115
 
3116
		if ( $( el ).css( "overflow" ) === "hidden") {
3117
			return false;
3118
		}
3119
 
3120
		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
3121
			has = false;
3122
 
3123
		if ( el[ scroll ] > 0 ) {
3124
			return true;
3125
		}
3126
 
3127
		// TODO: determine which cases actually cause this to happen
3128
		// if the element doesn't have the scroll set, see if it's possible to
3129
		// set the scroll
3130
		el[ scroll ] = 1;
3131
		has = ( el[ scroll ] > 0 );
3132
		el[ scroll ] = 0;
3133
		return has;
3134
	},
3135
 
3136
	_create: function() {
3137
 
3138
		var n, i, handle, axis, hname,
3139
			that = this,
3140
			o = this.options;
3141
		this.element.addClass("ui-resizable");
3142
 
3143
		$.extend(this, {
3144
			_aspectRatio: !!(o.aspectRatio),
3145
			aspectRatio: o.aspectRatio,
3146
			originalElement: this.element,
3147
			_proportionallyResizeElements: [],
3148
			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
3149
		});
3150
 
3151
		// Wrap the element if it cannot hold child nodes
3152
		if (this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)) {
3153
 
3154
			this.element.wrap(
3155
				$("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
3156
					position: this.element.css("position"),
3157
					width: this.element.outerWidth(),
3158
					height: this.element.outerHeight(),
3159
					top: this.element.css("top"),
3160
					left: this.element.css("left")
3161
				})
3162
			);
3163
 
3164
			this.element = this.element.parent().data(
3165
				"ui-resizable", this.element.resizable( "instance" )
3166
			);
3167
 
3168
			this.elementIsWrapper = true;
3169
 
3170
			this.element.css({
3171
				marginLeft: this.originalElement.css("marginLeft"),
3172
				marginTop: this.originalElement.css("marginTop"),
3173
				marginRight: this.originalElement.css("marginRight"),
3174
				marginBottom: this.originalElement.css("marginBottom")
3175
			});
3176
			this.originalElement.css({
3177
				marginLeft: 0,
3178
				marginTop: 0,
3179
				marginRight: 0,
3180
				marginBottom: 0
3181
			});
3182
			// support: Safari
3183
			// Prevent Safari textarea resize
3184
			this.originalResizeStyle = this.originalElement.css("resize");
3185
			this.originalElement.css("resize", "none");
3186
 
3187
			this._proportionallyResizeElements.push( this.originalElement.css({
3188
				position: "static",
3189
				zoom: 1,
3190
				display: "block"
3191
			}) );
3192
 
3193
			// support: IE9
3194
			// avoid IE jump (hard set the margin)
3195
			this.originalElement.css({ margin: this.originalElement.css("margin") });
3196
 
3197
			this._proportionallyResize();
3198
		}
3199
 
3200
		this.handles = o.handles ||
3201
			( !$(".ui-resizable-handle", this.element).length ?
3202
				"e,s,se" : {
3203
					n: ".ui-resizable-n",
3204
					e: ".ui-resizable-e",
3205
					s: ".ui-resizable-s",
3206
					w: ".ui-resizable-w",
3207
					se: ".ui-resizable-se",
3208
					sw: ".ui-resizable-sw",
3209
					ne: ".ui-resizable-ne",
3210
					nw: ".ui-resizable-nw"
3211
				} );
3212
 
3213
		this._handles = $();
3214
		if ( this.handles.constructor === String ) {
3215
 
3216
			if ( this.handles === "all") {
3217
				this.handles = "n,e,s,w,se,sw,ne,nw";
3218
			}
3219
 
3220
			n = this.handles.split(",");
3221
			this.handles = {};
3222
 
3223
			for (i = 0; i < n.length; i++) {
3224
 
3225
				handle = $.trim(n[i]);
3226
				hname = "ui-resizable-" + handle;
3227
				axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
3228
 
3229
				axis.css({ zIndex: o.zIndex });
3230
 
3231
				// TODO : What's going on here?
3232
				if ("se" === handle) {
3233
					axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
3234
				}
3235
 
3236
				this.handles[handle] = ".ui-resizable-" + handle;
3237
				this.element.append(axis);
3238
			}
3239
 
3240
		}
3241
 
3242
		this._renderAxis = function(target) {
3243
 
3244
			var i, axis, padPos, padWrapper;
3245
 
3246
			target = target || this.element;
3247
 
3248
			for (i in this.handles) {
3249
 
3250
				if (this.handles[i].constructor === String) {
3251
					this.handles[i] = this.element.children( this.handles[ i ] ).first().show();
3252
				} else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
3253
					this.handles[ i ] = $( this.handles[ i ] );
3254
					this._on( this.handles[ i ], { "mousedown": that._mouseDown });
3255
				}
3256
 
3257
				if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)) {
3258
 
3259
					axis = $(this.handles[i], this.element);
3260
 
3261
					padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
3262
 
3263
					padPos = [ "padding",
3264
						/ne|nw|n/.test(i) ? "Top" :
3265
						/se|sw|s/.test(i) ? "Bottom" :
3266
						/^e$/.test(i) ? "Right" : "Left" ].join("");
3267
 
3268
					target.css(padPos, padWrapper);
3269
 
3270
					this._proportionallyResize();
3271
				}
3272
 
3273
				this._handles = this._handles.add( this.handles[ i ] );
3274
			}
3275
		};
3276
 
3277
		// TODO: make renderAxis a prototype function
3278
		this._renderAxis(this.element);
3279
 
3280
		this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
3281
		this._handles.disableSelection();
3282
 
3283
		this._handles.mouseover(function() {
3284
			if (!that.resizing) {
3285
				if (this.className) {
3286
					axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
3287
				}
3288
				that.axis = axis && axis[1] ? axis[1] : "se";
3289
			}
3290
		});
3291
 
3292
		if (o.autoHide) {
3293
			this._handles.hide();
3294
			$(this.element)
3295
				.addClass("ui-resizable-autohide")
3296
				.mouseenter(function() {
3297
					if (o.disabled) {
3298
						return;
3299
					}
3300
					$(this).removeClass("ui-resizable-autohide");
3301
					that._handles.show();
3302
				})
3303
				.mouseleave(function() {
3304
					if (o.disabled) {
3305
						return;
3306
					}
3307
					if (!that.resizing) {
3308
						$(this).addClass("ui-resizable-autohide");
3309
						that._handles.hide();
3310
					}
3311
				});
3312
		}
3313
 
3314
		this._mouseInit();
3315
	},
3316
 
3317
	_destroy: function() {
3318
 
3319
		this._mouseDestroy();
3320
 
3321
		var wrapper,
3322
			_destroy = function(exp) {
3323
				$(exp)
3324
					.removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
3325
					.removeData("resizable")
3326
					.removeData("ui-resizable")
3327
					.unbind(".resizable")
3328
					.find(".ui-resizable-handle")
3329
						.remove();
3330
			};
3331
 
3332
		// TODO: Unwrap at same DOM position
3333
		if (this.elementIsWrapper) {
3334
			_destroy(this.element);
3335
			wrapper = this.element;
3336
			this.originalElement.css({
3337
				position: wrapper.css("position"),
3338
				width: wrapper.outerWidth(),
3339
				height: wrapper.outerHeight(),
3340
				top: wrapper.css("top"),
3341
				left: wrapper.css("left")
3342
			}).insertAfter( wrapper );
3343
			wrapper.remove();
3344
		}
3345
 
3346
		this.originalElement.css("resize", this.originalResizeStyle);
3347
		_destroy(this.originalElement);
3348
 
3349
		return this;
3350
	},
3351
 
3352
	_mouseCapture: function(event) {
3353
		var i, handle,
3354
			capture = false;
3355
 
3356
		for (i in this.handles) {
3357
			handle = $(this.handles[i])[0];
3358
			if (handle === event.target || $.contains(handle, event.target)) {
3359
				capture = true;
3360
			}
3361
		}
3362
 
3363
		return !this.options.disabled && capture;
3364
	},
3365
 
3366
	_mouseStart: function(event) {
3367
 
3368
		var curleft, curtop, cursor,
3369
			o = this.options,
3370
			el = this.element;
3371
 
3372
		this.resizing = true;
3373
 
3374
		this._renderProxy();
3375
 
3376
		curleft = this._num(this.helper.css("left"));
3377
		curtop = this._num(this.helper.css("top"));
3378
 
3379
		if (o.containment) {
3380
			curleft += $(o.containment).scrollLeft() || 0;
3381
			curtop += $(o.containment).scrollTop() || 0;
3382
		}
3383
 
3384
		this.offset = this.helper.offset();
3385
		this.position = { left: curleft, top: curtop };
3386
 
3387
		this.size = this._helper ? {
3388
				width: this.helper.width(),
3389
				height: this.helper.height()
3390
			} : {
3391
				width: el.width(),
3392
				height: el.height()
3393
			};
3394
 
3395
		this.originalSize = this._helper ? {
3396
				width: el.outerWidth(),
3397
				height: el.outerHeight()
3398
			} : {
3399
				width: el.width(),
3400
				height: el.height()
3401
			};
3402
 
3403
		this.sizeDiff = {
3404
			width: el.outerWidth() - el.width(),
3405
			height: el.outerHeight() - el.height()
3406
		};
3407
 
3408
		this.originalPosition = { left: curleft, top: curtop };
3409
		this.originalMousePosition = { left: event.pageX, top: event.pageY };
3410
 
3411
		this.aspectRatio = (typeof o.aspectRatio === "number") ?
3412
			o.aspectRatio :
3413
			((this.originalSize.width / this.originalSize.height) || 1);
3414
 
3415
		cursor = $(".ui-resizable-" + this.axis).css("cursor");
3416
		$("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
3417
 
3418
		el.addClass("ui-resizable-resizing");
3419
		this._propagate("start", event);
3420
		return true;
3421
	},
3422
 
3423
	_mouseDrag: function(event) {
3424
 
3425
		var data, props,
3426
			smp = this.originalMousePosition,
3427
			a = this.axis,
3428
			dx = (event.pageX - smp.left) || 0,
3429
			dy = (event.pageY - smp.top) || 0,
3430
			trigger = this._change[a];
3431
 
3432
		this._updatePrevProperties();
3433
 
3434
		if (!trigger) {
3435
			return false;
3436
		}
3437
 
3438
		data = trigger.apply(this, [ event, dx, dy ]);
3439
 
3440
		this._updateVirtualBoundaries(event.shiftKey);
3441
		if (this._aspectRatio || event.shiftKey) {
3442
			data = this._updateRatio(data, event);
3443
		}
3444
 
3445
		data = this._respectSize(data, event);
3446
 
3447
		this._updateCache(data);
3448
 
3449
		this._propagate("resize", event);
3450
 
3451
		props = this._applyChanges();
3452
 
3453
		if ( !this._helper && this._proportionallyResizeElements.length ) {
3454
			this._proportionallyResize();
3455
		}
3456
 
3457
		if ( !$.isEmptyObject( props ) ) {
3458
			this._updatePrevProperties();
3459
			this._trigger( "resize", event, this.ui() );
3460
			this._applyChanges();
3461
		}
3462
 
3463
		return false;
3464
	},
3465
 
3466
	_mouseStop: function(event) {
3467
 
3468
		this.resizing = false;
3469
		var pr, ista, soffseth, soffsetw, s, left, top,
3470
			o = this.options, that = this;
3471
 
3472
		if (this._helper) {
3473
 
3474
			pr = this._proportionallyResizeElements;
3475
			ista = pr.length && (/textarea/i).test(pr[0].nodeName);
3476
			soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height;
3477
			soffsetw = ista ? 0 : that.sizeDiff.width;
3478
 
3479
			s = {
3480
				width: (that.helper.width()  - soffsetw),
3481
				height: (that.helper.height() - soffseth)
3482
			};
3483
			left = (parseInt(that.element.css("left"), 10) +
3484
				(that.position.left - that.originalPosition.left)) || null;
3485
			top = (parseInt(that.element.css("top"), 10) +
3486
				(that.position.top - that.originalPosition.top)) || null;
3487
 
3488
			if (!o.animate) {
3489
				this.element.css($.extend(s, { top: top, left: left }));
3490
			}
3491
 
3492
			that.helper.height(that.size.height);
3493
			that.helper.width(that.size.width);
3494
 
3495
			if (this._helper && !o.animate) {
3496
				this._proportionallyResize();
3497
			}
3498
		}
3499
 
3500
		$("body").css("cursor", "auto");
3501
 
3502
		this.element.removeClass("ui-resizable-resizing");
3503
 
3504
		this._propagate("stop", event);
3505
 
3506
		if (this._helper) {
3507
			this.helper.remove();
3508
		}
3509
 
3510
		return false;
3511
 
3512
	},
3513
 
3514
	_updatePrevProperties: function() {
3515
		this.prevPosition = {
3516
			top: this.position.top,
3517
			left: this.position.left
3518
		};
3519
		this.prevSize = {
3520
			width: this.size.width,
3521
			height: this.size.height
3522
		};
3523
	},
3524
 
3525
	_applyChanges: function() {
3526
		var props = {};
3527
 
3528
		if ( this.position.top !== this.prevPosition.top ) {
3529
			props.top = this.position.top + "px";
3530
		}
3531
		if ( this.position.left !== this.prevPosition.left ) {
3532
			props.left = this.position.left + "px";
3533
		}
3534
		if ( this.size.width !== this.prevSize.width ) {
3535
			props.width = this.size.width + "px";
3536
		}
3537
		if ( this.size.height !== this.prevSize.height ) {
3538
			props.height = this.size.height + "px";
3539
		}
3540
 
3541
		this.helper.css( props );
3542
 
3543
		return props;
3544
	},
3545
 
3546
	_updateVirtualBoundaries: function(forceAspectRatio) {
3547
		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
3548
			o = this.options;
3549
 
3550
		b = {
3551
			minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0,
3552
			maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity,
3553
			minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0,
3554
			maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity
3555
		};
3556
 
3557
		if (this._aspectRatio || forceAspectRatio) {
3558
			pMinWidth = b.minHeight * this.aspectRatio;
3559
			pMinHeight = b.minWidth / this.aspectRatio;
3560
			pMaxWidth = b.maxHeight * this.aspectRatio;
3561
			pMaxHeight = b.maxWidth / this.aspectRatio;
3562
 
3563
			if (pMinWidth > b.minWidth) {
3564
				b.minWidth = pMinWidth;
3565
			}
3566
			if (pMinHeight > b.minHeight) {
3567
				b.minHeight = pMinHeight;
3568
			}
3569
			if (pMaxWidth < b.maxWidth) {
3570
				b.maxWidth = pMaxWidth;
3571
			}
3572
			if (pMaxHeight < b.maxHeight) {
3573
				b.maxHeight = pMaxHeight;
3574
			}
3575
		}
3576
		this._vBoundaries = b;
3577
	},
3578
 
3579
	_updateCache: function(data) {
3580
		this.offset = this.helper.offset();
3581
		if (this._isNumber(data.left)) {
3582
			this.position.left = data.left;
3583
		}
3584
		if (this._isNumber(data.top)) {
3585
			this.position.top = data.top;
3586
		}
3587
		if (this._isNumber(data.height)) {
3588
			this.size.height = data.height;
3589
		}
3590
		if (this._isNumber(data.width)) {
3591
			this.size.width = data.width;
3592
		}
3593
	},
3594
 
3595
	_updateRatio: function( data ) {
3596
 
3597
		var cpos = this.position,
3598
			csize = this.size,
3599
			a = this.axis;
3600
 
3601
		if (this._isNumber(data.height)) {
3602
			data.width = (data.height * this.aspectRatio);
3603
		} else if (this._isNumber(data.width)) {
3604
			data.height = (data.width / this.aspectRatio);
3605
		}
3606
 
3607
		if (a === "sw") {
3608
			data.left = cpos.left + (csize.width - data.width);
3609
			data.top = null;
3610
		}
3611
		if (a === "nw") {
3612
			data.top = cpos.top + (csize.height - data.height);
3613
			data.left = cpos.left + (csize.width - data.width);
3614
		}
3615
 
3616
		return data;
3617
	},
3618
 
3619
	_respectSize: function( data ) {
3620
 
3621
		var o = this._vBoundaries,
3622
			a = this.axis,
3623
			ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width),
3624
			ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
3625
			isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width),
3626
			isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
3627
			dw = this.originalPosition.left + this.originalSize.width,
3628
			dh = this.position.top + this.size.height,
3629
			cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
3630
		if (isminw) {
3631
			data.width = o.minWidth;
3632
		}
3633
		if (isminh) {
3634
			data.height = o.minHeight;
3635
		}
3636
		if (ismaxw) {
3637
			data.width = o.maxWidth;
3638
		}
3639
		if (ismaxh) {
3640
			data.height = o.maxHeight;
3641
		}
3642
 
3643
		if (isminw && cw) {
3644
			data.left = dw - o.minWidth;
3645
		}
3646
		if (ismaxw && cw) {
3647
			data.left = dw - o.maxWidth;
3648
		}
3649
		if (isminh && ch) {
3650
			data.top = dh - o.minHeight;
3651
		}
3652
		if (ismaxh && ch) {
3653
			data.top = dh - o.maxHeight;
3654
		}
3655
 
3656
		// Fixing jump error on top/left - bug #2330
3657
		if (!data.width && !data.height && !data.left && data.top) {
3658
			data.top = null;
3659
		} else if (!data.width && !data.height && !data.top && data.left) {
3660
			data.left = null;
3661
		}
3662
 
3663
		return data;
3664
	},
3665
 
3666
	_getPaddingPlusBorderDimensions: function( element ) {
3667
		var i = 0,
3668
			widths = [],
3669
			borders = [
3670
				element.css( "borderTopWidth" ),
3671
				element.css( "borderRightWidth" ),
3672
				element.css( "borderBottomWidth" ),
3673
				element.css( "borderLeftWidth" )
3674
			],
3675
			paddings = [
3676
				element.css( "paddingTop" ),
3677
				element.css( "paddingRight" ),
3678
				element.css( "paddingBottom" ),
3679
				element.css( "paddingLeft" )
3680
			];
3681
 
3682
		for ( ; i < 4; i++ ) {
3683
			widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 );
3684
			widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 );
3685
		}
3686
 
3687
		return {
3688
			height: widths[ 0 ] + widths[ 2 ],
3689
			width: widths[ 1 ] + widths[ 3 ]
3690
		};
3691
	},
3692
 
3693
	_proportionallyResize: function() {
3694
 
3695
		if (!this._proportionallyResizeElements.length) {
3696
			return;
3697
		}
3698
 
3699
		var prel,
3700
			i = 0,
3701
			element = this.helper || this.element;
3702
 
3703
		for ( ; i < this._proportionallyResizeElements.length; i++) {
3704
 
3705
			prel = this._proportionallyResizeElements[i];
3706
 
3707
			// TODO: Seems like a bug to cache this.outerDimensions
3708
			// considering that we are in a loop.
3709
			if (!this.outerDimensions) {
3710
				this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
3711
			}
3712
 
3713
			prel.css({
3714
				height: (element.height() - this.outerDimensions.height) || 0,
3715
				width: (element.width() - this.outerDimensions.width) || 0
3716
			});
3717
 
3718
		}
3719
 
3720
	},
3721
 
3722
	_renderProxy: function() {
3723
 
3724
		var el = this.element, o = this.options;
3725
		this.elementOffset = el.offset();
3726
 
3727
		if (this._helper) {
3728
 
3729
			this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
3730
 
3731
			this.helper.addClass(this._helper).css({
3732
				width: this.element.outerWidth() - 1,
3733
				height: this.element.outerHeight() - 1,
3734
				position: "absolute",
3735
				left: this.elementOffset.left + "px",
3736
				top: this.elementOffset.top + "px",
3737
				zIndex: ++o.zIndex //TODO: Don't modify option
3738
			});
3739
 
3740
			this.helper
3741
				.appendTo("body")
3742
				.disableSelection();
3743
 
3744
		} else {
3745
			this.helper = this.element;
3746
		}
3747
 
3748
	},
3749
 
3750
	_change: {
3751
		e: function(event, dx) {
3752
			return { width: this.originalSize.width + dx };
3753
		},
3754
		w: function(event, dx) {
3755
			var cs = this.originalSize, sp = this.originalPosition;
3756
			return { left: sp.left + dx, width: cs.width - dx };
3757
		},
3758
		n: function(event, dx, dy) {
3759
			var cs = this.originalSize, sp = this.originalPosition;
3760
			return { top: sp.top + dy, height: cs.height - dy };
3761
		},
3762
		s: function(event, dx, dy) {
3763
			return { height: this.originalSize.height + dy };
3764
		},
3765
		se: function(event, dx, dy) {
3766
			return $.extend(this._change.s.apply(this, arguments),
3767
				this._change.e.apply(this, [ event, dx, dy ]));
3768
		},
3769
		sw: function(event, dx, dy) {
3770
			return $.extend(this._change.s.apply(this, arguments),
3771
				this._change.w.apply(this, [ event, dx, dy ]));
3772
		},
3773
		ne: function(event, dx, dy) {
3774
			return $.extend(this._change.n.apply(this, arguments),
3775
				this._change.e.apply(this, [ event, dx, dy ]));
3776
		},
3777
		nw: function(event, dx, dy) {
3778
			return $.extend(this._change.n.apply(this, arguments),
3779
				this._change.w.apply(this, [ event, dx, dy ]));
3780
		}
3781
	},
3782
 
3783
	_propagate: function(n, event) {
3784
		$.ui.plugin.call(this, n, [ event, this.ui() ]);
3785
		(n !== "resize" && this._trigger(n, event, this.ui()));
3786
	},
3787
 
3788
	plugins: {},
3789
 
3790
	ui: function() {
3791
		return {
3792
			originalElement: this.originalElement,
3793
			element: this.element,
3794
			helper: this.helper,
3795
			position: this.position,
3796
			size: this.size,
3797
			originalSize: this.originalSize,
3798
			originalPosition: this.originalPosition
3799
		};
3800
	}
3801
 
3802
});
3803
 
3804
/*
3805
 * Resizable Extensions
3806
 */
3807
 
3808
$.ui.plugin.add("resizable", "animate", {
3809
 
3810
	stop: function( event ) {
3811
		var that = $(this).resizable( "instance" ),
3812
			o = that.options,
3813
			pr = that._proportionallyResizeElements,
3814
			ista = pr.length && (/textarea/i).test(pr[0].nodeName),
3815
			soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height,
3816
			soffsetw = ista ? 0 : that.sizeDiff.width,
3817
			style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
3818
			left = (parseInt(that.element.css("left"), 10) +
3819
				(that.position.left - that.originalPosition.left)) || null,
3820
			top = (parseInt(that.element.css("top"), 10) +
3821
				(that.position.top - that.originalPosition.top)) || null;
3822
 
3823
		that.element.animate(
3824
			$.extend(style, top && left ? { top: top, left: left } : {}), {
3825
				duration: o.animateDuration,
3826
				easing: o.animateEasing,
3827
				step: function() {
3828
 
3829
					var data = {
3830
						width: parseInt(that.element.css("width"), 10),
3831
						height: parseInt(that.element.css("height"), 10),
3832
						top: parseInt(that.element.css("top"), 10),
3833
						left: parseInt(that.element.css("left"), 10)
3834
					};
3835
 
3836
					if (pr && pr.length) {
3837
						$(pr[0]).css({ width: data.width, height: data.height });
3838
					}
3839
 
3840
					// propagating resize, and updating values for each animation step
3841
					that._updateCache(data);
3842
					that._propagate("resize", event);
3843
 
3844
				}
3845
			}
3846
		);
3847
	}
3848
 
3849
});
3850
 
3851
$.ui.plugin.add( "resizable", "containment", {
3852
 
3853
	start: function() {
3854
		var element, p, co, ch, cw, width, height,
3855
			that = $( this ).resizable( "instance" ),
3856
			o = that.options,
3857
			el = that.element,
3858
			oc = o.containment,
3859
			ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
3860
 
3861
		if ( !ce ) {
3862
			return;
3863
		}
3864
 
3865
		that.containerElement = $( ce );
3866
 
3867
		if ( /document/.test( oc ) || oc === document ) {
3868
			that.containerOffset = {
3869
				left: 0,
3870
				top: 0
3871
			};
3872
			that.containerPosition = {
3873
				left: 0,
3874
				top: 0
3875
			};
3876
 
3877
			that.parentData = {
3878
				element: $( document ),
3879
				left: 0,
3880
				top: 0,
3881
				width: $( document ).width(),
3882
				height: $( document ).height() || document.body.parentNode.scrollHeight
3883
			};
3884
		} else {
3885
			element = $( ce );
3886
			p = [];
3887
			$([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) {
3888
				p[ i ] = that._num( element.css( "padding" + name ) );
3889
			});
3890
 
3891
			that.containerOffset = element.offset();
3892
			that.containerPosition = element.position();
3893
			that.containerSize = {
3894
				height: ( element.innerHeight() - p[ 3 ] ),
3895
				width: ( element.innerWidth() - p[ 1 ] )
3896
			};
3897
 
3898
			co = that.containerOffset;
3899
			ch = that.containerSize.height;
3900
			cw = that.containerSize.width;
3901
			width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
3902
			height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
3903
 
3904
			that.parentData = {
3905
				element: ce,
3906
				left: co.left,
3907
				top: co.top,
3908
				width: width,
3909
				height: height
3910
			};
3911
		}
3912
	},
3913
 
3914
	resize: function( event ) {
3915
		var woset, hoset, isParent, isOffsetRelative,
3916
			that = $( this ).resizable( "instance" ),
3917
			o = that.options,
3918
			co = that.containerOffset,
3919
			cp = that.position,
3920
			pRatio = that._aspectRatio || event.shiftKey,
3921
			cop = {
3922
				top: 0,
3923
				left: 0
3924
			},
3925
			ce = that.containerElement,
3926
			continueResize = true;
3927
 
3928
		if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
3929
			cop = co;
3930
		}
3931
 
3932
		if ( cp.left < ( that._helper ? co.left : 0 ) ) {
3933
			that.size.width = that.size.width +
3934
				( that._helper ?
3935
					( that.position.left - co.left ) :
3936
					( that.position.left - cop.left ) );
3937
 
3938
			if ( pRatio ) {
3939
				that.size.height = that.size.width / that.aspectRatio;
3940
				continueResize = false;
3941
			}
3942
			that.position.left = o.helper ? co.left : 0;
3943
		}
3944
 
3945
		if ( cp.top < ( that._helper ? co.top : 0 ) ) {
3946
			that.size.height = that.size.height +
3947
				( that._helper ?
3948
					( that.position.top - co.top ) :
3949
					that.position.top );
3950
 
3951
			if ( pRatio ) {
3952
				that.size.width = that.size.height * that.aspectRatio;
3953
				continueResize = false;
3954
			}
3955
			that.position.top = that._helper ? co.top : 0;
3956
		}
3957
 
3958
		isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
3959
		isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
3960
 
3961
		if ( isParent && isOffsetRelative ) {
3962
			that.offset.left = that.parentData.left + that.position.left;
3963
			that.offset.top = that.parentData.top + that.position.top;
3964
		} else {
3965
			that.offset.left = that.element.offset().left;
3966
			that.offset.top = that.element.offset().top;
3967
		}
3968
 
3969
		woset = Math.abs( that.sizeDiff.width +
3970
			(that._helper ?
3971
				that.offset.left - cop.left :
3972
				(that.offset.left - co.left)) );
3973
 
3974
		hoset = Math.abs( that.sizeDiff.height +
3975
			(that._helper ?
3976
				that.offset.top - cop.top :
3977
				(that.offset.top - co.top)) );
3978
 
3979
		if ( woset + that.size.width >= that.parentData.width ) {
3980
			that.size.width = that.parentData.width - woset;
3981
			if ( pRatio ) {
3982
				that.size.height = that.size.width / that.aspectRatio;
3983
				continueResize = false;
3984
			}
3985
		}
3986
 
3987
		if ( hoset + that.size.height >= that.parentData.height ) {
3988
			that.size.height = that.parentData.height - hoset;
3989
			if ( pRatio ) {
3990
				that.size.width = that.size.height * that.aspectRatio;
3991
				continueResize = false;
3992
			}
3993
		}
3994
 
3995
		if ( !continueResize ) {
3996
			that.position.left = that.prevPosition.left;
3997
			that.position.top = that.prevPosition.top;
3998
			that.size.width = that.prevSize.width;
3999
			that.size.height = that.prevSize.height;
4000
		}
4001
	},
4002
 
4003
	stop: function() {
4004
		var that = $( this ).resizable( "instance" ),
4005
			o = that.options,
4006
			co = that.containerOffset,
4007
			cop = that.containerPosition,
4008
			ce = that.containerElement,
4009
			helper = $( that.helper ),
4010
			ho = helper.offset(),
4011
			w = helper.outerWidth() - that.sizeDiff.width,
4012
			h = helper.outerHeight() - that.sizeDiff.height;
4013
 
4014
		if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
4015
			$( this ).css({
4016
				left: ho.left - cop.left - co.left,
4017
				width: w,
4018
				height: h
4019
			});
4020
		}
4021
 
4022
		if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
4023
			$( this ).css({
4024
				left: ho.left - cop.left - co.left,
4025
				width: w,
4026
				height: h
4027
			});
4028
		}
4029
	}
4030
});
4031
 
4032
$.ui.plugin.add("resizable", "alsoResize", {
4033
 
4034
	start: function() {
4035
		var that = $(this).resizable( "instance" ),
4036
			o = that.options;
4037
 
4038
		$(o.alsoResize).each(function() {
4039
			var el = $(this);
4040
			el.data("ui-resizable-alsoresize", {
4041
				width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
4042
				left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
4043
			});
4044
		});
4045
	},
4046
 
4047
	resize: function(event, ui) {
4048
		var that = $(this).resizable( "instance" ),
4049
			o = that.options,
4050
			os = that.originalSize,
4051
			op = that.originalPosition,
4052
			delta = {
4053
				height: (that.size.height - os.height) || 0,
4054
				width: (that.size.width - os.width) || 0,
4055
				top: (that.position.top - op.top) || 0,
4056
				left: (that.position.left - op.left) || 0
4057
			};
4058
 
4059
			$(o.alsoResize).each(function() {
4060
				var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
4061
					css = el.parents(ui.originalElement[0]).length ?
4062
							[ "width", "height" ] :
4063
							[ "width", "height", "top", "left" ];
4064
 
4065
				$.each(css, function(i, prop) {
4066
					var sum = (start[prop] || 0) + (delta[prop] || 0);
4067
					if (sum && sum >= 0) {
4068
						style[prop] = sum || null;
4069
					}
4070
				});
4071
 
4072
				el.css(style);
4073
			});
4074
	},
4075
 
4076
	stop: function() {
4077
		$(this).removeData("resizable-alsoresize");
4078
	}
4079
});
4080
 
4081
$.ui.plugin.add("resizable", "ghost", {
4082
 
4083
	start: function() {
4084
 
4085
		var that = $(this).resizable( "instance" ), o = that.options, cs = that.size;
4086
 
4087
		that.ghost = that.originalElement.clone();
4088
		that.ghost
4089
			.css({
4090
				opacity: 0.25,
4091
				display: "block",
4092
				position: "relative",
4093
				height: cs.height,
4094
				width: cs.width,
4095
				margin: 0,
4096
				left: 0,
4097
				top: 0
4098
			})
4099
			.addClass("ui-resizable-ghost")
4100
			.addClass(typeof o.ghost === "string" ? o.ghost : "");
4101
 
4102
		that.ghost.appendTo(that.helper);
4103
 
4104
	},
4105
 
4106
	resize: function() {
4107
		var that = $(this).resizable( "instance" );
4108
		if (that.ghost) {
4109
			that.ghost.css({
4110
				position: "relative",
4111
				height: that.size.height,
4112
				width: that.size.width
4113
			});
4114
		}
4115
	},
4116
 
4117
	stop: function() {
4118
		var that = $(this).resizable( "instance" );
4119
		if (that.ghost && that.helper) {
4120
			that.helper.get(0).removeChild(that.ghost.get(0));
4121
		}
4122
	}
4123
 
4124
});
4125
 
4126
$.ui.plugin.add("resizable", "grid", {
4127
 
4128
	resize: function() {
4129
		var outerDimensions,
4130
			that = $(this).resizable( "instance" ),
4131
			o = that.options,
4132
			cs = that.size,
4133
			os = that.originalSize,
4134
			op = that.originalPosition,
4135
			a = that.axis,
4136
			grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
4137
			gridX = (grid[0] || 1),
4138
			gridY = (grid[1] || 1),
4139
			ox = Math.round((cs.width - os.width) / gridX) * gridX,
4140
			oy = Math.round((cs.height - os.height) / gridY) * gridY,
4141
			newWidth = os.width + ox,
4142
			newHeight = os.height + oy,
4143
			isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
4144
			isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
4145
			isMinWidth = o.minWidth && (o.minWidth > newWidth),
4146
			isMinHeight = o.minHeight && (o.minHeight > newHeight);
4147
 
4148
		o.grid = grid;
4149
 
4150
		if (isMinWidth) {
4151
			newWidth += gridX;
4152
		}
4153
		if (isMinHeight) {
4154
			newHeight += gridY;
4155
		}
4156
		if (isMaxWidth) {
4157
			newWidth -= gridX;
4158
		}
4159
		if (isMaxHeight) {
4160
			newHeight -= gridY;
4161
		}
4162
 
4163
		if (/^(se|s|e)$/.test(a)) {
4164
			that.size.width = newWidth;
4165
			that.size.height = newHeight;
4166
		} else if (/^(ne)$/.test(a)) {
4167
			that.size.width = newWidth;
4168
			that.size.height = newHeight;
4169
			that.position.top = op.top - oy;
4170
		} else if (/^(sw)$/.test(a)) {
4171
			that.size.width = newWidth;
4172
			that.size.height = newHeight;
4173
			that.position.left = op.left - ox;
4174
		} else {
4175
			if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) {
4176
				outerDimensions = that._getPaddingPlusBorderDimensions( this );
4177
			}
4178
 
4179
			if ( newHeight - gridY > 0 ) {
4180
				that.size.height = newHeight;
4181
				that.position.top = op.top - oy;
4182
			} else {
4183
				newHeight = gridY - outerDimensions.height;
4184
				that.size.height = newHeight;
4185
				that.position.top = op.top + os.height - newHeight;
4186
			}
4187
			if ( newWidth - gridX > 0 ) {
4188
				that.size.width = newWidth;
4189
				that.position.left = op.left - ox;
4190
			} else {
4191
				newWidth = gridX - outerDimensions.width;
4192
				that.size.width = newWidth;
4193
				that.position.left = op.left + os.width - newWidth;
4194
			}
4195
		}
4196
	}
4197
 
4198
});
4199
 
4200
var resizable = $.ui.resizable;
4201
 
4202
 
4203
/*!
4204
 * jQuery UI Selectable 1.11.4
4205
 * http://jqueryui.com
4206
 *
4207
 * Copyright jQuery Foundation and other contributors
4208
 * Released under the MIT license.
4209
 * http://jquery.org/license
4210
 *
4211
 * http://api.jqueryui.com/selectable/
4212
 */
4213
 
4214
 
4215
var selectable = $.widget("ui.selectable", $.ui.mouse, {
4216
	version: "1.11.4",
4217
	options: {
4218
		appendTo: "body",
4219
		autoRefresh: true,
4220
		distance: 0,
4221
		filter: "*",
4222
		tolerance: "touch",
4223
 
4224
		// callbacks
4225
		selected: null,
4226
		selecting: null,
4227
		start: null,
4228
		stop: null,
4229
		unselected: null,
4230
		unselecting: null
4231
	},
4232
	_create: function() {
4233
		var selectees,
4234
			that = this;
4235
 
4236
		this.element.addClass("ui-selectable");
4237
 
4238
		this.dragged = false;
4239
 
4240
		// cache selectee children based on filter
4241
		this.refresh = function() {
4242
			selectees = $(that.options.filter, that.element[0]);
4243
			selectees.addClass("ui-selectee");
4244
			selectees.each(function() {
4245
				var $this = $(this),
4246
					pos = $this.offset();
4247
				$.data(this, "selectable-item", {
4248
					element: this,
4249
					$element: $this,
4250
					left: pos.left,
4251
					top: pos.top,
4252
					right: pos.left + $this.outerWidth(),
4253
					bottom: pos.top + $this.outerHeight(),
4254
					startselected: false,
4255
					selected: $this.hasClass("ui-selected"),
4256
					selecting: $this.hasClass("ui-selecting"),
4257
					unselecting: $this.hasClass("ui-unselecting")
4258
				});
4259
			});
4260
		};
4261
		this.refresh();
4262
 
4263
		this.selectees = selectees.addClass("ui-selectee");
4264
 
4265
		this._mouseInit();
4266
 
4267
		this.helper = $("<div class='ui-selectable-helper'></div>");
4268
	},
4269
 
4270
	_destroy: function() {
4271
		this.selectees
4272
			.removeClass("ui-selectee")
4273
			.removeData("selectable-item");
4274
		this.element
4275
			.removeClass("ui-selectable ui-selectable-disabled");
4276
		this._mouseDestroy();
4277
	},
4278
 
4279
	_mouseStart: function(event) {
4280
		var that = this,
4281
			options = this.options;
4282
 
4283
		this.opos = [ event.pageX, event.pageY ];
4284
 
4285
		if (this.options.disabled) {
4286
			return;
4287
		}
4288
 
4289
		this.selectees = $(options.filter, this.element[0]);
4290
 
4291
		this._trigger("start", event);
4292
 
4293
		$(options.appendTo).append(this.helper);
4294
		// position helper (lasso)
4295
		this.helper.css({
4296
			"left": event.pageX,
4297
			"top": event.pageY,
4298
			"width": 0,
4299
			"height": 0
4300
		});
4301
 
4302
		if (options.autoRefresh) {
4303
			this.refresh();
4304
		}
4305
 
4306
		this.selectees.filter(".ui-selected").each(function() {
4307
			var selectee = $.data(this, "selectable-item");
4308
			selectee.startselected = true;
4309
			if (!event.metaKey && !event.ctrlKey) {
4310
				selectee.$element.removeClass("ui-selected");
4311
				selectee.selected = false;
4312
				selectee.$element.addClass("ui-unselecting");
4313
				selectee.unselecting = true;
4314
				// selectable UNSELECTING callback
4315
				that._trigger("unselecting", event, {
4316
					unselecting: selectee.element
4317
				});
4318
			}
4319
		});
4320
 
4321
		$(event.target).parents().addBack().each(function() {
4322
			var doSelect,
4323
				selectee = $.data(this, "selectable-item");
4324
			if (selectee) {
4325
				doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
4326
				selectee.$element
4327
					.removeClass(doSelect ? "ui-unselecting" : "ui-selected")
4328
					.addClass(doSelect ? "ui-selecting" : "ui-unselecting");
4329
				selectee.unselecting = !doSelect;
4330
				selectee.selecting = doSelect;
4331
				selectee.selected = doSelect;
4332
				// selectable (UN)SELECTING callback
4333
				if (doSelect) {
4334
					that._trigger("selecting", event, {
4335
						selecting: selectee.element
4336
					});
4337
				} else {
4338
					that._trigger("unselecting", event, {
4339
						unselecting: selectee.element
4340
					});
4341
				}
4342
				return false;
4343
			}
4344
		});
4345
 
4346
	},
4347
 
4348
	_mouseDrag: function(event) {
4349
 
4350
		this.dragged = true;
4351
 
4352
		if (this.options.disabled) {
4353
			return;
4354
		}
4355
 
4356
		var tmp,
4357
			that = this,
4358
			options = this.options,
4359
			x1 = this.opos[0],
4360
			y1 = this.opos[1],
4361
			x2 = event.pageX,
4362
			y2 = event.pageY;
4363
 
4364
		if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
4365
		if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
4366
		this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 });
4367
 
4368
		this.selectees.each(function() {
4369
			var selectee = $.data(this, "selectable-item"),
4370
				hit = false;
4371
 
4372
			//prevent helper from being selected if appendTo: selectable
4373
			if (!selectee || selectee.element === that.element[0]) {
4374
				return;
4375
			}
4376
 
4377
			if (options.tolerance === "touch") {
4378
				hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
4379
			} else if (options.tolerance === "fit") {
4380
				hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
4381
			}
4382
 
4383
			if (hit) {
4384
				// SELECT
4385
				if (selectee.selected) {
4386
					selectee.$element.removeClass("ui-selected");
4387
					selectee.selected = false;
4388
				}
4389
				if (selectee.unselecting) {
4390
					selectee.$element.removeClass("ui-unselecting");
4391
					selectee.unselecting = false;
4392
				}
4393
				if (!selectee.selecting) {
4394
					selectee.$element.addClass("ui-selecting");
4395
					selectee.selecting = true;
4396
					// selectable SELECTING callback
4397
					that._trigger("selecting", event, {
4398
						selecting: selectee.element
4399
					});
4400
				}
4401
			} else {
4402
				// UNSELECT
4403
				if (selectee.selecting) {
4404
					if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
4405
						selectee.$element.removeClass("ui-selecting");
4406
						selectee.selecting = false;
4407
						selectee.$element.addClass("ui-selected");
4408
						selectee.selected = true;
4409
					} else {
4410
						selectee.$element.removeClass("ui-selecting");
4411
						selectee.selecting = false;
4412
						if (selectee.startselected) {
4413
							selectee.$element.addClass("ui-unselecting");
4414
							selectee.unselecting = true;
4415
						}
4416
						// selectable UNSELECTING callback
4417
						that._trigger("unselecting", event, {
4418
							unselecting: selectee.element
4419
						});
4420
					}
4421
				}
4422
				if (selectee.selected) {
4423
					if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
4424
						selectee.$element.removeClass("ui-selected");
4425
						selectee.selected = false;
4426
 
4427
						selectee.$element.addClass("ui-unselecting");
4428
						selectee.unselecting = true;
4429
						// selectable UNSELECTING callback
4430
						that._trigger("unselecting", event, {
4431
							unselecting: selectee.element
4432
						});
4433
					}
4434
				}
4435
			}
4436
		});
4437
 
4438
		return false;
4439
	},
4440
 
4441
	_mouseStop: function(event) {
4442
		var that = this;
4443
 
4444
		this.dragged = false;
4445
 
4446
		$(".ui-unselecting", this.element[0]).each(function() {
4447
			var selectee = $.data(this, "selectable-item");
4448
			selectee.$element.removeClass("ui-unselecting");
4449
			selectee.unselecting = false;
4450
			selectee.startselected = false;
4451
			that._trigger("unselected", event, {
4452
				unselected: selectee.element
4453
			});
4454
		});
4455
		$(".ui-selecting", this.element[0]).each(function() {
4456
			var selectee = $.data(this, "selectable-item");
4457
			selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
4458
			selectee.selecting = false;
4459
			selectee.selected = true;
4460
			selectee.startselected = true;
4461
			that._trigger("selected", event, {
4462
				selected: selectee.element
4463
			});
4464
		});
4465
		this._trigger("stop", event);
4466
 
4467
		this.helper.remove();
4468
 
4469
		return false;
4470
	}
4471
 
4472
});
4473
 
4474
 
4475
/*!
4476
 * jQuery UI Sortable 1.11.4
4477
 * http://jqueryui.com
4478
 *
4479
 * Copyright jQuery Foundation and other contributors
4480
 * Released under the MIT license.
4481
 * http://jquery.org/license
4482
 *
4483
 * http://api.jqueryui.com/sortable/
4484
 */
4485
 
4486
 
4487
var sortable = $.widget("ui.sortable", $.ui.mouse, {
4488
	version: "1.11.4",
4489
	widgetEventPrefix: "sort",
4490
	ready: false,
4491
	options: {
4492
		appendTo: "parent",
4493
		axis: false,
4494
		connectWith: false,
4495
		containment: false,
4496
		cursor: "auto",
4497
		cursorAt: false,
4498
		dropOnEmpty: true,
4499
		forcePlaceholderSize: false,
4500
		forceHelperSize: false,
4501
		grid: false,
4502
		handle: false,
4503
		helper: "original",
4504
		items: "> *",
4505
		opacity: false,
4506
		placeholder: false,
4507
		revert: false,
4508
		scroll: true,
4509
		scrollSensitivity: 20,
4510
		scrollSpeed: 20,
4511
		scope: "default",
4512
		tolerance: "intersect",
4513
		zIndex: 1000,
4514
 
4515
		// callbacks
4516
		activate: null,
4517
		beforeStop: null,
4518
		change: null,
4519
		deactivate: null,
4520
		out: null,
4521
		over: null,
4522
		receive: null,
4523
		remove: null,
4524
		sort: null,
4525
		start: null,
4526
		stop: null,
4527
		update: null
4528
	},
4529
 
4530
	_isOverAxis: function( x, reference, size ) {
4531
		return ( x >= reference ) && ( x < ( reference + size ) );
4532
	},
4533
 
4534
	_isFloating: function( item ) {
4535
		return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
4536
	},
4537
 
4538
	_create: function() {
4539
		this.containerCache = {};
4540
		this.element.addClass("ui-sortable");
4541
 
4542
		//Get the items
4543
		this.refresh();
4544
 
4545
		//Let's determine the parent's offset
4546
		this.offset = this.element.offset();
4547
 
4548
		//Initialize mouse events for interaction
4549
		this._mouseInit();
4550
 
4551
		this._setHandleClassName();
4552
 
4553
		//We're ready to go
4554
		this.ready = true;
4555
 
4556
	},
4557
 
4558
	_setOption: function( key, value ) {
4559
		this._super( key, value );
4560
 
4561
		if ( key === "handle" ) {
4562
			this._setHandleClassName();
4563
		}
4564
	},
4565
 
4566
	_setHandleClassName: function() {
4567
		this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" );
4568
		$.each( this.items, function() {
4569
			( this.instance.options.handle ?
4570
				this.item.find( this.instance.options.handle ) : this.item )
4571
				.addClass( "ui-sortable-handle" );
4572
		});
4573
	},
4574
 
4575
	_destroy: function() {
4576
		this.element
4577
			.removeClass( "ui-sortable ui-sortable-disabled" )
4578
			.find( ".ui-sortable-handle" )
4579
				.removeClass( "ui-sortable-handle" );
4580
		this._mouseDestroy();
4581
 
4582
		for ( var i = this.items.length - 1; i >= 0; i-- ) {
4583
			this.items[i].item.removeData(this.widgetName + "-item");
4584
		}
4585
 
4586
		return this;
4587
	},
4588
 
4589
	_mouseCapture: function(event, overrideHandle) {
4590
		var currentItem = null,
4591
			validHandle = false,
4592
			that = this;
4593
 
4594
		if (this.reverting) {
4595
			return false;
4596
		}
4597
 
4598
		if(this.options.disabled || this.options.type === "static") {
4599
			return false;
4600
		}
4601
 
4602
		//We have to refresh the items data once first
4603
		this._refreshItems(event);
4604
 
4605
		//Find out if the clicked node (or one of its parents) is a actual item in this.items
4606
		$(event.target).parents().each(function() {
4607
			if($.data(this, that.widgetName + "-item") === that) {
4608
				currentItem = $(this);
4609
				return false;
4610
			}
4611
		});
4612
		if($.data(event.target, that.widgetName + "-item") === that) {
4613
			currentItem = $(event.target);
4614
		}
4615
 
4616
		if(!currentItem) {
4617
			return false;
4618
		}
4619
		if(this.options.handle && !overrideHandle) {
4620
			$(this.options.handle, currentItem).find("*").addBack().each(function() {
4621
				if(this === event.target) {
4622
					validHandle = true;
4623
				}
4624
			});
4625
			if(!validHandle) {
4626
				return false;
4627
			}
4628
		}
4629
 
4630
		this.currentItem = currentItem;
4631
		this._removeCurrentsFromItems();
4632
		return true;
4633
 
4634
	},
4635
 
4636
	_mouseStart: function(event, overrideHandle, noActivation) {
4637
 
4638
		var i, body,
4639
			o = this.options;
4640
 
4641
		this.currentContainer = this;
4642
 
4643
		//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
4644
		this.refreshPositions();
4645
 
4646
		//Create and append the visible helper
4647
		this.helper = this._createHelper(event);
4648
 
4649
		//Cache the helper size
4650
		this._cacheHelperProportions();
4651
 
4652
		/*
4653
		 * - Position generation -
4654
		 * This block generates everything position related - it's the core of draggables.
4655
		 */
4656
 
4657
		//Cache the margins of the original element
4658
		this._cacheMargins();
4659
 
4660
		//Get the next scrolling parent
4661
		this.scrollParent = this.helper.scrollParent();
4662
 
4663
		//The element's absolute position on the page minus margins
4664
		this.offset = this.currentItem.offset();
4665
		this.offset = {
4666
			top: this.offset.top - this.margins.top,
4667
			left: this.offset.left - this.margins.left
4668
		};
4669
 
4670
		$.extend(this.offset, {
4671
			click: { //Where the click happened, relative to the element
4672
				left: event.pageX - this.offset.left,
4673
				top: event.pageY - this.offset.top
4674
			},
4675
			parent: this._getParentOffset(),
4676
			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
4677
		});
4678
 
4679
		// Only after we got the offset, we can change the helper's position to absolute
4680
		// TODO: Still need to figure out a way to make relative sorting possible
4681
		this.helper.css("position", "absolute");
4682
		this.cssPosition = this.helper.css("position");
4683
 
4684
		//Generate the original position
4685
		this.originalPosition = this._generatePosition(event);
4686
		this.originalPageX = event.pageX;
4687
		this.originalPageY = event.pageY;
4688
 
4689
		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
4690
		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
4691
 
4692
		//Cache the former DOM position
4693
		this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
4694
 
4695
		//If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
4696
		if(this.helper[0] !== this.currentItem[0]) {
4697
			this.currentItem.hide();
4698
		}
4699
 
4700
		//Create the placeholder
4701
		this._createPlaceholder();
4702
 
4703
		//Set a containment if given in the options
4704
		if(o.containment) {
4705
			this._setContainment();
4706
		}
4707
 
4708
		if( o.cursor && o.cursor !== "auto" ) { // cursor option
4709
			body = this.document.find( "body" );
4710
 
4711
			// support: IE
4712
			this.storedCursor = body.css( "cursor" );
4713
			body.css( "cursor", o.cursor );
4714
 
4715
			this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
4716
		}
4717
 
4718
		if(o.opacity) { // opacity option
4719
			if (this.helper.css("opacity")) {
4720
				this._storedOpacity = this.helper.css("opacity");
4721
			}
4722
			this.helper.css("opacity", o.opacity);
4723
		}
4724
 
4725
		if(o.zIndex) { // zIndex option
4726
			if (this.helper.css("zIndex")) {
4727
				this._storedZIndex = this.helper.css("zIndex");
4728
			}
4729
			this.helper.css("zIndex", o.zIndex);
4730
		}
4731
 
4732
		//Prepare scrolling
4733
		if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
4734
			this.overflowOffset = this.scrollParent.offset();
4735
		}
4736
 
4737
		//Call callbacks
4738
		this._trigger("start", event, this._uiHash());
4739
 
4740
		//Recache the helper size
4741
		if(!this._preserveHelperProportions) {
4742
			this._cacheHelperProportions();
4743
		}
4744
 
4745
 
4746
		//Post "activate" events to possible containers
4747
		if( !noActivation ) {
4748
			for ( i = this.containers.length - 1; i >= 0; i-- ) {
4749
				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
4750
			}
4751
		}
4752
 
4753
		//Prepare possible droppables
4754
		if($.ui.ddmanager) {
4755
			$.ui.ddmanager.current = this;
4756
		}
4757
 
4758
		if ($.ui.ddmanager && !o.dropBehaviour) {
4759
			$.ui.ddmanager.prepareOffsets(this, event);
4760
		}
4761
 
4762
		this.dragging = true;
4763
 
4764
		this.helper.addClass("ui-sortable-helper");
4765
		this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
4766
		return true;
4767
 
4768
	},
4769
 
4770
	_mouseDrag: function(event) {
4771
		var i, item, itemElement, intersection,
4772
			o = this.options,
4773
			scrolled = false;
4774
 
4775
		//Compute the helpers position
4776
		this.position = this._generatePosition(event);
4777
		this.positionAbs = this._convertPositionTo("absolute");
4778
 
4779
		if (!this.lastPositionAbs) {
4780
			this.lastPositionAbs = this.positionAbs;
4781
		}
4782
 
4783
		//Do scrolling
4784
		if(this.options.scroll) {
4785
			if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
4786
 
4787
				if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
4788
					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
4789
				} else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
4790
					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
4791
				}
4792
 
4793
				if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
4794
					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
4795
				} else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
4796
					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
4797
				}
4798
 
4799
			} else {
4800
 
4801
				if(event.pageY - this.document.scrollTop() < o.scrollSensitivity) {
4802
					scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed);
4803
				} else if(this.window.height() - (event.pageY - this.document.scrollTop()) < o.scrollSensitivity) {
4804
					scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed);
4805
				}
4806
 
4807
				if(event.pageX - this.document.scrollLeft() < o.scrollSensitivity) {
4808
					scrolled = this.document.scrollLeft(this.document.scrollLeft() - o.scrollSpeed);
4809
				} else if(this.window.width() - (event.pageX - this.document.scrollLeft()) < o.scrollSensitivity) {
4810
					scrolled = this.document.scrollLeft(this.document.scrollLeft() + o.scrollSpeed);
4811
				}
4812
 
4813
			}
4814
 
4815
			if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
4816
				$.ui.ddmanager.prepareOffsets(this, event);
4817
			}
4818
		}
4819
 
4820
		//Regenerate the absolute position used for position checks
4821
		this.positionAbs = this._convertPositionTo("absolute");
4822
 
4823
		//Set the helper position
4824
		if(!this.options.axis || this.options.axis !== "y") {
4825
			this.helper[0].style.left = this.position.left+"px";
4826
		}
4827
		if(!this.options.axis || this.options.axis !== "x") {
4828
			this.helper[0].style.top = this.position.top+"px";
4829
		}
4830
 
4831
		//Rearrange
4832
		for (i = this.items.length - 1; i >= 0; i--) {
4833
 
4834
			//Cache variables and intersection, continue if no intersection
4835
			item = this.items[i];
4836
			itemElement = item.item[0];
4837
			intersection = this._intersectsWithPointer(item);
4838
			if (!intersection) {
4839
				continue;
4840
			}
4841
 
4842
			// Only put the placeholder inside the current Container, skip all
4843
			// items from other containers. This works because when moving
4844
			// an item from one container to another the
4845
			// currentContainer is switched before the placeholder is moved.
4846
			//
4847
			// Without this, moving items in "sub-sortables" can cause
4848
			// the placeholder to jitter between the outer and inner container.
4849
			if (item.instance !== this.currentContainer) {
4850
				continue;
4851
			}
4852
 
4853
			// cannot intersect with itself
4854
			// no useless actions that have been done before
4855
			// no action if the item moved is the parent of the item checked
4856
			if (itemElement !== this.currentItem[0] &&
4857
				this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
4858
				!$.contains(this.placeholder[0], itemElement) &&
4859
				(this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
4860
			) {
4861
 
4862
				this.direction = intersection === 1 ? "down" : "up";
4863
 
4864
				if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
4865
					this._rearrange(event, item);
4866
				} else {
4867
					break;
4868
				}
4869
 
4870
				this._trigger("change", event, this._uiHash());
4871
				break;
4872
			}
4873
		}
4874
 
4875
		//Post events to containers
4876
		this._contactContainers(event);
4877
 
4878
		//Interconnect with droppables
4879
		if($.ui.ddmanager) {
4880
			$.ui.ddmanager.drag(this, event);
4881
		}
4882
 
4883
		//Call callbacks
4884
		this._trigger("sort", event, this._uiHash());
4885
 
4886
		this.lastPositionAbs = this.positionAbs;
4887
		return false;
4888
 
4889
	},
4890
 
4891
	_mouseStop: function(event, noPropagation) {
4892
 
4893
		if(!event) {
4894
			return;
4895
		}
4896
 
4897
		//If we are using droppables, inform the manager about the drop
4898
		if ($.ui.ddmanager && !this.options.dropBehaviour) {
4899
			$.ui.ddmanager.drop(this, event);
4900
		}
4901
 
4902
		if(this.options.revert) {
4903
			var that = this,
4904
				cur = this.placeholder.offset(),
4905
				axis = this.options.axis,
4906
				animation = {};
4907
 
4908
			if ( !axis || axis === "x" ) {
4909
				animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollLeft);
4910
			}
4911
			if ( !axis || axis === "y" ) {
4912
				animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollTop);
4913
			}
4914
			this.reverting = true;
4915
			$(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
4916
				that._clear(event);
4917
			});
4918
		} else {
4919
			this._clear(event, noPropagation);
4920
		}
4921
 
4922
		return false;
4923
 
4924
	},
4925
 
4926
	cancel: function() {
4927
 
4928
		if(this.dragging) {
4929
 
4930
			this._mouseUp({ target: null });
4931
 
4932
			if(this.options.helper === "original") {
4933
				this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4934
			} else {
4935
				this.currentItem.show();
4936
			}
4937
 
4938
			//Post deactivating events to containers
4939
			for (var i = this.containers.length - 1; i >= 0; i--){
4940
				this.containers[i]._trigger("deactivate", null, this._uiHash(this));
4941
				if(this.containers[i].containerCache.over) {
4942
					this.containers[i]._trigger("out", null, this._uiHash(this));
4943
					this.containers[i].containerCache.over = 0;
4944
				}
4945
			}
4946
 
4947
		}
4948
 
4949
		if (this.placeholder) {
4950
			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4951
			if(this.placeholder[0].parentNode) {
4952
				this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4953
			}
4954
			if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
4955
				this.helper.remove();
4956
			}
4957
 
4958
			$.extend(this, {
4959
				helper: null,
4960
				dragging: false,
4961
				reverting: false,
4962
				_noFinalSort: null
4963
			});
4964
 
4965
			if(this.domPosition.prev) {
4966
				$(this.domPosition.prev).after(this.currentItem);
4967
			} else {
4968
				$(this.domPosition.parent).prepend(this.currentItem);
4969
			}
4970
		}
4971
 
4972
		return this;
4973
 
4974
	},
4975
 
4976
	serialize: function(o) {
4977
 
4978
		var items = this._getItemsAsjQuery(o && o.connected),
4979
			str = [];
4980
		o = o || {};
4981
 
4982
		$(items).each(function() {
4983
			var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
4984
			if (res) {
4985
				str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
4986
			}
4987
		});
4988
 
4989
		if(!str.length && o.key) {
4990
			str.push(o.key + "=");
4991
		}
4992
 
4993
		return str.join("&");
4994
 
4995
	},
4996
 
4997
	toArray: function(o) {
4998
 
4999
		var items = this._getItemsAsjQuery(o && o.connected),
5000
			ret = [];
5001
 
5002
		o = o || {};
5003
 
5004
		items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
5005
		return ret;
5006
 
5007
	},
5008
 
5009
	/* Be careful with the following core functions */
5010
	_intersectsWith: function(item) {
5011
 
5012
		var x1 = this.positionAbs.left,
5013
			x2 = x1 + this.helperProportions.width,
5014
			y1 = this.positionAbs.top,
5015
			y2 = y1 + this.helperProportions.height,
5016
			l = item.left,
5017
			r = l + item.width,
5018
			t = item.top,
5019
			b = t + item.height,
5020
			dyClick = this.offset.click.top,
5021
			dxClick = this.offset.click.left,
5022
			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
5023
			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
5024
			isOverElement = isOverElementHeight && isOverElementWidth;
5025
 
5026
		if ( this.options.tolerance === "pointer" ||
5027
			this.options.forcePointerForContainers ||
5028
			(this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
5029
		) {
5030
			return isOverElement;
5031
		} else {
5032
 
5033
			return (l < x1 + (this.helperProportions.width / 2) && // Right Half
5034
				x2 - (this.helperProportions.width / 2) < r && // Left Half
5035
				t < y1 + (this.helperProportions.height / 2) && // Bottom Half
5036
				y2 - (this.helperProportions.height / 2) < b ); // Top Half
5037
 
5038
		}
5039
	},
5040
 
5041
	_intersectsWithPointer: function(item) {
5042
 
5043
		var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
5044
			isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
5045
			isOverElement = isOverElementHeight && isOverElementWidth,
5046
			verticalDirection = this._getDragVerticalDirection(),
5047
			horizontalDirection = this._getDragHorizontalDirection();
5048
 
5049
		if (!isOverElement) {
5050
			return false;
5051
		}
5052
 
5053
		return this.floating ?
5054
			( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
5055
			: ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
5056
 
5057
	},
5058
 
5059
	_intersectsWithSides: function(item) {
5060
 
5061
		var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
5062
			isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
5063
			verticalDirection = this._getDragVerticalDirection(),
5064
			horizontalDirection = this._getDragHorizontalDirection();
5065
 
5066
		if (this.floating && horizontalDirection) {
5067
			return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
5068
		} else {
5069
			return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
5070
		}
5071
 
5072
	},
5073
 
5074
	_getDragVerticalDirection: function() {
5075
		var delta = this.positionAbs.top - this.lastPositionAbs.top;
5076
		return delta !== 0 && (delta > 0 ? "down" : "up");
5077
	},
5078
 
5079
	_getDragHorizontalDirection: function() {
5080
		var delta = this.positionAbs.left - this.lastPositionAbs.left;
5081
		return delta !== 0 && (delta > 0 ? "right" : "left");
5082
	},
5083
 
5084
	refresh: function(event) {
5085
		this._refreshItems(event);
5086
		this._setHandleClassName();
5087
		this.refreshPositions();
5088
		return this;
5089
	},
5090
 
5091
	_connectWith: function() {
5092
		var options = this.options;
5093
		return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
5094
	},
5095
 
5096
	_getItemsAsjQuery: function(connected) {
5097
 
5098
		var i, j, cur, inst,
5099
			items = [],
5100
			queries = [],
5101
			connectWith = this._connectWith();
5102
 
5103
		if(connectWith && connected) {
5104
			for (i = connectWith.length - 1; i >= 0; i--){
5105
				cur = $(connectWith[i], this.document[0]);
5106
				for ( j = cur.length - 1; j >= 0; j--){
5107
					inst = $.data(cur[j], this.widgetFullName);
5108
					if(inst && inst !== this && !inst.options.disabled) {
5109
						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]);
5110
					}
5111
				}
5112
			}
5113
		}
5114
 
5115
		queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]);
5116
 
5117
		function addItems() {
5118
			items.push( this );
5119
		}
5120
		for (i = queries.length - 1; i >= 0; i--){
5121
			queries[i][0].each( addItems );
5122
		}
5123
 
5124
		return $(items);
5125
 
5126
	},
5127
 
5128
	_removeCurrentsFromItems: function() {
5129
 
5130
		var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
5131
 
5132
		this.items = $.grep(this.items, function (item) {
5133
			for (var j=0; j < list.length; j++) {
5134
				if(list[j] === item.item[0]) {
5135
					return false;
5136
				}
5137
			}
5138
			return true;
5139
		});
5140
 
5141
	},
5142
 
5143
	_refreshItems: function(event) {
5144
 
5145
		this.items = [];
5146
		this.containers = [this];
5147
 
5148
		var i, j, cur, inst, targetData, _queries, item, queriesLength,
5149
			items = this.items,
5150
			queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
5151
			connectWith = this._connectWith();
5152
 
5153
		if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
5154
			for (i = connectWith.length - 1; i >= 0; i--){
5155
				cur = $(connectWith[i], this.document[0]);
5156
				for (j = cur.length - 1; j >= 0; j--){
5157
					inst = $.data(cur[j], this.widgetFullName);
5158
					if(inst && inst !== this && !inst.options.disabled) {
5159
						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
5160
						this.containers.push(inst);
5161
					}
5162
				}
5163
			}
5164
		}
5165
 
5166
		for (i = queries.length - 1; i >= 0; i--) {
5167
			targetData = queries[i][1];
5168
			_queries = queries[i][0];
5169
 
5170
			for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
5171
				item = $(_queries[j]);
5172
 
5173
				item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
5174
 
5175
				items.push({
5176
					item: item,
5177
					instance: targetData,
5178
					width: 0, height: 0,
5179
					left: 0, top: 0
5180
				});
5181
			}
5182
		}
5183
 
5184
	},
5185
 
5186
	refreshPositions: function(fast) {
5187
 
5188
		// Determine whether items are being displayed horizontally
5189
		this.floating = this.items.length ?
5190
			this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
5191
			false;
5192
 
5193
		//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
5194
		if(this.offsetParent && this.helper) {
5195
			this.offset.parent = this._getParentOffset();
5196
		}
5197
 
5198
		var i, item, t, p;
5199
 
5200
		for (i = this.items.length - 1; i >= 0; i--){
5201
			item = this.items[i];
5202
 
5203
			//We ignore calculating positions of all connected containers when we're not over them
5204
			if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
5205
				continue;
5206
			}
5207
 
5208
			t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
5209
 
5210
			if (!fast) {
5211
				item.width = t.outerWidth();
5212
				item.height = t.outerHeight();
5213
			}
5214
 
5215
			p = t.offset();
5216
			item.left = p.left;
5217
			item.top = p.top;
5218
		}
5219
 
5220
		if(this.options.custom && this.options.custom.refreshContainers) {
5221
			this.options.custom.refreshContainers.call(this);
5222
		} else {
5223
			for (i = this.containers.length - 1; i >= 0; i--){
5224
				p = this.containers[i].element.offset();
5225
				this.containers[i].containerCache.left = p.left;
5226
				this.containers[i].containerCache.top = p.top;
5227
				this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
5228
				this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
5229
			}
5230
		}
5231
 
5232
		return this;
5233
	},
5234
 
5235
	_createPlaceholder: function(that) {
5236
		that = that || this;
5237
		var className,
5238
			o = that.options;
5239
 
5240
		if(!o.placeholder || o.placeholder.constructor === String) {
5241
			className = o.placeholder;
5242
			o.placeholder = {
5243
				element: function() {
5244
 
5245
					var nodeName = that.currentItem[0].nodeName.toLowerCase(),
5246
						element = $( "<" + nodeName + ">", that.document[0] )
5247
							.addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
5248
							.removeClass("ui-sortable-helper");
5249
 
5250
					if ( nodeName === "tbody" ) {
5251
						that._createTrPlaceholder(
5252
							that.currentItem.find( "tr" ).eq( 0 ),
5253
							$( "<tr>", that.document[ 0 ] ).appendTo( element )
5254
						);
5255
					} else if ( nodeName === "tr" ) {
5256
						that._createTrPlaceholder( that.currentItem, element );
5257
					} else if ( nodeName === "img" ) {
5258
						element.attr( "src", that.currentItem.attr( "src" ) );
5259
					}
5260
 
5261
					if ( !className ) {
5262
						element.css( "visibility", "hidden" );
5263
					}
5264
 
5265
					return element;
5266
				},
5267
				update: function(container, p) {
5268
 
5269
					// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
5270
					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
5271
					if(className && !o.forcePlaceholderSize) {
5272
						return;
5273
					}
5274
 
5275
					//If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
5276
					if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
5277
					if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
5278
				}
5279
			};
5280
		}
5281
 
5282
		//Create the placeholder
5283
		that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
5284
 
5285
		//Append it after the actual current item
5286
		that.currentItem.after(that.placeholder);
5287
 
5288
		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
5289
		o.placeholder.update(that, that.placeholder);
5290
 
5291
	},
5292
 
5293
	_createTrPlaceholder: function( sourceTr, targetTr ) {
5294
		var that = this;
5295
 
5296
		sourceTr.children().each(function() {
5297
			$( "<td>&#160;</td>", that.document[ 0 ] )
5298
				.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
5299
				.appendTo( targetTr );
5300
		});
5301
	},
5302
 
5303
	_contactContainers: function(event) {
5304
		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis,
5305
			innermostContainer = null,
5306
			innermostIndex = null;
5307
 
5308
		// get innermost container that intersects with item
5309
		for (i = this.containers.length - 1; i >= 0; i--) {
5310
 
5311
			// never consider a container that's located within the item itself
5312
			if($.contains(this.currentItem[0], this.containers[i].element[0])) {
5313
				continue;
5314
			}
5315
 
5316
			if(this._intersectsWith(this.containers[i].containerCache)) {
5317
 
5318
				// if we've already found a container and it's more "inner" than this, then continue
5319
				if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
5320
					continue;
5321
				}
5322
 
5323
				innermostContainer = this.containers[i];
5324
				innermostIndex = i;
5325
 
5326
			} else {
5327
				// container doesn't intersect. trigger "out" event if necessary
5328
				if(this.containers[i].containerCache.over) {
5329
					this.containers[i]._trigger("out", event, this._uiHash(this));
5330
					this.containers[i].containerCache.over = 0;
5331
				}
5332
			}
5333
 
5334
		}
5335
 
5336
		// if no intersecting containers found, return
5337
		if(!innermostContainer) {
5338
			return;
5339
		}
5340
 
5341
		// move the item into the container if it's not there already
5342
		if(this.containers.length === 1) {
5343
			if (!this.containers[innermostIndex].containerCache.over) {
5344
				this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
5345
				this.containers[innermostIndex].containerCache.over = 1;
5346
			}
5347
		} else {
5348
 
5349
			//When entering a new container, we will find the item with the least distance and append our item near it
5350
			dist = 10000;
5351
			itemWithLeastDistance = null;
5352
			floating = innermostContainer.floating || this._isFloating(this.currentItem);
5353
			posProperty = floating ? "left" : "top";
5354
			sizeProperty = floating ? "width" : "height";
5355
			axis = floating ? "clientX" : "clientY";
5356
 
5357
			for (j = this.items.length - 1; j >= 0; j--) {
5358
				if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
5359
					continue;
5360
				}
5361
				if(this.items[j].item[0] === this.currentItem[0]) {
5362
					continue;
5363
				}
5364
 
5365
				cur = this.items[j].item.offset()[posProperty];
5366
				nearBottom = false;
5367
				if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
5368
					nearBottom = true;
5369
				}
5370
 
5371
				if ( Math.abs( event[ axis ] - cur ) < dist ) {
5372
					dist = Math.abs( event[ axis ] - cur );
5373
					itemWithLeastDistance = this.items[ j ];
5374
					this.direction = nearBottom ? "up": "down";
5375
				}
5376
			}
5377
 
5378
			//Check if dropOnEmpty is enabled
5379
			if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
5380
				return;
5381
			}
5382
 
5383
			if(this.currentContainer === this.containers[innermostIndex]) {
5384
				if ( !this.currentContainer.containerCache.over ) {
5385
					this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
5386
					this.currentContainer.containerCache.over = 1;
5387
				}
5388
				return;
5389
			}
5390
 
5391
			itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
5392
			this._trigger("change", event, this._uiHash());
5393
			this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
5394
			this.currentContainer = this.containers[innermostIndex];
5395
 
5396
			//Update the placeholder
5397
			this.options.placeholder.update(this.currentContainer, this.placeholder);
5398
 
5399
			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
5400
			this.containers[innermostIndex].containerCache.over = 1;
5401
		}
5402
 
5403
 
5404
	},
5405
 
5406
	_createHelper: function(event) {
5407
 
5408
		var o = this.options,
5409
			helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
5410
 
5411
		//Add the helper to the DOM if that didn't happen already
5412
		if(!helper.parents("body").length) {
5413
			$(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
5414
		}
5415
 
5416
		if(helper[0] === this.currentItem[0]) {
5417
			this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
5418
		}
5419
 
5420
		if(!helper[0].style.width || o.forceHelperSize) {
5421
			helper.width(this.currentItem.width());
5422
		}
5423
		if(!helper[0].style.height || o.forceHelperSize) {
5424
			helper.height(this.currentItem.height());
5425
		}
5426
 
5427
		return helper;
5428
 
5429
	},
5430
 
5431
	_adjustOffsetFromHelper: function(obj) {
5432
		if (typeof obj === "string") {
5433
			obj = obj.split(" ");
5434
		}
5435
		if ($.isArray(obj)) {
5436
			obj = {left: +obj[0], top: +obj[1] || 0};
5437
		}
5438
		if ("left" in obj) {
5439
			this.offset.click.left = obj.left + this.margins.left;
5440
		}
5441
		if ("right" in obj) {
5442
			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
5443
		}
5444
		if ("top" in obj) {
5445
			this.offset.click.top = obj.top + this.margins.top;
5446
		}
5447
		if ("bottom" in obj) {
5448
			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
5449
		}
5450
	},
5451
 
5452
	_getParentOffset: function() {
5453
 
5454
 
5455
		//Get the offsetParent and cache its position
5456
		this.offsetParent = this.helper.offsetParent();
5457
		var po = this.offsetParent.offset();
5458
 
5459
		// This is a special case where we need to modify a offset calculated on start, since the following happened:
5460
		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
5461
		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
5462
		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
5463
		if(this.cssPosition === "absolute" && this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) {
5464
			po.left += this.scrollParent.scrollLeft();
5465
			po.top += this.scrollParent.scrollTop();
5466
		}
5467
 
5468
		// This needs to be actually done for all browsers, since pageX/pageY includes this information
5469
		// with an ugly IE fix
5470
		if( this.offsetParent[0] === this.document[0].body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
5471
			po = { top: 0, left: 0 };
5472
		}
5473
 
5474
		return {
5475
			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
5476
			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
5477
		};
5478
 
5479
	},
5480
 
5481
	_getRelativeOffset: function() {
5482
 
5483
		if(this.cssPosition === "relative") {
5484
			var p = this.currentItem.position();
5485
			return {
5486
				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
5487
				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
5488
			};
5489
		} else {
5490
			return { top: 0, left: 0 };
5491
		}
5492
 
5493
	},
5494
 
5495
	_cacheMargins: function() {
5496
		this.margins = {
5497
			left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
5498
			top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
5499
		};
5500
	},
5501
 
5502
	_cacheHelperProportions: function() {
5503
		this.helperProportions = {
5504
			width: this.helper.outerWidth(),
5505
			height: this.helper.outerHeight()
5506
		};
5507
	},
5508
 
5509
	_setContainment: function() {
5510
 
5511
		var ce, co, over,
5512
			o = this.options;
5513
		if(o.containment === "parent") {
5514
			o.containment = this.helper[0].parentNode;
5515
		}
5516
		if(o.containment === "document" || o.containment === "window") {
5517
			this.containment = [
5518
 
5519
 
5520
				o.containment === "document" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left,
5521
				(o.containment === "document" ? this.document.width() : this.window.height() || this.document[0].body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
5522
			];
5523
		}
5524
 
5525
		if(!(/^(document|window|parent)$/).test(o.containment)) {
5526
			ce = $(o.containment)[0];
5527
			co = $(o.containment).offset();
5528
			over = ($(ce).css("overflow") !== "hidden");
5529
 
5530
			this.containment = [
5531
				co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
5532
				co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
5533
				co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
5534
				co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
5535
			];
5536
		}
5537
 
5538
	},
5539
 
5540
	_convertPositionTo: function(d, pos) {
5541
 
5542
		if(!pos) {
5543
			pos = this.position;
5544
		}
5545
		var mod = d === "absolute" ? 1 : -1,
5546
			scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
5547
			scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
5548
 
5549
		return {
5550
			top: (
5551
				pos.top	+																// The absolute mouse position
5552
				this.offset.relative.top * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
5553
				this.offset.parent.top * mod -											// The offsetParent's offset without borders (offset + border)
5554
				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
5555
			),
5556
			left: (
5557
				pos.left +																// The absolute mouse position
5558
				this.offset.relative.left * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
5559
				this.offset.parent.left * mod	-										// The offsetParent's offset without borders (offset + border)
5560
				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
5561
			)
5562
		};
5563
 
5564
	},
5565
 
5566
	_generatePosition: function(event) {
5567
 
5568
		var top, left,
5569
			o = this.options,
5570
			pageX = event.pageX,
5571
			pageY = event.pageY,
5572
			scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
5573
 
5574
		// This is another very weird special case that only happens for relative elements:
5575
		// 1. If the css position is relative
5576
		// 2. and the scroll parent is the document or similar to the offset parent
5577
		// we have to refresh the relative offset during the scroll so there are no jumps
5578
		if(this.cssPosition === "relative" && !(this.scrollParent[0] !== this.document[0] && this.scrollParent[0] !== this.offsetParent[0])) {
5579
			this.offset.relative = this._getRelativeOffset();
5580
		}
5581
 
5582
		/*
5583
		 * - Position constraining -
5584
		 * Constrain the position to a mix of grid, containment.
5585
		 */
5586
 
5587
		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
5588
 
5589
			if(this.containment) {
5590
				if(event.pageX - this.offset.click.left < this.containment[0]) {
5591
					pageX = this.containment[0] + this.offset.click.left;
5592
				}
5593
				if(event.pageY - this.offset.click.top < this.containment[1]) {
5594
					pageY = this.containment[1] + this.offset.click.top;
5595
				}
5596
				if(event.pageX - this.offset.click.left > this.containment[2]) {
5597
					pageX = this.containment[2] + this.offset.click.left;
5598
				}
5599
				if(event.pageY - this.offset.click.top > this.containment[3]) {
5600
					pageY = this.containment[3] + this.offset.click.top;
5601
				}
5602
			}
5603
 
5604
			if(o.grid) {
5605
				top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
5606
				pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
5607
 
5608
				left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
5609
				pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
5610
			}
5611
 
5612
		}
5613
 
5614
		return {
5615
			top: (
5616
				pageY -																// The absolute mouse position
5617
				this.offset.click.top -													// Click offset (relative to the element)
5618
				this.offset.relative.top	-											// Only for relative positioned nodes: Relative offset from element to offset parent
5619
				this.offset.parent.top +												// The offsetParent's offset without borders (offset + border)
5620
				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
5621
			),
5622
			left: (
5623
				pageX -																// The absolute mouse position
5624
				this.offset.click.left -												// Click offset (relative to the element)
5625
				this.offset.relative.left	-											// Only for relative positioned nodes: Relative offset from element to offset parent
5626
				this.offset.parent.left +												// The offsetParent's offset without borders (offset + border)
5627
				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
5628
			)
5629
		};
5630
 
5631
	},
5632
 
5633
	_rearrange: function(event, i, a, hardRefresh) {
5634
 
5635
		a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling));
5636
 
5637
		//Various things done here to improve the performance:
5638
		// 1. we create a setTimeout, that calls refreshPositions
5639
		// 2. on the instance, we have a counter variable, that get's higher after every append
5640
		// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
5641
		// 4. this lets only the last addition to the timeout stack through
5642
		this.counter = this.counter ? ++this.counter : 1;
5643
		var counter = this.counter;
5644
 
5645
		this._delay(function() {
5646
			if(counter === this.counter) {
5647
				this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
5648
			}
5649
		});
5650
 
5651
	},
5652
 
5653
	_clear: function(event, noPropagation) {
5654
 
5655
		this.reverting = false;
5656
		// We delay all events that have to be triggered to after the point where the placeholder has been removed and
5657
		// everything else normalized again
5658
		var i,
5659
			delayedTriggers = [];
5660
 
5661
		// We first have to update the dom position of the actual currentItem
5662
		// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
5663
		if(!this._noFinalSort && this.currentItem.parent().length) {
5664
			this.placeholder.before(this.currentItem);
5665
		}
5666
		this._noFinalSort = null;
5667
 
5668
		if(this.helper[0] === this.currentItem[0]) {
5669
			for(i in this._storedCSS) {
5670
				if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
5671
					this._storedCSS[i] = "";
5672
				}
5673
			}
5674
			this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
5675
		} else {
5676
			this.currentItem.show();
5677
		}
5678
 
5679
		if(this.fromOutside && !noPropagation) {
5680
			delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
5681
		}
5682
		if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
5683
			delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
5684
		}
5685
 
5686
		// Check if the items Container has Changed and trigger appropriate
5687
		// events.
5688
		if (this !== this.currentContainer) {
5689
			if(!noPropagation) {
5690
				delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
5691
				delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
5692
				delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
5693
			}
5694
		}
5695
 
5696
 
5697
		//Post events to containers
5698
		function delayEvent( type, instance, container ) {
5699
			return function( event ) {
5700
				container._trigger( type, event, instance._uiHash( instance ) );
5701
			};
5702
		}
5703
		for (i = this.containers.length - 1; i >= 0; i--){
5704
			if (!noPropagation) {
5705
				delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
5706
			}
5707
			if(this.containers[i].containerCache.over) {
5708
				delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
5709
				this.containers[i].containerCache.over = 0;
5710
			}
5711
		}
5712
 
5713
		//Do what was originally in plugins
5714
		if ( this.storedCursor ) {
5715
			this.document.find( "body" ).css( "cursor", this.storedCursor );
5716
			this.storedStylesheet.remove();
5717
		}
5718
		if(this._storedOpacity) {
5719
			this.helper.css("opacity", this._storedOpacity);
5720
		}
5721
		if(this._storedZIndex) {
5722
			this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
5723
		}
5724
 
5725
		this.dragging = false;
5726
 
5727
		if(!noPropagation) {
5728
			this._trigger("beforeStop", event, this._uiHash());
5729
		}
5730
 
5731
		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
5732
		this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
5733
 
5734
		if ( !this.cancelHelperRemoval ) {
5735
			if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
5736
				this.helper.remove();
5737
			}
5738
			this.helper = null;
5739
		}
5740
 
5741
		if(!noPropagation) {
5742
			for (i=0; i < delayedTriggers.length; i++) {
5743
				delayedTriggers[i].call(this, event);
5744
			} //Trigger all delayed events
5745
			this._trigger("stop", event, this._uiHash());
5746
		}
5747
 
5748
		this.fromOutside = false;
5749
		return !this.cancelHelperRemoval;
5750
 
5751
	},
5752
 
5753
	_trigger: function() {
5754
		if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
5755
			this.cancel();
5756
		}
5757
	},
5758
 
5759
	_uiHash: function(_inst) {
5760
		var inst = _inst || this;
5761
		return {
5762
			helper: inst.helper,
5763
			placeholder: inst.placeholder || $([]),
5764
			position: inst.position,
5765
			originalPosition: inst.originalPosition,
5766
			offset: inst.positionAbs,
5767
			item: inst.currentItem,
5768
			sender: _inst ? _inst.element : null
5769
		};
5770
	}
5771
 
5772
});
5773
 
5774
 
5775
/*!
5776
 * jQuery UI Accordion 1.11.4
5777
 * http://jqueryui.com
5778
 *
5779
 * Copyright jQuery Foundation and other contributors
5780
 * Released under the MIT license.
5781
 * http://jquery.org/license
5782
 *
5783
 * http://api.jqueryui.com/accordion/
5784
 */
5785
 
5786
 
5787
var accordion = $.widget( "ui.accordion", {
5788
	version: "1.11.4",
5789
	options: {
5790
		active: 0,
5791
		animate: {},
5792
		collapsible: false,
5793
		event: "click",
5794
		header: "> li > :first-child,> :not(li):even",
5795
		heightStyle: "auto",
5796
		icons: {
5797
			activeHeader: "ui-icon-triangle-1-s",
5798
			header: "ui-icon-triangle-1-e"
5799
		},
5800
 
5801
		// callbacks
5802
		activate: null,
5803
		beforeActivate: null
5804
	},
5805
 
5806
	hideProps: {
5807
		borderTopWidth: "hide",
5808
		borderBottomWidth: "hide",
5809
		paddingTop: "hide",
5810
		paddingBottom: "hide",
5811
		height: "hide"
5812
	},
5813
 
5814
	showProps: {
5815
		borderTopWidth: "show",
5816
		borderBottomWidth: "show",
5817
		paddingTop: "show",
5818
		paddingBottom: "show",
5819
		height: "show"
5820
	},
5821
 
5822
	_create: function() {
5823
		var options = this.options;
5824
		this.prevShow = this.prevHide = $();
5825
		this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
5826
			// ARIA
5827
			.attr( "role", "tablist" );
5828
 
5829
		// don't allow collapsible: false and active: false / null
5830
		if ( !options.collapsible && (options.active === false || options.active == null) ) {
5831
			options.active = 0;
5832
		}
5833
 
5834
		this._processPanels();
5835
		// handle negative values
5836
		if ( options.active < 0 ) {
5837
			options.active += this.headers.length;
5838
		}
5839
		this._refresh();
5840
	},
5841
 
5842
	_getCreateEventData: function() {
5843
		return {
5844
			header: this.active,
5845
			panel: !this.active.length ? $() : this.active.next()
5846
		};
5847
	},
5848
 
5849
	_createIcons: function() {
5850
		var icons = this.options.icons;
5851
		if ( icons ) {
5852
			$( "<span>" )
5853
				.addClass( "ui-accordion-header-icon ui-icon " + icons.header )
5854
				.prependTo( this.headers );
5855
			this.active.children( ".ui-accordion-header-icon" )
5856
				.removeClass( icons.header )
5857
				.addClass( icons.activeHeader );
5858
			this.headers.addClass( "ui-accordion-icons" );
5859
		}
5860
	},
5861
 
5862
	_destroyIcons: function() {
5863
		this.headers
5864
			.removeClass( "ui-accordion-icons" )
5865
			.children( ".ui-accordion-header-icon" )
5866
				.remove();
5867
	},
5868
 
5869
	_destroy: function() {
5870
		var contents;
5871
 
5872
		// clean up main element
5873
		this.element
5874
			.removeClass( "ui-accordion ui-widget ui-helper-reset" )
5875
			.removeAttr( "role" );
5876
 
5877
		// clean up headers
5878
		this.headers
5879
			.removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " +
5880
				"ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
5881
			.removeAttr( "role" )
5882
			.removeAttr( "aria-expanded" )
5883
			.removeAttr( "aria-selected" )
5884
			.removeAttr( "aria-controls" )
5885
			.removeAttr( "tabIndex" )
5886
			.removeUniqueId();
5887
 
5888
		this._destroyIcons();
5889
 
5890
		// clean up content panels
5891
		contents = this.headers.next()
5892
			.removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " +
5893
				"ui-accordion-content ui-accordion-content-active ui-state-disabled" )
5894
			.css( "display", "" )
5895
			.removeAttr( "role" )
5896
			.removeAttr( "aria-hidden" )
5897
			.removeAttr( "aria-labelledby" )
5898
			.removeUniqueId();
5899
 
5900
		if ( this.options.heightStyle !== "content" ) {
5901
			contents.css( "height", "" );
5902
		}
5903
	},
5904
 
5905
	_setOption: function( key, value ) {
5906
		if ( key === "active" ) {
5907
			// _activate() will handle invalid values and update this.options
5908
			this._activate( value );
5909
			return;
5910
		}
5911
 
5912
		if ( key === "event" ) {
5913
			if ( this.options.event ) {
5914
				this._off( this.headers, this.options.event );
5915
			}
5916
			this._setupEvents( value );
5917
		}
5918
 
5919
		this._super( key, value );
5920
 
5921
		// setting collapsible: false while collapsed; open first panel
5922
		if ( key === "collapsible" && !value && this.options.active === false ) {
5923
			this._activate( 0 );
5924
		}
5925
 
5926
		if ( key === "icons" ) {
5927
			this._destroyIcons();
5928
			if ( value ) {
5929
				this._createIcons();
5930
			}
5931
		}
5932
 
5933
		// #5332 - opacity doesn't cascade to positioned elements in IE
5934
		// so we need to add the disabled class to the headers and panels
5935
		if ( key === "disabled" ) {
5936
			this.element
5937
				.toggleClass( "ui-state-disabled", !!value )
5938
				.attr( "aria-disabled", value );
5939
			this.headers.add( this.headers.next() )
5940
				.toggleClass( "ui-state-disabled", !!value );
5941
		}
5942
	},
5943
 
5944
	_keydown: function( event ) {
5945
		if ( event.altKey || event.ctrlKey ) {
5946
			return;
5947
		}
5948
 
5949
		var keyCode = $.ui.keyCode,
5950
			length = this.headers.length,
5951
			currentIndex = this.headers.index( event.target ),
5952
			toFocus = false;
5953
 
5954
		switch ( event.keyCode ) {
5955
			case keyCode.RIGHT:
5956
			case keyCode.DOWN:
5957
				toFocus = this.headers[ ( currentIndex + 1 ) % length ];
5958
				break;
5959
			case keyCode.LEFT:
5960
			case keyCode.UP:
5961
				toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
5962
				break;
5963
			case keyCode.SPACE:
5964
			case keyCode.ENTER:
5965
				this._eventHandler( event );
5966
				break;
5967
			case keyCode.HOME:
5968
				toFocus = this.headers[ 0 ];
5969
				break;
5970
			case keyCode.END:
5971
				toFocus = this.headers[ length - 1 ];
5972
				break;
5973
		}
5974
 
5975
		if ( toFocus ) {
5976
			$( event.target ).attr( "tabIndex", -1 );
5977
			$( toFocus ).attr( "tabIndex", 0 );
5978
			toFocus.focus();
5979
			event.preventDefault();
5980
		}
5981
	},
5982
 
5983
	_panelKeyDown: function( event ) {
5984
		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
5985
			$( event.currentTarget ).prev().focus();
5986
		}
5987
	},
5988
 
5989
	refresh: function() {
5990
		var options = this.options;
5991
		this._processPanels();
5992
 
5993
		// was collapsed or no panel
5994
		if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
5995
			options.active = false;
5996
			this.active = $();
5997
		// active false only when collapsible is true
5998
		} else if ( options.active === false ) {
5999
			this._activate( 0 );
6000
		// was active, but active panel is gone
6001
		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
6002
			// all remaining panel are disabled
6003
			if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
6004
				options.active = false;
6005
				this.active = $();
6006
			// activate previous panel
6007
			} else {
6008
				this._activate( Math.max( 0, options.active - 1 ) );
6009
			}
6010
		// was active, active panel still exists
6011
		} else {
6012
			// make sure active index is correct
6013
			options.active = this.headers.index( this.active );
6014
		}
6015
 
6016
		this._destroyIcons();
6017
 
6018
		this._refresh();
6019
	},
6020
 
6021
	_processPanels: function() {
6022
		var prevHeaders = this.headers,
6023
			prevPanels = this.panels;
6024
 
6025
		this.headers = this.element.find( this.options.header )
6026
			.addClass( "ui-accordion-header ui-state-default ui-corner-all" );
6027
 
6028
		this.panels = this.headers.next()
6029
			.addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
6030
			.filter( ":not(.ui-accordion-content-active)" )
6031
			.hide();
6032
 
6033
		// Avoid memory leaks (#10056)
6034
		if ( prevPanels ) {
6035
			this._off( prevHeaders.not( this.headers ) );
6036
			this._off( prevPanels.not( this.panels ) );
6037
		}
6038
	},
6039
 
6040
	_refresh: function() {
6041
		var maxHeight,
6042
			options = this.options,
6043
			heightStyle = options.heightStyle,
6044
			parent = this.element.parent();
6045
 
6046
		this.active = this._findActive( options.active )
6047
			.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
6048
			.removeClass( "ui-corner-all" );
6049
		this.active.next()
6050
			.addClass( "ui-accordion-content-active" )
6051
			.show();
6052
 
6053
		this.headers
6054
			.attr( "role", "tab" )
6055
			.each(function() {
6056
				var header = $( this ),
6057
					headerId = header.uniqueId().attr( "id" ),
6058
					panel = header.next(),
6059
					panelId = panel.uniqueId().attr( "id" );
6060
				header.attr( "aria-controls", panelId );
6061
				panel.attr( "aria-labelledby", headerId );
6062
			})
6063
			.next()
6064
				.attr( "role", "tabpanel" );
6065
 
6066
		this.headers
6067
			.not( this.active )
6068
			.attr({
6069
				"aria-selected": "false",
6070
				"aria-expanded": "false",
6071
				tabIndex: -1
6072
			})
6073
			.next()
6074
				.attr({
6075
					"aria-hidden": "true"
6076
				})
6077
				.hide();
6078
 
6079
		// make sure at least one header is in the tab order
6080
		if ( !this.active.length ) {
6081
			this.headers.eq( 0 ).attr( "tabIndex", 0 );
6082
		} else {
6083
			this.active.attr({
6084
				"aria-selected": "true",
6085
				"aria-expanded": "true",
6086
				tabIndex: 0
6087
			})
6088
			.next()
6089
				.attr({
6090
					"aria-hidden": "false"
6091
				});
6092
		}
6093
 
6094
		this._createIcons();
6095
 
6096
		this._setupEvents( options.event );
6097
 
6098
		if ( heightStyle === "fill" ) {
6099
			maxHeight = parent.height();
6100
			this.element.siblings( ":visible" ).each(function() {
6101
				var elem = $( this ),
6102
					position = elem.css( "position" );
6103
 
6104
				if ( position === "absolute" || position === "fixed" ) {
6105
					return;
6106
				}
6107
				maxHeight -= elem.outerHeight( true );
6108
			});
6109
 
6110
			this.headers.each(function() {
6111
				maxHeight -= $( this ).outerHeight( true );
6112
			});
6113
 
6114
			this.headers.next()
6115
				.each(function() {
6116
					$( this ).height( Math.max( 0, maxHeight -
6117
						$( this ).innerHeight() + $( this ).height() ) );
6118
				})
6119
				.css( "overflow", "auto" );
6120
		} else if ( heightStyle === "auto" ) {
6121
			maxHeight = 0;
6122
			this.headers.next()
6123
				.each(function() {
6124
					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
6125
				})
6126
				.height( maxHeight );
6127
		}
6128
	},
6129
 
6130
	_activate: function( index ) {
6131
		var active = this._findActive( index )[ 0 ];
6132
 
6133
		// trying to activate the already active panel
6134
		if ( active === this.active[ 0 ] ) {
6135
			return;
6136
		}
6137
 
6138
		// trying to collapse, simulate a click on the currently active header
6139
		active = active || this.active[ 0 ];
6140
 
6141
		this._eventHandler({
6142
			target: active,
6143
			currentTarget: active,
6144
			preventDefault: $.noop
6145
		});
6146
	},
6147
 
6148
	_findActive: function( selector ) {
6149
		return typeof selector === "number" ? this.headers.eq( selector ) : $();
6150
	},
6151
 
6152
	_setupEvents: function( event ) {
6153
		var events = {
6154
			keydown: "_keydown"
6155
		};
6156
		if ( event ) {
6157
			$.each( event.split( " " ), function( index, eventName ) {
6158
				events[ eventName ] = "_eventHandler";
6159
			});
6160
		}
6161
 
6162
		this._off( this.headers.add( this.headers.next() ) );
6163
		this._on( this.headers, events );
6164
		this._on( this.headers.next(), { keydown: "_panelKeyDown" });
6165
		this._hoverable( this.headers );
6166
		this._focusable( this.headers );
6167
	},
6168
 
6169
	_eventHandler: function( event ) {
6170
		var options = this.options,
6171
			active = this.active,
6172
			clicked = $( event.currentTarget ),
6173
			clickedIsActive = clicked[ 0 ] === active[ 0 ],
6174
			collapsing = clickedIsActive && options.collapsible,
6175
			toShow = collapsing ? $() : clicked.next(),
6176
			toHide = active.next(),
6177
			eventData = {
6178
				oldHeader: active,
6179
				oldPanel: toHide,
6180
				newHeader: collapsing ? $() : clicked,
6181
				newPanel: toShow
6182
			};
6183
 
6184
		event.preventDefault();
6185
 
6186
		if (
6187
				// click on active header, but not collapsible
6188
				( clickedIsActive && !options.collapsible ) ||
6189
				// allow canceling activation
6190
				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
6191
			return;
6192
		}
6193
 
6194
		options.active = collapsing ? false : this.headers.index( clicked );
6195
 
6196
		// when the call to ._toggle() comes after the class changes
6197
		// it causes a very odd bug in IE 8 (see #6720)
6198
		this.active = clickedIsActive ? $() : clicked;
6199
		this._toggle( eventData );
6200
 
6201
		// switch classes
6202
		// corner classes on the previously active header stay after the animation
6203
		active.removeClass( "ui-accordion-header-active ui-state-active" );
6204
		if ( options.icons ) {
6205
			active.children( ".ui-accordion-header-icon" )
6206
				.removeClass( options.icons.activeHeader )
6207
				.addClass( options.icons.header );
6208
		}
6209
 
6210
		if ( !clickedIsActive ) {
6211
			clicked
6212
				.removeClass( "ui-corner-all" )
6213
				.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
6214
			if ( options.icons ) {
6215
				clicked.children( ".ui-accordion-header-icon" )
6216
					.removeClass( options.icons.header )
6217
					.addClass( options.icons.activeHeader );
6218
			}
6219
 
6220
			clicked
6221
				.next()
6222
				.addClass( "ui-accordion-content-active" );
6223
		}
6224
	},
6225
 
6226
	_toggle: function( data ) {
6227
		var toShow = data.newPanel,
6228
			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
6229
 
6230
		// handle activating a panel during the animation for another activation
6231
		this.prevShow.add( this.prevHide ).stop( true, true );
6232
		this.prevShow = toShow;
6233
		this.prevHide = toHide;
6234
 
6235
		if ( this.options.animate ) {
6236
			this._animate( toShow, toHide, data );
6237
		} else {
6238
			toHide.hide();
6239
			toShow.show();
6240
			this._toggleComplete( data );
6241
		}
6242
 
6243
		toHide.attr({
6244
			"aria-hidden": "true"
6245
		});
6246
		toHide.prev().attr({
6247
			"aria-selected": "false",
6248
			"aria-expanded": "false"
6249
		});
6250
		// if we're switching panels, remove the old header from the tab order
6251
		// if we're opening from collapsed state, remove the previous header from the tab order
6252
		// if we're collapsing, then keep the collapsing header in the tab order
6253
		if ( toShow.length && toHide.length ) {
6254
			toHide.prev().attr({
6255
				"tabIndex": -1,
6256
				"aria-expanded": "false"
6257
			});
6258
		} else if ( toShow.length ) {
6259
			this.headers.filter(function() {
6260
				return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
6261
			})
6262
			.attr( "tabIndex", -1 );
6263
		}
6264
 
6265
		toShow
6266
			.attr( "aria-hidden", "false" )
6267
			.prev()
6268
				.attr({
6269
					"aria-selected": "true",
6270
					"aria-expanded": "true",
6271
					tabIndex: 0
6272
				});
6273
	},
6274
 
6275
	_animate: function( toShow, toHide, data ) {
6276
		var total, easing, duration,
6277
			that = this,
6278
			adjust = 0,
6279
			boxSizing = toShow.css( "box-sizing" ),
6280
			down = toShow.length &&
6281
				( !toHide.length || ( toShow.index() < toHide.index() ) ),
6282
			animate = this.options.animate || {},
6283
			options = down && animate.down || animate,
6284
			complete = function() {
6285
				that._toggleComplete( data );
6286
			};
6287
 
6288
		if ( typeof options === "number" ) {
6289
			duration = options;
6290
		}
6291
		if ( typeof options === "string" ) {
6292
			easing = options;
6293
		}
6294
		// fall back from options to animation in case of partial down settings
6295
		easing = easing || options.easing || animate.easing;
6296
		duration = duration || options.duration || animate.duration;
6297
 
6298
		if ( !toHide.length ) {
6299
			return toShow.animate( this.showProps, duration, easing, complete );
6300
		}
6301
		if ( !toShow.length ) {
6302
			return toHide.animate( this.hideProps, duration, easing, complete );
6303
		}
6304
 
6305
		total = toShow.show().outerHeight();
6306
		toHide.animate( this.hideProps, {
6307
			duration: duration,
6308
			easing: easing,
6309
			step: function( now, fx ) {
6310
				fx.now = Math.round( now );
6311
			}
6312
		});
6313
		toShow
6314
			.hide()
6315
			.animate( this.showProps, {
6316
				duration: duration,
6317
				easing: easing,
6318
				complete: complete,
6319
				step: function( now, fx ) {
6320
					fx.now = Math.round( now );
6321
					if ( fx.prop !== "height" ) {
6322
						if ( boxSizing === "content-box" ) {
6323
							adjust += fx.now;
6324
						}
6325
					} else if ( that.options.heightStyle !== "content" ) {
6326
						fx.now = Math.round( total - toHide.outerHeight() - adjust );
6327
						adjust = 0;
6328
					}
6329
				}
6330
			});
6331
	},
6332
 
6333
	_toggleComplete: function( data ) {
6334
		var toHide = data.oldPanel;
6335
 
6336
		toHide
6337
			.removeClass( "ui-accordion-content-active" )
6338
			.prev()
6339
				.removeClass( "ui-corner-top" )
6340
				.addClass( "ui-corner-all" );
6341
 
6342
		// Work around for rendering bug in IE (#5421)
6343
		if ( toHide.length ) {
6344
			toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
6345
		}
6346
		this._trigger( "activate", null, data );
6347
	}
6348
});
6349
 
6350
 
6351
/*!
6352
 * jQuery UI Menu 1.11.4
6353
 * http://jqueryui.com
6354
 *
6355
 * Copyright jQuery Foundation and other contributors
6356
 * Released under the MIT license.
6357
 * http://jquery.org/license
6358
 *
6359
 * http://api.jqueryui.com/menu/
6360
 */
6361
 
6362
 
6363
var menu = $.widget( "ui.menu", {
6364
	version: "1.11.4",
6365
	defaultElement: "<ul>",
6366
	delay: 300,
6367
	options: {
6368
		icons: {
6369
			submenu: "ui-icon-carat-1-e"
6370
		},
6371
		items: "> *",
6372
		menus: "ul",
6373
		position: {
6374
			my: "left-1 top",
6375
			at: "right top"
6376
		},
6377
		role: "menu",
6378
 
6379
		// callbacks
6380
		blur: null,
6381
		focus: null,
6382
		select: null
6383
	},
6384
 
6385
	_create: function() {
6386
		this.activeMenu = this.element;
6387
 
6388
		// Flag used to prevent firing of the click handler
6389
		// as the event bubbles up through nested menus
6390
		this.mouseHandled = false;
6391
		this.element
6392
			.uniqueId()
6393
			.addClass( "ui-menu ui-widget ui-widget-content" )
6394
			.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
6395
			.attr({
6396
				role: this.options.role,
6397
				tabIndex: 0
6398
			});
6399
 
6400
		if ( this.options.disabled ) {
6401
			this.element
6402
				.addClass( "ui-state-disabled" )
6403
				.attr( "aria-disabled", "true" );
6404
		}
6405
 
6406
		this._on({
6407
			// Prevent focus from sticking to links inside menu after clicking
6408
			// them (focus should always stay on UL during navigation).
6409
			"mousedown .ui-menu-item": function( event ) {
6410
				event.preventDefault();
6411
			},
6412
			"click .ui-menu-item": function( event ) {
6413
				var target = $( event.target );
6414
				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
6415
					this.select( event );
6416
 
6417
					// Only set the mouseHandled flag if the event will bubble, see #9469.
6418
					if ( !event.isPropagationStopped() ) {
6419
						this.mouseHandled = true;
6420
					}
6421
 
6422
					// Open submenu on click
6423
					if ( target.has( ".ui-menu" ).length ) {
6424
						this.expand( event );
6425
					} else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
6426
 
6427
						// Redirect focus to the menu
6428
						this.element.trigger( "focus", [ true ] );
6429
 
6430
						// If the active item is on the top level, let it stay active.
6431
						// Otherwise, blur the active item since it is no longer visible.
6432
						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
6433
							clearTimeout( this.timer );
6434
						}
6435
					}
6436
				}
6437
			},
6438
			"mouseenter .ui-menu-item": function( event ) {
6439
				// Ignore mouse events while typeahead is active, see #10458.
6440
				// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
6441
				// is over an item in the menu
6442
				if ( this.previousFilter ) {
6443
					return;
6444
				}
6445
				var target = $( event.currentTarget );
6446
				// Remove ui-state-active class from siblings of the newly focused menu item
6447
				// to avoid a jump caused by adjacent elements both having a class with a border
6448
				target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" );
6449
				this.focus( event, target );
6450
			},
6451
			mouseleave: "collapseAll",
6452
			"mouseleave .ui-menu": "collapseAll",
6453
			focus: function( event, keepActiveItem ) {
6454
				// If there's already an active item, keep it active
6455
				// If not, activate the first item
6456
				var item = this.active || this.element.find( this.options.items ).eq( 0 );
6457
 
6458
				if ( !keepActiveItem ) {
6459
					this.focus( event, item );
6460
				}
6461
			},
6462
			blur: function( event ) {
6463
				this._delay(function() {
6464
					if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
6465
						this.collapseAll( event );
6466
					}
6467
				});
6468
			},
6469
			keydown: "_keydown"
6470
		});
6471
 
6472
		this.refresh();
6473
 
6474
		// Clicks outside of a menu collapse any open menus
6475
		this._on( this.document, {
6476
			click: function( event ) {
6477
				if ( this._closeOnDocumentClick( event ) ) {
6478
					this.collapseAll( event );
6479
				}
6480
 
6481
				// Reset the mouseHandled flag
6482
				this.mouseHandled = false;
6483
			}
6484
		});
6485
	},
6486
 
6487
	_destroy: function() {
6488
		// Destroy (sub)menus
6489
		this.element
6490
			.removeAttr( "aria-activedescendant" )
6491
			.find( ".ui-menu" ).addBack()
6492
				.removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" )
6493
				.removeAttr( "role" )
6494
				.removeAttr( "tabIndex" )
6495
				.removeAttr( "aria-labelledby" )
6496
				.removeAttr( "aria-expanded" )
6497
				.removeAttr( "aria-hidden" )
6498
				.removeAttr( "aria-disabled" )
6499
				.removeUniqueId()
6500
				.show();
6501
 
6502
		// Destroy menu items
6503
		this.element.find( ".ui-menu-item" )
6504
			.removeClass( "ui-menu-item" )
6505
			.removeAttr( "role" )
6506
			.removeAttr( "aria-disabled" )
6507
			.removeUniqueId()
6508
			.removeClass( "ui-state-hover" )
6509
			.removeAttr( "tabIndex" )
6510
			.removeAttr( "role" )
6511
			.removeAttr( "aria-haspopup" )
6512
			.children().each( function() {
6513
				var elem = $( this );
6514
				if ( elem.data( "ui-menu-submenu-carat" ) ) {
6515
					elem.remove();
6516
				}
6517
			});
6518
 
6519
		// Destroy menu dividers
6520
		this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
6521
	},
6522
 
6523
	_keydown: function( event ) {
6524
		var match, prev, character, skip,
6525
			preventDefault = true;
6526
 
6527
		switch ( event.keyCode ) {
6528
		case $.ui.keyCode.PAGE_UP:
6529
			this.previousPage( event );
6530
			break;
6531
		case $.ui.keyCode.PAGE_DOWN:
6532
			this.nextPage( event );
6533
			break;
6534
		case $.ui.keyCode.HOME:
6535
			this._move( "first", "first", event );
6536
			break;
6537
		case $.ui.keyCode.END:
6538
			this._move( "last", "last", event );
6539
			break;
6540
		case $.ui.keyCode.UP:
6541
			this.previous( event );
6542
			break;
6543
		case $.ui.keyCode.DOWN:
6544
			this.next( event );
6545
			break;
6546
		case $.ui.keyCode.LEFT:
6547
			this.collapse( event );
6548
			break;
6549
		case $.ui.keyCode.RIGHT:
6550
			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
6551
				this.expand( event );
6552
			}
6553
			break;
6554
		case $.ui.keyCode.ENTER:
6555
		case $.ui.keyCode.SPACE:
6556
			this._activate( event );
6557
			break;
6558
		case $.ui.keyCode.ESCAPE:
6559
			this.collapse( event );
6560
			break;
6561
		default:
6562
			preventDefault = false;
6563
			prev = this.previousFilter || "";
6564
			character = String.fromCharCode( event.keyCode );
6565
			skip = false;
6566
 
6567
			clearTimeout( this.filterTimer );
6568
 
6569
			if ( character === prev ) {
6570
				skip = true;
6571
			} else {
6572
				character = prev + character;
6573
			}
6574
 
6575
			match = this._filterMenuItems( character );
6576
			match = skip && match.index( this.active.next() ) !== -1 ?
6577
				this.active.nextAll( ".ui-menu-item" ) :
6578
				match;
6579
 
6580
			// If no matches on the current filter, reset to the last character pressed
6581
			// to move down the menu to the first item that starts with that character
6582
			if ( !match.length ) {
6583
				character = String.fromCharCode( event.keyCode );
6584
				match = this._filterMenuItems( character );
6585
			}
6586
 
6587
			if ( match.length ) {
6588
				this.focus( event, match );
6589
				this.previousFilter = character;
6590
				this.filterTimer = this._delay(function() {
6591
					delete this.previousFilter;
6592
				}, 1000 );
6593
			} else {
6594
				delete this.previousFilter;
6595
			}
6596
		}
6597
 
6598
		if ( preventDefault ) {
6599
			event.preventDefault();
6600
		}
6601
	},
6602
 
6603
	_activate: function( event ) {
6604
		if ( !this.active.is( ".ui-state-disabled" ) ) {
6605
			if ( this.active.is( "[aria-haspopup='true']" ) ) {
6606
				this.expand( event );
6607
			} else {
6608
				this.select( event );
6609
			}
6610
		}
6611
	},
6612
 
6613
	refresh: function() {
6614
		var menus, items,
6615
			that = this,
6616
			icon = this.options.icons.submenu,
6617
			submenus = this.element.find( this.options.menus );
6618
 
6619
		this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
6620
 
6621
		// Initialize nested menus
6622
		submenus.filter( ":not(.ui-menu)" )
6623
			.addClass( "ui-menu ui-widget ui-widget-content ui-front" )
6624
			.hide()
6625
			.attr({
6626
				role: this.options.role,
6627
				"aria-hidden": "true",
6628
				"aria-expanded": "false"
6629
			})
6630
			.each(function() {
6631
				var menu = $( this ),
6632
					item = menu.parent(),
6633
					submenuCarat = $( "<span>" )
6634
						.addClass( "ui-menu-icon ui-icon " + icon )
6635
						.data( "ui-menu-submenu-carat", true );
6636
 
6637
				item
6638
					.attr( "aria-haspopup", "true" )
6639
					.prepend( submenuCarat );
6640
				menu.attr( "aria-labelledby", item.attr( "id" ) );
6641
			});
6642
 
6643
		menus = submenus.add( this.element );
6644
		items = menus.find( this.options.items );
6645
 
6646
		// Initialize menu-items containing spaces and/or dashes only as dividers
6647
		items.not( ".ui-menu-item" ).each(function() {
6648
			var item = $( this );
6649
			if ( that._isDivider( item ) ) {
6650
				item.addClass( "ui-widget-content ui-menu-divider" );
6651
			}
6652
		});
6653
 
6654
		// Don't refresh list items that are already adapted
6655
		items.not( ".ui-menu-item, .ui-menu-divider" )
6656
			.addClass( "ui-menu-item" )
6657
			.uniqueId()
6658
			.attr({
6659
				tabIndex: -1,
6660
				role: this._itemRole()
6661
			});
6662
 
6663
		// Add aria-disabled attribute to any disabled menu item
6664
		items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
6665
 
6666
		// If the active item has been removed, blur the menu
6667
		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
6668
			this.blur();
6669
		}
6670
	},
6671
 
6672
	_itemRole: function() {
6673
		return {
6674
			menu: "menuitem",
6675
			listbox: "option"
6676
		}[ this.options.role ];
6677
	},
6678
 
6679
	_setOption: function( key, value ) {
6680
		if ( key === "icons" ) {
6681
			this.element.find( ".ui-menu-icon" )
6682
				.removeClass( this.options.icons.submenu )
6683
				.addClass( value.submenu );
6684
		}
6685
		if ( key === "disabled" ) {
6686
			this.element
6687
				.toggleClass( "ui-state-disabled", !!value )
6688
				.attr( "aria-disabled", value );
6689
		}
6690
		this._super( key, value );
6691
	},
6692
 
6693
	focus: function( event, item ) {
6694
		var nested, focused;
6695
		this.blur( event, event && event.type === "focus" );
6696
 
6697
		this._scrollIntoView( item );
6698
 
6699
		this.active = item.first();
6700
		focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" );
6701
		// Only update aria-activedescendant if there's a role
6702
		// otherwise we assume focus is managed elsewhere
6703
		if ( this.options.role ) {
6704
			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
6705
		}
6706
 
6707
		// Highlight active parent menu item, if any
6708
		this.active
6709
			.parent()
6710
			.closest( ".ui-menu-item" )
6711
			.addClass( "ui-state-active" );
6712
 
6713
		if ( event && event.type === "keydown" ) {
6714
			this._close();
6715
		} else {
6716
			this.timer = this._delay(function() {
6717
				this._close();
6718
			}, this.delay );
6719
		}
6720
 
6721
		nested = item.children( ".ui-menu" );
6722
		if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
6723
			this._startOpening(nested);
6724
		}
6725
		this.activeMenu = item.parent();
6726
 
6727
		this._trigger( "focus", event, { item: item } );
6728
	},
6729
 
6730
	_scrollIntoView: function( item ) {
6731
		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
6732
		if ( this._hasScroll() ) {
6733
			borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
6734
			paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
6735
			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
6736
			scroll = this.activeMenu.scrollTop();
6737
			elementHeight = this.activeMenu.height();
6738
			itemHeight = item.outerHeight();
6739
 
6740
			if ( offset < 0 ) {
6741
				this.activeMenu.scrollTop( scroll + offset );
6742
			} else if ( offset + itemHeight > elementHeight ) {
6743
				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
6744
			}
6745
		}
6746
	},
6747
 
6748
	blur: function( event, fromFocus ) {
6749
		if ( !fromFocus ) {
6750
			clearTimeout( this.timer );
6751
		}
6752
 
6753
		if ( !this.active ) {
6754
			return;
6755
		}
6756
 
6757
		this.active.removeClass( "ui-state-focus" );
6758
		this.active = null;
6759
 
6760
		this._trigger( "blur", event, { item: this.active } );
6761
	},
6762
 
6763
	_startOpening: function( submenu ) {
6764
		clearTimeout( this.timer );
6765
 
6766
		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
6767
		// shift in the submenu position when mousing over the carat icon
6768
		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
6769
			return;
6770
		}
6771
 
6772
		this.timer = this._delay(function() {
6773
			this._close();
6774
			this._open( submenu );
6775
		}, this.delay );
6776
	},
6777
 
6778
	_open: function( submenu ) {
6779
		var position = $.extend({
6780
			of: this.active
6781
		}, this.options.position );
6782
 
6783
		clearTimeout( this.timer );
6784
		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
6785
			.hide()
6786
			.attr( "aria-hidden", "true" );
6787
 
6788
		submenu
6789
			.show()
6790
			.removeAttr( "aria-hidden" )
6791
			.attr( "aria-expanded", "true" )
6792
			.position( position );
6793
	},
6794
 
6795
	collapseAll: function( event, all ) {
6796
		clearTimeout( this.timer );
6797
		this.timer = this._delay(function() {
6798
			// If we were passed an event, look for the submenu that contains the event
6799
			var currentMenu = all ? this.element :
6800
				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
6801
 
6802
			// If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
6803
			if ( !currentMenu.length ) {
6804
				currentMenu = this.element;
6805
			}
6806
 
6807
			this._close( currentMenu );
6808
 
6809
			this.blur( event );
6810
			this.activeMenu = currentMenu;
6811
		}, this.delay );
6812
	},
6813
 
6814
	// With no arguments, closes the currently active menu - if nothing is active
6815
	// it closes all menus.  If passed an argument, it will search for menus BELOW
6816
	_close: function( startMenu ) {
6817
		if ( !startMenu ) {
6818
			startMenu = this.active ? this.active.parent() : this.element;
6819
		}
6820
 
6821
		startMenu
6822
			.find( ".ui-menu" )
6823
				.hide()
6824
				.attr( "aria-hidden", "true" )
6825
				.attr( "aria-expanded", "false" )
6826
			.end()
6827
			.find( ".ui-state-active" ).not( ".ui-state-focus" )
6828
				.removeClass( "ui-state-active" );
6829
	},
6830
 
6831
	_closeOnDocumentClick: function( event ) {
6832
		return !$( event.target ).closest( ".ui-menu" ).length;
6833
	},
6834
 
6835
	_isDivider: function( item ) {
6836
 
6837
		// Match hyphen, em dash, en dash
6838
		return !/[^\-\u2014\u2013\s]/.test( item.text() );
6839
	},
6840
 
6841
	collapse: function( event ) {
6842
		var newItem = this.active &&
6843
			this.active.parent().closest( ".ui-menu-item", this.element );
6844
		if ( newItem && newItem.length ) {
6845
			this._close();
6846
			this.focus( event, newItem );
6847
		}
6848
	},
6849
 
6850
	expand: function( event ) {
6851
		var newItem = this.active &&
6852
			this.active
6853
				.children( ".ui-menu " )
6854
				.find( this.options.items )
6855
				.first();
6856
 
6857
		if ( newItem && newItem.length ) {
6858
			this._open( newItem.parent() );
6859
 
6860
			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
6861
			this._delay(function() {
6862
				this.focus( event, newItem );
6863
			});
6864
		}
6865
	},
6866
 
6867
	next: function( event ) {
6868
		this._move( "next", "first", event );
6869
	},
6870
 
6871
	previous: function( event ) {
6872
		this._move( "prev", "last", event );
6873
	},
6874
 
6875
	isFirstItem: function() {
6876
		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
6877
	},
6878
 
6879
	isLastItem: function() {
6880
		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
6881
	},
6882
 
6883
	_move: function( direction, filter, event ) {
6884
		var next;
6885
		if ( this.active ) {
6886
			if ( direction === "first" || direction === "last" ) {
6887
				next = this.active
6888
					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
6889
					.eq( -1 );
6890
			} else {
6891
				next = this.active
6892
					[ direction + "All" ]( ".ui-menu-item" )
6893
					.eq( 0 );
6894
			}
6895
		}
6896
		if ( !next || !next.length || !this.active ) {
6897
			next = this.activeMenu.find( this.options.items )[ filter ]();
6898
		}
6899
 
6900
		this.focus( event, next );
6901
	},
6902
 
6903
	nextPage: function( event ) {
6904
		var item, base, height;
6905
 
6906
		if ( !this.active ) {
6907
			this.next( event );
6908
			return;
6909
		}
6910
		if ( this.isLastItem() ) {
6911
			return;
6912
		}
6913
		if ( this._hasScroll() ) {
6914
			base = this.active.offset().top;
6915
			height = this.element.height();
6916
			this.active.nextAll( ".ui-menu-item" ).each(function() {
6917
				item = $( this );
6918
				return item.offset().top - base - height < 0;
6919
			});
6920
 
6921
			this.focus( event, item );
6922
		} else {
6923
			this.focus( event, this.activeMenu.find( this.options.items )
6924
				[ !this.active ? "first" : "last" ]() );
6925
		}
6926
	},
6927
 
6928
	previousPage: function( event ) {
6929
		var item, base, height;
6930
		if ( !this.active ) {
6931
			this.next( event );
6932
			return;
6933
		}
6934
		if ( this.isFirstItem() ) {
6935
			return;
6936
		}
6937
		if ( this._hasScroll() ) {
6938
			base = this.active.offset().top;
6939
			height = this.element.height();
6940
			this.active.prevAll( ".ui-menu-item" ).each(function() {
6941
				item = $( this );
6942
				return item.offset().top - base + height > 0;
6943
			});
6944
 
6945
			this.focus( event, item );
6946
		} else {
6947
			this.focus( event, this.activeMenu.find( this.options.items ).first() );
6948
		}
6949
	},
6950
 
6951
	_hasScroll: function() {
6952
		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
6953
	},
6954
 
6955
	select: function( event ) {
6956
		// TODO: It should never be possible to not have an active item at this
6957
		// point, but the tests don't trigger mouseenter before click.
6958
		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
6959
		var ui = { item: this.active };
6960
		if ( !this.active.has( ".ui-menu" ).length ) {
6961
			this.collapseAll( event, true );
6962
		}
6963
		this._trigger( "select", event, ui );
6964
	},
6965
 
6966
	_filterMenuItems: function(character) {
6967
		var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
6968
			regex = new RegExp( "^" + escapedCharacter, "i" );
6969
 
6970
		return this.activeMenu
6971
			.find( this.options.items )
6972
 
6973
			// Only match on items, not dividers or other content (#10571)
6974
			.filter( ".ui-menu-item" )
6975
			.filter(function() {
6976
				return regex.test( $.trim( $( this ).text() ) );
6977
			});
6978
	}
6979
});
6980
 
6981
 
6982
/*!
6983
 * jQuery UI Autocomplete 1.11.4
6984
 * http://jqueryui.com
6985
 *
6986
 * Copyright jQuery Foundation and other contributors
6987
 * Released under the MIT license.
6988
 * http://jquery.org/license
6989
 *
6990
 * http://api.jqueryui.com/autocomplete/
6991
 */
6992
 
6993
 
6994
$.widget( "ui.autocomplete", {
6995
	version: "1.11.4",
6996
	defaultElement: "<input>",
6997
	options: {
6998
		appendTo: null,
6999
		autoFocus: false,
7000
		delay: 300,
7001
		minLength: 1,
7002
		position: {
7003
			my: "left top",
7004
			at: "left bottom",
7005
			collision: "none"
7006
		},
7007
		source: null,
7008
 
7009
		// callbacks
7010
		change: null,
7011
		close: null,
7012
		focus: null,
7013
		open: null,
7014
		response: null,
7015
		search: null,
7016
		select: null
7017
	},
7018
 
7019
	requestIndex: 0,
7020
	pending: 0,
7021
 
7022
	_create: function() {
7023
		// Some browsers only repeat keydown events, not keypress events,
7024
		// so we use the suppressKeyPress flag to determine if we've already
7025
		// handled the keydown event. #7269
7026
		// Unfortunately the code for & in keypress is the same as the up arrow,
7027
		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
7028
		// events when we know the keydown event was used to modify the
7029
		// search term. #7799
7030
		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
7031
			nodeName = this.element[ 0 ].nodeName.toLowerCase(),
7032
			isTextarea = nodeName === "textarea",
7033
			isInput = nodeName === "input";
7034
 
7035
		this.isMultiLine =
7036
			// Textareas are always multi-line
7037
			isTextarea ? true :
7038
			// Inputs are always single-line, even if inside a contentEditable element
7039
			// IE also treats inputs as contentEditable
7040
			isInput ? false :
7041
			// All other element types are determined by whether or not they're contentEditable
7042
			this.element.prop( "isContentEditable" );
7043
 
7044
		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
7045
		this.isNewMenu = true;
7046
 
7047
		this.element
7048
			.addClass( "ui-autocomplete-input" )
7049
			.attr( "autocomplete", "off" );
7050
 
7051
		this._on( this.element, {
7052
			keydown: function( event ) {
7053
				if ( this.element.prop( "readOnly" ) ) {
7054
					suppressKeyPress = true;
7055
					suppressInput = true;
7056
					suppressKeyPressRepeat = true;
7057
					return;
7058
				}
7059
 
7060
				suppressKeyPress = false;
7061
				suppressInput = false;
7062
				suppressKeyPressRepeat = false;
7063
				var keyCode = $.ui.keyCode;
7064
				switch ( event.keyCode ) {
7065
				case keyCode.PAGE_UP:
7066
					suppressKeyPress = true;
7067
					this._move( "previousPage", event );
7068
					break;
7069
				case keyCode.PAGE_DOWN:
7070
					suppressKeyPress = true;
7071
					this._move( "nextPage", event );
7072
					break;
7073
				case keyCode.UP:
7074
					suppressKeyPress = true;
7075
					this._keyEvent( "previous", event );
7076
					break;
7077
				case keyCode.DOWN:
7078
					suppressKeyPress = true;
7079
					this._keyEvent( "next", event );
7080
					break;
7081
				case keyCode.ENTER:
7082
					// when menu is open and has focus
7083
					if ( this.menu.active ) {
7084
						// #6055 - Opera still allows the keypress to occur
7085
						// which causes forms to submit
7086
						suppressKeyPress = true;
7087
						event.preventDefault();
7088
						this.menu.select( event );
7089
					}
7090
					break;
7091
				case keyCode.TAB:
7092
					if ( this.menu.active ) {
7093
						this.menu.select( event );
7094
					}
7095
					break;
7096
				case keyCode.ESCAPE:
7097
					if ( this.menu.element.is( ":visible" ) ) {
7098
						if ( !this.isMultiLine ) {
7099
							this._value( this.term );
7100
						}
7101
						this.close( event );
7102
						// Different browsers have different default behavior for escape
7103
						// Single press can mean undo or clear
7104
						// Double press in IE means clear the whole form
7105
						event.preventDefault();
7106
					}
7107
					break;
7108
				default:
7109
					suppressKeyPressRepeat = true;
7110
					// search timeout should be triggered before the input value is changed
7111
					this._searchTimeout( event );
7112
					break;
7113
				}
7114
			},
7115
			keypress: function( event ) {
7116
				if ( suppressKeyPress ) {
7117
					suppressKeyPress = false;
7118
					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
7119
						event.preventDefault();
7120
					}
7121
					return;
7122
				}
7123
				if ( suppressKeyPressRepeat ) {
7124
					return;
7125
				}
7126
 
7127
				// replicate some key handlers to allow them to repeat in Firefox and Opera
7128
				var keyCode = $.ui.keyCode;
7129
				switch ( event.keyCode ) {
7130
				case keyCode.PAGE_UP:
7131
					this._move( "previousPage", event );
7132
					break;
7133
				case keyCode.PAGE_DOWN:
7134
					this._move( "nextPage", event );
7135
					break;
7136
				case keyCode.UP:
7137
					this._keyEvent( "previous", event );
7138
					break;
7139
				case keyCode.DOWN:
7140
					this._keyEvent( "next", event );
7141
					break;
7142
				}
7143
			},
7144
			input: function( event ) {
7145
				if ( suppressInput ) {
7146
					suppressInput = false;
7147
					event.preventDefault();
7148
					return;
7149
				}
7150
				this._searchTimeout( event );
7151
			},
7152
			focus: function() {
7153
				this.selectedItem = null;
7154
				this.previous = this._value();
7155
			},
7156
			blur: function( event ) {
7157
				if ( this.cancelBlur ) {
7158
					delete this.cancelBlur;
7159
					return;
7160
				}
7161
 
7162
				clearTimeout( this.searching );
7163
				this.close( event );
7164
				this._change( event );
7165
			}
7166
		});
7167
 
7168
		this._initSource();
7169
		this.menu = $( "<ul>" )
7170
			.addClass( "ui-autocomplete ui-front" )
7171
			.appendTo( this._appendTo() )
7172
			.menu({
7173
				// disable ARIA support, the live region takes care of that
7174
				role: null
7175
			})
7176
			.hide()
7177
			.menu( "instance" );
7178
 
7179
		this._on( this.menu.element, {
7180
			mousedown: function( event ) {
7181
				// prevent moving focus out of the text field
7182
				event.preventDefault();
7183
 
7184
				// IE doesn't prevent moving focus even with event.preventDefault()
7185
				// so we set a flag to know when we should ignore the blur event
7186
				this.cancelBlur = true;
7187
				this._delay(function() {
7188
					delete this.cancelBlur;
7189
				});
7190
 
7191
				// clicking on the scrollbar causes focus to shift to the body
7192
				// but we can't detect a mouseup or a click immediately afterward
7193
				// so we have to track the next mousedown and close the menu if
7194
				// the user clicks somewhere outside of the autocomplete
7195
				var menuElement = this.menu.element[ 0 ];
7196
				if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
7197
					this._delay(function() {
7198
						var that = this;
7199
						this.document.one( "mousedown", function( event ) {
7200
							if ( event.target !== that.element[ 0 ] &&
7201
									event.target !== menuElement &&
7202
									!$.contains( menuElement, event.target ) ) {
7203
								that.close();
7204
							}
7205
						});
7206
					});
7207
				}
7208
			},
7209
			menufocus: function( event, ui ) {
7210
				var label, item;
7211
				// support: Firefox
7212
				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
7213
				if ( this.isNewMenu ) {
7214
					this.isNewMenu = false;
7215
					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
7216
						this.menu.blur();
7217
 
7218
						this.document.one( "mousemove", function() {
7219
							$( event.target ).trigger( event.originalEvent );
7220
						});
7221
 
7222
						return;
7223
					}
7224
				}
7225
 
7226
				item = ui.item.data( "ui-autocomplete-item" );
7227
				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
7228
					// use value to match what will end up in the input, if it was a key event
7229
					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
7230
						this._value( item.value );
7231
					}
7232
				}
7233
 
7234
				// Announce the value in the liveRegion
7235
				label = ui.item.attr( "aria-label" ) || item.value;
7236
				if ( label && $.trim( label ).length ) {
7237
					this.liveRegion.children().hide();
7238
					$( "<div>" ).text( label ).appendTo( this.liveRegion );
7239
				}
7240
			},
7241
			menuselect: function( event, ui ) {
7242
				var item = ui.item.data( "ui-autocomplete-item" ),
7243
					previous = this.previous;
7244
 
7245
				// only trigger when focus was lost (click on menu)
7246
				if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
7247
					this.element.focus();
7248
					this.previous = previous;
7249
					// #6109 - IE triggers two focus events and the second
7250
					// is asynchronous, so we need to reset the previous
7251
					// term synchronously and asynchronously :-(
7252
					this._delay(function() {
7253
						this.previous = previous;
7254
						this.selectedItem = item;
7255
					});
7256
				}
7257
 
7258
				if ( false !== this._trigger( "select", event, { item: item } ) ) {
7259
					this._value( item.value );
7260
				}
7261
				// reset the term after the select event
7262
				// this allows custom select handling to work properly
7263
				this.term = this._value();
7264
 
7265
				this.close( event );
7266
				this.selectedItem = item;
7267
			}
7268
		});
7269
 
7270
		this.liveRegion = $( "<span>", {
7271
				role: "status",
7272
				"aria-live": "assertive",
7273
				"aria-relevant": "additions"
7274
			})
7275
			.addClass( "ui-helper-hidden-accessible" )
7276
			.appendTo( this.document[ 0 ].body );
7277
 
7278
		// turning off autocomplete prevents the browser from remembering the
7279
		// value when navigating through history, so we re-enable autocomplete
7280
		// if the page is unloaded before the widget is destroyed. #7790
7281
		this._on( this.window, {
7282
			beforeunload: function() {
7283
				this.element.removeAttr( "autocomplete" );
7284
			}
7285
		});
7286
	},
7287
 
7288
	_destroy: function() {
7289
		clearTimeout( this.searching );
7290
		this.element
7291
			.removeClass( "ui-autocomplete-input" )
7292
			.removeAttr( "autocomplete" );
7293
		this.menu.element.remove();
7294
		this.liveRegion.remove();
7295
	},
7296
 
7297
	_setOption: function( key, value ) {
7298
		this._super( key, value );
7299
		if ( key === "source" ) {
7300
			this._initSource();
7301
		}
7302
		if ( key === "appendTo" ) {
7303
			this.menu.element.appendTo( this._appendTo() );
7304
		}
7305
		if ( key === "disabled" && value && this.xhr ) {
7306
			this.xhr.abort();
7307
		}
7308
	},
7309
 
7310
	_appendTo: function() {
7311
		var element = this.options.appendTo;
7312
 
7313
		if ( element ) {
7314
			element = element.jquery || element.nodeType ?
7315
				$( element ) :
7316
				this.document.find( element ).eq( 0 );
7317
		}
7318
 
7319
		if ( !element || !element[ 0 ] ) {
7320
			element = this.element.closest( ".ui-front" );
7321
		}
7322
 
7323
		if ( !element.length ) {
7324
			element = this.document[ 0 ].body;
7325
		}
7326
 
7327
		return element;
7328
	},
7329
 
7330
	_initSource: function() {
7331
		var array, url,
7332
			that = this;
7333
		if ( $.isArray( this.options.source ) ) {
7334
			array = this.options.source;
7335
			this.source = function( request, response ) {
7336
				response( $.ui.autocomplete.filter( array, request.term ) );
7337
			};
7338
		} else if ( typeof this.options.source === "string" ) {
7339
			url = this.options.source;
7340
			this.source = function( request, response ) {
7341
				if ( that.xhr ) {
7342
					that.xhr.abort();
7343
				}
7344
				that.xhr = $.ajax({
7345
					url: url,
7346
					data: request,
7347
					dataType: "json",
7348
					success: function( data ) {
7349
						response( data );
7350
					},
7351
					error: function() {
7352
						response([]);
7353
					}
7354
				});
7355
			};
7356
		} else {
7357
			this.source = this.options.source;
7358
		}
7359
	},
7360
 
7361
	_searchTimeout: function( event ) {
7362
		clearTimeout( this.searching );
7363
		this.searching = this._delay(function() {
7364
 
7365
			// Search if the value has changed, or if the user retypes the same value (see #7434)
7366
			var equalValues = this.term === this._value(),
7367
				menuVisible = this.menu.element.is( ":visible" ),
7368
				modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
7369
 
7370
			if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
7371
				this.selectedItem = null;
7372
				this.search( null, event );
7373
			}
7374
		}, this.options.delay );
7375
	},
7376
 
7377
	search: function( value, event ) {
7378
		value = value != null ? value : this._value();
7379
 
7380
		// always save the actual value, not the one passed as an argument
7381
		this.term = this._value();
7382
 
7383
		if ( value.length < this.options.minLength ) {
7384
			return this.close( event );
7385
		}
7386
 
7387
		if ( this._trigger( "search", event ) === false ) {
7388
			return;
7389
		}
7390
 
7391
		return this._search( value );
7392
	},
7393
 
7394
	_search: function( value ) {
7395
		this.pending++;
7396
		this.element.addClass( "ui-autocomplete-loading" );
7397
		this.cancelSearch = false;
7398
 
7399
		this.source( { term: value }, this._response() );
7400
	},
7401
 
7402
	_response: function() {
7403
		var index = ++this.requestIndex;
7404
 
7405
		return $.proxy(function( content ) {
7406
			if ( index === this.requestIndex ) {
7407
				this.__response( content );
7408
			}
7409
 
7410
			this.pending--;
7411
			if ( !this.pending ) {
7412
				this.element.removeClass( "ui-autocomplete-loading" );
7413
			}
7414
		}, this );
7415
	},
7416
 
7417
	__response: function( content ) {
7418
		if ( content ) {
7419
			content = this._normalize( content );
7420
		}
7421
		this._trigger( "response", null, { content: content } );
7422
		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
7423
			this._suggest( content );
7424
			this._trigger( "open" );
7425
		} else {
7426
			// use ._close() instead of .close() so we don't cancel future searches
7427
			this._close();
7428
		}
7429
	},
7430
 
7431
	close: function( event ) {
7432
		this.cancelSearch = true;
7433
		this._close( event );
7434
	},
7435
 
7436
	_close: function( event ) {
7437
		if ( this.menu.element.is( ":visible" ) ) {
7438
			this.menu.element.hide();
7439
			this.menu.blur();
7440
			this.isNewMenu = true;
7441
			this._trigger( "close", event );
7442
		}
7443
	},
7444
 
7445
	_change: function( event ) {
7446
		if ( this.previous !== this._value() ) {
7447
			this._trigger( "change", event, { item: this.selectedItem } );
7448
		}
7449
	},
7450
 
7451
	_normalize: function( items ) {
7452
		// assume all items have the right format when the first item is complete
7453
		if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
7454
			return items;
7455
		}
7456
		return $.map( items, function( item ) {
7457
			if ( typeof item === "string" ) {
7458
				return {
7459
					label: item,
7460
					value: item
7461
				};
7462
			}
7463
			return $.extend( {}, item, {
7464
				label: item.label || item.value,
7465
				value: item.value || item.label
7466
			});
7467
		});
7468
	},
7469
 
7470
	_suggest: function( items ) {
7471
		var ul = this.menu.element.empty();
7472
		this._renderMenu( ul, items );
7473
		this.isNewMenu = true;
7474
		this.menu.refresh();
7475
 
7476
		// size and position menu
7477
		ul.show();
7478
		this._resizeMenu();
7479
		ul.position( $.extend({
7480
			of: this.element
7481
		}, this.options.position ) );
7482
 
7483
		if ( this.options.autoFocus ) {
7484
			this.menu.next();
7485
		}
7486
	},
7487
 
7488
	_resizeMenu: function() {
7489
		var ul = this.menu.element;
7490
		ul.outerWidth( Math.max(
7491
			// Firefox wraps long text (possibly a rounding bug)
7492
			// so we add 1px to avoid the wrapping (#7513)
7493
			ul.width( "" ).outerWidth() + 1,
7494
			this.element.outerWidth()
7495
		) );
7496
	},
7497
 
7498
	_renderMenu: function( ul, items ) {
7499
		var that = this;
7500
		$.each( items, function( index, item ) {
7501
			that._renderItemData( ul, item );
7502
		});
7503
	},
7504
 
7505
	_renderItemData: function( ul, item ) {
7506
		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
7507
	},
7508
 
7509
	_renderItem: function( ul, item ) {
7510
		return $( "<li>" ).text( item.label ).appendTo( ul );
7511
	},
7512
 
7513
	_move: function( direction, event ) {
7514
		if ( !this.menu.element.is( ":visible" ) ) {
7515
			this.search( null, event );
7516
			return;
7517
		}
7518
		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
7519
				this.menu.isLastItem() && /^next/.test( direction ) ) {
7520
 
7521
			if ( !this.isMultiLine ) {
7522
				this._value( this.term );
7523
			}
7524
 
7525
			this.menu.blur();
7526
			return;
7527
		}
7528
		this.menu[ direction ]( event );
7529
	},
7530
 
7531
	widget: function() {
7532
		return this.menu.element;
7533
	},
7534
 
7535
	_value: function() {
7536
		return this.valueMethod.apply( this.element, arguments );
7537
	},
7538
 
7539
	_keyEvent: function( keyEvent, event ) {
7540
		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
7541
			this._move( keyEvent, event );
7542
 
7543
			// prevents moving cursor to beginning/end of the text field in some browsers
7544
			event.preventDefault();
7545
		}
7546
	}
7547
});
7548
 
7549
$.extend( $.ui.autocomplete, {
7550
	escapeRegex: function( value ) {
7551
		return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
7552
	},
7553
	filter: function( array, term ) {
7554
		var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
7555
		return $.grep( array, function( value ) {
7556
			return matcher.test( value.label || value.value || value );
7557
		});
7558
	}
7559
});
7560
 
7561
// live region extension, adding a `messages` option
7562
// NOTE: This is an experimental API. We are still investigating
7563
// a full solution for string manipulation and internationalization.
7564
$.widget( "ui.autocomplete", $.ui.autocomplete, {
7565
	options: {
7566
		messages: {
7567
			noResults: "No search results.",
7568
			results: function( amount ) {
7569
				return amount + ( amount > 1 ? " results are" : " result is" ) +
7570
					" available, use up and down arrow keys to navigate.";
7571
			}
7572
		}
7573
	},
7574
 
7575
	__response: function( content ) {
7576
		var message;
7577
		this._superApply( arguments );
7578
		if ( this.options.disabled || this.cancelSearch ) {
7579
			return;
7580
		}
7581
		if ( content && content.length ) {
7582
			message = this.options.messages.results( content.length );
7583
		} else {
7584
			message = this.options.messages.noResults;
7585
		}
7586
		this.liveRegion.children().hide();
7587
		$( "<div>" ).text( message ).appendTo( this.liveRegion );
7588
	}
7589
});
7590
 
7591
var autocomplete = $.ui.autocomplete;
7592
 
7593
 
7594
/*!
7595
 * jQuery UI Button 1.11.4
7596
 * http://jqueryui.com
7597
 *
7598
 * Copyright jQuery Foundation and other contributors
7599
 * Released under the MIT license.
7600
 * http://jquery.org/license
7601
 *
7602
 * http://api.jqueryui.com/button/
7603
 */
7604
 
7605
 
7606
var lastActive,
7607
	baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
7608
	typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
7609
	formResetHandler = function() {
7610
		var form = $( this );
7611
		setTimeout(function() {
7612
			form.find( ":ui-button" ).button( "refresh" );
7613
		}, 1 );
7614
	},
7615
	radioGroup = function( radio ) {
7616
		var name = radio.name,
7617
			form = radio.form,
7618
			radios = $( [] );
7619
		if ( name ) {
7620
			name = name.replace( /'/g, "\\'" );
7621
			if ( form ) {
7622
				radios = $( form ).find( "[name='" + name + "'][type=radio]" );
7623
			} else {
7624
				radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument )
7625
					.filter(function() {
7626
						return !this.form;
7627
					});
7628
			}
7629
		}
7630
		return radios;
7631
	};
7632
 
7633
$.widget( "ui.button", {
7634
	version: "1.11.4",
7635
	defaultElement: "<button>",
7636
	options: {
7637
		disabled: null,
7638
		text: true,
7639
		label: null,
7640
		icons: {
7641
			primary: null,
7642
			secondary: null
7643
		}
7644
	},
7645
	_create: function() {
7646
		this.element.closest( "form" )
7647
			.unbind( "reset" + this.eventNamespace )
7648
			.bind( "reset" + this.eventNamespace, formResetHandler );
7649
 
7650
		if ( typeof this.options.disabled !== "boolean" ) {
7651
			this.options.disabled = !!this.element.prop( "disabled" );
7652
		} else {
7653
			this.element.prop( "disabled", this.options.disabled );
7654
		}
7655
 
7656
		this._determineButtonType();
7657
		this.hasTitle = !!this.buttonElement.attr( "title" );
7658
 
7659
		var that = this,
7660
			options = this.options,
7661
			toggleButton = this.type === "checkbox" || this.type === "radio",
7662
			activeClass = !toggleButton ? "ui-state-active" : "";
7663
 
7664
		if ( options.label === null ) {
7665
			options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
7666
		}
7667
 
7668
		this._hoverable( this.buttonElement );
7669
 
7670
		this.buttonElement
7671
			.addClass( baseClasses )
7672
			.attr( "role", "button" )
7673
			.bind( "mouseenter" + this.eventNamespace, function() {
7674
				if ( options.disabled ) {
7675
					return;
7676
				}
7677
				if ( this === lastActive ) {
7678
					$( this ).addClass( "ui-state-active" );
7679
				}
7680
			})
7681
			.bind( "mouseleave" + this.eventNamespace, function() {
7682
				if ( options.disabled ) {
7683
					return;
7684
				}
7685
				$( this ).removeClass( activeClass );
7686
			})
7687
			.bind( "click" + this.eventNamespace, function( event ) {
7688
				if ( options.disabled ) {
7689
					event.preventDefault();
7690
					event.stopImmediatePropagation();
7691
				}
7692
			});
7693
 
7694
		// Can't use _focusable() because the element that receives focus
7695
		// and the element that gets the ui-state-focus class are different
7696
		this._on({
7697
			focus: function() {
7698
				this.buttonElement.addClass( "ui-state-focus" );
7699
			},
7700
			blur: function() {
7701
				this.buttonElement.removeClass( "ui-state-focus" );
7702
			}
7703
		});
7704
 
7705
		if ( toggleButton ) {
7706
			this.element.bind( "change" + this.eventNamespace, function() {
7707
				that.refresh();
7708
			});
7709
		}
7710
 
7711
		if ( this.type === "checkbox" ) {
7712
			this.buttonElement.bind( "click" + this.eventNamespace, function() {
7713
				if ( options.disabled ) {
7714
					return false;
7715
				}
7716
			});
7717
		} else if ( this.type === "radio" ) {
7718
			this.buttonElement.bind( "click" + this.eventNamespace, function() {
7719
				if ( options.disabled ) {
7720
					return false;
7721
				}
7722
				$( this ).addClass( "ui-state-active" );
7723
				that.buttonElement.attr( "aria-pressed", "true" );
7724
 
7725
				var radio = that.element[ 0 ];
7726
				radioGroup( radio )
7727
					.not( radio )
7728
					.map(function() {
7729
						return $( this ).button( "widget" )[ 0 ];
7730
					})
7731
					.removeClass( "ui-state-active" )
7732
					.attr( "aria-pressed", "false" );
7733
			});
7734
		} else {
7735
			this.buttonElement
7736
				.bind( "mousedown" + this.eventNamespace, function() {
7737
					if ( options.disabled ) {
7738
						return false;
7739
					}
7740
					$( this ).addClass( "ui-state-active" );
7741
					lastActive = this;
7742
					that.document.one( "mouseup", function() {
7743
						lastActive = null;
7744
					});
7745
				})
7746
				.bind( "mouseup" + this.eventNamespace, function() {
7747
					if ( options.disabled ) {
7748
						return false;
7749
					}
7750
					$( this ).removeClass( "ui-state-active" );
7751
				})
7752
				.bind( "keydown" + this.eventNamespace, function(event) {
7753
					if ( options.disabled ) {
7754
						return false;
7755
					}
7756
					if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
7757
						$( this ).addClass( "ui-state-active" );
7758
					}
7759
				})
7760
				// see #8559, we bind to blur here in case the button element loses
7761
				// focus between keydown and keyup, it would be left in an "active" state
7762
				.bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
7763
					$( this ).removeClass( "ui-state-active" );
7764
				});
7765
 
7766
			if ( this.buttonElement.is("a") ) {
7767
				this.buttonElement.keyup(function(event) {
7768
					if ( event.keyCode === $.ui.keyCode.SPACE ) {
7769
						// TODO pass through original event correctly (just as 2nd argument doesn't work)
7770
						$( this ).click();
7771
					}
7772
				});
7773
			}
7774
		}
7775
 
7776
		this._setOption( "disabled", options.disabled );
7777
		this._resetButton();
7778
	},
7779
 
7780
	_determineButtonType: function() {
7781
		var ancestor, labelSelector, checked;
7782
 
7783
		if ( this.element.is("[type=checkbox]") ) {
7784
			this.type = "checkbox";
7785
		} else if ( this.element.is("[type=radio]") ) {
7786
			this.type = "radio";
7787
		} else if ( this.element.is("input") ) {
7788
			this.type = "input";
7789
		} else {
7790
			this.type = "button";
7791
		}
7792
 
7793
		if ( this.type === "checkbox" || this.type === "radio" ) {
7794
			// we don't search against the document in case the element
7795
			// is disconnected from the DOM
7796
			ancestor = this.element.parents().last();
7797
			labelSelector = "label[for='" + this.element.attr("id") + "']";
7798
			this.buttonElement = ancestor.find( labelSelector );
7799
			if ( !this.buttonElement.length ) {
7800
				ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
7801
				this.buttonElement = ancestor.filter( labelSelector );
7802
				if ( !this.buttonElement.length ) {
7803
					this.buttonElement = ancestor.find( labelSelector );
7804
				}
7805
			}
7806
			this.element.addClass( "ui-helper-hidden-accessible" );
7807
 
7808
			checked = this.element.is( ":checked" );
7809
			if ( checked ) {
7810
				this.buttonElement.addClass( "ui-state-active" );
7811
			}
7812
			this.buttonElement.prop( "aria-pressed", checked );
7813
		} else {
7814
			this.buttonElement = this.element;
7815
		}
7816
	},
7817
 
7818
	widget: function() {
7819
		return this.buttonElement;
7820
	},
7821
 
7822
	_destroy: function() {
7823
		this.element
7824
			.removeClass( "ui-helper-hidden-accessible" );
7825
		this.buttonElement
7826
			.removeClass( baseClasses + " ui-state-active " + typeClasses )
7827
			.removeAttr( "role" )
7828
			.removeAttr( "aria-pressed" )
7829
			.html( this.buttonElement.find(".ui-button-text").html() );
7830
 
7831
		if ( !this.hasTitle ) {
7832
			this.buttonElement.removeAttr( "title" );
7833
		}
7834
	},
7835
 
7836
	_setOption: function( key, value ) {
7837
		this._super( key, value );
7838
		if ( key === "disabled" ) {
7839
			this.widget().toggleClass( "ui-state-disabled", !!value );
7840
			this.element.prop( "disabled", !!value );
7841
			if ( value ) {
7842
				if ( this.type === "checkbox" || this.type === "radio" ) {
7843
					this.buttonElement.removeClass( "ui-state-focus" );
7844
				} else {
7845
					this.buttonElement.removeClass( "ui-state-focus ui-state-active" );
7846
				}
7847
			}
7848
			return;
7849
		}
7850
		this._resetButton();
7851
	},
7852
 
7853
	refresh: function() {
7854
		//See #8237 & #8828
7855
		var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
7856
 
7857
		if ( isDisabled !== this.options.disabled ) {
7858
			this._setOption( "disabled", isDisabled );
7859
		}
7860
		if ( this.type === "radio" ) {
7861
			radioGroup( this.element[0] ).each(function() {
7862
				if ( $( this ).is( ":checked" ) ) {
7863
					$( this ).button( "widget" )
7864
						.addClass( "ui-state-active" )
7865
						.attr( "aria-pressed", "true" );
7866
				} else {
7867
					$( this ).button( "widget" )
7868
						.removeClass( "ui-state-active" )
7869
						.attr( "aria-pressed", "false" );
7870
				}
7871
			});
7872
		} else if ( this.type === "checkbox" ) {
7873
			if ( this.element.is( ":checked" ) ) {
7874
				this.buttonElement
7875
					.addClass( "ui-state-active" )
7876
					.attr( "aria-pressed", "true" );
7877
			} else {
7878
				this.buttonElement
7879
					.removeClass( "ui-state-active" )
7880
					.attr( "aria-pressed", "false" );
7881
			}
7882
		}
7883
	},
7884
 
7885
	_resetButton: function() {
7886
		if ( this.type === "input" ) {
7887
			if ( this.options.label ) {
7888
				this.element.val( this.options.label );
7889
			}
7890
			return;
7891
		}
7892
		var buttonElement = this.buttonElement.removeClass( typeClasses ),
7893
			buttonText = $( "<span></span>", this.document[0] )
7894
				.addClass( "ui-button-text" )
7895
				.html( this.options.label )
7896
				.appendTo( buttonElement.empty() )
7897
				.text(),
7898
			icons = this.options.icons,
7899
			multipleIcons = icons.primary && icons.secondary,
7900
			buttonClasses = [];
7901
 
7902
		if ( icons.primary || icons.secondary ) {
7903
			if ( this.options.text ) {
7904
				buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
7905
			}
7906
 
7907
			if ( icons.primary ) {
7908
				buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
7909
			}
7910
 
7911
			if ( icons.secondary ) {
7912
				buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
7913
			}
7914
 
7915
			if ( !this.options.text ) {
7916
				buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
7917
 
7918
				if ( !this.hasTitle ) {
7919
					buttonElement.attr( "title", $.trim( buttonText ) );
7920
				}
7921
			}
7922
		} else {
7923
			buttonClasses.push( "ui-button-text-only" );
7924
		}
7925
		buttonElement.addClass( buttonClasses.join( " " ) );
7926
	}
7927
});
7928
 
7929
$.widget( "ui.buttonset", {
7930
	version: "1.11.4",
7931
	options: {
7932
		items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
7933
	},
7934
 
7935
	_create: function() {
7936
		this.element.addClass( "ui-buttonset" );
7937
	},
7938
 
7939
	_init: function() {
7940
		this.refresh();
7941
	},
7942
 
7943
	_setOption: function( key, value ) {
7944
		if ( key === "disabled" ) {
7945
			this.buttons.button( "option", key, value );
7946
		}
7947
 
7948
		this._super( key, value );
7949
	},
7950
 
7951
	refresh: function() {
7952
		var rtl = this.element.css( "direction" ) === "rtl",
7953
			allButtons = this.element.find( this.options.items ),
7954
			existingButtons = allButtons.filter( ":ui-button" );
7955
 
7956
		// Initialize new buttons
7957
		allButtons.not( ":ui-button" ).button();
7958
 
7959
		// Refresh existing buttons
7960
		existingButtons.button( "refresh" );
7961
 
7962
		this.buttons = allButtons
7963
			.map(function() {
7964
				return $( this ).button( "widget" )[ 0 ];
7965
			})
7966
				.removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
7967
				.filter( ":first" )
7968
					.addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
7969
				.end()
7970
				.filter( ":last" )
7971
					.addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
7972
				.end()
7973
			.end();
7974
	},
7975
 
7976
	_destroy: function() {
7977
		this.element.removeClass( "ui-buttonset" );
7978
		this.buttons
7979
			.map(function() {
7980
				return $( this ).button( "widget" )[ 0 ];
7981
			})
7982
				.removeClass( "ui-corner-left ui-corner-right" )
7983
			.end()
7984
			.button( "destroy" );
7985
	}
7986
});
7987
 
7988
var button = $.ui.button;
7989
 
7990
 
7991
/*!
7992
 * jQuery UI Datepicker 1.11.4
7993
 * http://jqueryui.com
7994
 *
7995
 * Copyright jQuery Foundation and other contributors
7996
 * Released under the MIT license.
7997
 * http://jquery.org/license
7998
 *
7999
 * http://api.jqueryui.com/datepicker/
8000
 */
8001
 
8002
 
8003
$.extend($.ui, { datepicker: { version: "1.11.4" } });
8004
 
8005
var datepicker_instActive;
8006
 
8007
function datepicker_getZindex( elem ) {
8008
	var position, value;
8009
	while ( elem.length && elem[ 0 ] !== document ) {
8010
		// Ignore z-index if position is set to a value where z-index is ignored by the browser
8011
		// This makes behavior of this function consistent across browsers
8012
		// WebKit always returns auto if the element is positioned
8013
		position = elem.css( "position" );
8014
		if ( position === "absolute" || position === "relative" || position === "fixed" ) {
8015
			// IE returns 0 when zIndex is not specified
8016
			// other browsers return a string
8017
			// we ignore the case of nested elements with an explicit value of 0
8018
			// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
8019
			value = parseInt( elem.css( "zIndex" ), 10 );
8020
			if ( !isNaN( value ) && value !== 0 ) {
8021
				return value;
8022
			}
8023
		}
8024
		elem = elem.parent();
8025
	}
8026
 
8027
	return 0;
8028
}
8029
/* Date picker manager.
8030
   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
8031
   Settings for (groups of) date pickers are maintained in an instance object,
8032
   allowing multiple different settings on the same page. */
8033
 
8034
function Datepicker() {
8035
	this._curInst = null; // The current instance in use
8036
	this._keyEvent = false; // If the last event was a key event
8037
	this._disabledInputs = []; // List of date picker inputs that have been disabled
8038
	this._datepickerShowing = false; // True if the popup picker is showing , false if not
8039
	this._inDialog = false; // True if showing within a "dialog", false if not
8040
	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
8041
	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
8042
	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
8043
	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
8044
	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
8045
	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
8046
	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
8047
	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
8048
	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
8049
	this.regional = []; // Available regional settings, indexed by language code
8050
	this.regional[""] = { // Default regional settings
8051
		closeText: "Done", // Display text for close link
8052
		prevText: "Prev", // Display text for previous month link
8053
		nextText: "Next", // Display text for next month link
8054
		currentText: "Today", // Display text for current month link
8055
		monthNames: ["January","February","March","April","May","June",
8056
			"July","August","September","October","November","December"], // Names of months for drop-down and formatting
8057
		monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
8058
		dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
8059
		dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
8060
		dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
8061
		weekHeader: "Wk", // Column header for week of the year
8062
		dateFormat: "mm/dd/yy", // See format options on parseDate
8063
		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
8064
		isRTL: false, // True if right-to-left language, false if left-to-right
8065
		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
8066
		yearSuffix: "" // Additional text to append to the year in the month headers
8067
	};
8068
	this._defaults = { // Global defaults for all the date picker instances
8069
		showOn: "focus", // "focus" for popup on focus,
8070
			// "button" for trigger button, or "both" for either
8071
		showAnim: "fadeIn", // Name of jQuery animation for popup
8072
		showOptions: {}, // Options for enhanced animations
8073
		defaultDate: null, // Used when field is blank: actual date,
8074
			// +/-number for offset from today, null for today
8075
		appendText: "", // Display text following the input box, e.g. showing the format
8076
		buttonText: "...", // Text for trigger button
8077
		buttonImage: "", // URL for trigger button image
8078
		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
8079
		hideIfNoPrevNext: false, // True to hide next/previous month links
8080
			// if not applicable, false to just disable them
8081
		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
8082
		gotoCurrent: false, // True if today link goes back to current selection instead
8083
		changeMonth: false, // True if month can be selected directly, false if only prev/next
8084
		changeYear: false, // True if year can be selected directly, false if only prev/next
8085
		yearRange: "c-10:c+10", // Range of years to display in drop-down,
8086
			// either relative to today's year (-nn:+nn), relative to currently displayed year
8087
			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
8088
		showOtherMonths: false, // True to show dates in other months, false to leave blank
8089
		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
8090
		showWeek: false, // True to show week of the year, false to not show it
8091
		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
8092
			// takes a Date and returns the number of the week for it
8093
		shortYearCutoff: "+10", // Short year values < this are in the current century,
8094
			// > this are in the previous century,
8095
			// string value starting with "+" for current year + value
8096
		minDate: null, // The earliest selectable date, or null for no limit
8097
		maxDate: null, // The latest selectable date, or null for no limit
8098
		duration: "fast", // Duration of display/closure
8099
		beforeShowDay: null, // Function that takes a date and returns an array with
8100
			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
8101
			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
8102
		beforeShow: null, // Function that takes an input field and
8103
			// returns a set of custom settings for the date picker
8104
		onSelect: null, // Define a callback function when a date is selected
8105
		onChangeMonthYear: null, // Define a callback function when the month or year is changed
8106
		onClose: null, // Define a callback function when the datepicker is closed
8107
		numberOfMonths: 1, // Number of months to show at a time
8108
		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
8109
		stepMonths: 1, // Number of months to step back/forward
8110
		stepBigMonths: 12, // Number of months to step back/forward for the big links
8111
		altField: "", // Selector for an alternate field to store selected dates into
8112
		altFormat: "", // The date format to use for the alternate field
8113
		constrainInput: true, // The input is constrained by the current date format
8114
		showButtonPanel: false, // True to show button panel, false to not show it
8115
		autoSize: false, // True to size the input for the date format, false to leave as is
8116
		disabled: false // The initial disabled state
8117
	};
8118
	$.extend(this._defaults, this.regional[""]);
8119
	this.regional.en = $.extend( true, {}, this.regional[ "" ]);
8120
	this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
8121
	this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
8122
}
8123
 
8124
$.extend(Datepicker.prototype, {
8125
	/* Class name added to elements to indicate already configured with a date picker. */
8126
	markerClassName: "hasDatepicker",
8127
 
8128
	//Keep track of the maximum number of rows displayed (see #7043)
8129
	maxRows: 4,
8130
 
8131
	// TODO rename to "widget" when switching to widget factory
8132
	_widgetDatepicker: function() {
8133
		return this.dpDiv;
8134
	},
8135
 
8136
	/* Override the default settings for all instances of the date picker.
8137
	 * @param  settings  object - the new settings to use as defaults (anonymous object)
8138
	 * @return the manager object
8139
	 */
8140
	setDefaults: function(settings) {
8141
		datepicker_extendRemove(this._defaults, settings || {});
8142
		return this;
8143
	},
8144
 
8145
	/* Attach the date picker to a jQuery selection.
8146
	 * @param  target	element - the target input field or division or span
8147
	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
8148
	 */
8149
	_attachDatepicker: function(target, settings) {
8150
		var nodeName, inline, inst;
8151
		nodeName = target.nodeName.toLowerCase();
8152
		inline = (nodeName === "div" || nodeName === "span");
8153
		if (!target.id) {
8154
			this.uuid += 1;
8155
			target.id = "dp" + this.uuid;
8156
		}
8157
		inst = this._newInst($(target), inline);
8158
		inst.settings = $.extend({}, settings || {});
8159
		if (nodeName === "input") {
8160
			this._connectDatepicker(target, inst);
8161
		} else if (inline) {
8162
			this._inlineDatepicker(target, inst);
8163
		}
8164
	},
8165
 
8166
	/* Create a new instance object. */
8167
	_newInst: function(target, inline) {
8168
		var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
8169
		return {id: id, input: target, // associated target
8170
			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
8171
			drawMonth: 0, drawYear: 0, // month being drawn
8172
			inline: inline, // is datepicker inline or not
8173
			dpDiv: (!inline ? this.dpDiv : // presentation div
8174
			datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
8175
	},
8176
 
8177
	/* Attach the date picker to an input field. */
8178
	_connectDatepicker: function(target, inst) {
8179
		var input = $(target);
8180
		inst.append = $([]);
8181
		inst.trigger = $([]);
8182
		if (input.hasClass(this.markerClassName)) {
8183
			return;
8184
		}
8185
		this._attachments(input, inst);
8186
		input.addClass(this.markerClassName).keydown(this._doKeyDown).
8187
			keypress(this._doKeyPress).keyup(this._doKeyUp);
8188
		this._autoSize(inst);
8189
		$.data(target, "datepicker", inst);
8190
		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
8191
		if( inst.settings.disabled ) {
8192
			this._disableDatepicker( target );
8193
		}
8194
	},
8195
 
8196
	/* Make attachments based on settings. */
8197
	_attachments: function(input, inst) {
8198
		var showOn, buttonText, buttonImage,
8199
			appendText = this._get(inst, "appendText"),
8200
			isRTL = this._get(inst, "isRTL");
8201
 
8202
		if (inst.append) {
8203
			inst.append.remove();
8204
		}
8205
		if (appendText) {
8206
			inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
8207
			input[isRTL ? "before" : "after"](inst.append);
8208
		}
8209
 
8210
		input.unbind("focus", this._showDatepicker);
8211
 
8212
		if (inst.trigger) {
8213
			inst.trigger.remove();
8214
		}
8215
 
8216
		showOn = this._get(inst, "showOn");
8217
		if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
8218
			input.focus(this._showDatepicker);
8219
		}
8220
		if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
8221
			buttonText = this._get(inst, "buttonText");
8222
			buttonImage = this._get(inst, "buttonImage");
8223
			inst.trigger = $(this._get(inst, "buttonImageOnly") ?
8224
				$("<img/>").addClass(this._triggerClass).
8225
					attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
8226
				$("<button type='button'></button>").addClass(this._triggerClass).
8227
					html(!buttonImage ? buttonText : $("<img/>").attr(
8228
					{ src:buttonImage, alt:buttonText, title:buttonText })));
8229
			input[isRTL ? "before" : "after"](inst.trigger);
8230
			inst.trigger.click(function() {
8231
				if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
8232
					$.datepicker._hideDatepicker();
8233
				} else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
8234
					$.datepicker._hideDatepicker();
8235
					$.datepicker._showDatepicker(input[0]);
8236
				} else {
8237
					$.datepicker._showDatepicker(input[0]);
8238
				}
8239
				return false;
8240
			});
8241
		}
8242
	},
8243
 
8244
	/* Apply the maximum length for the date format. */
8245
	_autoSize: function(inst) {
8246
		if (this._get(inst, "autoSize") && !inst.inline) {
8247
			var findMax, max, maxI, i,
8248
				date = new Date(2009, 12 - 1, 20), // Ensure double digits
8249
				dateFormat = this._get(inst, "dateFormat");
8250
 
8251
			if (dateFormat.match(/[DM]/)) {
8252
				findMax = function(names) {
8253
					max = 0;
8254
					maxI = 0;
8255
					for (i = 0; i < names.length; i++) {
8256
						if (names[i].length > max) {
8257
							max = names[i].length;
8258
							maxI = i;
8259
						}
8260
					}
8261
					return maxI;
8262
				};
8263
				date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
8264
					"monthNames" : "monthNamesShort"))));
8265
				date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
8266
					"dayNames" : "dayNamesShort"))) + 20 - date.getDay());
8267
			}
8268
			inst.input.attr("size", this._formatDate(inst, date).length);
8269
		}
8270
	},
8271
 
8272
	/* Attach an inline date picker to a div. */
8273
	_inlineDatepicker: function(target, inst) {
8274
		var divSpan = $(target);
8275
		if (divSpan.hasClass(this.markerClassName)) {
8276
			return;
8277
		}
8278
		divSpan.addClass(this.markerClassName).append(inst.dpDiv);
8279
		$.data(target, "datepicker", inst);
8280
		this._setDate(inst, this._getDefaultDate(inst), true);
8281
		this._updateDatepicker(inst);
8282
		this._updateAlternate(inst);
8283
		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
8284
		if( inst.settings.disabled ) {
8285
			this._disableDatepicker( target );
8286
		}
8287
		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
8288
		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
8289
		inst.dpDiv.css( "display", "block" );
8290
	},
8291
 
8292
	/* Pop-up the date picker in a "dialog" box.
8293
	 * @param  input element - ignored
8294
	 * @param  date	string or Date - the initial date to display
8295
	 * @param  onSelect  function - the function to call when a date is selected
8296
	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
8297
	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
8298
	 *					event - with x/y coordinates or
8299
	 *					leave empty for default (screen centre)
8300
	 * @return the manager object
8301
	 */
8302
	_dialogDatepicker: function(input, date, onSelect, settings, pos) {
8303
		var id, browserWidth, browserHeight, scrollX, scrollY,
8304
			inst = this._dialogInst; // internal instance
8305
 
8306
		if (!inst) {
8307
			this.uuid += 1;
8308
			id = "dp" + this.uuid;
8309
			this._dialogInput = $("<input type='text' id='" + id +
8310
				"' style='position: absolute; top: -100px; width: 0px;'/>");
8311
			this._dialogInput.keydown(this._doKeyDown);
8312
			$("body").append(this._dialogInput);
8313
			inst = this._dialogInst = this._newInst(this._dialogInput, false);
8314
			inst.settings = {};
8315
			$.data(this._dialogInput[0], "datepicker", inst);
8316
		}
8317
		datepicker_extendRemove(inst.settings, settings || {});
8318
		date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
8319
		this._dialogInput.val(date);
8320
 
8321
		this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
8322
		if (!this._pos) {
8323
			browserWidth = document.documentElement.clientWidth;
8324
			browserHeight = document.documentElement.clientHeight;
8325
			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
8326
			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
8327
			this._pos = // should use actual width/height below
8328
				[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
8329
		}
8330
 
8331
		// move input on screen for focus, but hidden behind dialog
8332
		this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
8333
		inst.settings.onSelect = onSelect;
8334
		this._inDialog = true;
8335
		this.dpDiv.addClass(this._dialogClass);
8336
		this._showDatepicker(this._dialogInput[0]);
8337
		if ($.blockUI) {
8338
			$.blockUI(this.dpDiv);
8339
		}
8340
		$.data(this._dialogInput[0], "datepicker", inst);
8341
		return this;
8342
	},
8343
 
8344
	/* Detach a datepicker from its control.
8345
	 * @param  target	element - the target input field or division or span
8346
	 */
8347
	_destroyDatepicker: function(target) {
8348
		var nodeName,
8349
			$target = $(target),
8350
			inst = $.data(target, "datepicker");
8351
 
8352
		if (!$target.hasClass(this.markerClassName)) {
8353
			return;
8354
		}
8355
 
8356
		nodeName = target.nodeName.toLowerCase();
8357
		$.removeData(target, "datepicker");
8358
		if (nodeName === "input") {
8359
			inst.append.remove();
8360
			inst.trigger.remove();
8361
			$target.removeClass(this.markerClassName).
8362
				unbind("focus", this._showDatepicker).
8363
				unbind("keydown", this._doKeyDown).
8364
				unbind("keypress", this._doKeyPress).
8365
				unbind("keyup", this._doKeyUp);
8366
		} else if (nodeName === "div" || nodeName === "span") {
8367
			$target.removeClass(this.markerClassName).empty();
8368
		}
8369
 
8370
		if ( datepicker_instActive === inst ) {
8371
			datepicker_instActive = null;
8372
		}
8373
	},
8374
 
8375
	/* Enable the date picker to a jQuery selection.
8376
	 * @param  target	element - the target input field or division or span
8377
	 */
8378
	_enableDatepicker: function(target) {
8379
		var nodeName, inline,
8380
			$target = $(target),
8381
			inst = $.data(target, "datepicker");
8382
 
8383
		if (!$target.hasClass(this.markerClassName)) {
8384
			return;
8385
		}
8386
 
8387
		nodeName = target.nodeName.toLowerCase();
8388
		if (nodeName === "input") {
8389
			target.disabled = false;
8390
			inst.trigger.filter("button").
8391
				each(function() { this.disabled = false; }).end().
8392
				filter("img").css({opacity: "1.0", cursor: ""});
8393
		} else if (nodeName === "div" || nodeName === "span") {
8394
			inline = $target.children("." + this._inlineClass);
8395
			inline.children().removeClass("ui-state-disabled");
8396
			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
8397
				prop("disabled", false);
8398
		}
8399
		this._disabledInputs = $.map(this._disabledInputs,
8400
			function(value) { return (value === target ? null : value); }); // delete entry
8401
	},
8402
 
8403
	/* Disable the date picker to a jQuery selection.
8404
	 * @param  target	element - the target input field or division or span
8405
	 */
8406
	_disableDatepicker: function(target) {
8407
		var nodeName, inline,
8408
			$target = $(target),
8409
			inst = $.data(target, "datepicker");
8410
 
8411
		if (!$target.hasClass(this.markerClassName)) {
8412
			return;
8413
		}
8414
 
8415
		nodeName = target.nodeName.toLowerCase();
8416
		if (nodeName === "input") {
8417
			target.disabled = true;
8418
			inst.trigger.filter("button").
8419
				each(function() { this.disabled = true; }).end().
8420
				filter("img").css({opacity: "0.5", cursor: "default"});
8421
		} else if (nodeName === "div" || nodeName === "span") {
8422
			inline = $target.children("." + this._inlineClass);
8423
			inline.children().addClass("ui-state-disabled");
8424
			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
8425
				prop("disabled", true);
8426
		}
8427
		this._disabledInputs = $.map(this._disabledInputs,
8428
			function(value) { return (value === target ? null : value); }); // delete entry
8429
		this._disabledInputs[this._disabledInputs.length] = target;
8430
	},
8431
 
8432
	/* Is the first field in a jQuery collection disabled as a datepicker?
8433
	 * @param  target	element - the target input field or division or span
8434
	 * @return boolean - true if disabled, false if enabled
8435
	 */
8436
	_isDisabledDatepicker: function(target) {
8437
		if (!target) {
8438
			return false;
8439
		}
8440
		for (var i = 0; i < this._disabledInputs.length; i++) {
8441
			if (this._disabledInputs[i] === target) {
8442
				return true;
8443
			}
8444
		}
8445
		return false;
8446
	},
8447
 
8448
	/* Retrieve the instance data for the target control.
8449
	 * @param  target  element - the target input field or division or span
8450
	 * @return  object - the associated instance data
8451
	 * @throws  error if a jQuery problem getting data
8452
	 */
8453
	_getInst: function(target) {
8454
		try {
8455
			return $.data(target, "datepicker");
8456
		}
8457
		catch (err) {
8458
			throw "Missing instance data for this datepicker";
8459
		}
8460
	},
8461
 
8462
	/* Update or retrieve the settings for a date picker attached to an input field or division.
8463
	 * @param  target  element - the target input field or division or span
8464
	 * @param  name	object - the new settings to update or
8465
	 *				string - the name of the setting to change or retrieve,
8466
	 *				when retrieving also "all" for all instance settings or
8467
	 *				"defaults" for all global defaults
8468
	 * @param  value   any - the new value for the setting
8469
	 *				(omit if above is an object or to retrieve a value)
8470
	 */
8471
	_optionDatepicker: function(target, name, value) {
8472
		var settings, date, minDate, maxDate,
8473
			inst = this._getInst(target);
8474
 
8475
		if (arguments.length === 2 && typeof name === "string") {
8476
			return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
8477
				(inst ? (name === "all" ? $.extend({}, inst.settings) :
8478
				this._get(inst, name)) : null));
8479
		}
8480
 
8481
		settings = name || {};
8482
		if (typeof name === "string") {
8483
			settings = {};
8484
			settings[name] = value;
8485
		}
8486
 
8487
		if (inst) {
8488
			if (this._curInst === inst) {
8489
				this._hideDatepicker();
8490
			}
8491
 
8492
			date = this._getDateDatepicker(target, true);
8493
			minDate = this._getMinMaxDate(inst, "min");
8494
			maxDate = this._getMinMaxDate(inst, "max");
8495
			datepicker_extendRemove(inst.settings, settings);
8496
			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
8497
			if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
8498
				inst.settings.minDate = this._formatDate(inst, minDate);
8499
			}
8500
			if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
8501
				inst.settings.maxDate = this._formatDate(inst, maxDate);
8502
			}
8503
			if ( "disabled" in settings ) {
8504
				if ( settings.disabled ) {
8505
					this._disableDatepicker(target);
8506
				} else {
8507
					this._enableDatepicker(target);
8508
				}
8509
			}
8510
			this._attachments($(target), inst);
8511
			this._autoSize(inst);
8512
			this._setDate(inst, date);
8513
			this._updateAlternate(inst);
8514
			this._updateDatepicker(inst);
8515
		}
8516
	},
8517
 
8518
	// change method deprecated
8519
	_changeDatepicker: function(target, name, value) {
8520
		this._optionDatepicker(target, name, value);
8521
	},
8522
 
8523
	/* Redraw the date picker attached to an input field or division.
8524
	 * @param  target  element - the target input field or division or span
8525
	 */
8526
	_refreshDatepicker: function(target) {
8527
		var inst = this._getInst(target);
8528
		if (inst) {
8529
			this._updateDatepicker(inst);
8530
		}
8531
	},
8532
 
8533
	/* Set the dates for a jQuery selection.
8534
	 * @param  target element - the target input field or division or span
8535
	 * @param  date	Date - the new date
8536
	 */
8537
	_setDateDatepicker: function(target, date) {
8538
		var inst = this._getInst(target);
8539
		if (inst) {
8540
			this._setDate(inst, date);
8541
			this._updateDatepicker(inst);
8542
			this._updateAlternate(inst);
8543
		}
8544
	},
8545
 
8546
	/* Get the date(s) for the first entry in a jQuery selection.
8547
	 * @param  target element - the target input field or division or span
8548
	 * @param  noDefault boolean - true if no default date is to be used
8549
	 * @return Date - the current date
8550
	 */
8551
	_getDateDatepicker: function(target, noDefault) {
8552
		var inst = this._getInst(target);
8553
		if (inst && !inst.inline) {
8554
			this._setDateFromField(inst, noDefault);
8555
		}
8556
		return (inst ? this._getDate(inst) : null);
8557
	},
8558
 
8559
	/* Handle keystrokes. */
8560
	_doKeyDown: function(event) {
8561
		var onSelect, dateStr, sel,
8562
			inst = $.datepicker._getInst(event.target),
8563
			handled = true,
8564
			isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
8565
 
8566
		inst._keyEvent = true;
8567
		if ($.datepicker._datepickerShowing) {
8568
			switch (event.keyCode) {
8569
				case 9: $.datepicker._hideDatepicker();
8570
						handled = false;
8571
						break; // hide on tab out
8572
				case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
8573
									$.datepicker._currentClass + ")", inst.dpDiv);
8574
						if (sel[0]) {
8575
							$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
8576
						}
8577
 
8578
						onSelect = $.datepicker._get(inst, "onSelect");
8579
						if (onSelect) {
8580
							dateStr = $.datepicker._formatDate(inst);
8581
 
8582
							// trigger custom callback
8583
							onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
8584
						} else {
8585
							$.datepicker._hideDatepicker();
8586
						}
8587
 
8588
						return false; // don't submit the form
8589
				case 27: $.datepicker._hideDatepicker();
8590
						break; // hide on escape
8591
				case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8592
							-$.datepicker._get(inst, "stepBigMonths") :
8593
							-$.datepicker._get(inst, "stepMonths")), "M");
8594
						break; // previous month/year on page up/+ ctrl
8595
				case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8596
							+$.datepicker._get(inst, "stepBigMonths") :
8597
							+$.datepicker._get(inst, "stepMonths")), "M");
8598
						break; // next month/year on page down/+ ctrl
8599
				case 35: if (event.ctrlKey || event.metaKey) {
8600
							$.datepicker._clearDate(event.target);
8601
						}
8602
						handled = event.ctrlKey || event.metaKey;
8603
						break; // clear on ctrl or command +end
8604
				case 36: if (event.ctrlKey || event.metaKey) {
8605
							$.datepicker._gotoToday(event.target);
8606
						}
8607
						handled = event.ctrlKey || event.metaKey;
8608
						break; // current on ctrl or command +home
8609
				case 37: if (event.ctrlKey || event.metaKey) {
8610
							$.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
8611
						}
8612
						handled = event.ctrlKey || event.metaKey;
8613
						// -1 day on ctrl or command +left
8614
						if (event.originalEvent.altKey) {
8615
							$.datepicker._adjustDate(event.target, (event.ctrlKey ?
8616
								-$.datepicker._get(inst, "stepBigMonths") :
8617
								-$.datepicker._get(inst, "stepMonths")), "M");
8618
						}
8619
						// next month/year on alt +left on Mac
8620
						break;
8621
				case 38: if (event.ctrlKey || event.metaKey) {
8622
							$.datepicker._adjustDate(event.target, -7, "D");
8623
						}
8624
						handled = event.ctrlKey || event.metaKey;
8625
						break; // -1 week on ctrl or command +up
8626
				case 39: if (event.ctrlKey || event.metaKey) {
8627
							$.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
8628
						}
8629
						handled = event.ctrlKey || event.metaKey;
8630
						// +1 day on ctrl or command +right
8631
						if (event.originalEvent.altKey) {
8632
							$.datepicker._adjustDate(event.target, (event.ctrlKey ?
8633
								+$.datepicker._get(inst, "stepBigMonths") :
8634
								+$.datepicker._get(inst, "stepMonths")), "M");
8635
						}
8636
						// next month/year on alt +right
8637
						break;
8638
				case 40: if (event.ctrlKey || event.metaKey) {
8639
							$.datepicker._adjustDate(event.target, +7, "D");
8640
						}
8641
						handled = event.ctrlKey || event.metaKey;
8642
						break; // +1 week on ctrl or command +down
8643
				default: handled = false;
8644
			}
8645
		} else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
8646
			$.datepicker._showDatepicker(this);
8647
		} else {
8648
			handled = false;
8649
		}
8650
 
8651
		if (handled) {
8652
			event.preventDefault();
8653
			event.stopPropagation();
8654
		}
8655
	},
8656
 
8657
	/* Filter entered characters - based on date format. */
8658
	_doKeyPress: function(event) {
8659
		var chars, chr,
8660
			inst = $.datepicker._getInst(event.target);
8661
 
8662
		if ($.datepicker._get(inst, "constrainInput")) {
8663
			chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
8664
			chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
8665
			return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
8666
		}
8667
	},
8668
 
8669
	/* Synchronise manual entry and field/alternate field. */
8670
	_doKeyUp: function(event) {
8671
		var date,
8672
			inst = $.datepicker._getInst(event.target);
8673
 
8674
		if (inst.input.val() !== inst.lastVal) {
8675
			try {
8676
				date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
8677
					(inst.input ? inst.input.val() : null),
8678
					$.datepicker._getFormatConfig(inst));
8679
 
8680
				if (date) { // only if valid
8681
					$.datepicker._setDateFromField(inst);
8682
					$.datepicker._updateAlternate(inst);
8683
					$.datepicker._updateDatepicker(inst);
8684
				}
8685
			}
8686
			catch (err) {
8687
			}
8688
		}
8689
		return true;
8690
	},
8691
 
8692
	/* Pop-up the date picker for a given input field.
8693
	 * If false returned from beforeShow event handler do not show.
8694
	 * @param  input  element - the input field attached to the date picker or
8695
	 *					event - if triggered by focus
8696
	 */
8697
	_showDatepicker: function(input) {
8698
		input = input.target || input;
8699
		if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
8700
			input = $("input", input.parentNode)[0];
8701
		}
8702
 
8703
		if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
8704
			return;
8705
		}
8706
 
8707
		var inst, beforeShow, beforeShowSettings, isFixed,
8708
			offset, showAnim, duration;
8709
 
8710
		inst = $.datepicker._getInst(input);
8711
		if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
8712
			$.datepicker._curInst.dpDiv.stop(true, true);
8713
			if ( inst && $.datepicker._datepickerShowing ) {
8714
				$.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
8715
			}
8716
		}
8717
 
8718
		beforeShow = $.datepicker._get(inst, "beforeShow");
8719
		beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
8720
		if(beforeShowSettings === false){
8721
			return;
8722
		}
8723
		datepicker_extendRemove(inst.settings, beforeShowSettings);
8724
 
8725
		inst.lastVal = null;
8726
		$.datepicker._lastInput = input;
8727
		$.datepicker._setDateFromField(inst);
8728
 
8729
		if ($.datepicker._inDialog) { // hide cursor
8730
			input.value = "";
8731
		}
8732
		if (!$.datepicker._pos) { // position below input
8733
			$.datepicker._pos = $.datepicker._findPos(input);
8734
			$.datepicker._pos[1] += input.offsetHeight; // add the height
8735
		}
8736
 
8737
		isFixed = false;
8738
		$(input).parents().each(function() {
8739
			isFixed |= $(this).css("position") === "fixed";
8740
			return !isFixed;
8741
		});
8742
 
8743
		offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
8744
		$.datepicker._pos = null;
8745
		//to avoid flashes on Firefox
8746
		inst.dpDiv.empty();
8747
		// determine sizing offscreen
8748
		inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
8749
		$.datepicker._updateDatepicker(inst);
8750
		// fix width for dynamic number of date pickers
8751
		// and adjust position before showing
8752
		offset = $.datepicker._checkOffset(inst, offset, isFixed);
8753
		inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
8754
			"static" : (isFixed ? "fixed" : "absolute")), display: "none",
8755
			left: offset.left + "px", top: offset.top + "px"});
8756
 
8757
		if (!inst.inline) {
8758
			showAnim = $.datepicker._get(inst, "showAnim");
8759
			duration = $.datepicker._get(inst, "duration");
8760
			inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
8761
			$.datepicker._datepickerShowing = true;
8762
 
8763
			if ( $.effects && $.effects.effect[ showAnim ] ) {
8764
				inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
8765
			} else {
8766
				inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
8767
			}
8768
 
8769
			if ( $.datepicker._shouldFocusInput( inst ) ) {
8770
				inst.input.focus();
8771
			}
8772
 
8773
			$.datepicker._curInst = inst;
8774
		}
8775
	},
8776
 
8777
	/* Generate the date picker content. */
8778
	_updateDatepicker: function(inst) {
8779
		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
8780
		datepicker_instActive = inst; // for delegate hover events
8781
		inst.dpDiv.empty().append(this._generateHTML(inst));
8782
		this._attachHandlers(inst);
8783
 
8784
		var origyearshtml,
8785
			numMonths = this._getNumberOfMonths(inst),
8786
			cols = numMonths[1],
8787
			width = 17,
8788
			activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
8789
 
8790
		if ( activeCell.length > 0 ) {
8791
			datepicker_handleMouseover.apply( activeCell.get( 0 ) );
8792
		}
8793
 
8794
		inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
8795
		if (cols > 1) {
8796
			inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
8797
		}
8798
		inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
8799
			"Class"]("ui-datepicker-multi");
8800
		inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
8801
			"Class"]("ui-datepicker-rtl");
8802
 
8803
		if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
8804
			inst.input.focus();
8805
		}
8806
 
8807
		// deffered render of the years select (to avoid flashes on Firefox)
8808
		if( inst.yearshtml ){
8809
			origyearshtml = inst.yearshtml;
8810
			setTimeout(function(){
8811
				//assure that inst.yearshtml didn't change.
8812
				if( origyearshtml === inst.yearshtml && inst.yearshtml ){
8813
					inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
8814
				}
8815
				origyearshtml = inst.yearshtml = null;
8816
			}, 0);
8817
		}
8818
	},
8819
 
8820
	// #6694 - don't focus the input if it's already focused
8821
	// this breaks the change event in IE
8822
	// Support: IE and jQuery <1.9
8823
	_shouldFocusInput: function( inst ) {
8824
		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
8825
	},
8826
 
8827
	/* Check positioning to remain on screen. */
8828
	_checkOffset: function(inst, offset, isFixed) {
8829
		var dpWidth = inst.dpDiv.outerWidth(),
8830
			dpHeight = inst.dpDiv.outerHeight(),
8831
			inputWidth = inst.input ? inst.input.outerWidth() : 0,
8832
			inputHeight = inst.input ? inst.input.outerHeight() : 0,
8833
			viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
8834
			viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
8835
 
8836
		offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
8837
		offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
8838
		offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
8839
 
8840
		// now check if datepicker is showing outside window viewport - move to a better place if so.
8841
		offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
8842
			Math.abs(offset.left + dpWidth - viewWidth) : 0);
8843
		offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
8844
			Math.abs(dpHeight + inputHeight) : 0);
8845
 
8846
		return offset;
8847
	},
8848
 
8849
	/* Find an object's position on the screen. */
8850
	_findPos: function(obj) {
8851
		var position,
8852
			inst = this._getInst(obj),
8853
			isRTL = this._get(inst, "isRTL");
8854
 
8855
		while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
8856
			obj = obj[isRTL ? "previousSibling" : "nextSibling"];
8857
		}
8858
 
8859
		position = $(obj).offset();
8860
		return [position.left, position.top];
8861
	},
8862
 
8863
	/* Hide the date picker from view.
8864
	 * @param  input  element - the input field attached to the date picker
8865
	 */
8866
	_hideDatepicker: function(input) {
8867
		var showAnim, duration, postProcess, onClose,
8868
			inst = this._curInst;
8869
 
8870
		if (!inst || (input && inst !== $.data(input, "datepicker"))) {
8871
			return;
8872
		}
8873
 
8874
		if (this._datepickerShowing) {
8875
			showAnim = this._get(inst, "showAnim");
8876
			duration = this._get(inst, "duration");
8877
			postProcess = function() {
8878
				$.datepicker._tidyDialog(inst);
8879
			};
8880
 
8881
			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
8882
			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
8883
				inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
8884
			} else {
8885
				inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
8886
					(showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
8887
			}
8888
 
8889
			if (!showAnim) {
8890
				postProcess();
8891
			}
8892
			this._datepickerShowing = false;
8893
 
8894
			onClose = this._get(inst, "onClose");
8895
			if (onClose) {
8896
				onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
8897
			}
8898
 
8899
			this._lastInput = null;
8900
			if (this._inDialog) {
8901
				this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
8902
				if ($.blockUI) {
8903
					$.unblockUI();
8904
					$("body").append(this.dpDiv);
8905
				}
8906
			}
8907
			this._inDialog = false;
8908
		}
8909
	},
8910
 
8911
	/* Tidy up after a dialog display. */
8912
	_tidyDialog: function(inst) {
8913
		inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
8914
	},
8915
 
8916
	/* Close date picker if clicked elsewhere. */
8917
	_checkExternalClick: function(event) {
8918
		if (!$.datepicker._curInst) {
8919
			return;
8920
		}
8921
 
8922
		var $target = $(event.target),
8923
			inst = $.datepicker._getInst($target[0]);
8924
 
8925
		if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
8926
				$target.parents("#" + $.datepicker._mainDivId).length === 0 &&
8927
				!$target.hasClass($.datepicker.markerClassName) &&
8928
				!$target.closest("." + $.datepicker._triggerClass).length &&
8929
				$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
8930
			( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
8931
				$.datepicker._hideDatepicker();
8932
		}
8933
	},
8934
 
8935
	/* Adjust one of the date sub-fields. */
8936
	_adjustDate: function(id, offset, period) {
8937
		var target = $(id),
8938
			inst = this._getInst(target[0]);
8939
 
8940
		if (this._isDisabledDatepicker(target[0])) {
8941
			return;
8942
		}
8943
		this._adjustInstDate(inst, offset +
8944
			(period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
8945
			period);
8946
		this._updateDatepicker(inst);
8947
	},
8948
 
8949
	/* Action for current link. */
8950
	_gotoToday: function(id) {
8951
		var date,
8952
			target = $(id),
8953
			inst = this._getInst(target[0]);
8954
 
8955
		if (this._get(inst, "gotoCurrent") && inst.currentDay) {
8956
			inst.selectedDay = inst.currentDay;
8957
			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8958
			inst.drawYear = inst.selectedYear = inst.currentYear;
8959
		} else {
8960
			date = new Date();
8961
			inst.selectedDay = date.getDate();
8962
			inst.drawMonth = inst.selectedMonth = date.getMonth();
8963
			inst.drawYear = inst.selectedYear = date.getFullYear();
8964
		}
8965
		this._notifyChange(inst);
8966
		this._adjustDate(target);
8967
	},
8968
 
8969
	/* Action for selecting a new month/year. */
8970
	_selectMonthYear: function(id, select, period) {
8971
		var target = $(id),
8972
			inst = this._getInst(target[0]);
8973
 
8974
		inst["selected" + (period === "M" ? "Month" : "Year")] =
8975
		inst["draw" + (period === "M" ? "Month" : "Year")] =
8976
			parseInt(select.options[select.selectedIndex].value,10);
8977
 
8978
		this._notifyChange(inst);
8979
		this._adjustDate(target);
8980
	},
8981
 
8982
	/* Action for selecting a day. */
8983
	_selectDay: function(id, month, year, td) {
8984
		var inst,
8985
			target = $(id);
8986
 
8987
		if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
8988
			return;
8989
		}
8990
 
8991
		inst = this._getInst(target[0]);
8992
		inst.selectedDay = inst.currentDay = $("a", td).html();
8993
		inst.selectedMonth = inst.currentMonth = month;
8994
		inst.selectedYear = inst.currentYear = year;
8995
		this._selectDate(id, this._formatDate(inst,
8996
			inst.currentDay, inst.currentMonth, inst.currentYear));
8997
	},
8998
 
8999
	/* Erase the input field and hide the date picker. */
9000
	_clearDate: function(id) {
9001
		var target = $(id);
9002
		this._selectDate(target, "");
9003
	},
9004
 
9005
	/* Update the input field with the selected date. */
9006
	_selectDate: function(id, dateStr) {
9007
		var onSelect,
9008
			target = $(id),
9009
			inst = this._getInst(target[0]);
9010
 
9011
		dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
9012
		if (inst.input) {
9013
			inst.input.val(dateStr);
9014
		}
9015
		this._updateAlternate(inst);
9016
 
9017
		onSelect = this._get(inst, "onSelect");
9018
		if (onSelect) {
9019
			onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
9020
		} else if (inst.input) {
9021
			inst.input.trigger("change"); // fire the change event
9022
		}
9023
 
9024
		if (inst.inline){
9025
			this._updateDatepicker(inst);
9026
		} else {
9027
			this._hideDatepicker();
9028
			this._lastInput = inst.input[0];
9029
			if (typeof(inst.input[0]) !== "object") {
9030
				inst.input.focus(); // restore focus
9031
			}
9032
			this._lastInput = null;
9033
		}
9034
	},
9035
 
9036
	/* Update any alternate field to synchronise with the main field. */
9037
	_updateAlternate: function(inst) {
9038
		var altFormat, date, dateStr,
9039
			altField = this._get(inst, "altField");
9040
 
9041
		if (altField) { // update alternate field too
9042
			altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
9043
			date = this._getDate(inst);
9044
			dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
9045
			$(altField).each(function() { $(this).val(dateStr); });
9046
		}
9047
	},
9048
 
9049
	/* Set as beforeShowDay function to prevent selection of weekends.
9050
	 * @param  date  Date - the date to customise
9051
	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
9052
	 */
9053
	noWeekends: function(date) {
9054
		var day = date.getDay();
9055
		return [(day > 0 && day < 6), ""];
9056
	},
9057
 
9058
	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
9059
	 * @param  date  Date - the date to get the week for
9060
	 * @return  number - the number of the week within the year that contains this date
9061
	 */
9062
	iso8601Week: function(date) {
9063
		var time,
9064
			checkDate = new Date(date.getTime());
9065
 
9066
		// Find Thursday of this week starting on Monday
9067
		checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
9068
 
9069
		time = checkDate.getTime();
9070
		checkDate.setMonth(0); // Compare with Jan 1
9071
		checkDate.setDate(1);
9072
		return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
9073
	},
9074
 
9075
	/* Parse a string value into a date object.
9076
	 * See formatDate below for the possible formats.
9077
	 *
9078
	 * @param  format string - the expected format of the date
9079
	 * @param  value string - the date in the above format
9080
	 * @param  settings Object - attributes include:
9081
	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
9082
	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
9083
	 *					dayNames		string[7] - names of the days from Sunday (optional)
9084
	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
9085
	 *					monthNames		string[12] - names of the months (optional)
9086
	 * @return  Date - the extracted date value or null if value is blank
9087
	 */
9088
	parseDate: function (format, value, settings) {
9089
		if (format == null || value == null) {
9090
			throw "Invalid arguments";
9091
		}
9092
 
9093
		value = (typeof value === "object" ? value.toString() : value + "");
9094
		if (value === "") {
9095
			return null;
9096
		}
9097
 
9098
		var iFormat, dim, extra,
9099
			iValue = 0,
9100
			shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
9101
			shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
9102
				new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
9103
			dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
9104
			dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
9105
			monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
9106
			monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
9107
			year = -1,
9108
			month = -1,
9109
			day = -1,
9110
			doy = -1,
9111
			literal = false,
9112
			date,
9113
			// Check whether a format character is doubled
9114
			lookAhead = function(match) {
9115
				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
9116
				if (matches) {
9117
					iFormat++;
9118
				}
9119
				return matches;
9120
			},
9121
			// Extract a number from the string value
9122
			getNumber = function(match) {
9123
				var isDoubled = lookAhead(match),
9124
					size = (match === "@" ? 14 : (match === "!" ? 20 :
9125
					(match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
9126
					minSize = (match === "y" ? size : 1),
9127
					digits = new RegExp("^\\d{" + minSize + "," + size + "}"),
9128
					num = value.substring(iValue).match(digits);
9129
				if (!num) {
9130
					throw "Missing number at position " + iValue;
9131
				}
9132
				iValue += num[0].length;
9133
				return parseInt(num[0], 10);
9134
			},
9135
			// Extract a name from the string value and convert to an index
9136
			getName = function(match, shortNames, longNames) {
9137
				var index = -1,
9138
					names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
9139
						return [ [k, v] ];
9140
					}).sort(function (a, b) {
9141
						return -(a[1].length - b[1].length);
9142
					});
9143
 
9144
				$.each(names, function (i, pair) {
9145
					var name = pair[1];
9146
					if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
9147
						index = pair[0];
9148
						iValue += name.length;
9149
						return false;
9150
					}
9151
				});
9152
				if (index !== -1) {
9153
					return index + 1;
9154
				} else {
9155
					throw "Unknown name at position " + iValue;
9156
				}
9157
			},
9158
			// Confirm that a literal character matches the string value
9159
			checkLiteral = function() {
9160
				if (value.charAt(iValue) !== format.charAt(iFormat)) {
9161
					throw "Unexpected literal at position " + iValue;
9162
				}
9163
				iValue++;
9164
			};
9165
 
9166
		for (iFormat = 0; iFormat < format.length; iFormat++) {
9167
			if (literal) {
9168
				if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
9169
					literal = false;
9170
				} else {
9171
					checkLiteral();
9172
				}
9173
			} else {
9174
				switch (format.charAt(iFormat)) {
9175
					case "d":
9176
						day = getNumber("d");
9177
						break;
9178
					case "D":
9179
						getName("D", dayNamesShort, dayNames);
9180
						break;
9181
					case "o":
9182
						doy = getNumber("o");
9183
						break;
9184
					case "m":
9185
						month = getNumber("m");
9186
						break;
9187
					case "M":
9188
						month = getName("M", monthNamesShort, monthNames);
9189
						break;
9190
					case "y":
9191
						year = getNumber("y");
9192
						break;
9193
					case "@":
9194
						date = new Date(getNumber("@"));
9195
						year = date.getFullYear();
9196
						month = date.getMonth() + 1;
9197
						day = date.getDate();
9198
						break;
9199
					case "!":
9200
						date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
9201
						year = date.getFullYear();
9202
						month = date.getMonth() + 1;
9203
						day = date.getDate();
9204
						break;
9205
					case "'":
9206
						if (lookAhead("'")){
9207
							checkLiteral();
9208
						} else {
9209
							literal = true;
9210
						}
9211
						break;
9212
					default:
9213
						checkLiteral();
9214
				}
9215
			}
9216
		}
9217
 
9218
		if (iValue < value.length){
9219
			extra = value.substr(iValue);
9220
			if (!/^\s+/.test(extra)) {
9221
				throw "Extra/unparsed characters found in date: " + extra;
9222
			}
9223
		}
9224
 
9225
		if (year === -1) {
9226
			year = new Date().getFullYear();
9227
		} else if (year < 100) {
9228
			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
9229
				(year <= shortYearCutoff ? 0 : -100);
9230
		}
9231
 
9232
		if (doy > -1) {
9233
			month = 1;
9234
			day = doy;
9235
			do {
9236
				dim = this._getDaysInMonth(year, month - 1);
9237
				if (day <= dim) {
9238
					break;
9239
				}
9240
				month++;
9241
				day -= dim;
9242
			} while (true);
9243
		}
9244
 
9245
		date = this._daylightSavingAdjust(new Date(year, month - 1, day));
9246
		if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
9247
			throw "Invalid date"; // E.g. 31/02/00
9248
		}
9249
		return date;
9250
	},
9251
 
9252
	/* Standard date formats. */
9253
	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
9254
	COOKIE: "D, dd M yy",
9255
	ISO_8601: "yy-mm-dd",
9256
	RFC_822: "D, d M y",
9257
	RFC_850: "DD, dd-M-y",
9258
	RFC_1036: "D, d M y",
9259
	RFC_1123: "D, d M yy",
9260
	RFC_2822: "D, d M yy",
9261
	RSS: "D, d M y", // RFC 822
9262
	TICKS: "!",
9263
	TIMESTAMP: "@",
9264
	W3C: "yy-mm-dd", // ISO 8601
9265
 
9266
	_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
9267
		Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
9268
 
9269
	/* Format a date object into a string value.
9270
	 * The format can be combinations of the following:
9271
	 * d  - day of month (no leading zero)
9272
	 * dd - day of month (two digit)
9273
	 * o  - day of year (no leading zeros)
9274
	 * oo - day of year (three digit)
9275
	 * D  - day name short
9276
	 * DD - day name long
9277
	 * m  - month of year (no leading zero)
9278
	 * mm - month of year (two digit)
9279
	 * M  - month name short
9280
	 * MM - month name long
9281
	 * y  - year (two digit)
9282
	 * yy - year (four digit)
9283
	 * @ - Unix timestamp (ms since 01/01/1970)
9284
	 * ! - Windows ticks (100ns since 01/01/0001)
9285
	 * "..." - literal text
9286
	 * '' - single quote
9287
	 *
9288
	 * @param  format string - the desired format of the date
9289
	 * @param  date Date - the date value to format
9290
	 * @param  settings Object - attributes include:
9291
	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
9292
	 *					dayNames		string[7] - names of the days from Sunday (optional)
9293
	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
9294
	 *					monthNames		string[12] - names of the months (optional)
9295
	 * @return  string - the date in the above format
9296
	 */
9297
	formatDate: function (format, date, settings) {
9298
		if (!date) {
9299
			return "";
9300
		}
9301
 
9302
		var iFormat,
9303
			dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
9304
			dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
9305
			monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
9306
			monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
9307
			// Check whether a format character is doubled
9308
			lookAhead = function(match) {
9309
				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
9310
				if (matches) {
9311
					iFormat++;
9312
				}
9313
				return matches;
9314
			},
9315
			// Format a number, with leading zero if necessary
9316
			formatNumber = function(match, value, len) {
9317
				var num = "" + value;
9318
				if (lookAhead(match)) {
9319
					while (num.length < len) {
9320
						num = "0" + num;
9321
					}
9322
				}
9323
				return num;
9324
			},
9325
			// Format a name, short or long as requested
9326
			formatName = function(match, value, shortNames, longNames) {
9327
				return (lookAhead(match) ? longNames[value] : shortNames[value]);
9328
			},
9329
			output = "",
9330
			literal = false;
9331
 
9332
		if (date) {
9333
			for (iFormat = 0; iFormat < format.length; iFormat++) {
9334
				if (literal) {
9335
					if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
9336
						literal = false;
9337
					} else {
9338
						output += format.charAt(iFormat);
9339
					}
9340
				} else {
9341
					switch (format.charAt(iFormat)) {
9342
						case "d":
9343
							output += formatNumber("d", date.getDate(), 2);
9344
							break;
9345
						case "D":
9346
							output += formatName("D", date.getDay(), dayNamesShort, dayNames);
9347
							break;
9348
						case "o":
9349
							output += formatNumber("o",
9350
								Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
9351
							break;
9352
						case "m":
9353
							output += formatNumber("m", date.getMonth() + 1, 2);
9354
							break;
9355
						case "M":
9356
							output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
9357
							break;
9358
						case "y":
9359
							output += (lookAhead("y") ? date.getFullYear() :
9360
								(date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
9361
							break;
9362
						case "@":
9363
							output += date.getTime();
9364
							break;
9365
						case "!":
9366
							output += date.getTime() * 10000 + this._ticksTo1970;
9367
							break;
9368
						case "'":
9369
							if (lookAhead("'")) {
9370
								output += "'";
9371
							} else {
9372
								literal = true;
9373
							}
9374
							break;
9375
						default:
9376
							output += format.charAt(iFormat);
9377
					}
9378
				}
9379
			}
9380
		}
9381
		return output;
9382
	},
9383
 
9384
	/* Extract all possible characters from the date format. */
9385
	_possibleChars: function (format) {
9386
		var iFormat,
9387
			chars = "",
9388
			literal = false,
9389
			// Check whether a format character is doubled
9390
			lookAhead = function(match) {
9391
				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
9392
				if (matches) {
9393
					iFormat++;
9394
				}
9395
				return matches;
9396
			};
9397
 
9398
		for (iFormat = 0; iFormat < format.length; iFormat++) {
9399
			if (literal) {
9400
				if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
9401
					literal = false;
9402
				} else {
9403
					chars += format.charAt(iFormat);
9404
				}
9405
			} else {
9406
				switch (format.charAt(iFormat)) {
9407
					case "d": case "m": case "y": case "@":
9408
						chars += "0123456789";
9409
						break;
9410
					case "D": case "M":
9411
						return null; // Accept anything
9412
					case "'":
9413
						if (lookAhead("'")) {
9414
							chars += "'";
9415
						} else {
9416
							literal = true;
9417
						}
9418
						break;
9419
					default:
9420
						chars += format.charAt(iFormat);
9421
				}
9422
			}
9423
		}
9424
		return chars;
9425
	},
9426
 
9427
	/* Get a setting value, defaulting if necessary. */
9428
	_get: function(inst, name) {
9429
		return inst.settings[name] !== undefined ?
9430
			inst.settings[name] : this._defaults[name];
9431
	},
9432
 
9433
	/* Parse existing date and initialise date picker. */
9434
	_setDateFromField: function(inst, noDefault) {
9435
		if (inst.input.val() === inst.lastVal) {
9436
			return;
9437
		}
9438
 
9439
		var dateFormat = this._get(inst, "dateFormat"),
9440
			dates = inst.lastVal = inst.input ? inst.input.val() : null,
9441
			defaultDate = this._getDefaultDate(inst),
9442
			date = defaultDate,
9443
			settings = this._getFormatConfig(inst);
9444
 
9445
		try {
9446
			date = this.parseDate(dateFormat, dates, settings) || defaultDate;
9447
		} catch (event) {
9448
			dates = (noDefault ? "" : dates);
9449
		}
9450
		inst.selectedDay = date.getDate();
9451
		inst.drawMonth = inst.selectedMonth = date.getMonth();
9452
		inst.drawYear = inst.selectedYear = date.getFullYear();
9453
		inst.currentDay = (dates ? date.getDate() : 0);
9454
		inst.currentMonth = (dates ? date.getMonth() : 0);
9455
		inst.currentYear = (dates ? date.getFullYear() : 0);
9456
		this._adjustInstDate(inst);
9457
	},
9458
 
9459
	/* Retrieve the default date shown on opening. */
9460
	_getDefaultDate: function(inst) {
9461
		return this._restrictMinMax(inst,
9462
			this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
9463
	},
9464
 
9465
	/* A date may be specified as an exact value or a relative one. */
9466
	_determineDate: function(inst, date, defaultDate) {
9467
		var offsetNumeric = function(offset) {
9468
				var date = new Date();
9469
				date.setDate(date.getDate() + offset);
9470
				return date;
9471
			},
9472
			offsetString = function(offset) {
9473
				try {
9474
					return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
9475
						offset, $.datepicker._getFormatConfig(inst));
9476
				}
9477
				catch (e) {
9478
					// Ignore
9479
				}
9480
 
9481
				var date = (offset.toLowerCase().match(/^c/) ?
9482
					$.datepicker._getDate(inst) : null) || new Date(),
9483
					year = date.getFullYear(),
9484
					month = date.getMonth(),
9485
					day = date.getDate(),
9486
					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
9487
					matches = pattern.exec(offset);
9488
 
9489
				while (matches) {
9490
					switch (matches[2] || "d") {
9491
						case "d" : case "D" :
9492
							day += parseInt(matches[1],10); break;
9493
						case "w" : case "W" :
9494
							day += parseInt(matches[1],10) * 7; break;
9495
						case "m" : case "M" :
9496
							month += parseInt(matches[1],10);
9497
							day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9498
							break;
9499
						case "y": case "Y" :
9500
							year += parseInt(matches[1],10);
9501
							day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9502
							break;
9503
					}
9504
					matches = pattern.exec(offset);
9505
				}
9506
				return new Date(year, month, day);
9507
			},
9508
			newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
9509
				(typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
9510
 
9511
		newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
9512
		if (newDate) {
9513
			newDate.setHours(0);
9514
			newDate.setMinutes(0);
9515
			newDate.setSeconds(0);
9516
			newDate.setMilliseconds(0);
9517
		}
9518
		return this._daylightSavingAdjust(newDate);
9519
	},
9520
 
9521
	/* Handle switch to/from daylight saving.
9522
	 * Hours may be non-zero on daylight saving cut-over:
9523
	 * > 12 when midnight changeover, but then cannot generate
9524
	 * midnight datetime, so jump to 1AM, otherwise reset.
9525
	 * @param  date  (Date) the date to check
9526
	 * @return  (Date) the corrected date
9527
	 */
9528
	_daylightSavingAdjust: function(date) {
9529
		if (!date) {
9530
			return null;
9531
		}
9532
		date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
9533
		return date;
9534
	},
9535
 
9536
	/* Set the date(s) directly. */
9537
	_setDate: function(inst, date, noChange) {
9538
		var clear = !date,
9539
			origMonth = inst.selectedMonth,
9540
			origYear = inst.selectedYear,
9541
			newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
9542
 
9543
		inst.selectedDay = inst.currentDay = newDate.getDate();
9544
		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
9545
		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
9546
		if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
9547
			this._notifyChange(inst);
9548
		}
9549
		this._adjustInstDate(inst);
9550
		if (inst.input) {
9551
			inst.input.val(clear ? "" : this._formatDate(inst));
9552
		}
9553
	},
9554
 
9555
	/* Retrieve the date(s) directly. */
9556
	_getDate: function(inst) {
9557
		var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
9558
			this._daylightSavingAdjust(new Date(
9559
			inst.currentYear, inst.currentMonth, inst.currentDay)));
9560
			return startDate;
9561
	},
9562
 
9563
	/* Attach the onxxx handlers.  These are declared statically so
9564
	 * they work with static code transformers like Caja.
9565
	 */
9566
	_attachHandlers: function(inst) {
9567
		var stepMonths = this._get(inst, "stepMonths"),
9568
			id = "#" + inst.id.replace( /\\\\/g, "\\" );
9569
		inst.dpDiv.find("[data-handler]").map(function () {
9570
			var handler = {
9571
				prev: function () {
9572
					$.datepicker._adjustDate(id, -stepMonths, "M");
9573
				},
9574
				next: function () {
9575
					$.datepicker._adjustDate(id, +stepMonths, "M");
9576
				},
9577
				hide: function () {
9578
					$.datepicker._hideDatepicker();
9579
				},
9580
				today: function () {
9581
					$.datepicker._gotoToday(id);
9582
				},
9583
				selectDay: function () {
9584
					$.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
9585
					return false;
9586
				},
9587
				selectMonth: function () {
9588
					$.datepicker._selectMonthYear(id, this, "M");
9589
					return false;
9590
				},
9591
				selectYear: function () {
9592
					$.datepicker._selectMonthYear(id, this, "Y");
9593
					return false;
9594
				}
9595
			};
9596
			$(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
9597
		});
9598
	},
9599
 
9600
	/* Generate the HTML for the current state of the date picker. */
9601
	_generateHTML: function(inst) {
9602
		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
9603
			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
9604
			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
9605
			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
9606
			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
9607
			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
9608
			tempDate = new Date(),
9609
			today = this._daylightSavingAdjust(
9610
				new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
9611
			isRTL = this._get(inst, "isRTL"),
9612
			showButtonPanel = this._get(inst, "showButtonPanel"),
9613
			hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
9614
			navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
9615
			numMonths = this._getNumberOfMonths(inst),
9616
			showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
9617
			stepMonths = this._get(inst, "stepMonths"),
9618
			isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
9619
			currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
9620
				new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
9621
			minDate = this._getMinMaxDate(inst, "min"),
9622
			maxDate = this._getMinMaxDate(inst, "max"),
9623
			drawMonth = inst.drawMonth - showCurrentAtPos,
9624
			drawYear = inst.drawYear;
9625
 
9626
		if (drawMonth < 0) {
9627
			drawMonth += 12;
9628
			drawYear--;
9629
		}
9630
		if (maxDate) {
9631
			maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
9632
				maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
9633
			maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
9634
			while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
9635
				drawMonth--;
9636
				if (drawMonth < 0) {
9637
					drawMonth = 11;
9638
					drawYear--;
9639
				}
9640
			}
9641
		}
9642
		inst.drawMonth = drawMonth;
9643
		inst.drawYear = drawYear;
9644
 
9645
		prevText = this._get(inst, "prevText");
9646
		prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
9647
			this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
9648
			this._getFormatConfig(inst)));
9649
 
9650
		prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
9651
			"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
9652
			" title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
9653
			(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>"));
9654
 
9655
		nextText = this._get(inst, "nextText");
9656
		nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
9657
			this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
9658
			this._getFormatConfig(inst)));
9659
 
9660
		next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
9661
			"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
9662
			" title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
9663
			(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>"));
9664
 
9665
		currentText = this._get(inst, "currentText");
9666
		gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
9667
		currentText = (!navigationAsDateFormat ? currentText :
9668
			this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
9669
 
9670
		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'>" +
9671
			this._get(inst, "closeText") + "</button>" : "");
9672
 
9673
		buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
9674
			(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'" +
9675
			">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
9676
 
9677
		firstDay = parseInt(this._get(inst, "firstDay"),10);
9678
		firstDay = (isNaN(firstDay) ? 0 : firstDay);
9679
 
9680
		showWeek = this._get(inst, "showWeek");
9681
		dayNames = this._get(inst, "dayNames");
9682
		dayNamesMin = this._get(inst, "dayNamesMin");
9683
		monthNames = this._get(inst, "monthNames");
9684
		monthNamesShort = this._get(inst, "monthNamesShort");
9685
		beforeShowDay = this._get(inst, "beforeShowDay");
9686
		showOtherMonths = this._get(inst, "showOtherMonths");
9687
		selectOtherMonths = this._get(inst, "selectOtherMonths");
9688
		defaultDate = this._getDefaultDate(inst);
9689
		html = "";
9690
		dow;
9691
		for (row = 0; row < numMonths[0]; row++) {
9692
			group = "";
9693
			this.maxRows = 4;
9694
			for (col = 0; col < numMonths[1]; col++) {
9695
				selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
9696
				cornerClass = " ui-corner-all";
9697
				calender = "";
9698
				if (isMultiMonth) {
9699
					calender += "<div class='ui-datepicker-group";
9700
					if (numMonths[1] > 1) {
9701
						switch (col) {
9702
							case 0: calender += " ui-datepicker-group-first";
9703
								cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
9704
							case numMonths[1]-1: calender += " ui-datepicker-group-last";
9705
								cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
9706
							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
9707
						}
9708
					}
9709
					calender += "'>";
9710
				}
9711
				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
9712
					(/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
9713
					(/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
9714
					this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
9715
					row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
9716
					"</div><table class='ui-datepicker-calendar'><thead>" +
9717
					"<tr>";
9718
				thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
9719
				for (dow = 0; dow < 7; dow++) { // days of the week
9720
					day = (dow + firstDay) % 7;
9721
					thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
9722
						"<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
9723
				}
9724
				calender += thead + "</tr></thead><tbody>";
9725
				daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
9726
				if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
9727
					inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
9728
				}
9729
				leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
9730
				curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
9731
				numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
9732
				this.maxRows = numRows;
9733
				printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
9734
				for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
9735
					calender += "<tr>";
9736
					tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
9737
						this._get(inst, "calculateWeek")(printDate) + "</td>");
9738
					for (dow = 0; dow < 7; dow++) { // create date picker days
9739
						daySettings = (beforeShowDay ?
9740
							beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
9741
						otherMonth = (printDate.getMonth() !== drawMonth);
9742
						unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
9743
							(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
9744
						tbody += "<td class='" +
9745
							((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
9746
							(otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
9747
							((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
9748
							(defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
9749
							// or defaultDate is current printedDate and defaultDate is selectedDate
9750
							" " + this._dayOverClass : "") + // highlight selected day
9751
							(unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
9752
							(otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
9753
							(printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
9754
							(printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
9755
							((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
9756
							(unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
9757
							(otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
9758
							(unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
9759
							(printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
9760
							(printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
9761
							(otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
9762
							"' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
9763
						printDate.setDate(printDate.getDate() + 1);
9764
						printDate = this._daylightSavingAdjust(printDate);
9765
					}
9766
					calender += tbody + "</tr>";
9767
				}
9768
				drawMonth++;
9769
				if (drawMonth > 11) {
9770
					drawMonth = 0;
9771
					drawYear++;
9772
				}
9773
				calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
9774
							((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
9775
				group += calender;
9776
			}
9777
			html += group;
9778
		}
9779
		html += buttonPanel;
9780
		inst._keyEvent = false;
9781
		return html;
9782
	},
9783
 
9784
	/* Generate the month and year header. */
9785
	_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
9786
			secondary, monthNames, monthNamesShort) {
9787
 
9788
		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
9789
			changeMonth = this._get(inst, "changeMonth"),
9790
			changeYear = this._get(inst, "changeYear"),
9791
			showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
9792
			html = "<div class='ui-datepicker-title'>",
9793
			monthHtml = "";
9794
 
9795
		// month selection
9796
		if (secondary || !changeMonth) {
9797
			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
9798
		} else {
9799
			inMinYear = (minDate && minDate.getFullYear() === drawYear);
9800
			inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
9801
			monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
9802
			for ( month = 0; month < 12; month++) {
9803
				if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
9804
					monthHtml += "<option value='" + month + "'" +
9805
						(month === drawMonth ? " selected='selected'" : "") +
9806
						">" + monthNamesShort[month] + "</option>";
9807
				}
9808
			}
9809
			monthHtml += "</select>";
9810
		}
9811
 
9812
		if (!showMonthAfterYear) {
9813
			html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
9814
		}
9815
 
9816
		// year selection
9817
		if ( !inst.yearshtml ) {
9818
			inst.yearshtml = "";
9819
			if (secondary || !changeYear) {
9820
				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
9821
			} else {
9822
				// determine range of years to display
9823
				years = this._get(inst, "yearRange").split(":");
9824
				thisYear = new Date().getFullYear();
9825
				determineYear = function(value) {
9826
					var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
9827
						(value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
9828
						parseInt(value, 10)));
9829
					return (isNaN(year) ? thisYear : year);
9830
				};
9831
				year = determineYear(years[0]);
9832
				endYear = Math.max(year, determineYear(years[1] || ""));
9833
				year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
9834
				endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
9835
				inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
9836
				for (; year <= endYear; year++) {
9837
					inst.yearshtml += "<option value='" + year + "'" +
9838
						(year === drawYear ? " selected='selected'" : "") +
9839
						">" + year + "</option>";
9840
				}
9841
				inst.yearshtml += "</select>";
9842
 
9843
				html += inst.yearshtml;
9844
				inst.yearshtml = null;
9845
			}
9846
		}
9847
 
9848
		html += this._get(inst, "yearSuffix");
9849
		if (showMonthAfterYear) {
9850
			html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
9851
		}
9852
		html += "</div>"; // Close datepicker_header
9853
		return html;
9854
	},
9855
 
9856
	/* Adjust one of the date sub-fields. */
9857
	_adjustInstDate: function(inst, offset, period) {
9858
		var year = inst.drawYear + (period === "Y" ? offset : 0),
9859
			month = inst.drawMonth + (period === "M" ? offset : 0),
9860
			day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
9861
			date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
9862
 
9863
		inst.selectedDay = date.getDate();
9864
		inst.drawMonth = inst.selectedMonth = date.getMonth();
9865
		inst.drawYear = inst.selectedYear = date.getFullYear();
9866
		if (period === "M" || period === "Y") {
9867
			this._notifyChange(inst);
9868
		}
9869
	},
9870
 
9871
	/* Ensure a date is within any min/max bounds. */
9872
	_restrictMinMax: function(inst, date) {
9873
		var minDate = this._getMinMaxDate(inst, "min"),
9874
			maxDate = this._getMinMaxDate(inst, "max"),
9875
			newDate = (minDate && date < minDate ? minDate : date);
9876
		return (maxDate && newDate > maxDate ? maxDate : newDate);
9877
	},
9878
 
9879
	/* Notify change of month/year. */
9880
	_notifyChange: function(inst) {
9881
		var onChange = this._get(inst, "onChangeMonthYear");
9882
		if (onChange) {
9883
			onChange.apply((inst.input ? inst.input[0] : null),
9884
				[inst.selectedYear, inst.selectedMonth + 1, inst]);
9885
		}
9886
	},
9887
 
9888
	/* Determine the number of months to show. */
9889
	_getNumberOfMonths: function(inst) {
9890
		var numMonths = this._get(inst, "numberOfMonths");
9891
		return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
9892
	},
9893
 
9894
	/* Determine the current maximum date - ensure no time components are set. */
9895
	_getMinMaxDate: function(inst, minMax) {
9896
		return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
9897
	},
9898
 
9899
	/* Find the number of days in a given month. */
9900
	_getDaysInMonth: function(year, month) {
9901
		return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
9902
	},
9903
 
9904
	/* Find the day of the week of the first of a month. */
9905
	_getFirstDayOfMonth: function(year, month) {
9906
		return new Date(year, month, 1).getDay();
9907
	},
9908
 
9909
	/* Determines if we should allow a "next/prev" month display change. */
9910
	_canAdjustMonth: function(inst, offset, curYear, curMonth) {
9911
		var numMonths = this._getNumberOfMonths(inst),
9912
			date = this._daylightSavingAdjust(new Date(curYear,
9913
			curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
9914
 
9915
		if (offset < 0) {
9916
			date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
9917
		}
9918
		return this._isInRange(inst, date);
9919
	},
9920
 
9921
	/* Is the given date in the accepted range? */
9922
	_isInRange: function(inst, date) {
9923
		var yearSplit, currentYear,
9924
			minDate = this._getMinMaxDate(inst, "min"),
9925
			maxDate = this._getMinMaxDate(inst, "max"),
9926
			minYear = null,
9927
			maxYear = null,
9928
			years = this._get(inst, "yearRange");
9929
			if (years){
9930
				yearSplit = years.split(":");
9931
				currentYear = new Date().getFullYear();
9932
				minYear = parseInt(yearSplit[0], 10);
9933
				maxYear = parseInt(yearSplit[1], 10);
9934
				if ( yearSplit[0].match(/[+\-].*/) ) {
9935
					minYear += currentYear;
9936
				}
9937
				if ( yearSplit[1].match(/[+\-].*/) ) {
9938
					maxYear += currentYear;
9939
				}
9940
			}
9941
 
9942
		return ((!minDate || date.getTime() >= minDate.getTime()) &&
9943
			(!maxDate || date.getTime() <= maxDate.getTime()) &&
9944
			(!minYear || date.getFullYear() >= minYear) &&
9945
			(!maxYear || date.getFullYear() <= maxYear));
9946
	},
9947
 
9948
	/* Provide the configuration settings for formatting/parsing. */
9949
	_getFormatConfig: function(inst) {
9950
		var shortYearCutoff = this._get(inst, "shortYearCutoff");
9951
		shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
9952
			new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
9953
		return {shortYearCutoff: shortYearCutoff,
9954
			dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
9955
			monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
9956
	},
9957
 
9958
	/* Format the given date for display. */
9959
	_formatDate: function(inst, day, month, year) {
9960
		if (!day) {
9961
			inst.currentDay = inst.selectedDay;
9962
			inst.currentMonth = inst.selectedMonth;
9963
			inst.currentYear = inst.selectedYear;
9964
		}
9965
		var date = (day ? (typeof day === "object" ? day :
9966
			this._daylightSavingAdjust(new Date(year, month, day))) :
9967
			this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
9968
		return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
9969
	}
9970
});
9971
 
9972
/*
9973
 * Bind hover events for datepicker elements.
9974
 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9975
 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9976
 */
9977
function datepicker_bindHover(dpDiv) {
9978
	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
9979
	return dpDiv.delegate(selector, "mouseout", function() {
9980
			$(this).removeClass("ui-state-hover");
9981
			if (this.className.indexOf("ui-datepicker-prev") !== -1) {
9982
				$(this).removeClass("ui-datepicker-prev-hover");
9983
			}
9984
			if (this.className.indexOf("ui-datepicker-next") !== -1) {
9985
				$(this).removeClass("ui-datepicker-next-hover");
9986
			}
9987
		})
9988
		.delegate( selector, "mouseover", datepicker_handleMouseover );
9989
}
9990
 
9991
function datepicker_handleMouseover() {
9992
	if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) {
9993
		$(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
9994
		$(this).addClass("ui-state-hover");
9995
		if (this.className.indexOf("ui-datepicker-prev") !== -1) {
9996
			$(this).addClass("ui-datepicker-prev-hover");
9997
		}
9998
		if (this.className.indexOf("ui-datepicker-next") !== -1) {
9999
			$(this).addClass("ui-datepicker-next-hover");
10000
		}
10001
	}
10002
}
10003
 
10004
/* jQuery extend now ignores nulls! */
10005
function datepicker_extendRemove(target, props) {
10006
	$.extend(target, props);
10007
	for (var name in props) {
10008
		if (props[name] == null) {
10009
			target[name] = props[name];
10010
		}
10011
	}
10012
	return target;
10013
}
10014
 
10015
/* Invoke the datepicker functionality.
10016
   @param  options  string - a command, optionally followed by additional parameters or
10017
					Object - settings for attaching new datepicker functionality
10018
   @return  jQuery object */
10019
$.fn.datepicker = function(options){
10020
 
10021
	/* Verify an empty collection wasn't passed - Fixes #6976 */
10022
	if ( !this.length ) {
10023
		return this;
10024
	}
10025
 
10026
	/* Initialise the date picker. */
10027
	if (!$.datepicker.initialized) {
10028
		$(document).mousedown($.datepicker._checkExternalClick);
10029
		$.datepicker.initialized = true;
10030
	}
10031
 
10032
	/* Append datepicker main container to body if not exist. */
10033
	if ($("#"+$.datepicker._mainDivId).length === 0) {
10034
		$("body").append($.datepicker.dpDiv);
10035
	}
10036
 
10037
	var otherArgs = Array.prototype.slice.call(arguments, 1);
10038
	if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
10039
		return $.datepicker["_" + options + "Datepicker"].
10040
			apply($.datepicker, [this[0]].concat(otherArgs));
10041
	}
10042
	if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
10043
		return $.datepicker["_" + options + "Datepicker"].
10044
			apply($.datepicker, [this[0]].concat(otherArgs));
10045
	}
10046
	return this.each(function() {
10047
		typeof options === "string" ?
10048
			$.datepicker["_" + options + "Datepicker"].
10049
				apply($.datepicker, [this].concat(otherArgs)) :
10050
			$.datepicker._attachDatepicker(this, options);
10051
	});
10052
};
10053
 
10054
$.datepicker = new Datepicker(); // singleton instance
10055
$.datepicker.initialized = false;
10056
$.datepicker.uuid = new Date().getTime();
10057
$.datepicker.version = "1.11.4";
10058
 
10059
var datepicker = $.datepicker;
10060
 
10061
 
10062
/*!
10063
 * jQuery UI Dialog 1.11.4
10064
 * http://jqueryui.com
10065
 *
10066
 * Copyright jQuery Foundation and other contributors
10067
 * Released under the MIT license.
10068
 * http://jquery.org/license
10069
 *
10070
 * http://api.jqueryui.com/dialog/
10071
 */
10072
 
10073
 
10074
var dialog = $.widget( "ui.dialog", {
10075
	version: "1.11.4",
10076
	options: {
10077
		appendTo: "body",
10078
		autoOpen: true,
10079
		buttons: [],
10080
		closeOnEscape: true,
10081
		closeText: "Close",
10082
		dialogClass: "",
10083
		draggable: true,
10084
		hide: null,
10085
		height: "auto",
10086
		maxHeight: null,
10087
		maxWidth: null,
10088
		minHeight: 150,
10089
		minWidth: 150,
10090
		modal: false,
10091
		position: {
10092
			my: "center",
10093
			at: "center",
10094
			of: window,
10095
			collision: "fit",
10096
			// Ensure the titlebar is always visible
10097
			using: function( pos ) {
10098
				var topOffset = $( this ).css( pos ).offset().top;
10099
				if ( topOffset < 0 ) {
10100
					$( this ).css( "top", pos.top - topOffset );
10101
				}
10102
			}
10103
		},
10104
		resizable: true,
10105
		show: null,
10106
		title: null,
10107
		width: 300,
10108
 
10109
		// callbacks
10110
		beforeClose: null,
10111
		close: null,
10112
		drag: null,
10113
		dragStart: null,
10114
		dragStop: null,
10115
		focus: null,
10116
		open: null,
10117
		resize: null,
10118
		resizeStart: null,
10119
		resizeStop: null
10120
	},
10121
 
10122
	sizeRelatedOptions: {
10123
		buttons: true,
10124
		height: true,
10125
		maxHeight: true,
10126
		maxWidth: true,
10127
		minHeight: true,
10128
		minWidth: true,
10129
		width: true
10130
	},
10131
 
10132
	resizableRelatedOptions: {
10133
		maxHeight: true,
10134
		maxWidth: true,
10135
		minHeight: true,
10136
		minWidth: true
10137
	},
10138
 
10139
	_create: function() {
10140
		this.originalCss = {
10141
			display: this.element[ 0 ].style.display,
10142
			width: this.element[ 0 ].style.width,
10143
			minHeight: this.element[ 0 ].style.minHeight,
10144
			maxHeight: this.element[ 0 ].style.maxHeight,
10145
			height: this.element[ 0 ].style.height
10146
		};
10147
		this.originalPosition = {
10148
			parent: this.element.parent(),
10149
			index: this.element.parent().children().index( this.element )
10150
		};
10151
		this.originalTitle = this.element.attr( "title" );
10152
		this.options.title = this.options.title || this.originalTitle;
10153
 
10154
		this._createWrapper();
10155
 
10156
		this.element
10157
			.show()
10158
			.removeAttr( "title" )
10159
			.addClass( "ui-dialog-content ui-widget-content" )
10160
			.appendTo( this.uiDialog );
10161
 
10162
		this._createTitlebar();
10163
		this._createButtonPane();
10164
 
10165
		if ( this.options.draggable && $.fn.draggable ) {
10166
			this._makeDraggable();
10167
		}
10168
		if ( this.options.resizable && $.fn.resizable ) {
10169
			this._makeResizable();
10170
		}
10171
 
10172
		this._isOpen = false;
10173
 
10174
		this._trackFocus();
10175
	},
10176
 
10177
	_init: function() {
10178
		if ( this.options.autoOpen ) {
10179
			this.open();
10180
		}
10181
	},
10182
 
10183
	_appendTo: function() {
10184
		var element = this.options.appendTo;
10185
		if ( element && (element.jquery || element.nodeType) ) {
10186
			return $( element );
10187
		}
10188
		return this.document.find( element || "body" ).eq( 0 );
10189
	},
10190
 
10191
	_destroy: function() {
10192
		var next,
10193
			originalPosition = this.originalPosition;
10194
 
10195
		this._untrackInstance();
10196
		this._destroyOverlay();
10197
 
10198
		this.element
10199
			.removeUniqueId()
10200
			.removeClass( "ui-dialog-content ui-widget-content" )
10201
			.css( this.originalCss )
10202
			// Without detaching first, the following becomes really slow
10203
			.detach();
10204
 
10205
		this.uiDialog.stop( true, true ).remove();
10206
 
10207
		if ( this.originalTitle ) {
10208
			this.element.attr( "title", this.originalTitle );
10209
		}
10210
 
10211
		next = originalPosition.parent.children().eq( originalPosition.index );
10212
		// Don't try to place the dialog next to itself (#8613)
10213
		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
10214
			next.before( this.element );
10215
		} else {
10216
			originalPosition.parent.append( this.element );
10217
		}
10218
	},
10219
 
10220
	widget: function() {
10221
		return this.uiDialog;
10222
	},
10223
 
10224
	disable: $.noop,
10225
	enable: $.noop,
10226
 
10227
	close: function( event ) {
10228
		var activeElement,
10229
			that = this;
10230
 
10231
		if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
10232
			return;
10233
		}
10234
 
10235
		this._isOpen = false;
10236
		this._focusedElement = null;
10237
		this._destroyOverlay();
10238
		this._untrackInstance();
10239
 
10240
		if ( !this.opener.filter( ":focusable" ).focus().length ) {
10241
 
10242
			// support: IE9
10243
			// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
10244
			try {
10245
				activeElement = this.document[ 0 ].activeElement;
10246
 
10247
				// Support: IE9, IE10
10248
				// If the <body> is blurred, IE will switch windows, see #4520
10249
				if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {
10250
 
10251
					// Hiding a focused element doesn't trigger blur in WebKit
10252
					// so in case we have nothing to focus on, explicitly blur the active element
10253
					// https://bugs.webkit.org/show_bug.cgi?id=47182
10254
					$( activeElement ).blur();
10255
				}
10256
			} catch ( error ) {}
10257
		}
10258
 
10259
		this._hide( this.uiDialog, this.options.hide, function() {
10260
			that._trigger( "close", event );
10261
		});
10262
	},
10263
 
10264
	isOpen: function() {
10265
		return this._isOpen;
10266
	},
10267
 
10268
	moveToTop: function() {
10269
		this._moveToTop();
10270
	},
10271
 
10272
	_moveToTop: function( event, silent ) {
10273
		var moved = false,
10274
			zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map(function() {
10275
				return +$( this ).css( "z-index" );
10276
			}).get(),
10277
			zIndexMax = Math.max.apply( null, zIndices );
10278
 
10279
		if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
10280
			this.uiDialog.css( "z-index", zIndexMax + 1 );
10281
			moved = true;
10282
		}
10283
 
10284
		if ( moved && !silent ) {
10285
			this._trigger( "focus", event );
10286
		}
10287
		return moved;
10288
	},
10289
 
10290
	open: function() {
10291
		var that = this;
10292
		if ( this._isOpen ) {
10293
			if ( this._moveToTop() ) {
10294
				this._focusTabbable();
10295
			}
10296
			return;
10297
		}
10298
 
10299
		this._isOpen = true;
10300
		this.opener = $( this.document[ 0 ].activeElement );
10301
 
10302
		this._size();
10303
		this._position();
10304
		this._createOverlay();
10305
		this._moveToTop( null, true );
10306
 
10307
		// Ensure the overlay is moved to the top with the dialog, but only when
10308
		// opening. The overlay shouldn't move after the dialog is open so that
10309
		// modeless dialogs opened after the modal dialog stack properly.
10310
		if ( this.overlay ) {
10311
			this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
10312
		}
10313
 
10314
		this._show( this.uiDialog, this.options.show, function() {
10315
			that._focusTabbable();
10316
			that._trigger( "focus" );
10317
		});
10318
 
10319
		// Track the dialog immediately upon openening in case a focus event
10320
		// somehow occurs outside of the dialog before an element inside the
10321
		// dialog is focused (#10152)
10322
		this._makeFocusTarget();
10323
 
10324
		this._trigger( "open" );
10325
	},
10326
 
10327
	_focusTabbable: function() {
10328
		// Set focus to the first match:
10329
		// 1. An element that was focused previously
10330
		// 2. First element inside the dialog matching [autofocus]
10331
		// 3. Tabbable element inside the content element
10332
		// 4. Tabbable element inside the buttonpane
10333
		// 5. The close button
10334
		// 6. The dialog itself
10335
		var hasFocus = this._focusedElement;
10336
		if ( !hasFocus ) {
10337
			hasFocus = this.element.find( "[autofocus]" );
10338
		}
10339
		if ( !hasFocus.length ) {
10340
			hasFocus = this.element.find( ":tabbable" );
10341
		}
10342
		if ( !hasFocus.length ) {
10343
			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
10344
		}
10345
		if ( !hasFocus.length ) {
10346
			hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
10347
		}
10348
		if ( !hasFocus.length ) {
10349
			hasFocus = this.uiDialog;
10350
		}
10351
		hasFocus.eq( 0 ).focus();
10352
	},
10353
 
10354
	_keepFocus: function( event ) {
10355
		function checkFocus() {
10356
			var activeElement = this.document[0].activeElement,
10357
				isActive = this.uiDialog[0] === activeElement ||
10358
					$.contains( this.uiDialog[0], activeElement );
10359
			if ( !isActive ) {
10360
				this._focusTabbable();
10361
			}
10362
		}
10363
		event.preventDefault();
10364
		checkFocus.call( this );
10365
		// support: IE
10366
		// IE <= 8 doesn't prevent moving focus even with event.preventDefault()
10367
		// so we check again later
10368
		this._delay( checkFocus );
10369
	},
10370
 
10371
	_createWrapper: function() {
10372
		this.uiDialog = $("<div>")
10373
			.addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
10374
				this.options.dialogClass )
10375
			.hide()
10376
			.attr({
10377
				// Setting tabIndex makes the div focusable
10378
				tabIndex: -1,
10379
				role: "dialog"
10380
			})
10381
			.appendTo( this._appendTo() );
10382
 
10383
		this._on( this.uiDialog, {
10384
			keydown: function( event ) {
10385
				if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
10386
						event.keyCode === $.ui.keyCode.ESCAPE ) {
10387
					event.preventDefault();
10388
					this.close( event );
10389
					return;
10390
				}
10391
 
10392
				// prevent tabbing out of dialogs
10393
				if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
10394
					return;
10395
				}
10396
				var tabbables = this.uiDialog.find( ":tabbable" ),
10397
					first = tabbables.filter( ":first" ),
10398
					last = tabbables.filter( ":last" );
10399
 
10400
				if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
10401
					this._delay(function() {
10402
						first.focus();
10403
					});
10404
					event.preventDefault();
10405
				} else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
10406
					this._delay(function() {
10407
						last.focus();
10408
					});
10409
					event.preventDefault();
10410
				}
10411
			},
10412
			mousedown: function( event ) {
10413
				if ( this._moveToTop( event ) ) {
10414
					this._focusTabbable();
10415
				}
10416
			}
10417
		});
10418
 
10419
		// We assume that any existing aria-describedby attribute means
10420
		// that the dialog content is marked up properly
10421
		// otherwise we brute force the content as the description
10422
		if ( !this.element.find( "[aria-describedby]" ).length ) {
10423
			this.uiDialog.attr({
10424
				"aria-describedby": this.element.uniqueId().attr( "id" )
10425
			});
10426
		}
10427
	},
10428
 
10429
	_createTitlebar: function() {
10430
		var uiDialogTitle;
10431
 
10432
		this.uiDialogTitlebar = $( "<div>" )
10433
			.addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" )
10434
			.prependTo( this.uiDialog );
10435
		this._on( this.uiDialogTitlebar, {
10436
			mousedown: function( event ) {
10437
				// Don't prevent click on close button (#8838)
10438
				// Focusing a dialog that is partially scrolled out of view
10439
				// causes the browser to scroll it into view, preventing the click event
10440
				if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
10441
					// Dialog isn't getting focus when dragging (#8063)
10442
					this.uiDialog.focus();
10443
				}
10444
			}
10445
		});
10446
 
10447
		// support: IE
10448
		// Use type="button" to prevent enter keypresses in textboxes from closing the
10449
		// dialog in IE (#9312)
10450
		this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
10451
			.button({
10452
				label: this.options.closeText,
10453
				icons: {
10454
					primary: "ui-icon-closethick"
10455
				},
10456
				text: false
10457
			})
10458
			.addClass( "ui-dialog-titlebar-close" )
10459
			.appendTo( this.uiDialogTitlebar );
10460
		this._on( this.uiDialogTitlebarClose, {
10461
			click: function( event ) {
10462
				event.preventDefault();
10463
				this.close( event );
10464
			}
10465
		});
10466
 
10467
		uiDialogTitle = $( "<span>" )
10468
			.uniqueId()
10469
			.addClass( "ui-dialog-title" )
10470
			.prependTo( this.uiDialogTitlebar );
10471
		this._title( uiDialogTitle );
10472
 
10473
		this.uiDialog.attr({
10474
			"aria-labelledby": uiDialogTitle.attr( "id" )
10475
		});
10476
	},
10477
 
10478
	_title: function( title ) {
10479
		if ( !this.options.title ) {
10480
			title.html( "&#160;" );
10481
		}
10482
		title.text( this.options.title );
10483
	},
10484
 
10485
	_createButtonPane: function() {
10486
		this.uiDialogButtonPane = $( "<div>" )
10487
			.addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
10488
 
10489
		this.uiButtonSet = $( "<div>" )
10490
			.addClass( "ui-dialog-buttonset" )
10491
			.appendTo( this.uiDialogButtonPane );
10492
 
10493
		this._createButtons();
10494
	},
10495
 
10496
	_createButtons: function() {
10497
		var that = this,
10498
			buttons = this.options.buttons;
10499
 
10500
		// if we already have a button pane, remove it
10501
		this.uiDialogButtonPane.remove();
10502
		this.uiButtonSet.empty();
10503
 
10504
		if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
10505
			this.uiDialog.removeClass( "ui-dialog-buttons" );
10506
			return;
10507
		}
10508
 
10509
		$.each( buttons, function( name, props ) {
10510
			var click, buttonOptions;
10511
			props = $.isFunction( props ) ?
10512
				{ click: props, text: name } :
10513
				props;
10514
			// Default to a non-submitting button
10515
			props = $.extend( { type: "button" }, props );
10516
			// Change the context for the click callback to be the main element
10517
			click = props.click;
10518
			props.click = function() {
10519
				click.apply( that.element[ 0 ], arguments );
10520
			};
10521
			buttonOptions = {
10522
				icons: props.icons,
10523
				text: props.showText
10524
			};
10525
			delete props.icons;
10526
			delete props.showText;
10527
			$( "<button></button>", props )
10528
				.button( buttonOptions )
10529
				.appendTo( that.uiButtonSet );
10530
		});
10531
		this.uiDialog.addClass( "ui-dialog-buttons" );
10532
		this.uiDialogButtonPane.appendTo( this.uiDialog );
10533
	},
10534
 
10535
	_makeDraggable: function() {
10536
		var that = this,
10537
			options = this.options;
10538
 
10539
		function filteredUi( ui ) {
10540
			return {
10541
				position: ui.position,
10542
				offset: ui.offset
10543
			};
10544
		}
10545
 
10546
		this.uiDialog.draggable({
10547
			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
10548
			handle: ".ui-dialog-titlebar",
10549
			containment: "document",
10550
			start: function( event, ui ) {
10551
				$( this ).addClass( "ui-dialog-dragging" );
10552
				that._blockFrames();
10553
				that._trigger( "dragStart", event, filteredUi( ui ) );
10554
			},
10555
			drag: function( event, ui ) {
10556
				that._trigger( "drag", event, filteredUi( ui ) );
10557
			},
10558
			stop: function( event, ui ) {
10559
				var left = ui.offset.left - that.document.scrollLeft(),
10560
					top = ui.offset.top - that.document.scrollTop();
10561
 
10562
				options.position = {
10563
					my: "left top",
10564
					at: "left" + (left >= 0 ? "+" : "") + left + " " +
10565
						"top" + (top >= 0 ? "+" : "") + top,
10566
					of: that.window
10567
				};
10568
				$( this ).removeClass( "ui-dialog-dragging" );
10569
				that._unblockFrames();
10570
				that._trigger( "dragStop", event, filteredUi( ui ) );
10571
			}
10572
		});
10573
	},
10574
 
10575
	_makeResizable: function() {
10576
		var that = this,
10577
			options = this.options,
10578
			handles = options.resizable,
10579
			// .ui-resizable has position: relative defined in the stylesheet
10580
			// but dialogs have to use absolute or fixed positioning
10581
			position = this.uiDialog.css("position"),
10582
			resizeHandles = typeof handles === "string" ?
10583
				handles	:
10584
				"n,e,s,w,se,sw,ne,nw";
10585
 
10586
		function filteredUi( ui ) {
10587
			return {
10588
				originalPosition: ui.originalPosition,
10589
				originalSize: ui.originalSize,
10590
				position: ui.position,
10591
				size: ui.size
10592
			};
10593
		}
10594
 
10595
		this.uiDialog.resizable({
10596
			cancel: ".ui-dialog-content",
10597
			containment: "document",
10598
			alsoResize: this.element,
10599
			maxWidth: options.maxWidth,
10600
			maxHeight: options.maxHeight,
10601
			minWidth: options.minWidth,
10602
			minHeight: this._minHeight(),
10603
			handles: resizeHandles,
10604
			start: function( event, ui ) {
10605
				$( this ).addClass( "ui-dialog-resizing" );
10606
				that._blockFrames();
10607
				that._trigger( "resizeStart", event, filteredUi( ui ) );
10608
			},
10609
			resize: function( event, ui ) {
10610
				that._trigger( "resize", event, filteredUi( ui ) );
10611
			},
10612
			stop: function( event, ui ) {
10613
				var offset = that.uiDialog.offset(),
10614
					left = offset.left - that.document.scrollLeft(),
10615
					top = offset.top - that.document.scrollTop();
10616
 
10617
				options.height = that.uiDialog.height();
10618
				options.width = that.uiDialog.width();
10619
				options.position = {
10620
					my: "left top",
10621
					at: "left" + (left >= 0 ? "+" : "") + left + " " +
10622
						"top" + (top >= 0 ? "+" : "") + top,
10623
					of: that.window
10624
				};
10625
				$( this ).removeClass( "ui-dialog-resizing" );
10626
				that._unblockFrames();
10627
				that._trigger( "resizeStop", event, filteredUi( ui ) );
10628
			}
10629
		})
10630
		.css( "position", position );
10631
	},
10632
 
10633
	_trackFocus: function() {
10634
		this._on( this.widget(), {
10635
			focusin: function( event ) {
10636
				this._makeFocusTarget();
10637
				this._focusedElement = $( event.target );
10638
			}
10639
		});
10640
	},
10641
 
10642
	_makeFocusTarget: function() {
10643
		this._untrackInstance();
10644
		this._trackingInstances().unshift( this );
10645
	},
10646
 
10647
	_untrackInstance: function() {
10648
		var instances = this._trackingInstances(),
10649
			exists = $.inArray( this, instances );
10650
		if ( exists !== -1 ) {
10651
			instances.splice( exists, 1 );
10652
		}
10653
	},
10654
 
10655
	_trackingInstances: function() {
10656
		var instances = this.document.data( "ui-dialog-instances" );
10657
		if ( !instances ) {
10658
			instances = [];
10659
			this.document.data( "ui-dialog-instances", instances );
10660
		}
10661
		return instances;
10662
	},
10663
 
10664
	_minHeight: function() {
10665
		var options = this.options;
10666
 
10667
		return options.height === "auto" ?
10668
			options.minHeight :
10669
			Math.min( options.minHeight, options.height );
10670
	},
10671
 
10672
	_position: function() {
10673
		// Need to show the dialog to get the actual offset in the position plugin
10674
		var isVisible = this.uiDialog.is( ":visible" );
10675
		if ( !isVisible ) {
10676
			this.uiDialog.show();
10677
		}
10678
		this.uiDialog.position( this.options.position );
10679
		if ( !isVisible ) {
10680
			this.uiDialog.hide();
10681
		}
10682
	},
10683
 
10684
	_setOptions: function( options ) {
10685
		var that = this,
10686
			resize = false,
10687
			resizableOptions = {};
10688
 
10689
		$.each( options, function( key, value ) {
10690
			that._setOption( key, value );
10691
 
10692
			if ( key in that.sizeRelatedOptions ) {
10693
				resize = true;
10694
			}
10695
			if ( key in that.resizableRelatedOptions ) {
10696
				resizableOptions[ key ] = value;
10697
			}
10698
		});
10699
 
10700
		if ( resize ) {
10701
			this._size();
10702
			this._position();
10703
		}
10704
		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
10705
			this.uiDialog.resizable( "option", resizableOptions );
10706
		}
10707
	},
10708
 
10709
	_setOption: function( key, value ) {
10710
		var isDraggable, isResizable,
10711
			uiDialog = this.uiDialog;
10712
 
10713
		if ( key === "dialogClass" ) {
10714
			uiDialog
10715
				.removeClass( this.options.dialogClass )
10716
				.addClass( value );
10717
		}
10718
 
10719
		if ( key === "disabled" ) {
10720
			return;
10721
		}
10722
 
10723
		this._super( key, value );
10724
 
10725
		if ( key === "appendTo" ) {
10726
			this.uiDialog.appendTo( this._appendTo() );
10727
		}
10728
 
10729
		if ( key === "buttons" ) {
10730
			this._createButtons();
10731
		}
10732
 
10733
		if ( key === "closeText" ) {
10734
			this.uiDialogTitlebarClose.button({
10735
				// Ensure that we always pass a string
10736
				label: "" + value
10737
			});
10738
		}
10739
 
10740
		if ( key === "draggable" ) {
10741
			isDraggable = uiDialog.is( ":data(ui-draggable)" );
10742
			if ( isDraggable && !value ) {
10743
				uiDialog.draggable( "destroy" );
10744
			}
10745
 
10746
			if ( !isDraggable && value ) {
10747
				this._makeDraggable();
10748
			}
10749
		}
10750
 
10751
		if ( key === "position" ) {
10752
			this._position();
10753
		}
10754
 
10755
		if ( key === "resizable" ) {
10756
			// currently resizable, becoming non-resizable
10757
			isResizable = uiDialog.is( ":data(ui-resizable)" );
10758
			if ( isResizable && !value ) {
10759
				uiDialog.resizable( "destroy" );
10760
			}
10761
 
10762
			// currently resizable, changing handles
10763
			if ( isResizable && typeof value === "string" ) {
10764
				uiDialog.resizable( "option", "handles", value );
10765
			}
10766
 
10767
			// currently non-resizable, becoming resizable
10768
			if ( !isResizable && value !== false ) {
10769
				this._makeResizable();
10770
			}
10771
		}
10772
 
10773
		if ( key === "title" ) {
10774
			this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
10775
		}
10776
	},
10777
 
10778
	_size: function() {
10779
		// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
10780
		// divs will both have width and height set, so we need to reset them
10781
		var nonContentHeight, minContentHeight, maxContentHeight,
10782
			options = this.options;
10783
 
10784
		// Reset content sizing
10785
		this.element.show().css({
10786
			width: "auto",
10787
			minHeight: 0,
10788
			maxHeight: "none",
10789
			height: 0
10790
		});
10791
 
10792
		if ( options.minWidth > options.width ) {
10793
			options.width = options.minWidth;
10794
		}
10795
 
10796
		// reset wrapper sizing
10797
		// determine the height of all the non-content elements
10798
		nonContentHeight = this.uiDialog.css({
10799
				height: "auto",
10800
				width: options.width
10801
			})
10802
			.outerHeight();
10803
		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
10804
		maxContentHeight = typeof options.maxHeight === "number" ?
10805
			Math.max( 0, options.maxHeight - nonContentHeight ) :
10806
			"none";
10807
 
10808
		if ( options.height === "auto" ) {
10809
			this.element.css({
10810
				minHeight: minContentHeight,
10811
				maxHeight: maxContentHeight,
10812
				height: "auto"
10813
			});
10814
		} else {
10815
			this.element.height( Math.max( 0, options.height - nonContentHeight ) );
10816
		}
10817
 
10818
		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
10819
			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
10820
		}
10821
	},
10822
 
10823
	_blockFrames: function() {
10824
		this.iframeBlocks = this.document.find( "iframe" ).map(function() {
10825
			var iframe = $( this );
10826
 
10827
			return $( "<div>" )
10828
				.css({
10829
					position: "absolute",
10830
					width: iframe.outerWidth(),
10831
					height: iframe.outerHeight()
10832
				})
10833
				.appendTo( iframe.parent() )
10834
				.offset( iframe.offset() )[0];
10835
		});
10836
	},
10837
 
10838
	_unblockFrames: function() {
10839
		if ( this.iframeBlocks ) {
10840
			this.iframeBlocks.remove();
10841
			delete this.iframeBlocks;
10842
		}
10843
	},
10844
 
10845
	_allowInteraction: function( event ) {
10846
		if ( $( event.target ).closest( ".ui-dialog" ).length ) {
10847
			return true;
10848
		}
10849
 
10850
		// TODO: Remove hack when datepicker implements
10851
		// the .ui-front logic (#8989)
10852
		return !!$( event.target ).closest( ".ui-datepicker" ).length;
10853
	},
10854
 
10855
	_createOverlay: function() {
10856
		if ( !this.options.modal ) {
10857
			return;
10858
		}
10859
 
10860
		// We use a delay in case the overlay is created from an
10861
		// event that we're going to be cancelling (#2804)
10862
		var isOpening = true;
10863
		this._delay(function() {
10864
			isOpening = false;
10865
		});
10866
 
10867
		if ( !this.document.data( "ui-dialog-overlays" ) ) {
10868
 
10869
			// Prevent use of anchors and inputs
10870
			// Using _on() for an event handler shared across many instances is
10871
			// safe because the dialogs stack and must be closed in reverse order
10872
			this._on( this.document, {
10873
				focusin: function( event ) {
10874
					if ( isOpening ) {
10875
						return;
10876
					}
10877
 
10878
					if ( !this._allowInteraction( event ) ) {
10879
						event.preventDefault();
10880
						this._trackingInstances()[ 0 ]._focusTabbable();
10881
					}
10882
				}
10883
			});
10884
		}
10885
 
10886
		this.overlay = $( "<div>" )
10887
			.addClass( "ui-widget-overlay ui-front" )
10888
			.appendTo( this._appendTo() );
10889
		this._on( this.overlay, {
10890
			mousedown: "_keepFocus"
10891
		});
10892
		this.document.data( "ui-dialog-overlays",
10893
			(this.document.data( "ui-dialog-overlays" ) || 0) + 1 );
10894
	},
10895
 
10896
	_destroyOverlay: function() {
10897
		if ( !this.options.modal ) {
10898
			return;
10899
		}
10900
 
10901
		if ( this.overlay ) {
10902
			var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
10903
 
10904
			if ( !overlays ) {
10905
				this.document
10906
					.unbind( "focusin" )
10907
					.removeData( "ui-dialog-overlays" );
10908
			} else {
10909
				this.document.data( "ui-dialog-overlays", overlays );
10910
			}
10911
 
10912
			this.overlay.remove();
10913
			this.overlay = null;
10914
		}
10915
	}
10916
});
10917
 
10918
 
10919
/*!
10920
 * jQuery UI Progressbar 1.11.4
10921
 * http://jqueryui.com
10922
 *
10923
 * Copyright jQuery Foundation and other contributors
10924
 * Released under the MIT license.
10925
 * http://jquery.org/license
10926
 *
10927
 * http://api.jqueryui.com/progressbar/
10928
 */
10929
 
10930
 
10931
var progressbar = $.widget( "ui.progressbar", {
10932
	version: "1.11.4",
10933
	options: {
10934
		max: 100,
10935
		value: 0,
10936
 
10937
		change: null,
10938
		complete: null
10939
	},
10940
 
10941
	min: 0,
10942
 
10943
	_create: function() {
10944
		// Constrain initial value
10945
		this.oldValue = this.options.value = this._constrainedValue();
10946
 
10947
		this.element
10948
			.addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10949
			.attr({
10950
				// Only set static values, aria-valuenow and aria-valuemax are
10951
				// set inside _refreshValue()
10952
				role: "progressbar",
10953
				"aria-valuemin": this.min
10954
			});
10955
 
10956
		this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
10957
			.appendTo( this.element );
10958
 
10959
		this._refreshValue();
10960
	},
10961
 
10962
	_destroy: function() {
10963
		this.element
10964
			.removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10965
			.removeAttr( "role" )
10966
			.removeAttr( "aria-valuemin" )
10967
			.removeAttr( "aria-valuemax" )
10968
			.removeAttr( "aria-valuenow" );
10969
 
10970
		this.valueDiv.remove();
10971
	},
10972
 
10973
	value: function( newValue ) {
10974
		if ( newValue === undefined ) {
10975
			return this.options.value;
10976
		}
10977
 
10978
		this.options.value = this._constrainedValue( newValue );
10979
		this._refreshValue();
10980
	},
10981
 
10982
	_constrainedValue: function( newValue ) {
10983
		if ( newValue === undefined ) {
10984
			newValue = this.options.value;
10985
		}
10986
 
10987
		this.indeterminate = newValue === false;
10988
 
10989
		// sanitize value
10990
		if ( typeof newValue !== "number" ) {
10991
			newValue = 0;
10992
		}
10993
 
10994
		return this.indeterminate ? false :
10995
			Math.min( this.options.max, Math.max( this.min, newValue ) );
10996
	},
10997
 
10998
	_setOptions: function( options ) {
10999
		// Ensure "value" option is set after other values (like max)
11000
		var value = options.value;
11001
		delete options.value;
11002
 
11003
		this._super( options );
11004
 
11005
		this.options.value = this._constrainedValue( value );
11006
		this._refreshValue();
11007
	},
11008
 
11009
	_setOption: function( key, value ) {
11010
		if ( key === "max" ) {
11011
			// Don't allow a max less than min
11012
			value = Math.max( this.min, value );
11013
		}
11014
		if ( key === "disabled" ) {
11015
			this.element
11016
				.toggleClass( "ui-state-disabled", !!value )
11017
				.attr( "aria-disabled", value );
11018
		}
11019
		this._super( key, value );
11020
	},
11021
 
11022
	_percentage: function() {
11023
		return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
11024
	},
11025
 
11026
	_refreshValue: function() {
11027
		var value = this.options.value,
11028
			percentage = this._percentage();
11029
 
11030
		this.valueDiv
11031
			.toggle( this.indeterminate || value > this.min )
11032
			.toggleClass( "ui-corner-right", value === this.options.max )
11033
			.width( percentage.toFixed(0) + "%" );
11034
 
11035
		this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
11036
 
11037
		if ( this.indeterminate ) {
11038
			this.element.removeAttr( "aria-valuenow" );
11039
			if ( !this.overlayDiv ) {
11040
				this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
11041
			}
11042
		} else {
11043
			this.element.attr({
11044
				"aria-valuemax": this.options.max,
11045
				"aria-valuenow": value
11046
			});
11047
			if ( this.overlayDiv ) {
11048
				this.overlayDiv.remove();
11049
				this.overlayDiv = null;
11050
			}
11051
		}
11052
 
11053
		if ( this.oldValue !== value ) {
11054
			this.oldValue = value;
11055
			this._trigger( "change" );
11056
		}
11057
		if ( value === this.options.max ) {
11058
			this._trigger( "complete" );
11059
		}
11060
	}
11061
});
11062
 
11063
 
11064
/*!
11065
 * jQuery UI Selectmenu 1.11.4
11066
 * http://jqueryui.com
11067
 *
11068
 * Copyright jQuery Foundation and other contributors
11069
 * Released under the MIT license.
11070
 * http://jquery.org/license
11071
 *
11072
 * http://api.jqueryui.com/selectmenu
11073
 */
11074
 
11075
 
11076
var selectmenu = $.widget( "ui.selectmenu", {
11077
	version: "1.11.4",
11078
	defaultElement: "<select>",
11079
	options: {
11080
		appendTo: null,
11081
		disabled: null,
11082
		icons: {
11083
			button: "ui-icon-triangle-1-s"
11084
		},
11085
		position: {
11086
			my: "left top",
11087
			at: "left bottom",
11088
			collision: "none"
11089
		},
11090
		width: null,
11091
 
11092
		// callbacks
11093
		change: null,
11094
		close: null,
11095
		focus: null,
11096
		open: null,
11097
		select: null
11098
	},
11099
 
11100
	_create: function() {
11101
		var selectmenuId = this.element.uniqueId().attr( "id" );
11102
		this.ids = {
11103
			element: selectmenuId,
11104
			button: selectmenuId + "-button",
11105
			menu: selectmenuId + "-menu"
11106
		};
11107
 
11108
		this._drawButton();
11109
		this._drawMenu();
11110
 
11111
		if ( this.options.disabled ) {
11112
			this.disable();
11113
		}
11114
	},
11115
 
11116
	_drawButton: function() {
11117
		var that = this;
11118
 
11119
		// Associate existing label with the new button
11120
		this.label = $( "label[for='" + this.ids.element + "']" ).attr( "for", this.ids.button );
11121
		this._on( this.label, {
11122
			click: function( event ) {
11123
				this.button.focus();
11124
				event.preventDefault();
11125
			}
11126
		});
11127
 
11128
		// Hide original select element
11129
		this.element.hide();
11130
 
11131
		// Create button
11132
		this.button = $( "<span>", {
11133
			"class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all",
11134
			tabindex: this.options.disabled ? -1 : 0,
11135
			id: this.ids.button,
11136
			role: "combobox",
11137
			"aria-expanded": "false",
11138
			"aria-autocomplete": "list",
11139
			"aria-owns": this.ids.menu,
11140
			"aria-haspopup": "true"
11141
		})
11142
			.insertAfter( this.element );
11143
 
11144
		$( "<span>", {
11145
			"class": "ui-icon " + this.options.icons.button
11146
		})
11147
			.prependTo( this.button );
11148
 
11149
		this.buttonText = $( "<span>", {
11150
			"class": "ui-selectmenu-text"
11151
		})
11152
			.appendTo( this.button );
11153
 
11154
		this._setText( this.buttonText, this.element.find( "option:selected" ).text() );
11155
		this._resizeButton();
11156
 
11157
		this._on( this.button, this._buttonEvents );
11158
		this.button.one( "focusin", function() {
11159
 
11160
			// Delay rendering the menu items until the button receives focus.
11161
			// The menu may have already been rendered via a programmatic open.
11162
			if ( !that.menuItems ) {
11163
				that._refreshMenu();
11164
			}
11165
		});
11166
		this._hoverable( this.button );
11167
		this._focusable( this.button );
11168
	},
11169
 
11170
	_drawMenu: function() {
11171
		var that = this;
11172
 
11173
		// Create menu
11174
		this.menu = $( "<ul>", {
11175
			"aria-hidden": "true",
11176
			"aria-labelledby": this.ids.button,
11177
			id: this.ids.menu
11178
		});
11179
 
11180
		// Wrap menu
11181
		this.menuWrap = $( "<div>", {
11182
			"class": "ui-selectmenu-menu ui-front"
11183
		})
11184
			.append( this.menu )
11185
			.appendTo( this._appendTo() );
11186
 
11187
		// Initialize menu widget
11188
		this.menuInstance = this.menu
11189
			.menu({
11190
				role: "listbox",
11191
				select: function( event, ui ) {
11192
					event.preventDefault();
11193
 
11194
					// support: IE8
11195
					// If the item was selected via a click, the text selection
11196
					// will be destroyed in IE
11197
					that._setSelection();
11198
 
11199
					that._select( ui.item.data( "ui-selectmenu-item" ), event );
11200
				},
11201
				focus: function( event, ui ) {
11202
					var item = ui.item.data( "ui-selectmenu-item" );
11203
 
11204
					// Prevent inital focus from firing and check if its a newly focused item
11205
					if ( that.focusIndex != null && item.index !== that.focusIndex ) {
11206
						that._trigger( "focus", event, { item: item } );
11207
						if ( !that.isOpen ) {
11208
							that._select( item, event );
11209
						}
11210
					}
11211
					that.focusIndex = item.index;
11212
 
11213
					that.button.attr( "aria-activedescendant",
11214
						that.menuItems.eq( item.index ).attr( "id" ) );
11215
				}
11216
			})
11217
			.menu( "instance" );
11218
 
11219
		// Adjust menu styles to dropdown
11220
		this.menu
11221
			.addClass( "ui-corner-bottom" )
11222
			.removeClass( "ui-corner-all" );
11223
 
11224
		// Don't close the menu on mouseleave
11225
		this.menuInstance._off( this.menu, "mouseleave" );
11226
 
11227
		// Cancel the menu's collapseAll on document click
11228
		this.menuInstance._closeOnDocumentClick = function() {
11229
			return false;
11230
		};
11231
 
11232
		// Selects often contain empty items, but never contain dividers
11233
		this.menuInstance._isDivider = function() {
11234
			return false;
11235
		};
11236
	},
11237
 
11238
	refresh: function() {
11239
		this._refreshMenu();
11240
		this._setText( this.buttonText, this._getSelectedItem().text() );
11241
		if ( !this.options.width ) {
11242
			this._resizeButton();
11243
		}
11244
	},
11245
 
11246
	_refreshMenu: function() {
11247
		this.menu.empty();
11248
 
11249
		var item,
11250
			options = this.element.find( "option" );
11251
 
11252
		if ( !options.length ) {
11253
			return;
11254
		}
11255
 
11256
		this._parseOptions( options );
11257
		this._renderMenu( this.menu, this.items );
11258
 
11259
		this.menuInstance.refresh();
11260
		this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" );
11261
 
11262
		item = this._getSelectedItem();
11263
 
11264
		// Update the menu to have the correct item focused
11265
		this.menuInstance.focus( null, item );
11266
		this._setAria( item.data( "ui-selectmenu-item" ) );
11267
 
11268
		// Set disabled state
11269
		this._setOption( "disabled", this.element.prop( "disabled" ) );
11270
	},
11271
 
11272
	open: function( event ) {
11273
		if ( this.options.disabled ) {
11274
			return;
11275
		}
11276
 
11277
		// If this is the first time the menu is being opened, render the items
11278
		if ( !this.menuItems ) {
11279
			this._refreshMenu();
11280
		} else {
11281
 
11282
			// Menu clears focus on close, reset focus to selected item
11283
			this.menu.find( ".ui-state-focus" ).removeClass( "ui-state-focus" );
11284
			this.menuInstance.focus( null, this._getSelectedItem() );
11285
		}
11286
 
11287
		this.isOpen = true;
11288
		this._toggleAttr();
11289
		this._resizeMenu();
11290
		this._position();
11291
 
11292
		this._on( this.document, this._documentClick );
11293
 
11294
		this._trigger( "open", event );
11295
	},
11296
 
11297
	_position: function() {
11298
		this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
11299
	},
11300
 
11301
	close: function( event ) {
11302
		if ( !this.isOpen ) {
11303
			return;
11304
		}
11305
 
11306
		this.isOpen = false;
11307
		this._toggleAttr();
11308
 
11309
		this.range = null;
11310
		this._off( this.document );
11311
 
11312
		this._trigger( "close", event );
11313
	},
11314
 
11315
	widget: function() {
11316
		return this.button;
11317
	},
11318
 
11319
	menuWidget: function() {
11320
		return this.menu;
11321
	},
11322
 
11323
	_renderMenu: function( ul, items ) {
11324
		var that = this,
11325
			currentOptgroup = "";
11326
 
11327
		$.each( items, function( index, item ) {
11328
			if ( item.optgroup !== currentOptgroup ) {
11329
				$( "<li>", {
11330
					"class": "ui-selectmenu-optgroup ui-menu-divider" +
11331
						( item.element.parent( "optgroup" ).prop( "disabled" ) ?
11332
							" ui-state-disabled" :
11333
							"" ),
11334
					text: item.optgroup
11335
				})
11336
					.appendTo( ul );
11337
 
11338
				currentOptgroup = item.optgroup;
11339
			}
11340
 
11341
			that._renderItemData( ul, item );
11342
		});
11343
	},
11344
 
11345
	_renderItemData: function( ul, item ) {
11346
		return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
11347
	},
11348
 
11349
	_renderItem: function( ul, item ) {
11350
		var li = $( "<li>" );
11351
 
11352
		if ( item.disabled ) {
11353
			li.addClass( "ui-state-disabled" );
11354
		}
11355
		this._setText( li, item.label );
11356
 
11357
		return li.appendTo( ul );
11358
	},
11359
 
11360
	_setText: function( element, value ) {
11361
		if ( value ) {
11362
			element.text( value );
11363
		} else {
11364
			element.html( "&#160;" );
11365
		}
11366
	},
11367
 
11368
	_move: function( direction, event ) {
11369
		var item, next,
11370
			filter = ".ui-menu-item";
11371
 
11372
		if ( this.isOpen ) {
11373
			item = this.menuItems.eq( this.focusIndex );
11374
		} else {
11375
			item = this.menuItems.eq( this.element[ 0 ].selectedIndex );
11376
			filter += ":not(.ui-state-disabled)";
11377
		}
11378
 
11379
		if ( direction === "first" || direction === "last" ) {
11380
			next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
11381
		} else {
11382
			next = item[ direction + "All" ]( filter ).eq( 0 );
11383
		}
11384
 
11385
		if ( next.length ) {
11386
			this.menuInstance.focus( event, next );
11387
		}
11388
	},
11389
 
11390
	_getSelectedItem: function() {
11391
		return this.menuItems.eq( this.element[ 0 ].selectedIndex );
11392
	},
11393
 
11394
	_toggle: function( event ) {
11395
		this[ this.isOpen ? "close" : "open" ]( event );
11396
	},
11397
 
11398
	_setSelection: function() {
11399
		var selection;
11400
 
11401
		if ( !this.range ) {
11402
			return;
11403
		}
11404
 
11405
		if ( window.getSelection ) {
11406
			selection = window.getSelection();
11407
			selection.removeAllRanges();
11408
			selection.addRange( this.range );
11409
 
11410
		// support: IE8
11411
		} else {
11412
			this.range.select();
11413
		}
11414
 
11415
		// support: IE
11416
		// Setting the text selection kills the button focus in IE, but
11417
		// restoring the focus doesn't kill the selection.
11418
		this.button.focus();
11419
	},
11420
 
11421
	_documentClick: {
11422
		mousedown: function( event ) {
11423
			if ( !this.isOpen ) {
11424
				return;
11425
			}
11426
 
11427
			if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + this.ids.button ).length ) {
11428
				this.close( event );
11429
			}
11430
		}
11431
	},
11432
 
11433
	_buttonEvents: {
11434
 
11435
		// Prevent text selection from being reset when interacting with the selectmenu (#10144)
11436
		mousedown: function() {
11437
			var selection;
11438
 
11439
			if ( window.getSelection ) {
11440
				selection = window.getSelection();
11441
				if ( selection.rangeCount ) {
11442
					this.range = selection.getRangeAt( 0 );
11443
				}
11444
 
11445
			// support: IE8
11446
			} else {
11447
				this.range = document.selection.createRange();
11448
			}
11449
		},
11450
 
11451
		click: function( event ) {
11452
			this._setSelection();
11453
			this._toggle( event );
11454
		},
11455
 
11456
		keydown: function( event ) {
11457
			var preventDefault = true;
11458
			switch ( event.keyCode ) {
11459
				case $.ui.keyCode.TAB:
11460
				case $.ui.keyCode.ESCAPE:
11461
					this.close( event );
11462
					preventDefault = false;
11463
					break;
11464
				case $.ui.keyCode.ENTER:
11465
					if ( this.isOpen ) {
11466
						this._selectFocusedItem( event );
11467
					}
11468
					break;
11469
				case $.ui.keyCode.UP:
11470
					if ( event.altKey ) {
11471
						this._toggle( event );
11472
					} else {
11473
						this._move( "prev", event );
11474
					}
11475
					break;
11476
				case $.ui.keyCode.DOWN:
11477
					if ( event.altKey ) {
11478
						this._toggle( event );
11479
					} else {
11480
						this._move( "next", event );
11481
					}
11482
					break;
11483
				case $.ui.keyCode.SPACE:
11484
					if ( this.isOpen ) {
11485
						this._selectFocusedItem( event );
11486
					} else {
11487
						this._toggle( event );
11488
					}
11489
					break;
11490
				case $.ui.keyCode.LEFT:
11491
					this._move( "prev", event );
11492
					break;
11493
				case $.ui.keyCode.RIGHT:
11494
					this._move( "next", event );
11495
					break;
11496
				case $.ui.keyCode.HOME:
11497
				case $.ui.keyCode.PAGE_UP:
11498
					this._move( "first", event );
11499
					break;
11500
				case $.ui.keyCode.END:
11501
				case $.ui.keyCode.PAGE_DOWN:
11502
					this._move( "last", event );
11503
					break;
11504
				default:
11505
					this.menu.trigger( event );
11506
					preventDefault = false;
11507
			}
11508
 
11509
			if ( preventDefault ) {
11510
				event.preventDefault();
11511
			}
11512
		}
11513
	},
11514
 
11515
	_selectFocusedItem: function( event ) {
11516
		var item = this.menuItems.eq( this.focusIndex );
11517
		if ( !item.hasClass( "ui-state-disabled" ) ) {
11518
			this._select( item.data( "ui-selectmenu-item" ), event );
11519
		}
11520
	},
11521
 
11522
	_select: function( item, event ) {
11523
		var oldIndex = this.element[ 0 ].selectedIndex;
11524
 
11525
		// Change native select element
11526
		this.element[ 0 ].selectedIndex = item.index;
11527
		this._setText( this.buttonText, item.label );
11528
		this._setAria( item );
11529
		this._trigger( "select", event, { item: item } );
11530
 
11531
		if ( item.index !== oldIndex ) {
11532
			this._trigger( "change", event, { item: item } );
11533
		}
11534
 
11535
		this.close( event );
11536
	},
11537
 
11538
	_setAria: function( item ) {
11539
		var id = this.menuItems.eq( item.index ).attr( "id" );
11540
 
11541
		this.button.attr({
11542
			"aria-labelledby": id,
11543
			"aria-activedescendant": id
11544
		});
11545
		this.menu.attr( "aria-activedescendant", id );
11546
	},
11547
 
11548
	_setOption: function( key, value ) {
11549
		if ( key === "icons" ) {
11550
			this.button.find( "span.ui-icon" )
11551
				.removeClass( this.options.icons.button )
11552
				.addClass( value.button );
11553
		}
11554
 
11555
		this._super( key, value );
11556
 
11557
		if ( key === "appendTo" ) {
11558
			this.menuWrap.appendTo( this._appendTo() );
11559
		}
11560
 
11561
		if ( key === "disabled" ) {
11562
			this.menuInstance.option( "disabled", value );
11563
			this.button
11564
				.toggleClass( "ui-state-disabled", value )
11565
				.attr( "aria-disabled", value );
11566
 
11567
			this.element.prop( "disabled", value );
11568
			if ( value ) {
11569
				this.button.attr( "tabindex", -1 );
11570
				this.close();
11571
			} else {
11572
				this.button.attr( "tabindex", 0 );
11573
			}
11574
		}
11575
 
11576
		if ( key === "width" ) {
11577
			this._resizeButton();
11578
		}
11579
	},
11580
 
11581
	_appendTo: function() {
11582
		var element = this.options.appendTo;
11583
 
11584
		if ( element ) {
11585
			element = element.jquery || element.nodeType ?
11586
				$( element ) :
11587
				this.document.find( element ).eq( 0 );
11588
		}
11589
 
11590
		if ( !element || !element[ 0 ] ) {
11591
			element = this.element.closest( ".ui-front" );
11592
		}
11593
 
11594
		if ( !element.length ) {
11595
			element = this.document[ 0 ].body;
11596
		}
11597
 
11598
		return element;
11599
	},
11600
 
11601
	_toggleAttr: function() {
11602
		this.button
11603
			.toggleClass( "ui-corner-top", this.isOpen )
11604
			.toggleClass( "ui-corner-all", !this.isOpen )
11605
			.attr( "aria-expanded", this.isOpen );
11606
		this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen );
11607
		this.menu.attr( "aria-hidden", !this.isOpen );
11608
	},
11609
 
11610
	_resizeButton: function() {
11611
		var width = this.options.width;
11612
 
11613
		if ( !width ) {
11614
			width = this.element.show().outerWidth();
11615
			this.element.hide();
11616
		}
11617
 
11618
		this.button.outerWidth( width );
11619
	},
11620
 
11621
	_resizeMenu: function() {
11622
		this.menu.outerWidth( Math.max(
11623
			this.button.outerWidth(),
11624
 
11625
			// support: IE10
11626
			// IE10 wraps long text (possibly a rounding bug)
11627
			// so we add 1px to avoid the wrapping
11628
			this.menu.width( "" ).outerWidth() + 1
11629
		) );
11630
	},
11631
 
11632
	_getCreateOptions: function() {
11633
		return { disabled: this.element.prop( "disabled" ) };
11634
	},
11635
 
11636
	_parseOptions: function( options ) {
11637
		var data = [];
11638
		options.each(function( index, item ) {
11639
			var option = $( item ),
11640
				optgroup = option.parent( "optgroup" );
11641
			data.push({
11642
				element: option,
11643
				index: index,
11644
				value: option.val(),
11645
				label: option.text(),
11646
				optgroup: optgroup.attr( "label" ) || "",
11647
				disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
11648
			});
11649
		});
11650
		this.items = data;
11651
	},
11652
 
11653
	_destroy: function() {
11654
		this.menuWrap.remove();
11655
		this.button.remove();
11656
		this.element.show();
11657
		this.element.removeUniqueId();
11658
		this.label.attr( "for", this.ids.element );
11659
	}
11660
});
11661
 
11662
 
11663
/*!
11664
 * jQuery UI Slider 1.11.4
11665
 * http://jqueryui.com
11666
 *
11667
 * Copyright jQuery Foundation and other contributors
11668
 * Released under the MIT license.
11669
 * http://jquery.org/license
11670
 *
11671
 * http://api.jqueryui.com/slider/
11672
 */
11673
 
11674
 
11675
var slider = $.widget( "ui.slider", $.ui.mouse, {
11676
	version: "1.11.4",
11677
	widgetEventPrefix: "slide",
11678
 
11679
	options: {
11680
		animate: false,
11681
		distance: 0,
11682
		max: 100,
11683
		min: 0,
11684
		orientation: "horizontal",
11685
		range: false,
11686
		step: 1,
11687
		value: 0,
11688
		values: null,
11689
 
11690
		// callbacks
11691
		change: null,
11692
		slide: null,
11693
		start: null,
11694
		stop: null
11695
	},
11696
 
11697
	// number of pages in a slider
11698
	// (how many times can you page up/down to go through the whole range)
11699
	numPages: 5,
11700
 
11701
	_create: function() {
11702
		this._keySliding = false;
11703
		this._mouseSliding = false;
11704
		this._animateOff = true;
11705
		this._handleIndex = null;
11706
		this._detectOrientation();
11707
		this._mouseInit();
11708
		this._calculateNewMax();
11709
 
11710
		this.element
11711
			.addClass( "ui-slider" +
11712
				" ui-slider-" + this.orientation +
11713
				" ui-widget" +
11714
				" ui-widget-content" +
11715
				" ui-corner-all");
11716
 
11717
		this._refresh();
11718
		this._setOption( "disabled", this.options.disabled );
11719
 
11720
		this._animateOff = false;
11721
	},
11722
 
11723
	_refresh: function() {
11724
		this._createRange();
11725
		this._createHandles();
11726
		this._setupEvents();
11727
		this._refreshValue();
11728
	},
11729
 
11730
	_createHandles: function() {
11731
		var i, handleCount,
11732
			options = this.options,
11733
			existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
11734
			handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>",
11735
			handles = [];
11736
 
11737
		handleCount = ( options.values && options.values.length ) || 1;
11738
 
11739
		if ( existingHandles.length > handleCount ) {
11740
			existingHandles.slice( handleCount ).remove();
11741
			existingHandles = existingHandles.slice( 0, handleCount );
11742
		}
11743
 
11744
		for ( i = existingHandles.length; i < handleCount; i++ ) {
11745
			handles.push( handle );
11746
		}
11747
 
11748
		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
11749
 
11750
		this.handle = this.handles.eq( 0 );
11751
 
11752
		this.handles.each(function( i ) {
11753
			$( this ).data( "ui-slider-handle-index", i );
11754
		});
11755
	},
11756
 
11757
	_createRange: function() {
11758
		var options = this.options,
11759
			classes = "";
11760
 
11761
		if ( options.range ) {
11762
			if ( options.range === true ) {
11763
				if ( !options.values ) {
11764
					options.values = [ this._valueMin(), this._valueMin() ];
11765
				} else if ( options.values.length && options.values.length !== 2 ) {
11766
					options.values = [ options.values[0], options.values[0] ];
11767
				} else if ( $.isArray( options.values ) ) {
11768
					options.values = options.values.slice(0);
11769
				}
11770
			}
11771
 
11772
			if ( !this.range || !this.range.length ) {
11773
				this.range = $( "<div></div>" )
11774
					.appendTo( this.element );
11775
 
11776
				classes = "ui-slider-range" +
11777
				// note: this isn't the most fittingly semantic framework class for this element,
11778
				// but worked best visually with a variety of themes
11779
				" ui-widget-header ui-corner-all";
11780
			} else {
11781
				this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
11782
					// Handle range switching from true to min/max
11783
					.css({
11784
						"left": "",
11785
						"bottom": ""
11786
					});
11787
			}
11788
 
11789
			this.range.addClass( classes +
11790
				( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
11791
		} else {
11792
			if ( this.range ) {
11793
				this.range.remove();
11794
			}
11795
			this.range = null;
11796
		}
11797
	},
11798
 
11799
	_setupEvents: function() {
11800
		this._off( this.handles );
11801
		this._on( this.handles, this._handleEvents );
11802
		this._hoverable( this.handles );
11803
		this._focusable( this.handles );
11804
	},
11805
 
11806
	_destroy: function() {
11807
		this.handles.remove();
11808
		if ( this.range ) {
11809
			this.range.remove();
11810
		}
11811
 
11812
		this.element
11813
			.removeClass( "ui-slider" +
11814
				" ui-slider-horizontal" +
11815
				" ui-slider-vertical" +
11816
				" ui-widget" +
11817
				" ui-widget-content" +
11818
				" ui-corner-all" );
11819
 
11820
		this._mouseDestroy();
11821
	},
11822
 
11823
	_mouseCapture: function( event ) {
11824
		var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
11825
			that = this,
11826
			o = this.options;
11827
 
11828
		if ( o.disabled ) {
11829
			return false;
11830
		}
11831
 
11832
		this.elementSize = {
11833
			width: this.element.outerWidth(),
11834
			height: this.element.outerHeight()
11835
		};
11836
		this.elementOffset = this.element.offset();
11837
 
11838
		position = { x: event.pageX, y: event.pageY };
11839
		normValue = this._normValueFromMouse( position );
11840
		distance = this._valueMax() - this._valueMin() + 1;
11841
		this.handles.each(function( i ) {
11842
			var thisDistance = Math.abs( normValue - that.values(i) );
11843
			if (( distance > thisDistance ) ||
11844
				( distance === thisDistance &&
11845
					(i === that._lastChangedValue || that.values(i) === o.min ))) {
11846
				distance = thisDistance;
11847
				closestHandle = $( this );
11848
				index = i;
11849
			}
11850
		});
11851
 
11852
		allowed = this._start( event, index );
11853
		if ( allowed === false ) {
11854
			return false;
11855
		}
11856
		this._mouseSliding = true;
11857
 
11858
		this._handleIndex = index;
11859
 
11860
		closestHandle
11861
			.addClass( "ui-state-active" )
11862
			.focus();
11863
 
11864
		offset = closestHandle.offset();
11865
		mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
11866
		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
11867
			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
11868
			top: event.pageY - offset.top -
11869
				( closestHandle.height() / 2 ) -
11870
				( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
11871
				( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
11872
				( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
11873
		};
11874
 
11875
		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
11876
			this._slide( event, index, normValue );
11877
		}
11878
		this._animateOff = true;
11879
		return true;
11880
	},
11881
 
11882
	_mouseStart: function() {
11883
		return true;
11884
	},
11885
 
11886
	_mouseDrag: function( event ) {
11887
		var position = { x: event.pageX, y: event.pageY },
11888
			normValue = this._normValueFromMouse( position );
11889
 
11890
		this._slide( event, this._handleIndex, normValue );
11891
 
11892
		return false;
11893
	},
11894
 
11895
	_mouseStop: function( event ) {
11896
		this.handles.removeClass( "ui-state-active" );
11897
		this._mouseSliding = false;
11898
 
11899
		this._stop( event, this._handleIndex );
11900
		this._change( event, this._handleIndex );
11901
 
11902
		this._handleIndex = null;
11903
		this._clickOffset = null;
11904
		this._animateOff = false;
11905
 
11906
		return false;
11907
	},
11908
 
11909
	_detectOrientation: function() {
11910
		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
11911
	},
11912
 
11913
	_normValueFromMouse: function( position ) {
11914
		var pixelTotal,
11915
			pixelMouse,
11916
			percentMouse,
11917
			valueTotal,
11918
			valueMouse;
11919
 
11920
		if ( this.orientation === "horizontal" ) {
11921
			pixelTotal = this.elementSize.width;
11922
			pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
11923
		} else {
11924
			pixelTotal = this.elementSize.height;
11925
			pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
11926
		}
11927
 
11928
		percentMouse = ( pixelMouse / pixelTotal );
11929
		if ( percentMouse > 1 ) {
11930
			percentMouse = 1;
11931
		}
11932
		if ( percentMouse < 0 ) {
11933
			percentMouse = 0;
11934
		}
11935
		if ( this.orientation === "vertical" ) {
11936
			percentMouse = 1 - percentMouse;
11937
		}
11938
 
11939
		valueTotal = this._valueMax() - this._valueMin();
11940
		valueMouse = this._valueMin() + percentMouse * valueTotal;
11941
 
11942
		return this._trimAlignValue( valueMouse );
11943
	},
11944
 
11945
	_start: function( event, index ) {
11946
		var uiHash = {
11947
			handle: this.handles[ index ],
11948
			value: this.value()
11949
		};
11950
		if ( this.options.values && this.options.values.length ) {
11951
			uiHash.value = this.values( index );
11952
			uiHash.values = this.values();
11953
		}
11954
		return this._trigger( "start", event, uiHash );
11955
	},
11956
 
11957
	_slide: function( event, index, newVal ) {
11958
		var otherVal,
11959
			newValues,
11960
			allowed;
11961
 
11962
		if ( this.options.values && this.options.values.length ) {
11963
			otherVal = this.values( index ? 0 : 1 );
11964
 
11965
			if ( ( this.options.values.length === 2 && this.options.range === true ) &&
11966
					( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
11967
				) {
11968
				newVal = otherVal;
11969
			}
11970
 
11971
			if ( newVal !== this.values( index ) ) {
11972
				newValues = this.values();
11973
				newValues[ index ] = newVal;
11974
				// A slide can be canceled by returning false from the slide callback
11975
				allowed = this._trigger( "slide", event, {
11976
					handle: this.handles[ index ],
11977
					value: newVal,
11978
					values: newValues
11979
				} );
11980
				otherVal = this.values( index ? 0 : 1 );
11981
				if ( allowed !== false ) {
11982
					this.values( index, newVal );
11983
				}
11984
			}
11985
		} else {
11986
			if ( newVal !== this.value() ) {
11987
				// A slide can be canceled by returning false from the slide callback
11988
				allowed = this._trigger( "slide", event, {
11989
					handle: this.handles[ index ],
11990
					value: newVal
11991
				} );
11992
				if ( allowed !== false ) {
11993
					this.value( newVal );
11994
				}
11995
			}
11996
		}
11997
	},
11998
 
11999
	_stop: function( event, index ) {
12000
		var uiHash = {
12001
			handle: this.handles[ index ],
12002
			value: this.value()
12003
		};
12004
		if ( this.options.values && this.options.values.length ) {
12005
			uiHash.value = this.values( index );
12006
			uiHash.values = this.values();
12007
		}
12008
 
12009
		this._trigger( "stop", event, uiHash );
12010
	},
12011
 
12012
	_change: function( event, index ) {
12013
		if ( !this._keySliding && !this._mouseSliding ) {
12014
			var uiHash = {
12015
				handle: this.handles[ index ],
12016
				value: this.value()
12017
			};
12018
			if ( this.options.values && this.options.values.length ) {
12019
				uiHash.value = this.values( index );
12020
				uiHash.values = this.values();
12021
			}
12022
 
12023
			//store the last changed value index for reference when handles overlap
12024
			this._lastChangedValue = index;
12025
 
12026
			this._trigger( "change", event, uiHash );
12027
		}
12028
	},
12029
 
12030
	value: function( newValue ) {
12031
		if ( arguments.length ) {
12032
			this.options.value = this._trimAlignValue( newValue );
12033
			this._refreshValue();
12034
			this._change( null, 0 );
12035
			return;
12036
		}
12037
 
12038
		return this._value();
12039
	},
12040
 
12041
	values: function( index, newValue ) {
12042
		var vals,
12043
			newValues,
12044
			i;
12045
 
12046
		if ( arguments.length > 1 ) {
12047
			this.options.values[ index ] = this._trimAlignValue( newValue );
12048
			this._refreshValue();
12049
			this._change( null, index );
12050
			return;
12051
		}
12052
 
12053
		if ( arguments.length ) {
12054
			if ( $.isArray( arguments[ 0 ] ) ) {
12055
				vals = this.options.values;
12056
				newValues = arguments[ 0 ];
12057
				for ( i = 0; i < vals.length; i += 1 ) {
12058
					vals[ i ] = this._trimAlignValue( newValues[ i ] );
12059
					this._change( null, i );
12060
				}
12061
				this._refreshValue();
12062
			} else {
12063
				if ( this.options.values && this.options.values.length ) {
12064
					return this._values( index );
12065
				} else {
12066
					return this.value();
12067
				}
12068
			}
12069
		} else {
12070
			return this._values();
12071
		}
12072
	},
12073
 
12074
	_setOption: function( key, value ) {
12075
		var i,
12076
			valsLength = 0;
12077
 
12078
		if ( key === "range" && this.options.range === true ) {
12079
			if ( value === "min" ) {
12080
				this.options.value = this._values( 0 );
12081
				this.options.values = null;
12082
			} else if ( value === "max" ) {
12083
				this.options.value = this._values( this.options.values.length - 1 );
12084
				this.options.values = null;
12085
			}
12086
		}
12087
 
12088
		if ( $.isArray( this.options.values ) ) {
12089
			valsLength = this.options.values.length;
12090
		}
12091
 
12092
		if ( key === "disabled" ) {
12093
			this.element.toggleClass( "ui-state-disabled", !!value );
12094
		}
12095
 
12096
		this._super( key, value );
12097
 
12098
		switch ( key ) {
12099
			case "orientation":
12100
				this._detectOrientation();
12101
				this.element
12102
					.removeClass( "ui-slider-horizontal ui-slider-vertical" )
12103
					.addClass( "ui-slider-" + this.orientation );
12104
				this._refreshValue();
12105
 
12106
				// Reset positioning from previous orientation
12107
				this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
12108
				break;
12109
			case "value":
12110
				this._animateOff = true;
12111
				this._refreshValue();
12112
				this._change( null, 0 );
12113
				this._animateOff = false;
12114
				break;
12115
			case "values":
12116
				this._animateOff = true;
12117
				this._refreshValue();
12118
				for ( i = 0; i < valsLength; i += 1 ) {
12119
					this._change( null, i );
12120
				}
12121
				this._animateOff = false;
12122
				break;
12123
			case "step":
12124
			case "min":
12125
			case "max":
12126
				this._animateOff = true;
12127
				this._calculateNewMax();
12128
				this._refreshValue();
12129
				this._animateOff = false;
12130
				break;
12131
			case "range":
12132
				this._animateOff = true;
12133
				this._refresh();
12134
				this._animateOff = false;
12135
				break;
12136
		}
12137
	},
12138
 
12139
	//internal value getter
12140
	// _value() returns value trimmed by min and max, aligned by step
12141
	_value: function() {
12142
		var val = this.options.value;
12143
		val = this._trimAlignValue( val );
12144
 
12145
		return val;
12146
	},
12147
 
12148
	//internal values getter
12149
	// _values() returns array of values trimmed by min and max, aligned by step
12150
	// _values( index ) returns single value trimmed by min and max, aligned by step
12151
	_values: function( index ) {
12152
		var val,
12153
			vals,
12154
			i;
12155
 
12156
		if ( arguments.length ) {
12157
			val = this.options.values[ index ];
12158
			val = this._trimAlignValue( val );
12159
 
12160
			return val;
12161
		} else if ( this.options.values && this.options.values.length ) {
12162
			// .slice() creates a copy of the array
12163
			// this copy gets trimmed by min and max and then returned
12164
			vals = this.options.values.slice();
12165
			for ( i = 0; i < vals.length; i += 1) {
12166
				vals[ i ] = this._trimAlignValue( vals[ i ] );
12167
			}
12168
 
12169
			return vals;
12170
		} else {
12171
			return [];
12172
		}
12173
	},
12174
 
12175
	// returns the step-aligned value that val is closest to, between (inclusive) min and max
12176
	_trimAlignValue: function( val ) {
12177
		if ( val <= this._valueMin() ) {
12178
			return this._valueMin();
12179
		}
12180
		if ( val >= this._valueMax() ) {
12181
			return this._valueMax();
12182
		}
12183
		var step = ( this.options.step > 0 ) ? this.options.step : 1,
12184
			valModStep = (val - this._valueMin()) % step,
12185
			alignValue = val - valModStep;
12186
 
12187
		if ( Math.abs(valModStep) * 2 >= step ) {
12188
			alignValue += ( valModStep > 0 ) ? step : ( -step );
12189
		}
12190
 
12191
		// Since JavaScript has problems with large floats, round
12192
		// the final value to 5 digits after the decimal point (see #4124)
12193
		return parseFloat( alignValue.toFixed(5) );
12194
	},
12195
 
12196
	_calculateNewMax: function() {
12197
		var max = this.options.max,
12198
			min = this._valueMin(),
12199
			step = this.options.step,
12200
			aboveMin = Math.floor( ( +( max - min ).toFixed( this._precision() ) ) / step ) * step;
12201
		max = aboveMin + min;
12202
		this.max = parseFloat( max.toFixed( this._precision() ) );
12203
	},
12204
 
12205
	_precision: function() {
12206
		var precision = this._precisionOf( this.options.step );
12207
		if ( this.options.min !== null ) {
12208
			precision = Math.max( precision, this._precisionOf( this.options.min ) );
12209
		}
12210
		return precision;
12211
	},
12212
 
12213
	_precisionOf: function( num ) {
12214
		var str = num.toString(),
12215
			decimal = str.indexOf( "." );
12216
		return decimal === -1 ? 0 : str.length - decimal - 1;
12217
	},
12218
 
12219
	_valueMin: function() {
12220
		return this.options.min;
12221
	},
12222
 
12223
	_valueMax: function() {
12224
		return this.max;
12225
	},
12226
 
12227
	_refreshValue: function() {
12228
		var lastValPercent, valPercent, value, valueMin, valueMax,
12229
			oRange = this.options.range,
12230
			o = this.options,
12231
			that = this,
12232
			animate = ( !this._animateOff ) ? o.animate : false,
12233
			_set = {};
12234
 
12235
		if ( this.options.values && this.options.values.length ) {
12236
			this.handles.each(function( i ) {
12237
				valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
12238
				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
12239
				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
12240
				if ( that.options.range === true ) {
12241
					if ( that.orientation === "horizontal" ) {
12242
						if ( i === 0 ) {
12243
							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
12244
						}
12245
						if ( i === 1 ) {
12246
							that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
12247
						}
12248
					} else {
12249
						if ( i === 0 ) {
12250
							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
12251
						}
12252
						if ( i === 1 ) {
12253
							that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
12254
						}
12255
					}
12256
				}
12257
				lastValPercent = valPercent;
12258
			});
12259
		} else {
12260
			value = this.value();
12261
			valueMin = this._valueMin();
12262
			valueMax = this._valueMax();
12263
			valPercent = ( valueMax !== valueMin ) ?
12264
					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
12265
					0;
12266
			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
12267
			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
12268
 
12269
			if ( oRange === "min" && this.orientation === "horizontal" ) {
12270
				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
12271
			}
12272
			if ( oRange === "max" && this.orientation === "horizontal" ) {
12273
				this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
12274
			}
12275
			if ( oRange === "min" && this.orientation === "vertical" ) {
12276
				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
12277
			}
12278
			if ( oRange === "max" && this.orientation === "vertical" ) {
12279
				this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
12280
			}
12281
		}
12282
	},
12283
 
12284
	_handleEvents: {
12285
		keydown: function( event ) {
12286
			var allowed, curVal, newVal, step,
12287
				index = $( event.target ).data( "ui-slider-handle-index" );
12288
 
12289
			switch ( event.keyCode ) {
12290
				case $.ui.keyCode.HOME:
12291
				case $.ui.keyCode.END:
12292
				case $.ui.keyCode.PAGE_UP:
12293
				case $.ui.keyCode.PAGE_DOWN:
12294
				case $.ui.keyCode.UP:
12295
				case $.ui.keyCode.RIGHT:
12296
				case $.ui.keyCode.DOWN:
12297
				case $.ui.keyCode.LEFT:
12298
					event.preventDefault();
12299
					if ( !this._keySliding ) {
12300
						this._keySliding = true;
12301
						$( event.target ).addClass( "ui-state-active" );
12302
						allowed = this._start( event, index );
12303
						if ( allowed === false ) {
12304
							return;
12305
						}
12306
					}
12307
					break;
12308
			}
12309
 
12310
			step = this.options.step;
12311
			if ( this.options.values && this.options.values.length ) {
12312
				curVal = newVal = this.values( index );
12313
			} else {
12314
				curVal = newVal = this.value();
12315
			}
12316
 
12317
			switch ( event.keyCode ) {
12318
				case $.ui.keyCode.HOME:
12319
					newVal = this._valueMin();
12320
					break;
12321
				case $.ui.keyCode.END:
12322
					newVal = this._valueMax();
12323
					break;
12324
				case $.ui.keyCode.PAGE_UP:
12325
					newVal = this._trimAlignValue(
12326
						curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
12327
					);
12328
					break;
12329
				case $.ui.keyCode.PAGE_DOWN:
12330
					newVal = this._trimAlignValue(
12331
						curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) );
12332
					break;
12333
				case $.ui.keyCode.UP:
12334
				case $.ui.keyCode.RIGHT:
12335
					if ( curVal === this._valueMax() ) {
12336
						return;
12337
					}
12338
					newVal = this._trimAlignValue( curVal + step );
12339
					break;
12340
				case $.ui.keyCode.DOWN:
12341
				case $.ui.keyCode.LEFT:
12342
					if ( curVal === this._valueMin() ) {
12343
						return;
12344
					}
12345
					newVal = this._trimAlignValue( curVal - step );
12346
					break;
12347
			}
12348
 
12349
			this._slide( event, index, newVal );
12350
		},
12351
		keyup: function( event ) {
12352
			var index = $( event.target ).data( "ui-slider-handle-index" );
12353
 
12354
			if ( this._keySliding ) {
12355
				this._keySliding = false;
12356
				this._stop( event, index );
12357
				this._change( event, index );
12358
				$( event.target ).removeClass( "ui-state-active" );
12359
			}
12360
		}
12361
	}
12362
});
12363
 
12364
 
12365
/*!
12366
 * jQuery UI Spinner 1.11.4
12367
 * http://jqueryui.com
12368
 *
12369
 * Copyright jQuery Foundation and other contributors
12370
 * Released under the MIT license.
12371
 * http://jquery.org/license
12372
 *
12373
 * http://api.jqueryui.com/spinner/
12374
 */
12375
 
12376
 
12377
function spinner_modifier( fn ) {
12378
	return function() {
12379
		var previous = this.element.val();
12380
		fn.apply( this, arguments );
12381
		this._refresh();
12382
		if ( previous !== this.element.val() ) {
12383
			this._trigger( "change" );
12384
		}
12385
	};
12386
}
12387
 
12388
var spinner = $.widget( "ui.spinner", {
12389
	version: "1.11.4",
12390
	defaultElement: "<input>",
12391
	widgetEventPrefix: "spin",
12392
	options: {
12393
		culture: null,
12394
		icons: {
12395
			down: "ui-icon-triangle-1-s",
12396
			up: "ui-icon-triangle-1-n"
12397
		},
12398
		incremental: true,
12399
		max: null,
12400
		min: null,
12401
		numberFormat: null,
12402
		page: 10,
12403
		step: 1,
12404
 
12405
		change: null,
12406
		spin: null,
12407
		start: null,
12408
		stop: null
12409
	},
12410
 
12411
	_create: function() {
12412
		// handle string values that need to be parsed
12413
		this._setOption( "max", this.options.max );
12414
		this._setOption( "min", this.options.min );
12415
		this._setOption( "step", this.options.step );
12416
 
12417
		// Only format if there is a value, prevents the field from being marked
12418
		// as invalid in Firefox, see #9573.
12419
		if ( this.value() !== "" ) {
12420
			// Format the value, but don't constrain.
12421
			this._value( this.element.val(), true );
12422
		}
12423
 
12424
		this._draw();
12425
		this._on( this._events );
12426
		this._refresh();
12427
 
12428
		// turning off autocomplete prevents the browser from remembering the
12429
		// value when navigating through history, so we re-enable autocomplete
12430
		// if the page is unloaded before the widget is destroyed. #7790
12431
		this._on( this.window, {
12432
			beforeunload: function() {
12433
				this.element.removeAttr( "autocomplete" );
12434
			}
12435
		});
12436
	},
12437
 
12438
	_getCreateOptions: function() {
12439
		var options = {},
12440
			element = this.element;
12441
 
12442
		$.each( [ "min", "max", "step" ], function( i, option ) {
12443
			var value = element.attr( option );
12444
			if ( value !== undefined && value.length ) {
12445
				options[ option ] = value;
12446
			}
12447
		});
12448
 
12449
		return options;
12450
	},
12451
 
12452
	_events: {
12453
		keydown: function( event ) {
12454
			if ( this._start( event ) && this._keydown( event ) ) {
12455
				event.preventDefault();
12456
			}
12457
		},
12458
		keyup: "_stop",
12459
		focus: function() {
12460
			this.previous = this.element.val();
12461
		},
12462
		blur: function( event ) {
12463
			if ( this.cancelBlur ) {
12464
				delete this.cancelBlur;
12465
				return;
12466
			}
12467
 
12468
			this._stop();
12469
			this._refresh();
12470
			if ( this.previous !== this.element.val() ) {
12471
				this._trigger( "change", event );
12472
			}
12473
		},
12474
		mousewheel: function( event, delta ) {
12475
			if ( !delta ) {
12476
				return;
12477
			}
12478
			if ( !this.spinning && !this._start( event ) ) {
12479
				return false;
12480
			}
12481
 
12482
			this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
12483
			clearTimeout( this.mousewheelTimer );
12484
			this.mousewheelTimer = this._delay(function() {
12485
				if ( this.spinning ) {
12486
					this._stop( event );
12487
				}
12488
			}, 100 );
12489
			event.preventDefault();
12490
		},
12491
		"mousedown .ui-spinner-button": function( event ) {
12492
			var previous;
12493
 
12494
			// We never want the buttons to have focus; whenever the user is
12495
			// interacting with the spinner, the focus should be on the input.
12496
			// If the input is focused then this.previous is properly set from
12497
			// when the input first received focus. If the input is not focused
12498
			// then we need to set this.previous based on the value before spinning.
12499
			previous = this.element[0] === this.document[0].activeElement ?
12500
				this.previous : this.element.val();
12501
			function checkFocus() {
12502
				var isActive = this.element[0] === this.document[0].activeElement;
12503
				if ( !isActive ) {
12504
					this.element.focus();
12505
					this.previous = previous;
12506
					// support: IE
12507
					// IE sets focus asynchronously, so we need to check if focus
12508
					// moved off of the input because the user clicked on the button.
12509
					this._delay(function() {
12510
						this.previous = previous;
12511
					});
12512
				}
12513
			}
12514
 
12515
			// ensure focus is on (or stays on) the text field
12516
			event.preventDefault();
12517
			checkFocus.call( this );
12518
 
12519
			// support: IE
12520
			// IE doesn't prevent moving focus even with event.preventDefault()
12521
			// so we set a flag to know when we should ignore the blur event
12522
			// and check (again) if focus moved off of the input.
12523
			this.cancelBlur = true;
12524
			this._delay(function() {
12525
				delete this.cancelBlur;
12526
				checkFocus.call( this );
12527
			});
12528
 
12529
			if ( this._start( event ) === false ) {
12530
				return;
12531
			}
12532
 
12533
			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
12534
		},
12535
		"mouseup .ui-spinner-button": "_stop",
12536
		"mouseenter .ui-spinner-button": function( event ) {
12537
			// button will add ui-state-active if mouse was down while mouseleave and kept down
12538
			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
12539
				return;
12540
			}
12541
 
12542
			if ( this._start( event ) === false ) {
12543
				return false;
12544
			}
12545
			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
12546
		},
12547
		// TODO: do we really want to consider this a stop?
12548
		// shouldn't we just stop the repeater and wait until mouseup before
12549
		// we trigger the stop event?
12550
		"mouseleave .ui-spinner-button": "_stop"
12551
	},
12552
 
12553
	_draw: function() {
12554
		var uiSpinner = this.uiSpinner = this.element
12555
			.addClass( "ui-spinner-input" )
12556
			.attr( "autocomplete", "off" )
12557
			.wrap( this._uiSpinnerHtml() )
12558
			.parent()
12559
				// add buttons
12560
				.append( this._buttonHtml() );
12561
 
12562
		this.element.attr( "role", "spinbutton" );
12563
 
12564
		// button bindings
12565
		this.buttons = uiSpinner.find( ".ui-spinner-button" )
12566
			.attr( "tabIndex", -1 )
12567
			.button()
12568
			.removeClass( "ui-corner-all" );
12569
 
12570
		// IE 6 doesn't understand height: 50% for the buttons
12571
		// unless the wrapper has an explicit height
12572
		if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
12573
				uiSpinner.height() > 0 ) {
12574
			uiSpinner.height( uiSpinner.height() );
12575
		}
12576
 
12577
		// disable spinner if element was already disabled
12578
		if ( this.options.disabled ) {
12579
			this.disable();
12580
		}
12581
	},
12582
 
12583
	_keydown: function( event ) {
12584
		var options = this.options,
12585
			keyCode = $.ui.keyCode;
12586
 
12587
		switch ( event.keyCode ) {
12588
		case keyCode.UP:
12589
			this._repeat( null, 1, event );
12590
			return true;
12591
		case keyCode.DOWN:
12592
			this._repeat( null, -1, event );
12593
			return true;
12594
		case keyCode.PAGE_UP:
12595
			this._repeat( null, options.page, event );
12596
			return true;
12597
		case keyCode.PAGE_DOWN:
12598
			this._repeat( null, -options.page, event );
12599
			return true;
12600
		}
12601
 
12602
		return false;
12603
	},
12604
 
12605
	_uiSpinnerHtml: function() {
12606
		return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
12607
	},
12608
 
12609
	_buttonHtml: function() {
12610
		return "" +
12611
			"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
12612
				"<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
12613
			"</a>" +
12614
			"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
12615
				"<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
12616
			"</a>";
12617
	},
12618
 
12619
	_start: function( event ) {
12620
		if ( !this.spinning && this._trigger( "start", event ) === false ) {
12621
			return false;
12622
		}
12623
 
12624
		if ( !this.counter ) {
12625
			this.counter = 1;
12626
		}
12627
		this.spinning = true;
12628
		return true;
12629
	},
12630
 
12631
	_repeat: function( i, steps, event ) {
12632
		i = i || 500;
12633
 
12634
		clearTimeout( this.timer );
12635
		this.timer = this._delay(function() {
12636
			this._repeat( 40, steps, event );
12637
		}, i );
12638
 
12639
		this._spin( steps * this.options.step, event );
12640
	},
12641
 
12642
	_spin: function( step, event ) {
12643
		var value = this.value() || 0;
12644
 
12645
		if ( !this.counter ) {
12646
			this.counter = 1;
12647
		}
12648
 
12649
		value = this._adjustValue( value + step * this._increment( this.counter ) );
12650
 
12651
		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
12652
			this._value( value );
12653
			this.counter++;
12654
		}
12655
	},
12656
 
12657
	_increment: function( i ) {
12658
		var incremental = this.options.incremental;
12659
 
12660
		if ( incremental ) {
12661
			return $.isFunction( incremental ) ?
12662
				incremental( i ) :
12663
				Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
12664
		}
12665
 
12666
		return 1;
12667
	},
12668
 
12669
	_precision: function() {
12670
		var precision = this._precisionOf( this.options.step );
12671
		if ( this.options.min !== null ) {
12672
			precision = Math.max( precision, this._precisionOf( this.options.min ) );
12673
		}
12674
		return precision;
12675
	},
12676
 
12677
	_precisionOf: function( num ) {
12678
		var str = num.toString(),
12679
			decimal = str.indexOf( "." );
12680
		return decimal === -1 ? 0 : str.length - decimal - 1;
12681
	},
12682
 
12683
	_adjustValue: function( value ) {
12684
		var base, aboveMin,
12685
			options = this.options;
12686
 
12687
		// make sure we're at a valid step
12688
		// - find out where we are relative to the base (min or 0)
12689
		base = options.min !== null ? options.min : 0;
12690
		aboveMin = value - base;
12691
		// - round to the nearest step
12692
		aboveMin = Math.round(aboveMin / options.step) * options.step;
12693
		// - rounding is based on 0, so adjust back to our base
12694
		value = base + aboveMin;
12695
 
12696
		// fix precision from bad JS floating point math
12697
		value = parseFloat( value.toFixed( this._precision() ) );
12698
 
12699
		// clamp the value
12700
		if ( options.max !== null && value > options.max) {
12701
			return options.max;
12702
		}
12703
		if ( options.min !== null && value < options.min ) {
12704
			return options.min;
12705
		}
12706
 
12707
		return value;
12708
	},
12709
 
12710
	_stop: function( event ) {
12711
		if ( !this.spinning ) {
12712
			return;
12713
		}
12714
 
12715
		clearTimeout( this.timer );
12716
		clearTimeout( this.mousewheelTimer );
12717
		this.counter = 0;
12718
		this.spinning = false;
12719
		this._trigger( "stop", event );
12720
	},
12721
 
12722
	_setOption: function( key, value ) {
12723
		if ( key === "culture" || key === "numberFormat" ) {
12724
			var prevValue = this._parse( this.element.val() );
12725
			this.options[ key ] = value;
12726
			this.element.val( this._format( prevValue ) );
12727
			return;
12728
		}
12729
 
12730
		if ( key === "max" || key === "min" || key === "step" ) {
12731
			if ( typeof value === "string" ) {
12732
				value = this._parse( value );
12733
			}
12734
		}
12735
		if ( key === "icons" ) {
12736
			this.buttons.first().find( ".ui-icon" )
12737
				.removeClass( this.options.icons.up )
12738
				.addClass( value.up );
12739
			this.buttons.last().find( ".ui-icon" )
12740
				.removeClass( this.options.icons.down )
12741
				.addClass( value.down );
12742
		}
12743
 
12744
		this._super( key, value );
12745
 
12746
		if ( key === "disabled" ) {
12747
			this.widget().toggleClass( "ui-state-disabled", !!value );
12748
			this.element.prop( "disabled", !!value );
12749
			this.buttons.button( value ? "disable" : "enable" );
12750
		}
12751
	},
12752
 
12753
	_setOptions: spinner_modifier(function( options ) {
12754
		this._super( options );
12755
	}),
12756
 
12757
	_parse: function( val ) {
12758
		if ( typeof val === "string" && val !== "" ) {
12759
			val = window.Globalize && this.options.numberFormat ?
12760
				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
12761
		}
12762
		return val === "" || isNaN( val ) ? null : val;
12763
	},
12764
 
12765
	_format: function( value ) {
12766
		if ( value === "" ) {
12767
			return "";
12768
		}
12769
		return window.Globalize && this.options.numberFormat ?
12770
			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
12771
			value;
12772
	},
12773
 
12774
	_refresh: function() {
12775
		this.element.attr({
12776
			"aria-valuemin": this.options.min,
12777
			"aria-valuemax": this.options.max,
12778
			// TODO: what should we do with values that can't be parsed?
12779
			"aria-valuenow": this._parse( this.element.val() )
12780
		});
12781
	},
12782
 
12783
	isValid: function() {
12784
		var value = this.value();
12785
 
12786
		// null is invalid
12787
		if ( value === null ) {
12788
			return false;
12789
		}
12790
 
12791
		// if value gets adjusted, it's invalid
12792
		return value === this._adjustValue( value );
12793
	},
12794
 
12795
	// update the value without triggering change
12796
	_value: function( value, allowAny ) {
12797
		var parsed;
12798
		if ( value !== "" ) {
12799
			parsed = this._parse( value );
12800
			if ( parsed !== null ) {
12801
				if ( !allowAny ) {
12802
					parsed = this._adjustValue( parsed );
12803
				}
12804
				value = this._format( parsed );
12805
			}
12806
		}
12807
		this.element.val( value );
12808
		this._refresh();
12809
	},
12810
 
12811
	_destroy: function() {
12812
		this.element
12813
			.removeClass( "ui-spinner-input" )
12814
			.prop( "disabled", false )
12815
			.removeAttr( "autocomplete" )
12816
			.removeAttr( "role" )
12817
			.removeAttr( "aria-valuemin" )
12818
			.removeAttr( "aria-valuemax" )
12819
			.removeAttr( "aria-valuenow" );
12820
		this.uiSpinner.replaceWith( this.element );
12821
	},
12822
 
12823
	stepUp: spinner_modifier(function( steps ) {
12824
		this._stepUp( steps );
12825
	}),
12826
	_stepUp: function( steps ) {
12827
		if ( this._start() ) {
12828
			this._spin( (steps || 1) * this.options.step );
12829
			this._stop();
12830
		}
12831
	},
12832
 
12833
	stepDown: spinner_modifier(function( steps ) {
12834
		this._stepDown( steps );
12835
	}),
12836
	_stepDown: function( steps ) {
12837
		if ( this._start() ) {
12838
			this._spin( (steps || 1) * -this.options.step );
12839
			this._stop();
12840
		}
12841
	},
12842
 
12843
	pageUp: spinner_modifier(function( pages ) {
12844
		this._stepUp( (pages || 1) * this.options.page );
12845
	}),
12846
 
12847
	pageDown: spinner_modifier(function( pages ) {
12848
		this._stepDown( (pages || 1) * this.options.page );
12849
	}),
12850
 
12851
	value: function( newVal ) {
12852
		if ( !arguments.length ) {
12853
			return this._parse( this.element.val() );
12854
		}
12855
		spinner_modifier( this._value ).call( this, newVal );
12856
	},
12857
 
12858
	widget: function() {
12859
		return this.uiSpinner;
12860
	}
12861
});
12862
 
12863
 
12864
/*!
12865
 * jQuery UI Tabs 1.11.4
12866
 * http://jqueryui.com
12867
 *
12868
 * Copyright jQuery Foundation and other contributors
12869
 * Released under the MIT license.
12870
 * http://jquery.org/license
12871
 *
12872
 * http://api.jqueryui.com/tabs/
12873
 */
12874
 
12875
 
12876
var tabs = $.widget( "ui.tabs", {
12877
	version: "1.11.4",
12878
	delay: 300,
12879
	options: {
12880
		active: null,
12881
		collapsible: false,
12882
		event: "click",
12883
		heightStyle: "content",
12884
		hide: null,
12885
		show: null,
12886
 
12887
		// callbacks
12888
		activate: null,
12889
		beforeActivate: null,
12890
		beforeLoad: null,
12891
		load: null
12892
	},
12893
 
12894
	_isLocal: (function() {
12895
		var rhash = /#.*$/;
12896
 
12897
		return function( anchor ) {
12898
			var anchorUrl, locationUrl;
12899
 
12900
			// support: IE7
12901
			// IE7 doesn't normalize the href property when set via script (#9317)
12902
			anchor = anchor.cloneNode( false );
12903
 
12904
			anchorUrl = anchor.href.replace( rhash, "" );
12905
			locationUrl = location.href.replace( rhash, "" );
12906
 
12907
			// decoding may throw an error if the URL isn't UTF-8 (#9518)
12908
			try {
12909
				anchorUrl = decodeURIComponent( anchorUrl );
12910
			} catch ( error ) {}
12911
			try {
12912
				locationUrl = decodeURIComponent( locationUrl );
12913
			} catch ( error ) {}
12914
 
12915
			return anchor.hash.length > 1 && anchorUrl === locationUrl;
12916
		};
12917
	})(),
12918
 
12919
	_create: function() {
12920
		var that = this,
12921
			options = this.options;
12922
 
12923
		this.running = false;
12924
 
12925
		this.element
12926
			.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
12927
			.toggleClass( "ui-tabs-collapsible", options.collapsible );
12928
 
12929
		this._processTabs();
12930
		options.active = this._initialActive();
12931
 
12932
		// Take disabling tabs via class attribute from HTML
12933
		// into account and update option properly.
12934
		if ( $.isArray( options.disabled ) ) {
12935
			options.disabled = $.unique( options.disabled.concat(
12936
				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
12937
					return that.tabs.index( li );
12938
				})
12939
			) ).sort();
12940
		}
12941
 
12942
		// check for length avoids error when initializing empty list
12943
		if ( this.options.active !== false && this.anchors.length ) {
12944
			this.active = this._findActive( options.active );
12945
		} else {
12946
			this.active = $();
12947
		}
12948
 
12949
		this._refresh();
12950
 
12951
		if ( this.active.length ) {
12952
			this.load( options.active );
12953
		}
12954
	},
12955
 
12956
	_initialActive: function() {
12957
		var active = this.options.active,
12958
			collapsible = this.options.collapsible,
12959
			locationHash = location.hash.substring( 1 );
12960
 
12961
		if ( active === null ) {
12962
			// check the fragment identifier in the URL
12963
			if ( locationHash ) {
12964
				this.tabs.each(function( i, tab ) {
12965
					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
12966
						active = i;
12967
						return false;
12968
					}
12969
				});
12970
			}
12971
 
12972
			// check for a tab marked active via a class
12973
			if ( active === null ) {
12974
				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
12975
			}
12976
 
12977
			// no active tab, set to false
12978
			if ( active === null || active === -1 ) {
12979
				active = this.tabs.length ? 0 : false;
12980
			}
12981
		}
12982
 
12983
		// handle numbers: negative, out of range
12984
		if ( active !== false ) {
12985
			active = this.tabs.index( this.tabs.eq( active ) );
12986
			if ( active === -1 ) {
12987
				active = collapsible ? false : 0;
12988
			}
12989
		}
12990
 
12991
		// don't allow collapsible: false and active: false
12992
		if ( !collapsible && active === false && this.anchors.length ) {
12993
			active = 0;
12994
		}
12995
 
12996
		return active;
12997
	},
12998
 
12999
	_getCreateEventData: function() {
13000
		return {
13001
			tab: this.active,
13002
			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
13003
		};
13004
	},
13005
 
13006
	_tabKeydown: function( event ) {
13007
		var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
13008
			selectedIndex = this.tabs.index( focusedTab ),
13009
			goingForward = true;
13010
 
13011
		if ( this._handlePageNav( event ) ) {
13012
			return;
13013
		}
13014
 
13015
		switch ( event.keyCode ) {
13016
			case $.ui.keyCode.RIGHT:
13017
			case $.ui.keyCode.DOWN:
13018
				selectedIndex++;
13019
				break;
13020
			case $.ui.keyCode.UP:
13021
			case $.ui.keyCode.LEFT:
13022
				goingForward = false;
13023
				selectedIndex--;
13024
				break;
13025
			case $.ui.keyCode.END:
13026
				selectedIndex = this.anchors.length - 1;
13027
				break;
13028
			case $.ui.keyCode.HOME:
13029
				selectedIndex = 0;
13030
				break;
13031
			case $.ui.keyCode.SPACE:
13032
				// Activate only, no collapsing
13033
				event.preventDefault();
13034
				clearTimeout( this.activating );
13035
				this._activate( selectedIndex );
13036
				return;
13037
			case $.ui.keyCode.ENTER:
13038
				// Toggle (cancel delayed activation, allow collapsing)
13039
				event.preventDefault();
13040
				clearTimeout( this.activating );
13041
				// Determine if we should collapse or activate
13042
				this._activate( selectedIndex === this.options.active ? false : selectedIndex );
13043
				return;
13044
			default:
13045
				return;
13046
		}
13047
 
13048
		// Focus the appropriate tab, based on which key was pressed
13049
		event.preventDefault();
13050
		clearTimeout( this.activating );
13051
		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
13052
 
13053
		// Navigating with control/command key will prevent automatic activation
13054
		if ( !event.ctrlKey && !event.metaKey ) {
13055
 
13056
			// Update aria-selected immediately so that AT think the tab is already selected.
13057
			// Otherwise AT may confuse the user by stating that they need to activate the tab,
13058
			// but the tab will already be activated by the time the announcement finishes.
13059
			focusedTab.attr( "aria-selected", "false" );
13060
			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
13061
 
13062
			this.activating = this._delay(function() {
13063
				this.option( "active", selectedIndex );
13064
			}, this.delay );
13065
		}
13066
	},
13067
 
13068
	_panelKeydown: function( event ) {
13069
		if ( this._handlePageNav( event ) ) {
13070
			return;
13071
		}
13072
 
13073
		// Ctrl+up moves focus to the current tab
13074
		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
13075
			event.preventDefault();
13076
			this.active.focus();
13077
		}
13078
	},
13079
 
13080
	// Alt+page up/down moves focus to the previous/next tab (and activates)
13081
	_handlePageNav: function( event ) {
13082
		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
13083
			this._activate( this._focusNextTab( this.options.active - 1, false ) );
13084
			return true;
13085
		}
13086
		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
13087
			this._activate( this._focusNextTab( this.options.active + 1, true ) );
13088
			return true;
13089
		}
13090
	},
13091
 
13092
	_findNextTab: function( index, goingForward ) {
13093
		var lastTabIndex = this.tabs.length - 1;
13094
 
13095
		function constrain() {
13096
			if ( index > lastTabIndex ) {
13097
				index = 0;
13098
			}
13099
			if ( index < 0 ) {
13100
				index = lastTabIndex;
13101
			}
13102
			return index;
13103
		}
13104
 
13105
		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
13106
			index = goingForward ? index + 1 : index - 1;
13107
		}
13108
 
13109
		return index;
13110
	},
13111
 
13112
	_focusNextTab: function( index, goingForward ) {
13113
		index = this._findNextTab( index, goingForward );
13114
		this.tabs.eq( index ).focus();
13115
		return index;
13116
	},
13117
 
13118
	_setOption: function( key, value ) {
13119
		if ( key === "active" ) {
13120
			// _activate() will handle invalid values and update this.options
13121
			this._activate( value );
13122
			return;
13123
		}
13124
 
13125
		if ( key === "disabled" ) {
13126
			// don't use the widget factory's disabled handling
13127
			this._setupDisabled( value );
13128
			return;
13129
		}
13130
 
13131
		this._super( key, value);
13132
 
13133
		if ( key === "collapsible" ) {
13134
			this.element.toggleClass( "ui-tabs-collapsible", value );
13135
			// Setting collapsible: false while collapsed; open first panel
13136
			if ( !value && this.options.active === false ) {
13137
				this._activate( 0 );
13138
			}
13139
		}
13140
 
13141
		if ( key === "event" ) {
13142
			this._setupEvents( value );
13143
		}
13144
 
13145
		if ( key === "heightStyle" ) {
13146
			this._setupHeightStyle( value );
13147
		}
13148
	},
13149
 
13150
	_sanitizeSelector: function( hash ) {
13151
		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
13152
	},
13153
 
13154
	refresh: function() {
13155
		var options = this.options,
13156
			lis = this.tablist.children( ":has(a[href])" );
13157
 
13158
		// get disabled tabs from class attribute from HTML
13159
		// this will get converted to a boolean if needed in _refresh()
13160
		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
13161
			return lis.index( tab );
13162
		});
13163
 
13164
		this._processTabs();
13165
 
13166
		// was collapsed or no tabs
13167
		if ( options.active === false || !this.anchors.length ) {
13168
			options.active = false;
13169
			this.active = $();
13170
		// was active, but active tab is gone
13171
		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
13172
			// all remaining tabs are disabled
13173
			if ( this.tabs.length === options.disabled.length ) {
13174
				options.active = false;
13175
				this.active = $();
13176
			// activate previous tab
13177
			} else {
13178
				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
13179
			}
13180
		// was active, active tab still exists
13181
		} else {
13182
			// make sure active index is correct
13183
			options.active = this.tabs.index( this.active );
13184
		}
13185
 
13186
		this._refresh();
13187
	},
13188
 
13189
	_refresh: function() {
13190
		this._setupDisabled( this.options.disabled );
13191
		this._setupEvents( this.options.event );
13192
		this._setupHeightStyle( this.options.heightStyle );
13193
 
13194
		this.tabs.not( this.active ).attr({
13195
			"aria-selected": "false",
13196
			"aria-expanded": "false",
13197
			tabIndex: -1
13198
		});
13199
		this.panels.not( this._getPanelForTab( this.active ) )
13200
			.hide()
13201
			.attr({
13202
				"aria-hidden": "true"
13203
			});
13204
 
13205
		// Make sure one tab is in the tab order
13206
		if ( !this.active.length ) {
13207
			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
13208
		} else {
13209
			this.active
13210
				.addClass( "ui-tabs-active ui-state-active" )
13211
				.attr({
13212
					"aria-selected": "true",
13213
					"aria-expanded": "true",
13214
					tabIndex: 0
13215
				});
13216
			this._getPanelForTab( this.active )
13217
				.show()
13218
				.attr({
13219
					"aria-hidden": "false"
13220
				});
13221
		}
13222
	},
13223
 
13224
	_processTabs: function() {
13225
		var that = this,
13226
			prevTabs = this.tabs,
13227
			prevAnchors = this.anchors,
13228
			prevPanels = this.panels;
13229
 
13230
		this.tablist = this._getList()
13231
			.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
13232
			.attr( "role", "tablist" )
13233
 
13234
			// Prevent users from focusing disabled tabs via click
13235
			.delegate( "> li", "mousedown" + this.eventNamespace, function( event ) {
13236
				if ( $( this ).is( ".ui-state-disabled" ) ) {
13237
					event.preventDefault();
13238
				}
13239
			})
13240
 
13241
			// support: IE <9
13242
			// Preventing the default action in mousedown doesn't prevent IE
13243
			// from focusing the element, so if the anchor gets focused, blur.
13244
			// We don't have to worry about focusing the previously focused
13245
			// element since clicking on a non-focusable element should focus
13246
			// the body anyway.
13247
			.delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
13248
				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
13249
					this.blur();
13250
				}
13251
			});
13252
 
13253
		this.tabs = this.tablist.find( "> li:has(a[href])" )
13254
			.addClass( "ui-state-default ui-corner-top" )
13255
			.attr({
13256
				role: "tab",
13257
				tabIndex: -1
13258
			});
13259
 
13260
		this.anchors = this.tabs.map(function() {
13261
				return $( "a", this )[ 0 ];
13262
			})
13263
			.addClass( "ui-tabs-anchor" )
13264
			.attr({
13265
				role: "presentation",
13266
				tabIndex: -1
13267
			});
13268
 
13269
		this.panels = $();
13270
 
13271
		this.anchors.each(function( i, anchor ) {
13272
			var selector, panel, panelId,
13273
				anchorId = $( anchor ).uniqueId().attr( "id" ),
13274
				tab = $( anchor ).closest( "li" ),
13275
				originalAriaControls = tab.attr( "aria-controls" );
13276
 
13277
			// inline tab
13278
			if ( that._isLocal( anchor ) ) {
13279
				selector = anchor.hash;
13280
				panelId = selector.substring( 1 );
13281
				panel = that.element.find( that._sanitizeSelector( selector ) );
13282
			// remote tab
13283
			} else {
13284
				// If the tab doesn't already have aria-controls,
13285
				// generate an id by using a throw-away element
13286
				panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
13287
				selector = "#" + panelId;
13288
				panel = that.element.find( selector );
13289
				if ( !panel.length ) {
13290
					panel = that._createPanel( panelId );
13291
					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
13292
				}
13293
				panel.attr( "aria-live", "polite" );
13294
			}
13295
 
13296
			if ( panel.length) {
13297
				that.panels = that.panels.add( panel );
13298
			}
13299
			if ( originalAriaControls ) {
13300
				tab.data( "ui-tabs-aria-controls", originalAriaControls );
13301
			}
13302
			tab.attr({
13303
				"aria-controls": panelId,
13304
				"aria-labelledby": anchorId
13305
			});
13306
			panel.attr( "aria-labelledby", anchorId );
13307
		});
13308
 
13309
		this.panels
13310
			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
13311
			.attr( "role", "tabpanel" );
13312
 
13313
		// Avoid memory leaks (#10056)
13314
		if ( prevTabs ) {
13315
			this._off( prevTabs.not( this.tabs ) );
13316
			this._off( prevAnchors.not( this.anchors ) );
13317
			this._off( prevPanels.not( this.panels ) );
13318
		}
13319
	},
13320
 
13321
	// allow overriding how to find the list for rare usage scenarios (#7715)
13322
	_getList: function() {
13323
		return this.tablist || this.element.find( "ol,ul" ).eq( 0 );
13324
	},
13325
 
13326
	_createPanel: function( id ) {
13327
		return $( "<div>" )
13328
			.attr( "id", id )
13329
			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
13330
			.data( "ui-tabs-destroy", true );
13331
	},
13332
 
13333
	_setupDisabled: function( disabled ) {
13334
		if ( $.isArray( disabled ) ) {
13335
			if ( !disabled.length ) {
13336
				disabled = false;
13337
			} else if ( disabled.length === this.anchors.length ) {
13338
				disabled = true;
13339
			}
13340
		}
13341
 
13342
		// disable tabs
13343
		for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
13344
			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
13345
				$( li )
13346
					.addClass( "ui-state-disabled" )
13347
					.attr( "aria-disabled", "true" );
13348
			} else {
13349
				$( li )
13350
					.removeClass( "ui-state-disabled" )
13351
					.removeAttr( "aria-disabled" );
13352
			}
13353
		}
13354
 
13355
		this.options.disabled = disabled;
13356
	},
13357
 
13358
	_setupEvents: function( event ) {
13359
		var events = {};
13360
		if ( event ) {
13361
			$.each( event.split(" "), function( index, eventName ) {
13362
				events[ eventName ] = "_eventHandler";
13363
			});
13364
		}
13365
 
13366
		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
13367
		// Always prevent the default action, even when disabled
13368
		this._on( true, this.anchors, {
13369
			click: function( event ) {
13370
				event.preventDefault();
13371
			}
13372
		});
13373
		this._on( this.anchors, events );
13374
		this._on( this.tabs, { keydown: "_tabKeydown" } );
13375
		this._on( this.panels, { keydown: "_panelKeydown" } );
13376
 
13377
		this._focusable( this.tabs );
13378
		this._hoverable( this.tabs );
13379
	},
13380
 
13381
	_setupHeightStyle: function( heightStyle ) {
13382
		var maxHeight,
13383
			parent = this.element.parent();
13384
 
13385
		if ( heightStyle === "fill" ) {
13386
			maxHeight = parent.height();
13387
			maxHeight -= this.element.outerHeight() - this.element.height();
13388
 
13389
			this.element.siblings( ":visible" ).each(function() {
13390
				var elem = $( this ),
13391
					position = elem.css( "position" );
13392
 
13393
				if ( position === "absolute" || position === "fixed" ) {
13394
					return;
13395
				}
13396
				maxHeight -= elem.outerHeight( true );
13397
			});
13398
 
13399
			this.element.children().not( this.panels ).each(function() {
13400
				maxHeight -= $( this ).outerHeight( true );
13401
			});
13402
 
13403
			this.panels.each(function() {
13404
				$( this ).height( Math.max( 0, maxHeight -
13405
					$( this ).innerHeight() + $( this ).height() ) );
13406
			})
13407
			.css( "overflow", "auto" );
13408
		} else if ( heightStyle === "auto" ) {
13409
			maxHeight = 0;
13410
			this.panels.each(function() {
13411
				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
13412
			}).height( maxHeight );
13413
		}
13414
	},
13415
 
13416
	_eventHandler: function( event ) {
13417
		var options = this.options,
13418
			active = this.active,
13419
			anchor = $( event.currentTarget ),
13420
			tab = anchor.closest( "li" ),
13421
			clickedIsActive = tab[ 0 ] === active[ 0 ],
13422
			collapsing = clickedIsActive && options.collapsible,
13423
			toShow = collapsing ? $() : this._getPanelForTab( tab ),
13424
			toHide = !active.length ? $() : this._getPanelForTab( active ),
13425
			eventData = {
13426
				oldTab: active,
13427
				oldPanel: toHide,
13428
				newTab: collapsing ? $() : tab,
13429
				newPanel: toShow
13430
			};
13431
 
13432
		event.preventDefault();
13433
 
13434
		if ( tab.hasClass( "ui-state-disabled" ) ||
13435
				// tab is already loading
13436
				tab.hasClass( "ui-tabs-loading" ) ||
13437
				// can't switch durning an animation
13438
				this.running ||
13439
				// click on active header, but not collapsible
13440
				( clickedIsActive && !options.collapsible ) ||
13441
				// allow canceling activation
13442
				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
13443
			return;
13444
		}
13445
 
13446
		options.active = collapsing ? false : this.tabs.index( tab );
13447
 
13448
		this.active = clickedIsActive ? $() : tab;
13449
		if ( this.xhr ) {
13450
			this.xhr.abort();
13451
		}
13452
 
13453
		if ( !toHide.length && !toShow.length ) {
13454
			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
13455
		}
13456
 
13457
		if ( toShow.length ) {
13458
			this.load( this.tabs.index( tab ), event );
13459
		}
13460
		this._toggle( event, eventData );
13461
	},
13462
 
13463
	// handles show/hide for selecting tabs
13464
	_toggle: function( event, eventData ) {
13465
		var that = this,
13466
			toShow = eventData.newPanel,
13467
			toHide = eventData.oldPanel;
13468
 
13469
		this.running = true;
13470
 
13471
		function complete() {
13472
			that.running = false;
13473
			that._trigger( "activate", event, eventData );
13474
		}
13475
 
13476
		function show() {
13477
			eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
13478
 
13479
			if ( toShow.length && that.options.show ) {
13480
				that._show( toShow, that.options.show, complete );
13481
			} else {
13482
				toShow.show();
13483
				complete();
13484
			}
13485
		}
13486
 
13487
		// start out by hiding, then showing, then completing
13488
		if ( toHide.length && this.options.hide ) {
13489
			this._hide( toHide, this.options.hide, function() {
13490
				eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
13491
				show();
13492
			});
13493
		} else {
13494
			eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
13495
			toHide.hide();
13496
			show();
13497
		}
13498
 
13499
		toHide.attr( "aria-hidden", "true" );
13500
		eventData.oldTab.attr({
13501
			"aria-selected": "false",
13502
			"aria-expanded": "false"
13503
		});
13504
		// If we're switching tabs, remove the old tab from the tab order.
13505
		// If we're opening from collapsed state, remove the previous tab from the tab order.
13506
		// If we're collapsing, then keep the collapsing tab in the tab order.
13507
		if ( toShow.length && toHide.length ) {
13508
			eventData.oldTab.attr( "tabIndex", -1 );
13509
		} else if ( toShow.length ) {
13510
			this.tabs.filter(function() {
13511
				return $( this ).attr( "tabIndex" ) === 0;
13512
			})
13513
			.attr( "tabIndex", -1 );
13514
		}
13515
 
13516
		toShow.attr( "aria-hidden", "false" );
13517
		eventData.newTab.attr({
13518
			"aria-selected": "true",
13519
			"aria-expanded": "true",
13520
			tabIndex: 0
13521
		});
13522
	},
13523
 
13524
	_activate: function( index ) {
13525
		var anchor,
13526
			active = this._findActive( index );
13527
 
13528
		// trying to activate the already active panel
13529
		if ( active[ 0 ] === this.active[ 0 ] ) {
13530
			return;
13531
		}
13532
 
13533
		// trying to collapse, simulate a click on the current active header
13534
		if ( !active.length ) {
13535
			active = this.active;
13536
		}
13537
 
13538
		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
13539
		this._eventHandler({
13540
			target: anchor,
13541
			currentTarget: anchor,
13542
			preventDefault: $.noop
13543
		});
13544
	},
13545
 
13546
	_findActive: function( index ) {
13547
		return index === false ? $() : this.tabs.eq( index );
13548
	},
13549
 
13550
	_getIndex: function( index ) {
13551
		// meta-function to give users option to provide a href string instead of a numerical index.
13552
		if ( typeof index === "string" ) {
13553
			index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
13554
		}
13555
 
13556
		return index;
13557
	},
13558
 
13559
	_destroy: function() {
13560
		if ( this.xhr ) {
13561
			this.xhr.abort();
13562
		}
13563
 
13564
		this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
13565
 
13566
		this.tablist
13567
			.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
13568
			.removeAttr( "role" );
13569
 
13570
		this.anchors
13571
			.removeClass( "ui-tabs-anchor" )
13572
			.removeAttr( "role" )
13573
			.removeAttr( "tabIndex" )
13574
			.removeUniqueId();
13575
 
13576
		this.tablist.unbind( this.eventNamespace );
13577
 
13578
		this.tabs.add( this.panels ).each(function() {
13579
			if ( $.data( this, "ui-tabs-destroy" ) ) {
13580
				$( this ).remove();
13581
			} else {
13582
				$( this )
13583
					.removeClass( "ui-state-default ui-state-active ui-state-disabled " +
13584
						"ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
13585
					.removeAttr( "tabIndex" )
13586
					.removeAttr( "aria-live" )
13587
					.removeAttr( "aria-busy" )
13588
					.removeAttr( "aria-selected" )
13589
					.removeAttr( "aria-labelledby" )
13590
					.removeAttr( "aria-hidden" )
13591
					.removeAttr( "aria-expanded" )
13592
					.removeAttr( "role" );
13593
			}
13594
		});
13595
 
13596
		this.tabs.each(function() {
13597
			var li = $( this ),
13598
				prev = li.data( "ui-tabs-aria-controls" );
13599
			if ( prev ) {
13600
				li
13601
					.attr( "aria-controls", prev )
13602
					.removeData( "ui-tabs-aria-controls" );
13603
			} else {
13604
				li.removeAttr( "aria-controls" );
13605
			}
13606
		});
13607
 
13608
		this.panels.show();
13609
 
13610
		if ( this.options.heightStyle !== "content" ) {
13611
			this.panels.css( "height", "" );
13612
		}
13613
	},
13614
 
13615
	enable: function( index ) {
13616
		var disabled = this.options.disabled;
13617
		if ( disabled === false ) {
13618
			return;
13619
		}
13620
 
13621
		if ( index === undefined ) {
13622
			disabled = false;
13623
		} else {
13624
			index = this._getIndex( index );
13625
			if ( $.isArray( disabled ) ) {
13626
				disabled = $.map( disabled, function( num ) {
13627
					return num !== index ? num : null;
13628
				});
13629
			} else {
13630
				disabled = $.map( this.tabs, function( li, num ) {
13631
					return num !== index ? num : null;
13632
				});
13633
			}
13634
		}
13635
		this._setupDisabled( disabled );
13636
	},
13637
 
13638
	disable: function( index ) {
13639
		var disabled = this.options.disabled;
13640
		if ( disabled === true ) {
13641
			return;
13642
		}
13643
 
13644
		if ( index === undefined ) {
13645
			disabled = true;
13646
		} else {
13647
			index = this._getIndex( index );
13648
			if ( $.inArray( index, disabled ) !== -1 ) {
13649
				return;
13650
			}
13651
			if ( $.isArray( disabled ) ) {
13652
				disabled = $.merge( [ index ], disabled ).sort();
13653
			} else {
13654
				disabled = [ index ];
13655
			}
13656
		}
13657
		this._setupDisabled( disabled );
13658
	},
13659
 
13660
	load: function( index, event ) {
13661
		index = this._getIndex( index );
13662
		var that = this,
13663
			tab = this.tabs.eq( index ),
13664
			anchor = tab.find( ".ui-tabs-anchor" ),
13665
			panel = this._getPanelForTab( tab ),
13666
			eventData = {
13667
				tab: tab,
13668
				panel: panel
13669
			},
13670
			complete = function( jqXHR, status ) {
13671
				if ( status === "abort" ) {
13672
					that.panels.stop( false, true );
13673
				}
13674
 
13675
				tab.removeClass( "ui-tabs-loading" );
13676
				panel.removeAttr( "aria-busy" );
13677
 
13678
				if ( jqXHR === that.xhr ) {
13679
					delete that.xhr;
13680
				}
13681
			};
13682
 
13683
		// not remote
13684
		if ( this._isLocal( anchor[ 0 ] ) ) {
13685
			return;
13686
		}
13687
 
13688
		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
13689
 
13690
		// support: jQuery <1.8
13691
		// jQuery <1.8 returns false if the request is canceled in beforeSend,
13692
		// but as of 1.8, $.ajax() always returns a jqXHR object.
13693
		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
13694
			tab.addClass( "ui-tabs-loading" );
13695
			panel.attr( "aria-busy", "true" );
13696
 
13697
			this.xhr
13698
				.done(function( response, status, jqXHR ) {
13699
					// support: jQuery <1.8
13700
					// http://bugs.jquery.com/ticket/11778
13701
					setTimeout(function() {
13702
						panel.html( response );
13703
						that._trigger( "load", event, eventData );
13704
 
13705
						complete( jqXHR, status );
13706
					}, 1 );
13707
				})
13708
				.fail(function( jqXHR, status ) {
13709
					// support: jQuery <1.8
13710
					// http://bugs.jquery.com/ticket/11778
13711
					setTimeout(function() {
13712
						complete( jqXHR, status );
13713
					}, 1 );
13714
				});
13715
		}
13716
	},
13717
 
13718
	_ajaxSettings: function( anchor, event, eventData ) {
13719
		var that = this;
13720
		return {
13721
			url: anchor.attr( "href" ),
13722
			beforeSend: function( jqXHR, settings ) {
13723
				return that._trigger( "beforeLoad", event,
13724
					$.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
13725
			}
13726
		};
13727
	},
13728
 
13729
	_getPanelForTab: function( tab ) {
13730
		var id = $( tab ).attr( "aria-controls" );
13731
		return this.element.find( this._sanitizeSelector( "#" + id ) );
13732
	}
13733
});
13734
 
13735
 
13736
/*!
13737
 * jQuery UI Tooltip 1.11.4
13738
 * http://jqueryui.com
13739
 *
13740
 * Copyright jQuery Foundation and other contributors
13741
 * Released under the MIT license.
13742
 * http://jquery.org/license
13743
 *
13744
 * http://api.jqueryui.com/tooltip/
13745
 */
13746
 
13747
 
13748
var tooltip = $.widget( "ui.tooltip", {
13749
	version: "1.11.4",
13750
	options: {
13751
		content: function() {
13752
			// support: IE<9, Opera in jQuery <1.7
13753
			// .text() can't accept undefined, so coerce to a string
13754
			var title = $( this ).attr( "title" ) || "";
13755
			// Escape title, since we're going from an attribute to raw HTML
13756
			return $( "<a>" ).text( title ).html();
13757
		},
13758
		hide: true,
13759
		// Disabled elements have inconsistent behavior across browsers (#8661)
13760
		items: "[title]:not([disabled])",
13761
		position: {
13762
			my: "left top+15",
13763
			at: "left bottom",
13764
			collision: "flipfit flip"
13765
		},
13766
		show: true,
13767
		tooltipClass: null,
13768
		track: false,
13769
 
13770
		// callbacks
13771
		close: null,
13772
		open: null
13773
	},
13774
 
13775
	_addDescribedBy: function( elem, id ) {
13776
		var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
13777
		describedby.push( id );
13778
		elem
13779
			.data( "ui-tooltip-id", id )
13780
			.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
13781
	},
13782
 
13783
	_removeDescribedBy: function( elem ) {
13784
		var id = elem.data( "ui-tooltip-id" ),
13785
			describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
13786
			index = $.inArray( id, describedby );
13787
 
13788
		if ( index !== -1 ) {
13789
			describedby.splice( index, 1 );
13790
		}
13791
 
13792
		elem.removeData( "ui-tooltip-id" );
13793
		describedby = $.trim( describedby.join( " " ) );
13794
		if ( describedby ) {
13795
			elem.attr( "aria-describedby", describedby );
13796
		} else {
13797
			elem.removeAttr( "aria-describedby" );
13798
		}
13799
	},
13800
 
13801
	_create: function() {
13802
		this._on({
13803
			mouseover: "open",
13804
			focusin: "open"
13805
		});
13806
 
13807
		// IDs of generated tooltips, needed for destroy
13808
		this.tooltips = {};
13809
 
13810
		// IDs of parent tooltips where we removed the title attribute
13811
		this.parents = {};
13812
 
13813
		if ( this.options.disabled ) {
13814
			this._disable();
13815
		}
13816
 
13817
		// Append the aria-live region so tooltips announce correctly
13818
		this.liveRegion = $( "<div>" )
13819
			.attr({
13820
				role: "log",
13821
				"aria-live": "assertive",
13822
				"aria-relevant": "additions"
13823
			})
13824
			.addClass( "ui-helper-hidden-accessible" )
13825
			.appendTo( this.document[ 0 ].body );
13826
	},
13827
 
13828
	_setOption: function( key, value ) {
13829
		var that = this;
13830
 
13831
		if ( key === "disabled" ) {
13832
			this[ value ? "_disable" : "_enable" ]();
13833
			this.options[ key ] = value;
13834
			// disable element style changes
13835
			return;
13836
		}
13837
 
13838
		this._super( key, value );
13839
 
13840
		if ( key === "content" ) {
13841
			$.each( this.tooltips, function( id, tooltipData ) {
13842
				that._updateContent( tooltipData.element );
13843
			});
13844
		}
13845
	},
13846
 
13847
	_disable: function() {
13848
		var that = this;
13849
 
13850
		// close open tooltips
13851
		$.each( this.tooltips, function( id, tooltipData ) {
13852
			var event = $.Event( "blur" );
13853
			event.target = event.currentTarget = tooltipData.element[ 0 ];
13854
			that.close( event, true );
13855
		});
13856
 
13857
		// remove title attributes to prevent native tooltips
13858
		this.element.find( this.options.items ).addBack().each(function() {
13859
			var element = $( this );
13860
			if ( element.is( "[title]" ) ) {
13861
				element
13862
					.data( "ui-tooltip-title", element.attr( "title" ) )
13863
					.removeAttr( "title" );
13864
			}
13865
		});
13866
	},
13867
 
13868
	_enable: function() {
13869
		// restore title attributes
13870
		this.element.find( this.options.items ).addBack().each(function() {
13871
			var element = $( this );
13872
			if ( element.data( "ui-tooltip-title" ) ) {
13873
				element.attr( "title", element.data( "ui-tooltip-title" ) );
13874
			}
13875
		});
13876
	},
13877
 
13878
	open: function( event ) {
13879
		var that = this,
13880
			target = $( event ? event.target : this.element )
13881
				// we need closest here due to mouseover bubbling,
13882
				// but always pointing at the same event target
13883
				.closest( this.options.items );
13884
 
13885
		// No element to show a tooltip for or the tooltip is already open
13886
		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
13887
			return;
13888
		}
13889
 
13890
		if ( target.attr( "title" ) ) {
13891
			target.data( "ui-tooltip-title", target.attr( "title" ) );
13892
		}
13893
 
13894
		target.data( "ui-tooltip-open", true );
13895
 
13896
		// kill parent tooltips, custom or native, for hover
13897
		if ( event && event.type === "mouseover" ) {
13898
			target.parents().each(function() {
13899
				var parent = $( this ),
13900
					blurEvent;
13901
				if ( parent.data( "ui-tooltip-open" ) ) {
13902
					blurEvent = $.Event( "blur" );
13903
					blurEvent.target = blurEvent.currentTarget = this;
13904
					that.close( blurEvent, true );
13905
				}
13906
				if ( parent.attr( "title" ) ) {
13907
					parent.uniqueId();
13908
					that.parents[ this.id ] = {
13909
						element: this,
13910
						title: parent.attr( "title" )
13911
					};
13912
					parent.attr( "title", "" );
13913
				}
13914
			});
13915
		}
13916
 
13917
		this._registerCloseHandlers( event, target );
13918
		this._updateContent( target, event );
13919
	},
13920
 
13921
	_updateContent: function( target, event ) {
13922
		var content,
13923
			contentOption = this.options.content,
13924
			that = this,
13925
			eventType = event ? event.type : null;
13926
 
13927
		if ( typeof contentOption === "string" ) {
13928
			return this._open( event, target, contentOption );
13929
		}
13930
 
13931
		content = contentOption.call( target[0], function( response ) {
13932
 
13933
			// IE may instantly serve a cached response for ajax requests
13934
			// delay this call to _open so the other call to _open runs first
13935
			that._delay(function() {
13936
 
13937
				// Ignore async response if tooltip was closed already
13938
				if ( !target.data( "ui-tooltip-open" ) ) {
13939
					return;
13940
				}
13941
 
13942
				// jQuery creates a special event for focusin when it doesn't
13943
				// exist natively. To improve performance, the native event
13944
				// object is reused and the type is changed. Therefore, we can't
13945
				// rely on the type being correct after the event finished
13946
				// bubbling, so we set it back to the previous value. (#8740)
13947
				if ( event ) {
13948
					event.type = eventType;
13949
				}
13950
				this._open( event, target, response );
13951
			});
13952
		});
13953
		if ( content ) {
13954
			this._open( event, target, content );
13955
		}
13956
	},
13957
 
13958
	_open: function( event, target, content ) {
13959
		var tooltipData, tooltip, delayedShow, a11yContent,
13960
			positionOption = $.extend( {}, this.options.position );
13961
 
13962
		if ( !content ) {
13963
			return;
13964
		}
13965
 
13966
		// Content can be updated multiple times. If the tooltip already
13967
		// exists, then just update the content and bail.
13968
		tooltipData = this._find( target );
13969
		if ( tooltipData ) {
13970
			tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
13971
			return;
13972
		}
13973
 
13974
		// if we have a title, clear it to prevent the native tooltip
13975
		// we have to check first to avoid defining a title if none exists
13976
		// (we don't want to cause an element to start matching [title])
13977
		//
13978
		// We use removeAttr only for key events, to allow IE to export the correct
13979
		// accessible attributes. For mouse events, set to empty string to avoid
13980
		// native tooltip showing up (happens only when removing inside mouseover).
13981
		if ( target.is( "[title]" ) ) {
13982
			if ( event && event.type === "mouseover" ) {
13983
				target.attr( "title", "" );
13984
			} else {
13985
				target.removeAttr( "title" );
13986
			}
13987
		}
13988
 
13989
		tooltipData = this._tooltip( target );
13990
		tooltip = tooltipData.tooltip;
13991
		this._addDescribedBy( target, tooltip.attr( "id" ) );
13992
		tooltip.find( ".ui-tooltip-content" ).html( content );
13993
 
13994
		// Support: Voiceover on OS X, JAWS on IE <= 9
13995
		// JAWS announces deletions even when aria-relevant="additions"
13996
		// Voiceover will sometimes re-read the entire log region's contents from the beginning
13997
		this.liveRegion.children().hide();
13998
		if ( content.clone ) {
13999
			a11yContent = content.clone();
14000
			a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
14001
		} else {
14002
			a11yContent = content;
14003
		}
14004
		$( "<div>" ).html( a11yContent ).appendTo( this.liveRegion );
14005
 
14006
		function position( event ) {
14007
			positionOption.of = event;
14008
			if ( tooltip.is( ":hidden" ) ) {
14009
				return;
14010
			}
14011
			tooltip.position( positionOption );
14012
		}
14013
		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
14014
			this._on( this.document, {
14015
				mousemove: position
14016
			});
14017
			// trigger once to override element-relative positioning
14018
			position( event );
14019
		} else {
14020
			tooltip.position( $.extend({
14021
				of: target
14022
			}, this.options.position ) );
14023
		}
14024
 
14025
		tooltip.hide();
14026
 
14027
		this._show( tooltip, this.options.show );
14028
		// Handle tracking tooltips that are shown with a delay (#8644). As soon
14029
		// as the tooltip is visible, position the tooltip using the most recent
14030
		// event.
14031
		if ( this.options.show && this.options.show.delay ) {
14032
			delayedShow = this.delayedShow = setInterval(function() {
14033
				if ( tooltip.is( ":visible" ) ) {
14034
					position( positionOption.of );
14035
					clearInterval( delayedShow );
14036
				}
14037
			}, $.fx.interval );
14038
		}
14039
 
14040
		this._trigger( "open", event, { tooltip: tooltip } );
14041
	},
14042
 
14043
	_registerCloseHandlers: function( event, target ) {
14044
		var events = {
14045
			keyup: function( event ) {
14046
				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
14047
					var fakeEvent = $.Event(event);
14048
					fakeEvent.currentTarget = target[0];
14049
					this.close( fakeEvent, true );
14050
				}
14051
			}
14052
		};
14053
 
14054
		// Only bind remove handler for delegated targets. Non-delegated
14055
		// tooltips will handle this in destroy.
14056
		if ( target[ 0 ] !== this.element[ 0 ] ) {
14057
			events.remove = function() {
14058
				this._removeTooltip( this._find( target ).tooltip );
14059
			};
14060
		}
14061
 
14062
		if ( !event || event.type === "mouseover" ) {
14063
			events.mouseleave = "close";
14064
		}
14065
		if ( !event || event.type === "focusin" ) {
14066
			events.focusout = "close";
14067
		}
14068
		this._on( true, target, events );
14069
	},
14070
 
14071
	close: function( event ) {
14072
		var tooltip,
14073
			that = this,
14074
			target = $( event ? event.currentTarget : this.element ),
14075
			tooltipData = this._find( target );
14076
 
14077
		// The tooltip may already be closed
14078
		if ( !tooltipData ) {
14079
 
14080
			// We set ui-tooltip-open immediately upon open (in open()), but only set the
14081
			// additional data once there's actually content to show (in _open()). So even if the
14082
			// tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
14083
			// the period between open() and _open().
14084
			target.removeData( "ui-tooltip-open" );
14085
			return;
14086
		}
14087
 
14088
		tooltip = tooltipData.tooltip;
14089
 
14090
		// disabling closes the tooltip, so we need to track when we're closing
14091
		// to avoid an infinite loop in case the tooltip becomes disabled on close
14092
		if ( tooltipData.closing ) {
14093
			return;
14094
		}
14095
 
14096
		// Clear the interval for delayed tracking tooltips
14097
		clearInterval( this.delayedShow );
14098
 
14099
		// only set title if we had one before (see comment in _open())
14100
		// If the title attribute has changed since open(), don't restore
14101
		if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
14102
			target.attr( "title", target.data( "ui-tooltip-title" ) );
14103
		}
14104
 
14105
		this._removeDescribedBy( target );
14106
 
14107
		tooltipData.hiding = true;
14108
		tooltip.stop( true );
14109
		this._hide( tooltip, this.options.hide, function() {
14110
			that._removeTooltip( $( this ) );
14111
		});
14112
 
14113
		target.removeData( "ui-tooltip-open" );
14114
		this._off( target, "mouseleave focusout keyup" );
14115
 
14116
		// Remove 'remove' binding only on delegated targets
14117
		if ( target[ 0 ] !== this.element[ 0 ] ) {
14118
			this._off( target, "remove" );
14119
		}
14120
		this._off( this.document, "mousemove" );
14121
 
14122
		if ( event && event.type === "mouseleave" ) {
14123
			$.each( this.parents, function( id, parent ) {
14124
				$( parent.element ).attr( "title", parent.title );
14125
				delete that.parents[ id ];
14126
			});
14127
		}
14128
 
14129
		tooltipData.closing = true;
14130
		this._trigger( "close", event, { tooltip: tooltip } );
14131
		if ( !tooltipData.hiding ) {
14132
			tooltipData.closing = false;
14133
		}
14134
	},
14135
 
14136
	_tooltip: function( element ) {
14137
		var tooltip = $( "<div>" )
14138
				.attr( "role", "tooltip" )
14139
				.addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
14140
					( this.options.tooltipClass || "" ) ),
14141
			id = tooltip.uniqueId().attr( "id" );
14142
 
14143
		$( "<div>" )
14144
			.addClass( "ui-tooltip-content" )
14145
			.appendTo( tooltip );
14146
 
14147
		tooltip.appendTo( this.document[0].body );
14148
 
14149
		return this.tooltips[ id ] = {
14150
			element: element,
14151
			tooltip: tooltip
14152
		};
14153
	},
14154
 
14155
	_find: function( target ) {
14156
		var id = target.data( "ui-tooltip-id" );
14157
		return id ? this.tooltips[ id ] : null;
14158
	},
14159
 
14160
	_removeTooltip: function( tooltip ) {
14161
		tooltip.remove();
14162
		delete this.tooltips[ tooltip.attr( "id" ) ];
14163
	},
14164
 
14165
	_destroy: function() {
14166
		var that = this;
14167
 
14168
		// close open tooltips
14169
		$.each( this.tooltips, function( id, tooltipData ) {
14170
			// Delegate to close method to handle common cleanup
14171
			var event = $.Event( "blur" ),
14172
				element = tooltipData.element;
14173
			event.target = event.currentTarget = element[ 0 ];
14174
			that.close( event, true );
14175
 
14176
			// Remove immediately; destroying an open tooltip doesn't use the
14177
			// hide animation
14178
			$( "#" + id ).remove();
14179
 
14180
			// Restore the title
14181
			if ( element.data( "ui-tooltip-title" ) ) {
14182
				// If the title attribute has changed since open(), don't restore
14183
				if ( !element.attr( "title" ) ) {
14184
					element.attr( "title", element.data( "ui-tooltip-title" ) );
14185
				}
14186
				element.removeData( "ui-tooltip-title" );
14187
			}
14188
		});
14189
		this.liveRegion.remove();
14190
	}
14191
});
14192
 
14193
 
14194
/*!
14195
 * jQuery UI Effects 1.11.4
14196
 * http://jqueryui.com
14197
 *
14198
 * Copyright jQuery Foundation and other contributors
14199
 * Released under the MIT license.
14200
 * http://jquery.org/license
14201
 *
14202
 * http://api.jqueryui.com/category/effects-core/
14203
 */
14204
 
14205
 
14206
var dataSpace = "ui-effects-",
14207
 
14208
	// Create a local jQuery because jQuery Color relies on it and the
14209
	// global may not exist with AMD and a custom build (#10199)
14210
	jQuery = $;
14211
 
14212
$.effects = {
14213
	effect: {}
14214
};
14215
 
14216
/*!
14217
 * jQuery Color Animations v2.1.2
14218
 * https://github.com/jquery/jquery-color
14219
 *
14220
 * Copyright 2014 jQuery Foundation and other contributors
14221
 * Released under the MIT license.
14222
 * http://jquery.org/license
14223
 *
14224
 * Date: Wed Jan 16 08:47:09 2013 -0600
14225
 */
14226
(function( jQuery, undefined ) {
14227
 
14228
	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
14229
 
14230
	// plusequals test for += 100 -= 100
14231
	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
14232
	// a set of RE's that can match strings and generate color tuples.
14233
	stringParsers = [ {
14234
			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
14235
			parse: function( execResult ) {
14236
				return [
14237
					execResult[ 1 ],
14238
					execResult[ 2 ],
14239
					execResult[ 3 ],
14240
					execResult[ 4 ]
14241
				];
14242
			}
14243
		}, {
14244
			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
14245
			parse: function( execResult ) {
14246
				return [
14247
					execResult[ 1 ] * 2.55,
14248
					execResult[ 2 ] * 2.55,
14249
					execResult[ 3 ] * 2.55,
14250
					execResult[ 4 ]
14251
				];
14252
			}
14253
		}, {
14254
			// this regex ignores A-F because it's compared against an already lowercased string
14255
			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
14256
			parse: function( execResult ) {
14257
				return [
14258
					parseInt( execResult[ 1 ], 16 ),
14259
					parseInt( execResult[ 2 ], 16 ),
14260
					parseInt( execResult[ 3 ], 16 )
14261
				];
14262
			}
14263
		}, {
14264
			// this regex ignores A-F because it's compared against an already lowercased string
14265
			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
14266
			parse: function( execResult ) {
14267
				return [
14268
					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
14269
					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
14270
					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
14271
				];
14272
			}
14273
		}, {
14274
			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
14275
			space: "hsla",
14276
			parse: function( execResult ) {
14277
				return [
14278
					execResult[ 1 ],
14279
					execResult[ 2 ] / 100,
14280
					execResult[ 3 ] / 100,
14281
					execResult[ 4 ]
14282
				];
14283
			}
14284
		} ],
14285
 
14286
	// jQuery.Color( )
14287
	color = jQuery.Color = function( color, green, blue, alpha ) {
14288
		return new jQuery.Color.fn.parse( color, green, blue, alpha );
14289
	},
14290
	spaces = {
14291
		rgba: {
14292
			props: {
14293
				red: {
14294
					idx: 0,
14295
					type: "byte"
14296
				},
14297
				green: {
14298
					idx: 1,
14299
					type: "byte"
14300
				},
14301
				blue: {
14302
					idx: 2,
14303
					type: "byte"
14304
				}
14305
			}
14306
		},
14307
 
14308
		hsla: {
14309
			props: {
14310
				hue: {
14311
					idx: 0,
14312
					type: "degrees"
14313
				},
14314
				saturation: {
14315
					idx: 1,
14316
					type: "percent"
14317
				},
14318
				lightness: {
14319
					idx: 2,
14320
					type: "percent"
14321
				}
14322
			}
14323
		}
14324
	},
14325
	propTypes = {
14326
		"byte": {
14327
			floor: true,
14328
			max: 255
14329
		},
14330
		"percent": {
14331
			max: 1
14332
		},
14333
		"degrees": {
14334
			mod: 360,
14335
			floor: true
14336
		}
14337
	},
14338
	support = color.support = {},
14339
 
14340
	// element for support tests
14341
	supportElem = jQuery( "<p>" )[ 0 ],
14342
 
14343
	// colors = jQuery.Color.names
14344
	colors,
14345
 
14346
	// local aliases of functions called often
14347
	each = jQuery.each;
14348
 
14349
// determine rgba support immediately
14350
supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
14351
support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
14352
 
14353
// define cache name and alpha properties
14354
// for rgba and hsla spaces
14355
each( spaces, function( spaceName, space ) {
14356
	space.cache = "_" + spaceName;
14357
	space.props.alpha = {
14358
		idx: 3,
14359
		type: "percent",
14360
		def: 1
14361
	};
14362
});
14363
 
14364
function clamp( value, prop, allowEmpty ) {
14365
	var type = propTypes[ prop.type ] || {};
14366
 
14367
	if ( value == null ) {
14368
		return (allowEmpty || !prop.def) ? null : prop.def;
14369
	}
14370
 
14371
	// ~~ is an short way of doing floor for positive numbers
14372
	value = type.floor ? ~~value : parseFloat( value );
14373
 
14374
	// IE will pass in empty strings as value for alpha,
14375
	// which will hit this case
14376
	if ( isNaN( value ) ) {
14377
		return prop.def;
14378
	}
14379
 
14380
	if ( type.mod ) {
14381
		// we add mod before modding to make sure that negatives values
14382
		// get converted properly: -10 -> 350
14383
		return (value + type.mod) % type.mod;
14384
	}
14385
 
14386
	// for now all property types without mod have min and max
14387
	return 0 > value ? 0 : type.max < value ? type.max : value;
14388
}
14389
 
14390
function stringParse( string ) {
14391
	var inst = color(),
14392
		rgba = inst._rgba = [];
14393
 
14394
	string = string.toLowerCase();
14395
 
14396
	each( stringParsers, function( i, parser ) {
14397
		var parsed,
14398
			match = parser.re.exec( string ),
14399
			values = match && parser.parse( match ),
14400
			spaceName = parser.space || "rgba";
14401
 
14402
		if ( values ) {
14403
			parsed = inst[ spaceName ]( values );
14404
 
14405
			// if this was an rgba parse the assignment might happen twice
14406
			// oh well....
14407
			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
14408
			rgba = inst._rgba = parsed._rgba;
14409
 
14410
			// exit each( stringParsers ) here because we matched
14411
			return false;
14412
		}
14413
	});
14414
 
14415
	// Found a stringParser that handled it
14416
	if ( rgba.length ) {
14417
 
14418
		// if this came from a parsed string, force "transparent" when alpha is 0
14419
		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
14420
		if ( rgba.join() === "0,0,0,0" ) {
14421
			jQuery.extend( rgba, colors.transparent );
14422
		}
14423
		return inst;
14424
	}
14425
 
14426
	// named colors
14427
	return colors[ string ];
14428
}
14429
 
14430
color.fn = jQuery.extend( color.prototype, {
14431
	parse: function( red, green, blue, alpha ) {
14432
		if ( red === undefined ) {
14433
			this._rgba = [ null, null, null, null ];
14434
			return this;
14435
		}
14436
		if ( red.jquery || red.nodeType ) {
14437
			red = jQuery( red ).css( green );
14438
			green = undefined;
14439
		}
14440
 
14441
		var inst = this,
14442
			type = jQuery.type( red ),
14443
			rgba = this._rgba = [];
14444
 
14445
		// more than 1 argument specified - assume ( red, green, blue, alpha )
14446
		if ( green !== undefined ) {
14447
			red = [ red, green, blue, alpha ];
14448
			type = "array";
14449
		}
14450
 
14451
		if ( type === "string" ) {
14452
			return this.parse( stringParse( red ) || colors._default );
14453
		}
14454
 
14455
		if ( type === "array" ) {
14456
			each( spaces.rgba.props, function( key, prop ) {
14457
				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
14458
			});
14459
			return this;
14460
		}
14461
 
14462
		if ( type === "object" ) {
14463
			if ( red instanceof color ) {
14464
				each( spaces, function( spaceName, space ) {
14465
					if ( red[ space.cache ] ) {
14466
						inst[ space.cache ] = red[ space.cache ].slice();
14467
					}
14468
				});
14469
			} else {
14470
				each( spaces, function( spaceName, space ) {
14471
					var cache = space.cache;
14472
					each( space.props, function( key, prop ) {
14473
 
14474
						// if the cache doesn't exist, and we know how to convert
14475
						if ( !inst[ cache ] && space.to ) {
14476
 
14477
							// if the value was null, we don't need to copy it
14478
							// if the key was alpha, we don't need to copy it either
14479
							if ( key === "alpha" || red[ key ] == null ) {
14480
								return;
14481
							}
14482
							inst[ cache ] = space.to( inst._rgba );
14483
						}
14484
 
14485
						// this is the only case where we allow nulls for ALL properties.
14486
						// call clamp with alwaysAllowEmpty
14487
						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
14488
					});
14489
 
14490
					// everything defined but alpha?
14491
					if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
14492
						// use the default of 1
14493
						inst[ cache ][ 3 ] = 1;
14494
						if ( space.from ) {
14495
							inst._rgba = space.from( inst[ cache ] );
14496
						}
14497
					}
14498
				});
14499
			}
14500
			return this;
14501
		}
14502
	},
14503
	is: function( compare ) {
14504
		var is = color( compare ),
14505
			same = true,
14506
			inst = this;
14507
 
14508
		each( spaces, function( _, space ) {
14509
			var localCache,
14510
				isCache = is[ space.cache ];
14511
			if (isCache) {
14512
				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
14513
				each( space.props, function( _, prop ) {
14514
					if ( isCache[ prop.idx ] != null ) {
14515
						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
14516
						return same;
14517
					}
14518
				});
14519
			}
14520
			return same;
14521
		});
14522
		return same;
14523
	},
14524
	_space: function() {
14525
		var used = [],
14526
			inst = this;
14527
		each( spaces, function( spaceName, space ) {
14528
			if ( inst[ space.cache ] ) {
14529
				used.push( spaceName );
14530
			}
14531
		});
14532
		return used.pop();
14533
	},
14534
	transition: function( other, distance ) {
14535
		var end = color( other ),
14536
			spaceName = end._space(),
14537
			space = spaces[ spaceName ],
14538
			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
14539
			start = startColor[ space.cache ] || space.to( startColor._rgba ),
14540
			result = start.slice();
14541
 
14542
		end = end[ space.cache ];
14543
		each( space.props, function( key, prop ) {
14544
			var index = prop.idx,
14545
				startValue = start[ index ],
14546
				endValue = end[ index ],
14547
				type = propTypes[ prop.type ] || {};
14548
 
14549
			// if null, don't override start value
14550
			if ( endValue === null ) {
14551
				return;
14552
			}
14553
			// if null - use end
14554
			if ( startValue === null ) {
14555
				result[ index ] = endValue;
14556
			} else {
14557
				if ( type.mod ) {
14558
					if ( endValue - startValue > type.mod / 2 ) {
14559
						startValue += type.mod;
14560
					} else if ( startValue - endValue > type.mod / 2 ) {
14561
						startValue -= type.mod;
14562
					}
14563
				}
14564
				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
14565
			}
14566
		});
14567
		return this[ spaceName ]( result );
14568
	},
14569
	blend: function( opaque ) {
14570
		// if we are already opaque - return ourself
14571
		if ( this._rgba[ 3 ] === 1 ) {
14572
			return this;
14573
		}
14574
 
14575
		var rgb = this._rgba.slice(),
14576
			a = rgb.pop(),
14577
			blend = color( opaque )._rgba;
14578
 
14579
		return color( jQuery.map( rgb, function( v, i ) {
14580
			return ( 1 - a ) * blend[ i ] + a * v;
14581
		}));
14582
	},
14583
	toRgbaString: function() {
14584
		var prefix = "rgba(",
14585
			rgba = jQuery.map( this._rgba, function( v, i ) {
14586
				return v == null ? ( i > 2 ? 1 : 0 ) : v;
14587
			});
14588
 
14589
		if ( rgba[ 3 ] === 1 ) {
14590
			rgba.pop();
14591
			prefix = "rgb(";
14592
		}
14593
 
14594
		return prefix + rgba.join() + ")";
14595
	},
14596
	toHslaString: function() {
14597
		var prefix = "hsla(",
14598
			hsla = jQuery.map( this.hsla(), function( v, i ) {
14599
				if ( v == null ) {
14600
					v = i > 2 ? 1 : 0;
14601
				}
14602
 
14603
				// catch 1 and 2
14604
				if ( i && i < 3 ) {
14605
					v = Math.round( v * 100 ) + "%";
14606
				}
14607
				return v;
14608
			});
14609
 
14610
		if ( hsla[ 3 ] === 1 ) {
14611
			hsla.pop();
14612
			prefix = "hsl(";
14613
		}
14614
		return prefix + hsla.join() + ")";
14615
	},
14616
	toHexString: function( includeAlpha ) {
14617
		var rgba = this._rgba.slice(),
14618
			alpha = rgba.pop();
14619
 
14620
		if ( includeAlpha ) {
14621
			rgba.push( ~~( alpha * 255 ) );
14622
		}
14623
 
14624
		return "#" + jQuery.map( rgba, function( v ) {
14625
 
14626
			// default to 0 when nulls exist
14627
			v = ( v || 0 ).toString( 16 );
14628
			return v.length === 1 ? "0" + v : v;
14629
		}).join("");
14630
	},
14631
	toString: function() {
14632
		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
14633
	}
14634
});
14635
color.fn.parse.prototype = color.fn;
14636
 
14637
// hsla conversions adapted from:
14638
// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
14639
 
14640
function hue2rgb( p, q, h ) {
14641
	h = ( h + 1 ) % 1;
14642
	if ( h * 6 < 1 ) {
14643
		return p + ( q - p ) * h * 6;
14644
	}
14645
	if ( h * 2 < 1) {
14646
		return q;
14647
	}
14648
	if ( h * 3 < 2 ) {
14649
		return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
14650
	}
14651
	return p;
14652
}
14653
 
14654
spaces.hsla.to = function( rgba ) {
14655
	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
14656
		return [ null, null, null, rgba[ 3 ] ];
14657
	}
14658
	var r = rgba[ 0 ] / 255,
14659
		g = rgba[ 1 ] / 255,
14660
		b = rgba[ 2 ] / 255,
14661
		a = rgba[ 3 ],
14662
		max = Math.max( r, g, b ),
14663
		min = Math.min( r, g, b ),
14664
		diff = max - min,
14665
		add = max + min,
14666
		l = add * 0.5,
14667
		h, s;
14668
 
14669
	if ( min === max ) {
14670
		h = 0;
14671
	} else if ( r === max ) {
14672
		h = ( 60 * ( g - b ) / diff ) + 360;
14673
	} else if ( g === max ) {
14674
		h = ( 60 * ( b - r ) / diff ) + 120;
14675
	} else {
14676
		h = ( 60 * ( r - g ) / diff ) + 240;
14677
	}
14678
 
14679
	// chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
14680
	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
14681
	if ( diff === 0 ) {
14682
		s = 0;
14683
	} else if ( l <= 0.5 ) {
14684
		s = diff / add;
14685
	} else {
14686
		s = diff / ( 2 - add );
14687
	}
14688
	return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
14689
};
14690
 
14691
spaces.hsla.from = function( hsla ) {
14692
	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
14693
		return [ null, null, null, hsla[ 3 ] ];
14694
	}
14695
	var h = hsla[ 0 ] / 360,
14696
		s = hsla[ 1 ],
14697
		l = hsla[ 2 ],
14698
		a = hsla[ 3 ],
14699
		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
14700
		p = 2 * l - q;
14701
 
14702
	return [
14703
		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
14704
		Math.round( hue2rgb( p, q, h ) * 255 ),
14705
		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
14706
		a
14707
	];
14708
};
14709
 
14710
each( spaces, function( spaceName, space ) {
14711
	var props = space.props,
14712
		cache = space.cache,
14713
		to = space.to,
14714
		from = space.from;
14715
 
14716
	// makes rgba() and hsla()
14717
	color.fn[ spaceName ] = function( value ) {
14718
 
14719
		// generate a cache for this space if it doesn't exist
14720
		if ( to && !this[ cache ] ) {
14721
			this[ cache ] = to( this._rgba );
14722
		}
14723
		if ( value === undefined ) {
14724
			return this[ cache ].slice();
14725
		}
14726
 
14727
		var ret,
14728
			type = jQuery.type( value ),
14729
			arr = ( type === "array" || type === "object" ) ? value : arguments,
14730
			local = this[ cache ].slice();
14731
 
14732
		each( props, function( key, prop ) {
14733
			var val = arr[ type === "object" ? key : prop.idx ];
14734
			if ( val == null ) {
14735
				val = local[ prop.idx ];
14736
			}
14737
			local[ prop.idx ] = clamp( val, prop );
14738
		});
14739
 
14740
		if ( from ) {
14741
			ret = color( from( local ) );
14742
			ret[ cache ] = local;
14743
			return ret;
14744
		} else {
14745
			return color( local );
14746
		}
14747
	};
14748
 
14749
	// makes red() green() blue() alpha() hue() saturation() lightness()
14750
	each( props, function( key, prop ) {
14751
		// alpha is included in more than one space
14752
		if ( color.fn[ key ] ) {
14753
			return;
14754
		}
14755
		color.fn[ key ] = function( value ) {
14756
			var vtype = jQuery.type( value ),
14757
				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
14758
				local = this[ fn ](),
14759
				cur = local[ prop.idx ],
14760
				match;
14761
 
14762
			if ( vtype === "undefined" ) {
14763
				return cur;
14764
			}
14765
 
14766
			if ( vtype === "function" ) {
14767
				value = value.call( this, cur );
14768
				vtype = jQuery.type( value );
14769
			}
14770
			if ( value == null && prop.empty ) {
14771
				return this;
14772
			}
14773
			if ( vtype === "string" ) {
14774
				match = rplusequals.exec( value );
14775
				if ( match ) {
14776
					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
14777
				}
14778
			}
14779
			local[ prop.idx ] = value;
14780
			return this[ fn ]( local );
14781
		};
14782
	});
14783
});
14784
 
14785
// add cssHook and .fx.step function for each named hook.
14786
// accept a space separated string of properties
14787
color.hook = function( hook ) {
14788
	var hooks = hook.split( " " );
14789
	each( hooks, function( i, hook ) {
14790
		jQuery.cssHooks[ hook ] = {
14791
			set: function( elem, value ) {
14792
				var parsed, curElem,
14793
					backgroundColor = "";
14794
 
14795
				if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
14796
					value = color( parsed || value );
14797
					if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
14798
						curElem = hook === "backgroundColor" ? elem.parentNode : elem;
14799
						while (
14800
							(backgroundColor === "" || backgroundColor === "transparent") &&
14801
							curElem && curElem.style
14802
						) {
14803
							try {
14804
								backgroundColor = jQuery.css( curElem, "backgroundColor" );
14805
								curElem = curElem.parentNode;
14806
							} catch ( e ) {
14807
							}
14808
						}
14809
 
14810
						value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
14811
							backgroundColor :
14812
							"_default" );
14813
					}
14814
 
14815
					value = value.toRgbaString();
14816
				}
14817
				try {
14818
					elem.style[ hook ] = value;
14819
				} catch ( e ) {
14820
					// wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
14821
				}
14822
			}
14823
		};
14824
		jQuery.fx.step[ hook ] = function( fx ) {
14825
			if ( !fx.colorInit ) {
14826
				fx.start = color( fx.elem, hook );
14827
				fx.end = color( fx.end );
14828
				fx.colorInit = true;
14829
			}
14830
			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
14831
		};
14832
	});
14833
 
14834
};
14835
 
14836
color.hook( stepHooks );
14837
 
14838
jQuery.cssHooks.borderColor = {
14839
	expand: function( value ) {
14840
		var expanded = {};
14841
 
14842
		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
14843
			expanded[ "border" + part + "Color" ] = value;
14844
		});
14845
		return expanded;
14846
	}
14847
};
14848
 
14849
// Basic color names only.
14850
// Usage of any of the other color names requires adding yourself or including
14851
// jquery.color.svg-names.js.
14852
colors = jQuery.Color.names = {
14853
	// 4.1. Basic color keywords
14854
	aqua: "#00ffff",
14855
	black: "#000000",
14856
	blue: "#0000ff",
14857
	fuchsia: "#ff00ff",
14858
	gray: "#808080",
14859
	green: "#008000",
14860
	lime: "#00ff00",
14861
	maroon: "#800000",
14862
	navy: "#000080",
14863
	olive: "#808000",
14864
	purple: "#800080",
14865
	red: "#ff0000",
14866
	silver: "#c0c0c0",
14867
	teal: "#008080",
14868
	white: "#ffffff",
14869
	yellow: "#ffff00",
14870
 
14871
	// 4.2.3. "transparent" color keyword
14872
	transparent: [ null, null, null, 0 ],
14873
 
14874
	_default: "#ffffff"
14875
};
14876
 
14877
})( jQuery );
14878
 
14879
/******************************************************************************/
14880
/****************************** CLASS ANIMATIONS ******************************/
14881
/******************************************************************************/
14882
(function() {
14883
 
14884
var classAnimationActions = [ "add", "remove", "toggle" ],
14885
	shorthandStyles = {
14886
		border: 1,
14887
		borderBottom: 1,
14888
		borderColor: 1,
14889
		borderLeft: 1,
14890
		borderRight: 1,
14891
		borderTop: 1,
14892
		borderWidth: 1,
14893
		margin: 1,
14894
		padding: 1
14895
	};
14896
 
14897
$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
14898
	$.fx.step[ prop ] = function( fx ) {
14899
		if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
14900
			jQuery.style( fx.elem, prop, fx.end );
14901
			fx.setAttr = true;
14902
		}
14903
	};
14904
});
14905
 
14906
function getElementStyles( elem ) {
14907
	var key, len,
14908
		style = elem.ownerDocument.defaultView ?
14909
			elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
14910
			elem.currentStyle,
14911
		styles = {};
14912
 
14913
	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
14914
		len = style.length;
14915
		while ( len-- ) {
14916
			key = style[ len ];
14917
			if ( typeof style[ key ] === "string" ) {
14918
				styles[ $.camelCase( key ) ] = style[ key ];
14919
			}
14920
		}
14921
	// support: Opera, IE <9
14922
	} else {
14923
		for ( key in style ) {
14924
			if ( typeof style[ key ] === "string" ) {
14925
				styles[ key ] = style[ key ];
14926
			}
14927
		}
14928
	}
14929
 
14930
	return styles;
14931
}
14932
 
14933
function styleDifference( oldStyle, newStyle ) {
14934
	var diff = {},
14935
		name, value;
14936
 
14937
	for ( name in newStyle ) {
14938
		value = newStyle[ name ];
14939
		if ( oldStyle[ name ] !== value ) {
14940
			if ( !shorthandStyles[ name ] ) {
14941
				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
14942
					diff[ name ] = value;
14943
				}
14944
			}
14945
		}
14946
	}
14947
 
14948
	return diff;
14949
}
14950
 
14951
// support: jQuery <1.8
14952
if ( !$.fn.addBack ) {
14953
	$.fn.addBack = function( selector ) {
14954
		return this.add( selector == null ?
14955
			this.prevObject : this.prevObject.filter( selector )
14956
		);
14957
	};
14958
}
14959
 
14960
$.effects.animateClass = function( value, duration, easing, callback ) {
14961
	var o = $.speed( duration, easing, callback );
14962
 
14963
	return this.queue( function() {
14964
		var animated = $( this ),
14965
			baseClass = animated.attr( "class" ) || "",
14966
			applyClassChange,
14967
			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
14968
 
14969
		// map the animated objects to store the original styles.
14970
		allAnimations = allAnimations.map(function() {
14971
			var el = $( this );
14972
			return {
14973
				el: el,
14974
				start: getElementStyles( this )
14975
			};
14976
		});
14977
 
14978
		// apply class change
14979
		applyClassChange = function() {
14980
			$.each( classAnimationActions, function(i, action) {
14981
				if ( value[ action ] ) {
14982
					animated[ action + "Class" ]( value[ action ] );
14983
				}
14984
			});
14985
		};
14986
		applyClassChange();
14987
 
14988
		// map all animated objects again - calculate new styles and diff
14989
		allAnimations = allAnimations.map(function() {
14990
			this.end = getElementStyles( this.el[ 0 ] );
14991
			this.diff = styleDifference( this.start, this.end );
14992
			return this;
14993
		});
14994
 
14995
		// apply original class
14996
		animated.attr( "class", baseClass );
14997
 
14998
		// map all animated objects again - this time collecting a promise
14999
		allAnimations = allAnimations.map(function() {
15000
			var styleInfo = this,
15001
				dfd = $.Deferred(),
15002
				opts = $.extend({}, o, {
15003
					queue: false,
15004
					complete: function() {
15005
						dfd.resolve( styleInfo );
15006
					}
15007
				});
15008
 
15009
			this.el.animate( this.diff, opts );
15010
			return dfd.promise();
15011
		});
15012
 
15013
		// once all animations have completed:
15014
		$.when.apply( $, allAnimations.get() ).done(function() {
15015
 
15016
			// set the final class
15017
			applyClassChange();
15018
 
15019
			// for each animated element,
15020
			// clear all css properties that were animated
15021
			$.each( arguments, function() {
15022
				var el = this.el;
15023
				$.each( this.diff, function(key) {
15024
					el.css( key, "" );
15025
				});
15026
			});
15027
 
15028
			// this is guarnteed to be there if you use jQuery.speed()
15029
			// it also handles dequeuing the next anim...
15030
			o.complete.call( animated[ 0 ] );
15031
		});
15032
	});
15033
};
15034
 
15035
$.fn.extend({
15036
	addClass: (function( orig ) {
15037
		return function( classNames, speed, easing, callback ) {
15038
			return speed ?
15039
				$.effects.animateClass.call( this,
15040
					{ add: classNames }, speed, easing, callback ) :
15041
				orig.apply( this, arguments );
15042
		};
15043
	})( $.fn.addClass ),
15044
 
15045
	removeClass: (function( orig ) {
15046
		return function( classNames, speed, easing, callback ) {
15047
			return arguments.length > 1 ?
15048
				$.effects.animateClass.call( this,
15049
					{ remove: classNames }, speed, easing, callback ) :
15050
				orig.apply( this, arguments );
15051
		};
15052
	})( $.fn.removeClass ),
15053
 
15054
	toggleClass: (function( orig ) {
15055
		return function( classNames, force, speed, easing, callback ) {
15056
			if ( typeof force === "boolean" || force === undefined ) {
15057
				if ( !speed ) {
15058
					// without speed parameter
15059
					return orig.apply( this, arguments );
15060
				} else {
15061
					return $.effects.animateClass.call( this,
15062
						(force ? { add: classNames } : { remove: classNames }),
15063
						speed, easing, callback );
15064
				}
15065
			} else {
15066
				// without force parameter
15067
				return $.effects.animateClass.call( this,
15068
					{ toggle: classNames }, force, speed, easing );
15069
			}
15070
		};
15071
	})( $.fn.toggleClass ),
15072
 
15073
	switchClass: function( remove, add, speed, easing, callback) {
15074
		return $.effects.animateClass.call( this, {
15075
			add: add,
15076
			remove: remove
15077
		}, speed, easing, callback );
15078
	}
15079
});
15080
 
15081
})();
15082
 
15083
/******************************************************************************/
15084
/*********************************** EFFECTS **********************************/
15085
/******************************************************************************/
15086
 
15087
(function() {
15088
 
15089
$.extend( $.effects, {
15090
	version: "1.11.4",
15091
 
15092
	// Saves a set of properties in a data storage
15093
	save: function( element, set ) {
15094
		for ( var i = 0; i < set.length; i++ ) {
15095
			if ( set[ i ] !== null ) {
15096
				element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
15097
			}
15098
		}
15099
	},
15100
 
15101
	// Restores a set of previously saved properties from a data storage
15102
	restore: function( element, set ) {
15103
		var val, i;
15104
		for ( i = 0; i < set.length; i++ ) {
15105
			if ( set[ i ] !== null ) {
15106
				val = element.data( dataSpace + set[ i ] );
15107
				// support: jQuery 1.6.2
15108
				// http://bugs.jquery.com/ticket/9917
15109
				// jQuery 1.6.2 incorrectly returns undefined for any falsy value.
15110
				// We can't differentiate between "" and 0 here, so we just assume
15111
				// empty string since it's likely to be a more common value...
15112
				if ( val === undefined ) {
15113
					val = "";
15114
				}
15115
				element.css( set[ i ], val );
15116
			}
15117
		}
15118
	},
15119
 
15120
	setMode: function( el, mode ) {
15121
		if (mode === "toggle") {
15122
			mode = el.is( ":hidden" ) ? "show" : "hide";
15123
		}
15124
		return mode;
15125
	},
15126
 
15127
	// Translates a [top,left] array into a baseline value
15128
	// this should be a little more flexible in the future to handle a string & hash
15129
	getBaseline: function( origin, original ) {
15130
		var y, x;
15131
		switch ( origin[ 0 ] ) {
15132
			case "top": y = 0; break;
15133
			case "middle": y = 0.5; break;
15134
			case "bottom": y = 1; break;
15135
			default: y = origin[ 0 ] / original.height;
15136
		}
15137
		switch ( origin[ 1 ] ) {
15138
			case "left": x = 0; break;
15139
			case "center": x = 0.5; break;
15140
			case "right": x = 1; break;
15141
			default: x = origin[ 1 ] / original.width;
15142
		}
15143
		return {
15144
			x: x,
15145
			y: y
15146
		};
15147
	},
15148
 
15149
	// Wraps the element around a wrapper that copies position properties
15150
	createWrapper: function( element ) {
15151
 
15152
		// if the element is already wrapped, return it
15153
		if ( element.parent().is( ".ui-effects-wrapper" )) {
15154
			return element.parent();
15155
		}
15156
 
15157
		// wrap the element
15158
		var props = {
15159
				width: element.outerWidth(true),
15160
				height: element.outerHeight(true),
15161
				"float": element.css( "float" )
15162
			},
15163
			wrapper = $( "<div></div>" )
15164
				.addClass( "ui-effects-wrapper" )
15165
				.css({
15166
					fontSize: "100%",
15167
					background: "transparent",
15168
					border: "none",
15169
					margin: 0,
15170
					padding: 0
15171
				}),
15172
			// Store the size in case width/height are defined in % - Fixes #5245
15173
			size = {
15174
				width: element.width(),
15175
				height: element.height()
15176
			},
15177
			active = document.activeElement;
15178
 
15179
		// support: Firefox
15180
		// Firefox incorrectly exposes anonymous content
15181
		// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
15182
		try {
15183
			active.id;
15184
		} catch ( e ) {
15185
			active = document.body;
15186
		}
15187
 
15188
		element.wrap( wrapper );
15189
 
15190
		// Fixes #7595 - Elements lose focus when wrapped.
15191
		if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
15192
			$( active ).focus();
15193
		}
15194
 
15195
		wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
15196
 
15197
		// transfer positioning properties to the wrapper
15198
		if ( element.css( "position" ) === "static" ) {
15199
			wrapper.css({ position: "relative" });
15200
			element.css({ position: "relative" });
15201
		} else {
15202
			$.extend( props, {
15203
				position: element.css( "position" ),
15204
				zIndex: element.css( "z-index" )
15205
			});
15206
			$.each([ "top", "left", "bottom", "right" ], function(i, pos) {
15207
				props[ pos ] = element.css( pos );
15208
				if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
15209
					props[ pos ] = "auto";
15210
				}
15211
			});
15212
			element.css({
15213
				position: "relative",
15214
				top: 0,
15215
				left: 0,
15216
				right: "auto",
15217
				bottom: "auto"
15218
			});
15219
		}
15220
		element.css(size);
15221
 
15222
		return wrapper.css( props ).show();
15223
	},
15224
 
15225
	removeWrapper: function( element ) {
15226
		var active = document.activeElement;
15227
 
15228
		if ( element.parent().is( ".ui-effects-wrapper" ) ) {
15229
			element.parent().replaceWith( element );
15230
 
15231
			// Fixes #7595 - Elements lose focus when wrapped.
15232
			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
15233
				$( active ).focus();
15234
			}
15235
		}
15236
 
15237
		return element;
15238
	},
15239
 
15240
	setTransition: function( element, list, factor, value ) {
15241
		value = value || {};
15242
		$.each( list, function( i, x ) {
15243
			var unit = element.cssUnit( x );
15244
			if ( unit[ 0 ] > 0 ) {
15245
				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
15246
			}
15247
		});
15248
		return value;
15249
	}
15250
});
15251
 
15252
// return an effect options object for the given parameters:
15253
function _normalizeArguments( effect, options, speed, callback ) {
15254
 
15255
	// allow passing all options as the first parameter
15256
	if ( $.isPlainObject( effect ) ) {
15257
		options = effect;
15258
		effect = effect.effect;
15259
	}
15260
 
15261
	// convert to an object
15262
	effect = { effect: effect };
15263
 
15264
	// catch (effect, null, ...)
15265
	if ( options == null ) {
15266
		options = {};
15267
	}
15268
 
15269
	// catch (effect, callback)
15270
	if ( $.isFunction( options ) ) {
15271
		callback = options;
15272
		speed = null;
15273
		options = {};
15274
	}
15275
 
15276
	// catch (effect, speed, ?)
15277
	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
15278
		callback = speed;
15279
		speed = options;
15280
		options = {};
15281
	}
15282
 
15283
	// catch (effect, options, callback)
15284
	if ( $.isFunction( speed ) ) {
15285
		callback = speed;
15286
		speed = null;
15287
	}
15288
 
15289
	// add options to effect
15290
	if ( options ) {
15291
		$.extend( effect, options );
15292
	}
15293
 
15294
	speed = speed || options.duration;
15295
	effect.duration = $.fx.off ? 0 :
15296
		typeof speed === "number" ? speed :
15297
		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
15298
		$.fx.speeds._default;
15299
 
15300
	effect.complete = callback || options.complete;
15301
 
15302
	return effect;
15303
}
15304
 
15305
function standardAnimationOption( option ) {
15306
	// Valid standard speeds (nothing, number, named speed)
15307
	if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
15308
		return true;
15309
	}
15310
 
15311
	// Invalid strings - treat as "normal" speed
15312
	if ( typeof option === "string" && !$.effects.effect[ option ] ) {
15313
		return true;
15314
	}
15315
 
15316
	// Complete callback
15317
	if ( $.isFunction( option ) ) {
15318
		return true;
15319
	}
15320
 
15321
	// Options hash (but not naming an effect)
15322
	if ( typeof option === "object" && !option.effect ) {
15323
		return true;
15324
	}
15325
 
15326
	// Didn't match any standard API
15327
	return false;
15328
}
15329
 
15330
$.fn.extend({
15331
	effect: function( /* effect, options, speed, callback */ ) {
15332
		var args = _normalizeArguments.apply( this, arguments ),
15333
			mode = args.mode,
15334
			queue = args.queue,
15335
			effectMethod = $.effects.effect[ args.effect ];
15336
 
15337
		if ( $.fx.off || !effectMethod ) {
15338
			// delegate to the original method (e.g., .show()) if possible
15339
			if ( mode ) {
15340
				return this[ mode ]( args.duration, args.complete );
15341
			} else {
15342
				return this.each( function() {
15343
					if ( args.complete ) {
15344
						args.complete.call( this );
15345
					}
15346
				});
15347
			}
15348
		}
15349
 
15350
		function run( next ) {
15351
			var elem = $( this ),
15352
				complete = args.complete,
15353
				mode = args.mode;
15354
 
15355
			function done() {
15356
				if ( $.isFunction( complete ) ) {
15357
					complete.call( elem[0] );
15358
				}
15359
				if ( $.isFunction( next ) ) {
15360
					next();
15361
				}
15362
			}
15363
 
15364
			// If the element already has the correct final state, delegate to
15365
			// the core methods so the internal tracking of "olddisplay" works.
15366
			if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
15367
				elem[ mode ]();
15368
				done();
15369
			} else {
15370
				effectMethod.call( elem[0], args, done );
15371
			}
15372
		}
15373
 
15374
		return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
15375
	},
15376
 
15377
	show: (function( orig ) {
15378
		return function( option ) {
15379
			if ( standardAnimationOption( option ) ) {
15380
				return orig.apply( this, arguments );
15381
			} else {
15382
				var args = _normalizeArguments.apply( this, arguments );
15383
				args.mode = "show";
15384
				return this.effect.call( this, args );
15385
			}
15386
		};
15387
	})( $.fn.show ),
15388
 
15389
	hide: (function( orig ) {
15390
		return function( option ) {
15391
			if ( standardAnimationOption( option ) ) {
15392
				return orig.apply( this, arguments );
15393
			} else {
15394
				var args = _normalizeArguments.apply( this, arguments );
15395
				args.mode = "hide";
15396
				return this.effect.call( this, args );
15397
			}
15398
		};
15399
	})( $.fn.hide ),
15400
 
15401
	toggle: (function( orig ) {
15402
		return function( option ) {
15403
			if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
15404
				return orig.apply( this, arguments );
15405
			} else {
15406
				var args = _normalizeArguments.apply( this, arguments );
15407
				args.mode = "toggle";
15408
				return this.effect.call( this, args );
15409
			}
15410
		};
15411
	})( $.fn.toggle ),
15412
 
15413
	// helper functions
15414
	cssUnit: function(key) {
15415
		var style = this.css( key ),
15416
			val = [];
15417
 
15418
		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
15419
			if ( style.indexOf( unit ) > 0 ) {
15420
				val = [ parseFloat( style ), unit ];
15421
			}
15422
		});
15423
		return val;
15424
	}
15425
});
15426
 
15427
})();
15428
 
15429
/******************************************************************************/
15430
/*********************************** EASING ***********************************/
15431
/******************************************************************************/
15432
 
15433
(function() {
15434
 
15435
// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
15436
 
15437
var baseEasings = {};
15438
 
15439
$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
15440
	baseEasings[ name ] = function( p ) {
15441
		return Math.pow( p, i + 2 );
15442
	};
15443
});
15444
 
15445
$.extend( baseEasings, {
15446
	Sine: function( p ) {
15447
		return 1 - Math.cos( p * Math.PI / 2 );
15448
	},
15449
	Circ: function( p ) {
15450
		return 1 - Math.sqrt( 1 - p * p );
15451
	},
15452
	Elastic: function( p ) {
15453
		return p === 0 || p === 1 ? p :
15454
			-Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
15455
	},
15456
	Back: function( p ) {
15457
		return p * p * ( 3 * p - 2 );
15458
	},
15459
	Bounce: function( p ) {
15460
		var pow2,
15461
			bounce = 4;
15462
 
15463
		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
15464
		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
15465
	}
15466
});
15467
 
15468
$.each( baseEasings, function( name, easeIn ) {
15469
	$.easing[ "easeIn" + name ] = easeIn;
15470
	$.easing[ "easeOut" + name ] = function( p ) {
15471
		return 1 - easeIn( 1 - p );
15472
	};
15473
	$.easing[ "easeInOut" + name ] = function( p ) {
15474
		return p < 0.5 ?
15475
			easeIn( p * 2 ) / 2 :
15476
			1 - easeIn( p * -2 + 2 ) / 2;
15477
	};
15478
});
15479
 
15480
})();
15481
 
15482
var effect = $.effects;
15483
 
15484
 
15485
/*!
15486
 * jQuery UI Effects Blind 1.11.4
15487
 * http://jqueryui.com
15488
 *
15489
 * Copyright jQuery Foundation and other contributors
15490
 * Released under the MIT license.
15491
 * http://jquery.org/license
15492
 *
15493
 * http://api.jqueryui.com/blind-effect/
15494
 */
15495
 
15496
 
15497
var effectBlind = $.effects.effect.blind = function( o, done ) {
15498
	// Create element
15499
	var el = $( this ),
15500
		rvertical = /up|down|vertical/,
15501
		rpositivemotion = /up|left|vertical|horizontal/,
15502
		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
15503
		mode = $.effects.setMode( el, o.mode || "hide" ),
15504
		direction = o.direction || "up",
15505
		vertical = rvertical.test( direction ),
15506
		ref = vertical ? "height" : "width",
15507
		ref2 = vertical ? "top" : "left",
15508
		motion = rpositivemotion.test( direction ),
15509
		animation = {},
15510
		show = mode === "show",
15511
		wrapper, distance, margin;
15512
 
15513
	// if already wrapped, the wrapper's properties are my property. #6245
15514
	if ( el.parent().is( ".ui-effects-wrapper" ) ) {
15515
		$.effects.save( el.parent(), props );
15516
	} else {
15517
		$.effects.save( el, props );
15518
	}
15519
	el.show();
15520
	wrapper = $.effects.createWrapper( el ).css({
15521
		overflow: "hidden"
15522
	});
15523
 
15524
	distance = wrapper[ ref ]();
15525
	margin = parseFloat( wrapper.css( ref2 ) ) || 0;
15526
 
15527
	animation[ ref ] = show ? distance : 0;
15528
	if ( !motion ) {
15529
		el
15530
			.css( vertical ? "bottom" : "right", 0 )
15531
			.css( vertical ? "top" : "left", "auto" )
15532
			.css({ position: "absolute" });
15533
 
15534
		animation[ ref2 ] = show ? margin : distance + margin;
15535
	}
15536
 
15537
	// start at 0 if we are showing
15538
	if ( show ) {
15539
		wrapper.css( ref, 0 );
15540
		if ( !motion ) {
15541
			wrapper.css( ref2, margin + distance );
15542
		}
15543
	}
15544
 
15545
	// Animate
15546
	wrapper.animate( animation, {
15547
		duration: o.duration,
15548
		easing: o.easing,
15549
		queue: false,
15550
		complete: function() {
15551
			if ( mode === "hide" ) {
15552
				el.hide();
15553
			}
15554
			$.effects.restore( el, props );
15555
			$.effects.removeWrapper( el );
15556
			done();
15557
		}
15558
	});
15559
};
15560
 
15561
 
15562
/*!
15563
 * jQuery UI Effects Bounce 1.11.4
15564
 * http://jqueryui.com
15565
 *
15566
 * Copyright jQuery Foundation and other contributors
15567
 * Released under the MIT license.
15568
 * http://jquery.org/license
15569
 *
15570
 * http://api.jqueryui.com/bounce-effect/
15571
 */
15572
 
15573
 
15574
var effectBounce = $.effects.effect.bounce = function( o, done ) {
15575
	var el = $( this ),
15576
		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
15577
 
15578
		// defaults:
15579
		mode = $.effects.setMode( el, o.mode || "effect" ),
15580
		hide = mode === "hide",
15581
		show = mode === "show",
15582
		direction = o.direction || "up",
15583
		distance = o.distance,
15584
		times = o.times || 5,
15585
 
15586
		// number of internal animations
15587
		anims = times * 2 + ( show || hide ? 1 : 0 ),
15588
		speed = o.duration / anims,
15589
		easing = o.easing,
15590
 
15591
		// utility:
15592
		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
15593
		motion = ( direction === "up" || direction === "left" ),
15594
		i,
15595
		upAnim,
15596
		downAnim,
15597
 
15598
		// we will need to re-assemble the queue to stack our animations in place
15599
		queue = el.queue(),
15600
		queuelen = queue.length;
15601
 
15602
	// Avoid touching opacity to prevent clearType and PNG issues in IE
15603
	if ( show || hide ) {
15604
		props.push( "opacity" );
15605
	}
15606
 
15607
	$.effects.save( el, props );
15608
	el.show();
15609
	$.effects.createWrapper( el ); // Create Wrapper
15610
 
15611
	// default distance for the BIGGEST bounce is the outer Distance / 3
15612
	if ( !distance ) {
15613
		distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
15614
	}
15615
 
15616
	if ( show ) {
15617
		downAnim = { opacity: 1 };
15618
		downAnim[ ref ] = 0;
15619
 
15620
		// if we are showing, force opacity 0 and set the initial position
15621
		// then do the "first" animation
15622
		el.css( "opacity", 0 )
15623
			.css( ref, motion ? -distance * 2 : distance * 2 )
15624
			.animate( downAnim, speed, easing );
15625
	}
15626
 
15627
	// start at the smallest distance if we are hiding
15628
	if ( hide ) {
15629
		distance = distance / Math.pow( 2, times - 1 );
15630
	}
15631
 
15632
	downAnim = {};
15633
	downAnim[ ref ] = 0;
15634
	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
15635
	for ( i = 0; i < times; i++ ) {
15636
		upAnim = {};
15637
		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
15638
 
15639
		el.animate( upAnim, speed, easing )
15640
			.animate( downAnim, speed, easing );
15641
 
15642
		distance = hide ? distance * 2 : distance / 2;
15643
	}
15644
 
15645
	// Last Bounce when Hiding
15646
	if ( hide ) {
15647
		upAnim = { opacity: 0 };
15648
		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
15649
 
15650
		el.animate( upAnim, speed, easing );
15651
	}
15652
 
15653
	el.queue(function() {
15654
		if ( hide ) {
15655
			el.hide();
15656
		}
15657
		$.effects.restore( el, props );
15658
		$.effects.removeWrapper( el );
15659
		done();
15660
	});
15661
 
15662
	// inject all the animations we just queued to be first in line (after "inprogress")
15663
	if ( queuelen > 1) {
15664
		queue.splice.apply( queue,
15665
			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
15666
	}
15667
	el.dequeue();
15668
 
15669
};
15670
 
15671
 
15672
/*!
15673
 * jQuery UI Effects Clip 1.11.4
15674
 * http://jqueryui.com
15675
 *
15676
 * Copyright jQuery Foundation and other contributors
15677
 * Released under the MIT license.
15678
 * http://jquery.org/license
15679
 *
15680
 * http://api.jqueryui.com/clip-effect/
15681
 */
15682
 
15683
 
15684
var effectClip = $.effects.effect.clip = function( o, done ) {
15685
	// Create element
15686
	var el = $( this ),
15687
		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
15688
		mode = $.effects.setMode( el, o.mode || "hide" ),
15689
		show = mode === "show",
15690
		direction = o.direction || "vertical",
15691
		vert = direction === "vertical",
15692
		size = vert ? "height" : "width",
15693
		position = vert ? "top" : "left",
15694
		animation = {},
15695
		wrapper, animate, distance;
15696
 
15697
	// Save & Show
15698
	$.effects.save( el, props );
15699
	el.show();
15700
 
15701
	// Create Wrapper
15702
	wrapper = $.effects.createWrapper( el ).css({
15703
		overflow: "hidden"
15704
	});
15705
	animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
15706
	distance = animate[ size ]();
15707
 
15708
	// Shift
15709
	if ( show ) {
15710
		animate.css( size, 0 );
15711
		animate.css( position, distance / 2 );
15712
	}
15713
 
15714
	// Create Animation Object:
15715
	animation[ size ] = show ? distance : 0;
15716
	animation[ position ] = show ? 0 : distance / 2;
15717
 
15718
	// Animate
15719
	animate.animate( animation, {
15720
		queue: false,
15721
		duration: o.duration,
15722
		easing: o.easing,
15723
		complete: function() {
15724
			if ( !show ) {
15725
				el.hide();
15726
			}
15727
			$.effects.restore( el, props );
15728
			$.effects.removeWrapper( el );
15729
			done();
15730
		}
15731
	});
15732
 
15733
};
15734
 
15735
 
15736
/*!
15737
 * jQuery UI Effects Drop 1.11.4
15738
 * http://jqueryui.com
15739
 *
15740
 * Copyright jQuery Foundation and other contributors
15741
 * Released under the MIT license.
15742
 * http://jquery.org/license
15743
 *
15744
 * http://api.jqueryui.com/drop-effect/
15745
 */
15746
 
15747
 
15748
var effectDrop = $.effects.effect.drop = function( o, done ) {
15749
 
15750
	var el = $( this ),
15751
		props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
15752
		mode = $.effects.setMode( el, o.mode || "hide" ),
15753
		show = mode === "show",
15754
		direction = o.direction || "left",
15755
		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
15756
		motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
15757
		animation = {
15758
			opacity: show ? 1 : 0
15759
		},
15760
		distance;
15761
 
15762
	// Adjust
15763
	$.effects.save( el, props );
15764
	el.show();
15765
	$.effects.createWrapper( el );
15766
 
15767
	distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
15768
 
15769
	if ( show ) {
15770
		el
15771
			.css( "opacity", 0 )
15772
			.css( ref, motion === "pos" ? -distance : distance );
15773
	}
15774
 
15775
	// Animation
15776
	animation[ ref ] = ( show ?
15777
		( motion === "pos" ? "+=" : "-=" ) :
15778
		( motion === "pos" ? "-=" : "+=" ) ) +
15779
		distance;
15780
 
15781
	// Animate
15782
	el.animate( animation, {
15783
		queue: false,
15784
		duration: o.duration,
15785
		easing: o.easing,
15786
		complete: function() {
15787
			if ( mode === "hide" ) {
15788
				el.hide();
15789
			}
15790
			$.effects.restore( el, props );
15791
			$.effects.removeWrapper( el );
15792
			done();
15793
		}
15794
	});
15795
};
15796
 
15797
 
15798
/*!
15799
 * jQuery UI Effects Explode 1.11.4
15800
 * http://jqueryui.com
15801
 *
15802
 * Copyright jQuery Foundation and other contributors
15803
 * Released under the MIT license.
15804
 * http://jquery.org/license
15805
 *
15806
 * http://api.jqueryui.com/explode-effect/
15807
 */
15808
 
15809
 
15810
var effectExplode = $.effects.effect.explode = function( o, done ) {
15811
 
15812
	var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
15813
		cells = rows,
15814
		el = $( this ),
15815
		mode = $.effects.setMode( el, o.mode || "hide" ),
15816
		show = mode === "show",
15817
 
15818
		// show and then visibility:hidden the element before calculating offset
15819
		offset = el.show().css( "visibility", "hidden" ).offset(),
15820
 
15821
		// width and height of a piece
15822
		width = Math.ceil( el.outerWidth() / cells ),
15823
		height = Math.ceil( el.outerHeight() / rows ),
15824
		pieces = [],
15825
 
15826
		// loop
15827
		i, j, left, top, mx, my;
15828
 
15829
	// children animate complete:
15830
	function childComplete() {
15831
		pieces.push( this );
15832
		if ( pieces.length === rows * cells ) {
15833
			animComplete();
15834
		}
15835
	}
15836
 
15837
	// clone the element for each row and cell.
15838
	for ( i = 0; i < rows ; i++ ) { // ===>
15839
		top = offset.top + i * height;
15840
		my = i - ( rows - 1 ) / 2 ;
15841
 
15842
		for ( j = 0; j < cells ; j++ ) { // |||
15843
			left = offset.left + j * width;
15844
			mx = j - ( cells - 1 ) / 2 ;
15845
 
15846
			// Create a clone of the now hidden main element that will be absolute positioned
15847
			// within a wrapper div off the -left and -top equal to size of our pieces
15848
			el
15849
				.clone()
15850
				.appendTo( "body" )
15851
				.wrap( "<div></div>" )
15852
				.css({
15853
					position: "absolute",
15854
					visibility: "visible",
15855
					left: -j * width,
15856
					top: -i * height
15857
				})
15858
 
15859
			// select the wrapper - make it overflow: hidden and absolute positioned based on
15860
			// where the original was located +left and +top equal to the size of pieces
15861
				.parent()
15862
				.addClass( "ui-effects-explode" )
15863
				.css({
15864
					position: "absolute",
15865
					overflow: "hidden",
15866
					width: width,
15867
					height: height,
15868
					left: left + ( show ? mx * width : 0 ),
15869
					top: top + ( show ? my * height : 0 ),
15870
					opacity: show ? 0 : 1
15871
				}).animate({
15872
					left: left + ( show ? 0 : mx * width ),
15873
					top: top + ( show ? 0 : my * height ),
15874
					opacity: show ? 1 : 0
15875
				}, o.duration || 500, o.easing, childComplete );
15876
		}
15877
	}
15878
 
15879
	function animComplete() {
15880
		el.css({
15881
			visibility: "visible"
15882
		});
15883
		$( pieces ).remove();
15884
		if ( !show ) {
15885
			el.hide();
15886
		}
15887
		done();
15888
	}
15889
};
15890
 
15891
 
15892
/*!
15893
 * jQuery UI Effects Fade 1.11.4
15894
 * http://jqueryui.com
15895
 *
15896
 * Copyright jQuery Foundation and other contributors
15897
 * Released under the MIT license.
15898
 * http://jquery.org/license
15899
 *
15900
 * http://api.jqueryui.com/fade-effect/
15901
 */
15902
 
15903
 
15904
var effectFade = $.effects.effect.fade = function( o, done ) {
15905
	var el = $( this ),
15906
		mode = $.effects.setMode( el, o.mode || "toggle" );
15907
 
15908
	el.animate({
15909
		opacity: mode
15910
	}, {
15911
		queue: false,
15912
		duration: o.duration,
15913
		easing: o.easing,
15914
		complete: done
15915
	});
15916
};
15917
 
15918
 
15919
/*!
15920
 * jQuery UI Effects Fold 1.11.4
15921
 * http://jqueryui.com
15922
 *
15923
 * Copyright jQuery Foundation and other contributors
15924
 * Released under the MIT license.
15925
 * http://jquery.org/license
15926
 *
15927
 * http://api.jqueryui.com/fold-effect/
15928
 */
15929
 
15930
 
15931
var effectFold = $.effects.effect.fold = function( o, done ) {
15932
 
15933
	// Create element
15934
	var el = $( this ),
15935
		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
15936
		mode = $.effects.setMode( el, o.mode || "hide" ),
15937
		show = mode === "show",
15938
		hide = mode === "hide",
15939
		size = o.size || 15,
15940
		percent = /([0-9]+)%/.exec( size ),
15941
		horizFirst = !!o.horizFirst,
15942
		widthFirst = show !== horizFirst,
15943
		ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
15944
		duration = o.duration / 2,
15945
		wrapper, distance,
15946
		animation1 = {},
15947
		animation2 = {};
15948
 
15949
	$.effects.save( el, props );
15950
	el.show();
15951
 
15952
	// Create Wrapper
15953
	wrapper = $.effects.createWrapper( el ).css({
15954
		overflow: "hidden"
15955
	});
15956
	distance = widthFirst ?
15957
		[ wrapper.width(), wrapper.height() ] :
15958
		[ wrapper.height(), wrapper.width() ];
15959
 
15960
	if ( percent ) {
15961
		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
15962
	}
15963
	if ( show ) {
15964
		wrapper.css( horizFirst ? {
15965
			height: 0,
15966
			width: size
15967
		} : {
15968
			height: size,
15969
			width: 0
15970
		});
15971
	}
15972
 
15973
	// Animation
15974
	animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
15975
	animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
15976
 
15977
	// Animate
15978
	wrapper
15979
		.animate( animation1, duration, o.easing )
15980
		.animate( animation2, duration, o.easing, function() {
15981
			if ( hide ) {
15982
				el.hide();
15983
			}
15984
			$.effects.restore( el, props );
15985
			$.effects.removeWrapper( el );
15986
			done();
15987
		});
15988
 
15989
};
15990
 
15991
 
15992
/*!
15993
 * jQuery UI Effects Highlight 1.11.4
15994
 * http://jqueryui.com
15995
 *
15996
 * Copyright jQuery Foundation and other contributors
15997
 * Released under the MIT license.
15998
 * http://jquery.org/license
15999
 *
16000
 * http://api.jqueryui.com/highlight-effect/
16001
 */
16002
 
16003
 
16004
var effectHighlight = $.effects.effect.highlight = function( o, done ) {
16005
	var elem = $( this ),
16006
		props = [ "backgroundImage", "backgroundColor", "opacity" ],
16007
		mode = $.effects.setMode( elem, o.mode || "show" ),
16008
		animation = {
16009
			backgroundColor: elem.css( "backgroundColor" )
16010
		};
16011
 
16012
	if (mode === "hide") {
16013
		animation.opacity = 0;
16014
	}
16015
 
16016
	$.effects.save( elem, props );
16017
 
16018
	elem
16019
		.show()
16020
		.css({
16021
			backgroundImage: "none",
16022
			backgroundColor: o.color || "#ffff99"
16023
		})
16024
		.animate( animation, {
16025
			queue: false,
16026
			duration: o.duration,
16027
			easing: o.easing,
16028
			complete: function() {
16029
				if ( mode === "hide" ) {
16030
					elem.hide();
16031
				}
16032
				$.effects.restore( elem, props );
16033
				done();
16034
			}
16035
		});
16036
};
16037
 
16038
 
16039
/*!
16040
 * jQuery UI Effects Size 1.11.4
16041
 * http://jqueryui.com
16042
 *
16043
 * Copyright jQuery Foundation and other contributors
16044
 * Released under the MIT license.
16045
 * http://jquery.org/license
16046
 *
16047
 * http://api.jqueryui.com/size-effect/
16048
 */
16049
 
16050
 
16051
var effectSize = $.effects.effect.size = function( o, done ) {
16052
 
16053
	// Create element
16054
	var original, baseline, factor,
16055
		el = $( this ),
16056
		props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
16057
 
16058
		// Always restore
16059
		props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
16060
 
16061
		// Copy for children
16062
		props2 = [ "width", "height", "overflow" ],
16063
		cProps = [ "fontSize" ],
16064
		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
16065
		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
16066
 
16067
		// Set options
16068
		mode = $.effects.setMode( el, o.mode || "effect" ),
16069
		restore = o.restore || mode !== "effect",
16070
		scale = o.scale || "both",
16071
		origin = o.origin || [ "middle", "center" ],
16072
		position = el.css( "position" ),
16073
		props = restore ? props0 : props1,
16074
		zero = {
16075
			height: 0,
16076
			width: 0,
16077
			outerHeight: 0,
16078
			outerWidth: 0
16079
		};
16080
 
16081
	if ( mode === "show" ) {
16082
		el.show();
16083
	}
16084
	original = {
16085
		height: el.height(),
16086
		width: el.width(),
16087
		outerHeight: el.outerHeight(),
16088
		outerWidth: el.outerWidth()
16089
	};
16090
 
16091
	if ( o.mode === "toggle" && mode === "show" ) {
16092
		el.from = o.to || zero;
16093
		el.to = o.from || original;
16094
	} else {
16095
		el.from = o.from || ( mode === "show" ? zero : original );
16096
		el.to = o.to || ( mode === "hide" ? zero : original );
16097
	}
16098
 
16099
	// Set scaling factor
16100
	factor = {
16101
		from: {
16102
			y: el.from.height / original.height,
16103
			x: el.from.width / original.width
16104
		},
16105
		to: {
16106
			y: el.to.height / original.height,
16107
			x: el.to.width / original.width
16108
		}
16109
	};
16110
 
16111
	// Scale the css box
16112
	if ( scale === "box" || scale === "both" ) {
16113
 
16114
		// Vertical props scaling
16115
		if ( factor.from.y !== factor.to.y ) {
16116
			props = props.concat( vProps );
16117
			el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
16118
			el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
16119
		}
16120
 
16121
		// Horizontal props scaling
16122
		if ( factor.from.x !== factor.to.x ) {
16123
			props = props.concat( hProps );
16124
			el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
16125
			el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
16126
		}
16127
	}
16128
 
16129
	// Scale the content
16130
	if ( scale === "content" || scale === "both" ) {
16131
 
16132
		// Vertical props scaling
16133
		if ( factor.from.y !== factor.to.y ) {
16134
			props = props.concat( cProps ).concat( props2 );
16135
			el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
16136
			el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
16137
		}
16138
	}
16139
 
16140
	$.effects.save( el, props );
16141
	el.show();
16142
	$.effects.createWrapper( el );
16143
	el.css( "overflow", "hidden" ).css( el.from );
16144
 
16145
	// Adjust
16146
	if (origin) { // Calculate baseline shifts
16147
		baseline = $.effects.getBaseline( origin, original );
16148
		el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
16149
		el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
16150
		el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
16151
		el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
16152
	}
16153
	el.css( el.from ); // set top & left
16154
 
16155
	// Animate
16156
	if ( scale === "content" || scale === "both" ) { // Scale the children
16157
 
16158
		// Add margins/font-size
16159
		vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
16160
		hProps = hProps.concat([ "marginLeft", "marginRight" ]);
16161
		props2 = props0.concat(vProps).concat(hProps);
16162
 
16163
		el.find( "*[width]" ).each( function() {
16164
			var child = $( this ),
16165
				c_original = {
16166
					height: child.height(),
16167
					width: child.width(),
16168
					outerHeight: child.outerHeight(),
16169
					outerWidth: child.outerWidth()
16170
				};
16171
			if (restore) {
16172
				$.effects.save(child, props2);
16173
			}
16174
 
16175
			child.from = {
16176
				height: c_original.height * factor.from.y,
16177
				width: c_original.width * factor.from.x,
16178
				outerHeight: c_original.outerHeight * factor.from.y,
16179
				outerWidth: c_original.outerWidth * factor.from.x
16180
			};
16181
			child.to = {
16182
				height: c_original.height * factor.to.y,
16183
				width: c_original.width * factor.to.x,
16184
				outerHeight: c_original.height * factor.to.y,
16185
				outerWidth: c_original.width * factor.to.x
16186
			};
16187
 
16188
			// Vertical props scaling
16189
			if ( factor.from.y !== factor.to.y ) {
16190
				child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
16191
				child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
16192
			}
16193
 
16194
			// Horizontal props scaling
16195
			if ( factor.from.x !== factor.to.x ) {
16196
				child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
16197
				child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
16198
			}
16199
 
16200
			// Animate children
16201
			child.css( child.from );
16202
			child.animate( child.to, o.duration, o.easing, function() {
16203
 
16204
				// Restore children
16205
				if ( restore ) {
16206
					$.effects.restore( child, props2 );
16207
				}
16208
			});
16209
		});
16210
	}
16211
 
16212
	// Animate
16213
	el.animate( el.to, {
16214
		queue: false,
16215
		duration: o.duration,
16216
		easing: o.easing,
16217
		complete: function() {
16218
			if ( el.to.opacity === 0 ) {
16219
				el.css( "opacity", el.from.opacity );
16220
			}
16221
			if ( mode === "hide" ) {
16222
				el.hide();
16223
			}
16224
			$.effects.restore( el, props );
16225
			if ( !restore ) {
16226
 
16227
				// we need to calculate our new positioning based on the scaling
16228
				if ( position === "static" ) {
16229
					el.css({
16230
						position: "relative",
16231
						top: el.to.top,
16232
						left: el.to.left
16233
					});
16234
				} else {
16235
					$.each([ "top", "left" ], function( idx, pos ) {
16236
						el.css( pos, function( _, str ) {
16237
							var val = parseInt( str, 10 ),
16238
								toRef = idx ? el.to.left : el.to.top;
16239
 
16240
							// if original was "auto", recalculate the new value from wrapper
16241
							if ( str === "auto" ) {
16242
								return toRef + "px";
16243
							}
16244
 
16245
							return val + toRef + "px";
16246
						});
16247
					});
16248
				}
16249
			}
16250
 
16251
			$.effects.removeWrapper( el );
16252
			done();
16253
		}
16254
	});
16255
 
16256
};
16257
 
16258
 
16259
/*!
16260
 * jQuery UI Effects Scale 1.11.4
16261
 * http://jqueryui.com
16262
 *
16263
 * Copyright jQuery Foundation and other contributors
16264
 * Released under the MIT license.
16265
 * http://jquery.org/license
16266
 *
16267
 * http://api.jqueryui.com/scale-effect/
16268
 */
16269
 
16270
 
16271
var effectScale = $.effects.effect.scale = function( o, done ) {
16272
 
16273
	// Create element
16274
	var el = $( this ),
16275
		options = $.extend( true, {}, o ),
16276
		mode = $.effects.setMode( el, o.mode || "effect" ),
16277
		percent = parseInt( o.percent, 10 ) ||
16278
			( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
16279
		direction = o.direction || "both",
16280
		origin = o.origin,
16281
		original = {
16282
			height: el.height(),
16283
			width: el.width(),
16284
			outerHeight: el.outerHeight(),
16285
			outerWidth: el.outerWidth()
16286
		},
16287
		factor = {
16288
			y: direction !== "horizontal" ? (percent / 100) : 1,
16289
			x: direction !== "vertical" ? (percent / 100) : 1
16290
		};
16291
 
16292
	// We are going to pass this effect to the size effect:
16293
	options.effect = "size";
16294
	options.queue = false;
16295
	options.complete = done;
16296
 
16297
	// Set default origin and restore for show/hide
16298
	if ( mode !== "effect" ) {
16299
		options.origin = origin || [ "middle", "center" ];
16300
		options.restore = true;
16301
	}
16302
 
16303
	options.from = o.from || ( mode === "show" ? {
16304
		height: 0,
16305
		width: 0,
16306
		outerHeight: 0,
16307
		outerWidth: 0
16308
	} : original );
16309
	options.to = {
16310
		height: original.height * factor.y,
16311
		width: original.width * factor.x,
16312
		outerHeight: original.outerHeight * factor.y,
16313
		outerWidth: original.outerWidth * factor.x
16314
	};
16315
 
16316
	// Fade option to support puff
16317
	if ( options.fade ) {
16318
		if ( mode === "show" ) {
16319
			options.from.opacity = 0;
16320
			options.to.opacity = 1;
16321
		}
16322
		if ( mode === "hide" ) {
16323
			options.from.opacity = 1;
16324
			options.to.opacity = 0;
16325
		}
16326
	}
16327
 
16328
	// Animate
16329
	el.effect( options );
16330
 
16331
};
16332
 
16333
 
16334
/*!
16335
 * jQuery UI Effects Puff 1.11.4
16336
 * http://jqueryui.com
16337
 *
16338
 * Copyright jQuery Foundation and other contributors
16339
 * Released under the MIT license.
16340
 * http://jquery.org/license
16341
 *
16342
 * http://api.jqueryui.com/puff-effect/
16343
 */
16344
 
16345
 
16346
var effectPuff = $.effects.effect.puff = function( o, done ) {
16347
	var elem = $( this ),
16348
		mode = $.effects.setMode( elem, o.mode || "hide" ),
16349
		hide = mode === "hide",
16350
		percent = parseInt( o.percent, 10 ) || 150,
16351
		factor = percent / 100,
16352
		original = {
16353
			height: elem.height(),
16354
			width: elem.width(),
16355
			outerHeight: elem.outerHeight(),
16356
			outerWidth: elem.outerWidth()
16357
		};
16358
 
16359
	$.extend( o, {
16360
		effect: "scale",
16361
		queue: false,
16362
		fade: true,
16363
		mode: mode,
16364
		complete: done,
16365
		percent: hide ? percent : 100,
16366
		from: hide ?
16367
			original :
16368
			{
16369
				height: original.height * factor,
16370
				width: original.width * factor,
16371
				outerHeight: original.outerHeight * factor,
16372
				outerWidth: original.outerWidth * factor
16373
			}
16374
	});
16375
 
16376
	elem.effect( o );
16377
};
16378
 
16379
 
16380
/*!
16381
 * jQuery UI Effects Pulsate 1.11.4
16382
 * http://jqueryui.com
16383
 *
16384
 * Copyright jQuery Foundation and other contributors
16385
 * Released under the MIT license.
16386
 * http://jquery.org/license
16387
 *
16388
 * http://api.jqueryui.com/pulsate-effect/
16389
 */
16390
 
16391
 
16392
var effectPulsate = $.effects.effect.pulsate = function( o, done ) {
16393
	var elem = $( this ),
16394
		mode = $.effects.setMode( elem, o.mode || "show" ),
16395
		show = mode === "show",
16396
		hide = mode === "hide",
16397
		showhide = ( show || mode === "hide" ),
16398
 
16399
		// showing or hiding leaves of the "last" animation
16400
		anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
16401
		duration = o.duration / anims,
16402
		animateTo = 0,
16403
		queue = elem.queue(),
16404
		queuelen = queue.length,
16405
		i;
16406
 
16407
	if ( show || !elem.is(":visible")) {
16408
		elem.css( "opacity", 0 ).show();
16409
		animateTo = 1;
16410
	}
16411
 
16412
	// anims - 1 opacity "toggles"
16413
	for ( i = 1; i < anims; i++ ) {
16414
		elem.animate({
16415
			opacity: animateTo
16416
		}, duration, o.easing );
16417
		animateTo = 1 - animateTo;
16418
	}
16419
 
16420
	elem.animate({
16421
		opacity: animateTo
16422
	}, duration, o.easing);
16423
 
16424
	elem.queue(function() {
16425
		if ( hide ) {
16426
			elem.hide();
16427
		}
16428
		done();
16429
	});
16430
 
16431
	// We just queued up "anims" animations, we need to put them next in the queue
16432
	if ( queuelen > 1 ) {
16433
		queue.splice.apply( queue,
16434
			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
16435
	}
16436
	elem.dequeue();
16437
};
16438
 
16439
 
16440
/*!
16441
 * jQuery UI Effects Shake 1.11.4
16442
 * http://jqueryui.com
16443
 *
16444
 * Copyright jQuery Foundation and other contributors
16445
 * Released under the MIT license.
16446
 * http://jquery.org/license
16447
 *
16448
 * http://api.jqueryui.com/shake-effect/
16449
 */
16450
 
16451
 
16452
var effectShake = $.effects.effect.shake = function( o, done ) {
16453
 
16454
	var el = $( this ),
16455
		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
16456
		mode = $.effects.setMode( el, o.mode || "effect" ),
16457
		direction = o.direction || "left",
16458
		distance = o.distance || 20,
16459
		times = o.times || 3,
16460
		anims = times * 2 + 1,
16461
		speed = Math.round( o.duration / anims ),
16462
		ref = (direction === "up" || direction === "down") ? "top" : "left",
16463
		positiveMotion = (direction === "up" || direction === "left"),
16464
		animation = {},
16465
		animation1 = {},
16466
		animation2 = {},
16467
		i,
16468
 
16469
		// we will need to re-assemble the queue to stack our animations in place
16470
		queue = el.queue(),
16471
		queuelen = queue.length;
16472
 
16473
	$.effects.save( el, props );
16474
	el.show();
16475
	$.effects.createWrapper( el );
16476
 
16477
	// Animation
16478
	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
16479
	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
16480
	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
16481
 
16482
	// Animate
16483
	el.animate( animation, speed, o.easing );
16484
 
16485
	// Shakes
16486
	for ( i = 1; i < times; i++ ) {
16487
		el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
16488
	}
16489
	el
16490
		.animate( animation1, speed, o.easing )
16491
		.animate( animation, speed / 2, o.easing )
16492
		.queue(function() {
16493
			if ( mode === "hide" ) {
16494
				el.hide();
16495
			}
16496
			$.effects.restore( el, props );
16497
			$.effects.removeWrapper( el );
16498
			done();
16499
		});
16500
 
16501
	// inject all the animations we just queued to be first in line (after "inprogress")
16502
	if ( queuelen > 1) {
16503
		queue.splice.apply( queue,
16504
			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
16505
	}
16506
	el.dequeue();
16507
 
16508
};
16509
 
16510
 
16511
/*!
16512
 * jQuery UI Effects Slide 1.11.4
16513
 * http://jqueryui.com
16514
 *
16515
 * Copyright jQuery Foundation and other contributors
16516
 * Released under the MIT license.
16517
 * http://jquery.org/license
16518
 *
16519
 * http://api.jqueryui.com/slide-effect/
16520
 */
16521
 
16522
 
16523
var effectSlide = $.effects.effect.slide = function( o, done ) {
16524
 
16525
	// Create element
16526
	var el = $( this ),
16527
		props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
16528
		mode = $.effects.setMode( el, o.mode || "show" ),
16529
		show = mode === "show",
16530
		direction = o.direction || "left",
16531
		ref = (direction === "up" || direction === "down") ? "top" : "left",
16532
		positiveMotion = (direction === "up" || direction === "left"),
16533
		distance,
16534
		animation = {};
16535
 
16536
	// Adjust
16537
	$.effects.save( el, props );
16538
	el.show();
16539
	distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
16540
 
16541
	$.effects.createWrapper( el ).css({
16542
		overflow: "hidden"
16543
	});
16544
 
16545
	if ( show ) {
16546
		el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
16547
	}
16548
 
16549
	// Animation
16550
	animation[ ref ] = ( show ?
16551
		( positiveMotion ? "+=" : "-=") :
16552
		( positiveMotion ? "-=" : "+=")) +
16553
		distance;
16554
 
16555
	// Animate
16556
	el.animate( animation, {
16557
		queue: false,
16558
		duration: o.duration,
16559
		easing: o.easing,
16560
		complete: function() {
16561
			if ( mode === "hide" ) {
16562
				el.hide();
16563
			}
16564
			$.effects.restore( el, props );
16565
			$.effects.removeWrapper( el );
16566
			done();
16567
		}
16568
	});
16569
};
16570
 
16571
 
16572
/*!
16573
 * jQuery UI Effects Transfer 1.11.4
16574
 * http://jqueryui.com
16575
 *
16576
 * Copyright jQuery Foundation and other contributors
16577
 * Released under the MIT license.
16578
 * http://jquery.org/license
16579
 *
16580
 * http://api.jqueryui.com/transfer-effect/
16581
 */
16582
 
16583
 
16584
var effectTransfer = $.effects.effect.transfer = function( o, done ) {
16585
	var elem = $( this ),
16586
		target = $( o.to ),
16587
		targetFixed = target.css( "position" ) === "fixed",
16588
		body = $("body"),
16589
		fixTop = targetFixed ? body.scrollTop() : 0,
16590
		fixLeft = targetFixed ? body.scrollLeft() : 0,
16591
		endPosition = target.offset(),
16592
		animation = {
16593
			top: endPosition.top - fixTop,
16594
			left: endPosition.left - fixLeft,
16595
			height: target.innerHeight(),
16596
			width: target.innerWidth()
16597
		},
16598
		startPosition = elem.offset(),
16599
		transfer = $( "<div class='ui-effects-transfer'></div>" )
16600
			.appendTo( document.body )
16601
			.addClass( o.className )
16602
			.css({
16603
				top: startPosition.top - fixTop,
16604
				left: startPosition.left - fixLeft,
16605
				height: elem.innerHeight(),
16606
				width: elem.innerWidth(),
16607
				position: targetFixed ? "fixed" : "absolute"
16608
			})
16609
			.animate( animation, o.duration, o.easing, function() {
16610
				transfer.remove();
16611
				done();
16612
			});
16613
};
16614
 
16615
 
16616
 
16617
}));