PageSourceSearch

https://www.duplexsteelalloys.com/assets/js/rangeslider-js.min.js

js duplexsteelalloys.com collected 2026-10-04 04:36:59 UTC 576,829 bytes, 37,411 lines download raw bytes

vendor: 9,816 bytes, lines 1-578
1/*! jQuery UI - v1.12.1 - 2016-09-14
2
3* http://jqueryui.com
4
5* Includes: widget.js, position.js, data.js, disable-selection.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js, focusable.js, form-reset-mixin.js, jquery-1-7.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/draggable.js, widgets/droppable.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/resizable.js, widgets/selectable.js, widgets/selectmenu.js, widgets/slider.js, widgets/sortable.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js
6
7* Copyright jQuery Foundation and other contributors; Licensed MIT */
8
9
10
11(function( factory ) {
12
13	if ( typeof define === "function" && define.amd ) {
14
15
16
17		// AMD. Register as an anonymous module.
18
19		define([ "jquery" ], factory );
20
21	} else {
22
23
24
25		// Browser globals
26
27		factory( jQuery );
28
29	}
30
31}(function( $ ) {
32
33
34
35$.ui = $.ui || {};
36
37
38
39var version = $.ui.version = "1.12.1";
40
41
42
43
44
45/*!
46
47 * jQuery UI Widget 1.12.1
48
49 * http://jqueryui.com
50
51 *
52
53 * Copyright jQuery Foundation and other contributors
54
55 * Released under the MIT license.
56
57 * http://jquery.org/license
58
59 */
60
61
62
63//>>label: Widget
64
65//>>group: Core
66
67//>>description: Provides a factory for creating stateful widgets with a common API.
68
69//>>docs: http://api.jqueryui.com/jQuery.widget/
70
71//>>demos: http://jqueryui.com/widget/
72
73
74
75
76
77
78
79var widgetUuid = 0;
80
81var widgetSlice = Array.prototype.slice;
82
83
84
85$.cleanData = ( function( orig ) {
86
87	return function( elems ) {
88
89		var events, elem, i;
90
91		for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
92
93			try {
94
95
96
97				// Only trigger remove when necessary to save time
98
99				events = $._data( elem, "events" );
100
101				if ( events && events.remove ) {
102
103					$( elem ).triggerHandler( "remove" );
104
105				}
106
107
108
109			// Http://bugs.jquery.com/ticket/8235
110
111			} catch ( e ) {}
112
113		}
114
115		orig( elems );
116
117	};
118
119} )( $.cleanData );
120
121
122
123$.widget = function( name, base, prototype ) {
124
125	var existingConstructor, constructor, basePrototype;
126
127
128
129	// ProxiedPrototype allows the provided prototype to remain unmodified
130
131	// so that it can be used as a mixin for multiple widgets (#8876)
132
133	var proxiedPrototype = {};
134
135
136
137	var namespace = name.split( "." )[ 0 ];
138
139	name = name.split( "." )[ 1 ];
140
141	var fullName = namespace + "-" + name;
142
143
144
145	if ( !prototype ) {
146
147		prototype = base;
148
149		base = $.Widget;
150
151	}
152
153
154
155	if ( $.isArray( prototype ) ) {
156
157		prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
158
159	}
160
161
162
163	// Create selector for plugin
164
165	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
166
167		return !!$.data( elem, fullName );
168
169	};
170
171
172
173	$[ namespace ] = $[ namespace ] || {};
174
175	existingConstructor = $[ namespace ][ name ];
176
177	constructor = $[ namespace ][ name ] = function( options, element ) {
178
179
180
181		// Allow instantiation without "new" keyword
182
183		if ( !this._createWidget ) {
184
185			return new constructor( options, element );
186
187		}
188
189
190
191		// Allow instantiation without initializing for simple inheritance
192
193		// must use "new" keyword (the code above always passes args)
194
195		if ( arguments.length ) {
196
197			this._createWidget( options, element );
198
199		}
200
201	};
202
203
204
205	// Extend with the existing constructor to carry over any static properties
206
207	$.extend( constructor, existingConstructor, {
208
209		version: prototype.version,
210
211
212
213		// Copy the object used to create the prototype in case we need to
214
215		// redefine the widget later
216
217		_proto: $.extend( {}, prototype ),
218
219
220
221		// Track widgets that inherit from this widget in case this widget is
222
223		// redefined after a widget inherits from it
224
225		_childConstructors: []
226
227	} );
228
229
230
231	basePrototype = new base();
232
233
234
235	// We need to make the options hash a property directly on the new instance
236
237	// otherwise we'll modify the options hash on the prototype that we're
238
239	// inheriting from
240
241	basePrototype.options = $.widget.extend( {}, basePrototype.options );
242
243	$.each( prototype, function( prop, value ) {
244
245		if ( !$.isFunction( value ) ) {
246
247			proxiedPrototype[ prop ] = value;
248
249			return;
250
251		}
252
253		proxiedPrototype[ prop ] = ( function() {
254
255			function _super() {
256
257				return base.prototype[ prop ].apply( this, arguments );
258
259			}
260
261
262
263			function _superApply( args ) {
264
265				return base.prototype[ prop ].apply( this, args );
266
267			}
268
269
270
271			return function() {
272
273				var __super = this._super;
274
275				var __superApply = this._superApply;
276
277				var returnValue;
278
279
280
281				this._super = _super;
282
283				this._superApply = _superApply;
284
285
286
287				returnValue = value.apply( this, arguments );
288
289
290
291				this._super = __super;
292
293				this._superApply = __superApply;
294
295
296
297				return returnValue;
298
299			};
300
301		} )();
302
303	} );
304
305	constructor.prototype = $.widget.extend( basePrototype, {
306
307
308
309		// TODO: remove support for widgetEventPrefix
310
311		// always use the name + a colon as the prefix, e.g., draggable:start
312
313		// don't prefix for widgets that aren't DOM-based
314
315		widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
316
317	}, proxiedPrototype, {
318
319		constructor: constructor,
320
321		namespace: namespace,
322
323		widgetName: name,
324
325		widgetFullName: fullName
326
327	} );
328
329
330
331	// If this widget is being redefined then we need to find all widgets that
332
333	// are inheriting from it and redefine all of them so that they inherit from
334
335	// the new version of this widget. We're essentially trying to replace one
336
337	// level in the prototype chain.
338
339	if ( existingConstructor ) {
340
341		$.each( existingConstructor._childConstructors, function( i, child ) {
342
343			var childPrototype = child.prototype;
344
345
346
347			// Redefine the child widget using the same prototype that was
348
349			// originally used, but inherit from the new version of the base
350
351			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
352
353				child._proto );
354
355		} );
356
357
358
359		// Remove the list of existing child constructors from the old constructor
360
361		// so the old child constructors can be garbage collected
362
363		delete existingConstructor._childConstructors;
364
365	} else {
366
367		base._childConstructors.push( constructor );
368
369	}
370
371
372
373	$.widget.bridge( name, constructor );
374
375
376
377	return constructor;
378
379};
380
381
382
383$.widget.extend = function( target ) {
384
385	var input = widgetSlice.call( arguments, 1 );
386
387	var inputIndex = 0;
388
389	var inputLength = input.length;
390
391	var key;
392
393	var value;
394
395
396
397	for ( ; inputIndex < inputLength; inputIndex++ ) {
398
399		for ( key in input[ inputIndex ] ) {
400
401			value = input[ inputIndex ][ key ];
402
403			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
404
405
406
407				// Clone objects
408
409				if ( $.isPlainObject( value ) ) {
410
411					target[ key ] = $.isPlainObject( target[ key ] ) ?
412
413						$.widget.extend( {}, target[ key ], value ) :
414
415
416
417						// Don't extend strings, arrays, etc. with objects
418
419						$.widget.extend( {}, value );
420
421
422
423				// Copy everything else by reference
424
425				} else {
426
427					target[ key ] = value;
428
429				}
430
431			}
432
433		}
434
435	}
436
437	return target;
438
439};
440
441
442
443$.widget.bridge = function( name, object ) {
444
445	var fullName = object.prototype.widgetFullName || name;
446
447	$.fn[ name ] = function( options ) {
448
449		var isMethodCall = typeof options === "string";
450
451		var args = widgetSlice.call( arguments, 1 );
452
453		var returnValue = this;
454
455
456
457		if ( isMethodCall ) {
458
459
460
461			// If this is an empty collection, we need to have the instance method
462
463			// return undefined instead of the jQuery instance
464
465			if ( !this.length && options === "instance" ) {
466
467				returnValue = undefined;
468
469			} else {
470
471				this.each( function() {
472
473					var methodValue;
474
475					var instance = $.data( this, fullName );
476
477
478
479					if ( options === "instance" ) {
480
481						returnValue = instance;
482
483						return false;
484
485					}
486
487
488
489					if ( !instance ) {
490
491						return $.error( "cannot call methods on " + name +
492
493							" prior to initialization; " +
494
495							"attempted to call method '" + options + "'" );
496
497					}
498
499
500
501					if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
502
503						return $.error( "no such method '" + options + "' for " + name +
504
505							" widget instance" );
506
507					}
508
509
510
511					methodValue = instance[ options ].apply( instance, args );
512
513
514
515					if ( methodValue !== instance && methodValue !== undefined ) {
516
517						returnValue = methodValue && methodValue.jquery ?
518
519							returnValue.pushStack( methodValue.get() ) :
520
521							methodValue;
522
523						return false;
524
525					}
526
527				} );
528
529			}
530
531		} else {
532
533
534
535			// Allow multiple hashes to be passed on init
536
537			if ( args.length ) {
538
539				options = $.widget.extend.apply( null, [ options ].concat( args ) );
540
541			}
542
543
544
545			this.each( function() {
546
547				var instance = $.data( this, fullName );
548
549				if ( instance ) {
550
551					instance.option( options || {} );
552
553					if ( instance._init ) {
554
555						instance._init();
556
557					}
558
559				} else {
560
561					$.data( this, fullName, new object( options, this ) );
562
563				}
564
565			} );
566
567		}
568
569
570
571		return returnValue;
572
573	};
574
575};
576
577
578
vendor: 4,454 bytes, lines 579-930
579$.Widget = function( /* options, element */ ) {};
580
581$.Widget._childConstructors = [];
582
583
584
585$.Widget.prototype = {
586
587	widgetName: "widget",
588
589	widgetEventPrefix: "",
590
591	defaultElement: "<div>",
592
593
594
595	options: {
596
597		classes: {},
598
599		disabled: false,
600
601
602
603		// Callbacks
604
605		create: null
606
607	},
608
609
610
611	_createWidget: function( options, element ) {
612
613		element = $( element || this.defaultElement || this )[ 0 ];
614
615		this.element = $( element );
616
617		this.uuid = widgetUuid++;
618
619		this.eventNamespace = "." + this.widgetName + this.uuid;
620
621
622
623		this.bindings = $();
624
625		this.hoverable = $();
626
627		this.focusable = $();
628
629		this.classesElementLookup = {};
630
631
632
633		if ( element !== this ) {
634
635			$.data( element, this.widgetFullName, this );
636
637			this._on( true, this.element, {
638
639				remove: function( event ) {
640
641					if ( event.target === element ) {
642
643						this.destroy();
644
645					}
646
647				}
648
649			} );
650
651			this.document = $( element.style ?
652
653
654
655				// Element within the document
656
657				element.ownerDocument :
658
659
660
661				// Element is window or document
662
663				element.document || element );
664
665			this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
666
667		}
668
669
670
671		this.options = $.widget.extend( {},
672
673			this.options,
674
675			this._getCreateOptions(),
676
677			options );
678
679
680
681		this._create();
682
683
684
685		if ( this.options.disabled ) {
686
687			this._setOptionDisabled( this.options.disabled );
688
689		}
690
691
692
693		this._trigger( "create", null, this._getCreateEventData() );
694
695		this._init();
696
697	},
698
699
700
701	_getCreateOptions: function() {
702
703		return {};
704
705	},
706
707
708
709	_getCreateEventData: $.noop,
710
711
712
713	_create: $.noop,
714
715
716
717	_init: $.noop,
718
719
720
721	destroy: function() {
722
723		var that = this;
724
725
726
727		this._destroy();
728
729		$.each( this.classesElementLookup, function( key, value ) {
730
731			that._removeClass( value, key );
732
733		} );
734
735
736
737		// We can probably remove the unbind calls in 2.0
738
739		// all event bindings should go through this._on()
740
741		this.element
742
743			.off( this.eventNamespace )
744
745			.removeData( this.widgetFullName );
746
747		this.widget()
748
749			.off( this.eventNamespace )
750
751			.removeAttr( "aria-disabled" );
752
753
754
755		// Clean up events and states
756
757		this.bindings.off( this.eventNamespace );
758
759	},
760
761
762
763	_destroy: $.noop,
764
765
766
767	widget: function() {
768
769		return this.element;
770
771	},
772
773
774
775	option: function( key, value ) {
776
777		var options = key;
778
779		var parts;
780
781		var curOption;
782
783		var i;
784
785
786
787		if ( arguments.length === 0 ) {
788
789
790
791			// Don't return a reference to the internal hash
792
793			return $.widget.extend( {}, this.options );
794
795		}
796
797
798
799		if ( typeof key === "string" ) {
800
801
802
803			// Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
804
805			options = {};
806
807			parts = key.split( "." );
808
809			key = parts.shift();
810
811			if ( parts.length ) {
812
813				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
814
815				for ( i = 0; i < parts.length - 1; i++ ) {
816
817					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
818
819					curOption = curOption[ parts[ i ] ];
820
821				}
822
823				key = parts.pop();
824
825				if ( arguments.length === 1 ) {
826
827					return curOption[ key ] === undefined ? null : curOption[ key ];
828
829				}
830
831				curOption[ key ] = value;
832
833			} else {
834
835				if ( arguments.length === 1 ) {
836
837					return this.options[ key ] === undefined ? null : this.options[ key ];
838
839				}
840
841				options[ key ] = value;
842
843			}
844
845		}
846
847
848
849		this._setOptions( options );
850
851
852
853		return this;
854
855	},
856
857
858
859	_setOptions: function( options ) {
860
861		var key;
862
863
864
865		for ( key in options ) {
866
867			this._setOption( key, options[ key ] );
868
869		}
870
871
872
873		return this;
874
875	},
876
877
878
879	_setOption: function( key, value ) {
880
881		if ( key === "classes" ) {
882
883			this._setOptionClasses( value );
884
885		}
886
887
888
889		this.options[ key ] = value;
890
891
892
893		if ( key === "disabled" ) {
894
895			this._setOptionDisabled( value );
896
897		}
898
899
900
901		return this;
902
903	},
904
905
906
907	_setOptionClasses: function( value ) {
908
909		var classKey, elements, currentElements;
910
911
912
913		for ( classKey in value ) {
914
915			currentElements = this.classesElementLookup[ classKey ];
916
917			if ( value[ classKey ] === this.options.classes[ classKey ] ||
918
919					!currentElements ||
920
921					!currentElements.length ) {
922
923				continue;
924
925			}
926
927
928
929			// We are doing this to create a new jQuery object because the _removeClass() call
930
vendor: 8,575 bytes, lines 931-1458
931			// on the next line is going to destroy the reference to the current elements being
932
933			// tracked. We need to save a copy of this collection so that we can add the new classes
934
935			// below.
936
937			elements = $( currentElements.get() );
938
939			this._removeClass( currentElements, classKey );
940
941
942
943			// We don't use _addClass() here, because that uses this.options.classes
944
945			// for generating the string of classes. We want to use the value passed in from
946
947			// _setOption(), this is the new value of the classes option which was passed to
948
949			// _setOption(). We pass this value directly to _classes().
950
951			elements.addClass( this._classes( {
952
953				element: elements,
954
955				keys: classKey,
956
957				classes: value,
958
959				add: true
960
961			} ) );
962
963		}
964
965	},
966
967
968
969	_setOptionDisabled: function( value ) {
970
971		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
972
973
974
975		// If the widget is becoming disabled, then nothing is interactive
976
977		if ( value ) {
978
979			this._removeClass( this.hoverable, null, "ui-state-hover" );
980
981			this._removeClass( this.focusable, null, "ui-state-focus" );
982
983		}
984
985	},
986
987
988
989	enable: function() {
990
991		return this._setOptions( { disabled: false } );
992
993	},
994
995
996
997	disable: function() {
998
999		return this._setOptions( { disabled: true } );
1000
1001	},
1002
1003
1004
1005	_classes: function( options ) {
1006
1007		var full = [];
1008
1009		var that = this;
1010
1011
1012
1013		options = $.extend( {
1014
1015			element: this.element,
1016
1017			classes: this.options.classes || {}
1018
1019		}, options );
1020
1021
1022
1023		function processClassString( classes, checkOption ) {
1024
1025			var current, i;
1026
1027			for ( i = 0; i < classes.length; i++ ) {
1028
1029				current = that.classesElementLookup[ classes[ i ] ] || $();
1030
1031				if ( options.add ) {
1032
1033					current = $( $.unique( current.get().concat( options.element.get() ) ) );
1034
1035				} else {
1036
1037					current = $( current.not( options.element ).get() );
1038
1039				}
1040
1041				that.classesElementLookup[ classes[ i ] ] = current;
1042
1043				full.push( classes[ i ] );
1044
1045				if ( checkOption && options.classes[ classes[ i ] ] ) {
1046
1047					full.push( options.classes[ classes[ i ] ] );
1048
1049				}
1050
1051			}
1052
1053		}
1054
1055
1056
1057		this._on( options.element, {
1058
1059			"remove": "_untrackClassesElement"
1060
1061		} );
1062
1063
1064
1065		if ( options.keys ) {
1066
1067			processClassString( options.keys.match( /\S+/g ) || [], true );
1068
1069		}
1070
1071		if ( options.extra ) {
1072
1073			processClassString( options.extra.match( /\S+/g ) || [] );
1074
1075		}
1076
1077
1078
1079		return full.join( " " );
1080
1081	},
1082
1083
1084
1085	_untrackClassesElement: function( event ) {
1086
1087		var that = this;
1088
1089		$.each( that.classesElementLookup, function( key, value ) {
1090
1091			if ( $.inArray( event.target, value ) !== -1 ) {
1092
1093				that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
1094
1095			}
1096
1097		} );
1098
1099	},
1100
1101
1102
1103	_removeClass: function( element, keys, extra ) {
1104
1105		return this._toggleClass( element, keys, extra, false );
1106
1107	},
1108
1109
1110
1111	_addClass: function( element, keys, extra ) {
1112
1113		return this._toggleClass( element, keys, extra, true );
1114
1115	},
1116
1117
1118
1119	_toggleClass: function( element, keys, extra, add ) {
1120
1121		add = ( typeof add === "boolean" ) ? add : extra;
1122
1123		var shift = ( typeof element === "string" || element === null ),
1124
1125			options = {
1126
1127				extra: shift ? keys : extra,
1128
1129				keys: shift ? element : keys,
1130
1131				element: shift ? this.element : element,
1132
1133				add: add
1134
1135			};
1136
1137		options.element.toggleClass( this._classes( options ), add );
1138
1139		return this;
1140
1141	},
1142
1143
1144
1145	_on: function( suppressDisabledCheck, element, handlers ) {
1146
1147		var delegateElement;
1148
1149		var instance = this;
1150
1151
1152
1153		// No suppressDisabledCheck flag, shuffle arguments
1154
1155		if ( typeof suppressDisabledCheck !== "boolean" ) {
1156
1157			handlers = element;
1158
1159			element = suppressDisabledCheck;
1160
1161			suppressDisabledCheck = false;
1162
1163		}
1164
1165
1166
1167		// No element argument, shuffle and use this.element
1168
1169		if ( !handlers ) {
1170
1171			handlers = element;
1172
1173			element = this.element;
1174
1175			delegateElement = this.widget();
1176
1177		} else {
1178
1179			element = delegateElement = $( element );
1180
1181			this.bindings = this.bindings.add( element );
1182
1183		}
1184
1185
1186
1187		$.each( handlers, function( event, handler ) {
1188
1189			function handlerProxy() {
1190
1191
1192
1193				// Allow widgets to customize the disabled handling
1194
1195				// - disabled as an array instead of boolean
1196
1197				// - disabled class as method for disabling individual parts
1198
1199				if ( !suppressDisabledCheck &&
1200
1201						( instance.options.disabled === true ||
1202
1203						$( this ).hasClass( "ui-state-disabled" ) ) ) {
1204
1205					return;
1206
1207				}
1208
1209				return ( typeof handler === "string" ? instance[ handler ] : handler )
1210
1211					.apply( instance, arguments );
1212
1213			}
1214
1215
1216
1217			// Copy the guid so direct unbinding works
1218
1219			if ( typeof handler !== "string" ) {
1220
1221				handlerProxy.guid = handler.guid =
1222
1223					handler.guid || handlerProxy.guid || $.guid++;
1224
1225			}
1226
1227
1228
1229			var match = event.match( /^([\w:-]*)\s*(.*)$/ );
1230
1231			var eventName = match[ 1 ] + instance.eventNamespace;
1232
1233			var selector = match[ 2 ];
1234
1235
1236
1237			if ( selector ) {
1238
1239				delegateElement.on( eventName, selector, handlerProxy );
1240
1241			} else {
1242
1243				element.on( eventName, handlerProxy );
1244
1245			}
1246
1247		} );
1248
1249	},
1250
1251
1252
1253	_off: function( element, eventName ) {
1254
1255		eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
1256
1257			this.eventNamespace;
1258
1259		element.off( eventName ).off( eventName );
1260
1261
1262
1263		// Clear the stack to avoid memory leaks (#10056)
1264
1265		this.bindings = $( this.bindings.not( element ).get() );
1266
1267		this.focusable = $( this.focusable.not( element ).get() );
1268
1269		this.hoverable = $( this.hoverable.not( element ).get() );
1270
1271	},
1272
1273
1274
1275	_delay: function( handler, delay ) {
1276
1277		function handlerProxy() {
1278
1279			return ( typeof handler === "string" ? instance[ handler ] : handler )
1280
1281				.apply( instance, arguments );
1282
1283		}
1284
1285		var instance = this;
1286
1287		return setTimeout( handlerProxy, delay || 0 );
1288
1289	},
1290
1291
1292
1293	_hoverable: function( element ) {
1294
1295		this.hoverable = this.hoverable.add( element );
1296
1297		this._on( element, {
1298
1299			mouseenter: function( event ) {
1300
1301				this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
1302
1303			},
1304
1305			mouseleave: function( event ) {
1306
1307				this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
1308
1309			}
1310
1311		} );
1312
1313	},
1314
1315
1316
1317	_focusable: function( element ) {
1318
1319		this.focusable = this.focusable.add( element );
1320
1321		this._on( element, {
1322
1323			focusin: function( event ) {
1324
1325				this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
1326
1327			},
1328
1329			focusout: function( event ) {
1330
1331				this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
1332
1333			}
1334
1335		} );
1336
1337	},
1338
1339
1340
1341	_trigger: function( type, event, data ) {
1342
1343		var prop, orig;
1344
1345		var callback = this.options[ type ];
1346
1347
1348
1349		data = data || {};
1350
1351		event = $.Event( event );
1352
1353		event.type = ( type === this.widgetEventPrefix ?
1354
1355			type :
1356
1357			this.widgetEventPrefix + type ).toLowerCase();
1358
1359
1360
1361		// The original event may come from any element
1362
1363		// so we need to reset the target on the new event
1364
1365		event.target = this.element[ 0 ];
1366
1367
1368
1369		// Copy original event properties over to the new event
1370
1371		orig = event.originalEvent;
1372
1373		if ( orig ) {
1374
1375			for ( prop in orig ) {
1376
1377				if ( !( prop in event ) ) {
1378
1379					event[ prop ] = orig[ prop ];
1380
1381				}
1382
1383			}
1384
1385		}
1386
1387
1388
1389		this.element.trigger( event, data );
1390
1391		return !( $.isFunction( callback ) &&
1392
1393			callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
1394
1395			event.isDefaultPrevented() );
1396
1397	}
1398
1399};
1400
1401
1402
1403$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
1404
1405	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
1406
1407		if ( typeof options === "string" ) {
1408
1409			options = { effect: options };
1410
1411		}
1412
1413
1414
1415		var hasOptions;
1416
1417		var effectName = !options ?
1418
1419			method :
1420
1421			options === true || typeof options === "number" ?
1422
1423				defaultEffect :
1424
1425				options.effect || defaultEffect;
1426
1427
1428
1429		options = options || {};
1430
1431		if ( typeof options === "number" ) {
1432
1433			options = { duration: options };
1434
1435		}
1436
1437
1438
1439		hasOptions = !$.isEmptyObject( options );
1440
1441		options.complete = callback;
1442
1443
1444
1445		if ( options.delay ) {
1446
1447			element.delay( options.delay );
1448
1449		}
1450
1451
1452
1453		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
1454
1455			element[ method ]( options );
1456
1457		} else if ( effectName !== method && element[ effectName ] ) {
1458
vendor: 5,342 bytes, lines 1459-1818
1459			element[ effectName ]( options.duration, options.easing, callback );
1460
1461		} else {
1462
1463			element.queue( function( next ) {
1464
1465				$( this )[ method ]();
1466
1467				if ( callback ) {
1468
1469					callback.call( element[ 0 ] );
1470
1471				}
1472
1473				next();
1474
1475			} );
1476
1477		}
1478
1479	};
1480
1481} );
1482
1483
1484
1485var widget = $.widget;
1486
1487
1488
1489
1490
1491/*!
1492
1493 * jQuery UI Position 1.12.1
1494
1495 * http://jqueryui.com
1496
1497 *
1498
1499 * Copyright jQuery Foundation and other contributors
1500
1501 * Released under the MIT license.
1502
1503 * http://jquery.org/license
1504
1505 *
1506
1507 * http://api.jqueryui.com/position/
1508
1509 */
1510
1511
1512
1513//>>label: Position
1514
1515//>>group: Core
1516
1517//>>description: Positions elements relative to other elements.
1518
1519//>>docs: http://api.jqueryui.com/position/
1520
1521//>>demos: http://jqueryui.com/position/
1522
1523
1524
1525
1526
1527( function() {
1528
1529var cachedScrollbarWidth,
1530
1531	max = Math.max,
1532
1533	abs = Math.abs,
1534
1535	rhorizontal = /left|center|right/,
1536
1537	rvertical = /top|center|bottom/,
1538
1539	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
1540
1541	rposition = /^\w+/,
1542
1543	rpercent = /%$/,
1544
1545	_position = $.fn.position;
1546
1547
1548
1549function getOffsets( offsets, width, height ) {
1550
1551	return [
1552
1553		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
1554
1555		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
1556
1557	];
1558
1559}
1560
1561
1562
1563function parseCss( element, property ) {
1564
1565	return parseInt( $.css( element, property ), 10 ) || 0;
1566
1567}
1568
1569
1570
1571function getDimensions( elem ) {
1572
1573	var raw = elem[ 0 ];
1574
1575	if ( raw.nodeType === 9 ) {
1576
1577		return {
1578
1579			width: elem.width(),
1580
1581			height: elem.height(),
1582
1583			offset: { top: 0, left: 0 }
1584
1585		};
1586
1587	}
1588
1589	if ( $.isWindow( raw ) ) {
1590
1591		return {
1592
1593			width: elem.width(),
1594
1595			height: elem.height(),
1596
1597			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
1598
1599		};
1600
1601	}
1602
1603	if ( raw.preventDefault ) {
1604
1605		return {
1606
1607			width: 0,
1608
1609			height: 0,
1610
1611			offset: { top: raw.pageY, left: raw.pageX }
1612
1613		};
1614
1615	}
1616
1617	return {
1618
1619		width: elem.outerWidth(),
1620
1621		height: elem.outerHeight(),
1622
1623		offset: elem.offset()
1624
1625	};
1626
1627}
1628
1629
1630
1631$.position = {
1632
1633	scrollbarWidth: function() {
1634
1635		if ( cachedScrollbarWidth !== undefined ) {
1636
1637			return cachedScrollbarWidth;
1638
1639		}
1640
1641		var w1, w2,
1642
1643			div = $( "<div " +
1644
1645				"style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>" +
1646
1647				"<div style='height:100px;width:auto;'></div></div>" ),
1648
1649			innerDiv = div.children()[ 0 ];
1650
1651
1652
1653		$( "body" ).append( div );
1654
1655		w1 = innerDiv.offsetWidth;
1656
1657		div.css( "overflow", "scroll" );
1658
1659
1660
1661		w2 = innerDiv.offsetWidth;
1662
1663
1664
1665		if ( w1 === w2 ) {
1666
1667			w2 = div[ 0 ].clientWidth;
1668
1669		}
1670
1671
1672
1673		div.remove();
1674
1675
1676
1677		return ( cachedScrollbarWidth = w1 - w2 );
1678
1679	},
1680
1681	getScrollInfo: function( within ) {
1682
1683		var overflowX = within.isWindow || within.isDocument ? "" :
1684
1685				within.element.css( "overflow-x" ),
1686
1687			overflowY = within.isWindow || within.isDocument ? "" :
1688
1689				within.element.css( "overflow-y" ),
1690
1691			hasOverflowX = overflowX === "scroll" ||
1692
1693				( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ),
1694
1695			hasOverflowY = overflowY === "scroll" ||
1696
1697				( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight );
1698
1699		return {
1700
1701			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
1702
1703			height: hasOverflowX ? $.position.scrollbarWidth() : 0
1704
1705		};
1706
1707	},
1708
1709	getWithinInfo: function( element ) {
1710
1711		var withinElement = $( element || window ),
1712
1713			isWindow = $.isWindow( withinElement[ 0 ] ),
1714
1715			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,
1716
1717			hasOffset = !isWindow && !isDocument;
1718
1719		return {
1720
1721			element: withinElement,
1722
1723			isWindow: isWindow,
1724
1725			isDocument: isDocument,
1726
1727			offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },
1728
1729			scrollLeft: withinElement.scrollLeft(),
1730
1731			scrollTop: withinElement.scrollTop(),
1732
1733			width: withinElement.outerWidth(),
1734
1735			height: withinElement.outerHeight()
1736
1737		};
1738
1739	}
1740
1741};
1742
1743
1744
1745$.fn.position = function( options ) {
1746
1747	if ( !options || !options.of ) {
1748
1749		return _position.apply( this, arguments );
1750
1751	}
1752
1753
1754
1755	// Make a copy, we don't want to modify arguments
1756
1757	options = $.extend( {}, options );
1758
1759
1760
1761	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
1762
1763		target = $( options.of ),
1764
1765		within = $.position.getWithinInfo( options.within ),
1766
1767		scrollInfo = $.position.getScrollInfo( within ),
1768
1769		collision = ( options.collision || "flip" ).split( " " ),
1770
1771		offsets = {};
1772
1773
1774
1775	dimensions = getDimensions( target );
1776
1777	if ( target[ 0 ].preventDefault ) {
1778
1779
1780
1781		// Force left top to allow flipping
1782
1783		options.at = "left top";
1784
1785	}
1786
1787	targetWidth = dimensions.width;
1788
1789	targetHeight = dimensions.height;
1790
1791	targetOffset = dimensions.offset;
1792
1793
1794
1795	// Clone to reuse original targetOffset later
1796
1797	basePosition = $.extend( {}, targetOffset );
1798
1799
1800
1801	// Force my and at to have valid horizontal and vertical positions
1802
1803	// if a value is missing or invalid, it will be converted to center
1804
1805	$.each( [ "my", "at" ], function() {
1806
1807		var pos = ( options[ this ] || "" ).split( " " ),
1808
1809			horizontalOffset,
1810
1811			verticalOffset;
1812
1813
1814
1815		if ( pos.length === 1 ) {
1816
1817			pos = rhorizontal.test( pos[ 0 ] ) ?
1818
vendor: 11,135 bytes, lines 1819-2471
1819				pos.concat( [ "center" ] ) :
1820
1821				rvertical.test( pos[ 0 ] ) ?
1822
1823					[ "center" ].concat( pos ) :
1824
1825					[ "center", "center" ];
1826
1827		}
1828
1829		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
1830
1831		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
1832
1833
1834
1835		// Calculate offsets
1836
1837		horizontalOffset = roffset.exec( pos[ 0 ] );
1838
1839		verticalOffset = roffset.exec( pos[ 1 ] );
1840
1841		offsets[ this ] = [
1842
1843			horizontalOffset ? horizontalOffset[ 0 ] : 0,
1844
1845			verticalOffset ? verticalOffset[ 0 ] : 0
1846
1847		];
1848
1849
1850
1851		// Reduce to just the positions without the offsets
1852
1853		options[ this ] = [
1854
1855			rposition.exec( pos[ 0 ] )[ 0 ],
1856
1857			rposition.exec( pos[ 1 ] )[ 0 ]
1858
1859		];
1860
1861	} );
1862
1863
1864
1865	// Normalize collision option
1866
1867	if ( collision.length === 1 ) {
1868
1869		collision[ 1 ] = collision[ 0 ];
1870
1871	}
1872
1873
1874
1875	if ( options.at[ 0 ] === "right" ) {
1876
1877		basePosition.left += targetWidth;
1878
1879	} else if ( options.at[ 0 ] === "center" ) {
1880
1881		basePosition.left += targetWidth / 2;
1882
1883	}
1884
1885
1886
1887	if ( options.at[ 1 ] === "bottom" ) {
1888
1889		basePosition.top += targetHeight;
1890
1891	} else if ( options.at[ 1 ] === "center" ) {
1892
1893		basePosition.top += targetHeight / 2;
1894
1895	}
1896
1897
1898
1899	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
1900
1901	basePosition.left += atOffset[ 0 ];
1902
1903	basePosition.top += atOffset[ 1 ];
1904
1905
1906
1907	return this.each( function() {
1908
1909		var collisionPosition, using,
1910
1911			elem = $( this ),
1912
1913			elemWidth = elem.outerWidth(),
1914
1915			elemHeight = elem.outerHeight(),
1916
1917			marginLeft = parseCss( this, "marginLeft" ),
1918
1919			marginTop = parseCss( this, "marginTop" ),
1920
1921			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) +
1922
1923				scrollInfo.width,
1924
1925			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) +
1926
1927				scrollInfo.height,
1928
1929			position = $.extend( {}, basePosition ),
1930
1931			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1932
1933
1934
1935		if ( options.my[ 0 ] === "right" ) {
1936
1937			position.left -= elemWidth;
1938
1939		} else if ( options.my[ 0 ] === "center" ) {
1940
1941			position.left -= elemWidth / 2;
1942
1943		}
1944
1945
1946
1947		if ( options.my[ 1 ] === "bottom" ) {
1948
1949			position.top -= elemHeight;
1950
1951		} else if ( options.my[ 1 ] === "center" ) {
1952
1953			position.top -= elemHeight / 2;
1954
1955		}
1956
1957
1958
1959		position.left += myOffset[ 0 ];
1960
1961		position.top += myOffset[ 1 ];
1962
1963
1964
1965		collisionPosition = {
1966
1967			marginLeft: marginLeft,
1968
1969			marginTop: marginTop
1970
1971		};
1972
1973
1974
1975		$.each( [ "left", "top" ], function( i, dir ) {
1976
1977			if ( $.ui.position[ collision[ i ] ] ) {
1978
1979				$.ui.position[ collision[ i ] ][ dir ]( position, {
1980
1981					targetWidth: targetWidth,
1982
1983					targetHeight: targetHeight,
1984
1985					elemWidth: elemWidth,
1986
1987					elemHeight: elemHeight,
1988
1989					collisionPosition: collisionPosition,
1990
1991					collisionWidth: collisionWidth,
1992
1993					collisionHeight: collisionHeight,
1994
1995					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1996
1997					my: options.my,
1998
1999					at: options.at,
2000
2001					within: within,
2002
2003					elem: elem
2004
2005				} );
2006
2007			}
2008
2009		} );
2010
2011
2012
2013		if ( options.using ) {
2014
2015
2016
2017			// Adds feedback as second argument to using callback, if present
2018
2019			using = function( props ) {
2020
2021				var left = targetOffset.left - position.left,
2022
2023					right = left + targetWidth - elemWidth,
2024
2025					top = targetOffset.top - position.top,
2026
2027					bottom = top + targetHeight - elemHeight,
2028
2029					feedback = {
2030
2031						target: {
2032
2033							element: target,
2034
2035							left: targetOffset.left,
2036
2037							top: targetOffset.top,
2038
2039							width: targetWidth,
2040
2041							height: targetHeight
2042
2043						},
2044
2045						element: {
2046
2047							element: elem,
2048
2049							left: position.left,
2050
2051							top: position.top,
2052
2053							width: elemWidth,
2054
2055							height: elemHeight
2056
2057						},
2058
2059						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
2060
2061						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
2062
2063					};
2064
2065				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
2066
2067					feedback.horizontal = "center";
2068
2069				}
2070
2071				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
2072
2073					feedback.vertical = "middle";
2074
2075				}
2076
2077				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
2078
2079					feedback.important = "horizontal";
2080
2081				} else {
2082
2083					feedback.important = "vertical";
2084
2085				}
2086
2087				options.using.call( this, props, feedback );
2088
2089			};
2090
2091		}
2092
2093
2094
2095		elem.offset( $.extend( position, { using: using } ) );
2096
2097	} );
2098
2099};
2100
2101
2102
2103$.ui.position = {
2104
2105	fit: {
2106
2107		left: function( position, data ) {
2108
2109			var within = data.within,
2110
2111				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
2112
2113				outerWidth = within.width,
2114
2115				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
2116
2117				overLeft = withinOffset - collisionPosLeft,
2118
2119				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
2120
2121				newOverRight;
2122
2123
2124
2125			// Element is wider than within
2126
2127			if ( data.collisionWidth > outerWidth ) {
2128
2129
2130
2131				// Element is initially over the left side of within
2132
2133				if ( overLeft > 0 && overRight <= 0 ) {
2134
2135					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth -
2136
2137						withinOffset;
2138
2139					position.left += overLeft - newOverRight;
2140
2141
2142
2143				// Element is initially over right side of within
2144
2145				} else if ( overRight > 0 && overLeft <= 0 ) {
2146
2147					position.left = withinOffset;
2148
2149
2150
2151				// Element is initially over both left and right sides of within
2152
2153				} else {
2154
2155					if ( overLeft > overRight ) {
2156
2157						position.left = withinOffset + outerWidth - data.collisionWidth;
2158
2159					} else {
2160
2161						position.left = withinOffset;
2162
2163					}
2164
2165				}
2166
2167
2168
2169			// Too far left -> align with left edge
2170
2171			} else if ( overLeft > 0 ) {
2172
2173				position.left += overLeft;
2174
2175
2176
2177			// Too far right -> align with right edge
2178
2179			} else if ( overRight > 0 ) {
2180
2181				position.left -= overRight;
2182
2183
2184
2185			// Adjust based on position and margin
2186
2187			} else {
2188
2189				position.left = max( position.left - collisionPosLeft, position.left );
2190
2191			}
2192
2193		},
2194
2195		top: function( position, data ) {
2196
2197			var within = data.within,
2198
2199				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
2200
2201				outerHeight = data.within.height,
2202
2203				collisionPosTop = position.top - data.collisionPosition.marginTop,
2204
2205				overTop = withinOffset - collisionPosTop,
2206
2207				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
2208
2209				newOverBottom;
2210
2211
2212
2213			// Element is taller than within
2214
2215			if ( data.collisionHeight > outerHeight ) {
2216
2217
2218
2219				// Element is initially over the top of within
2220
2221				if ( overTop > 0 && overBottom <= 0 ) {
2222
2223					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight -
2224
2225						withinOffset;
2226
2227					position.top += overTop - newOverBottom;
2228
2229
2230
2231				// Element is initially over bottom of within
2232
2233				} else if ( overBottom > 0 && overTop <= 0 ) {
2234
2235					position.top = withinOffset;
2236
2237
2238
2239				// Element is initially over both top and bottom of within
2240
2241				} else {
2242
2243					if ( overTop > overBottom ) {
2244
2245						position.top = withinOffset + outerHeight - data.collisionHeight;
2246
2247					} else {
2248
2249						position.top = withinOffset;
2250
2251					}
2252
2253				}
2254
2255
2256
2257			// Too far up -> align with top
2258
2259			} else if ( overTop > 0 ) {
2260
2261				position.top += overTop;
2262
2263
2264
2265			// Too far down -> align with bottom edge
2266
2267			} else if ( overBottom > 0 ) {
2268
2269				position.top -= overBottom;
2270
2271
2272
2273			// Adjust based on position and margin
2274
2275			} else {
2276
2277				position.top = max( position.top - collisionPosTop, position.top );
2278
2279			}
2280
2281		}
2282
2283	},
2284
2285	flip: {
2286
2287		left: function( position, data ) {
2288
2289			var within = data.within,
2290
2291				withinOffset = within.offset.left + within.scrollLeft,
2292
2293				outerWidth = within.width,
2294
2295				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
2296
2297				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
2298
2299				overLeft = collisionPosLeft - offsetLeft,
2300
2301				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
2302
2303				myOffset = data.my[ 0 ] === "left" ?
2304
2305					-data.elemWidth :
2306
2307					data.my[ 0 ] === "right" ?
2308
2309						data.elemWidth :
2310
2311						0,
2312
2313				atOffset = data.at[ 0 ] === "left" ?
2314
2315					data.targetWidth :
2316
2317					data.at[ 0 ] === "right" ?
2318
2319						-data.targetWidth :
2320
2321						0,
2322
2323				offset = -2 * data.offset[ 0 ],
2324
2325				newOverRight,
2326
2327				newOverLeft;
2328
2329
2330
2331			if ( overLeft < 0 ) {
2332
2333				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -
2334
2335					outerWidth - withinOffset;
2336
2337				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
2338
2339					position.left += myOffset + atOffset + offset;
2340
2341				}
2342
2343			} else if ( overRight > 0 ) {
2344
2345				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +
2346
2347					atOffset + offset - offsetLeft;
2348
2349				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
2350
2351					position.left += myOffset + atOffset + offset;
2352
2353				}
2354
2355			}
2356
2357		},
2358
2359		top: function( position, data ) {
2360
2361			var within = data.within,
2362
2363				withinOffset = within.offset.top + within.scrollTop,
2364
2365				outerHeight = within.height,
2366
2367				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
2368
2369				collisionPosTop = position.top - data.collisionPosition.marginTop,
2370
2371				overTop = collisionPosTop - offsetTop,
2372
2373				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
2374
2375				top = data.my[ 1 ] === "top",
2376
2377				myOffset = top ?
2378
2379					-data.elemHeight :
2380
2381					data.my[ 1 ] === "bottom" ?
2382
2383						data.elemHeight :
2384
2385						0,
2386
2387				atOffset = data.at[ 1 ] === "top" ?
2388
2389					data.targetHeight :
2390
2391					data.at[ 1 ] === "bottom" ?
2392
2393						-data.targetHeight :
2394
2395						0,
2396
2397				offset = -2 * data.offset[ 1 ],
2398
2399				newOverTop,
2400
2401				newOverBottom;
2402
2403			if ( overTop < 0 ) {
2404
2405				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -
2406
2407					outerHeight - withinOffset;
2408
2409				if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
2410
2411					position.top += myOffset + atOffset + offset;
2412
2413				}
2414
2415			} else if ( overBottom > 0 ) {
2416
2417				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +
2418
2419					offset - offsetTop;
2420
2421				if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
2422
2423					position.top += myOffset + atOffset + offset;
2424
2425				}
2426
2427			}
2428
2429		}
2430
2431	},
2432
2433	flipfit: {
2434
2435		left: function() {
2436
2437			$.ui.position.flip.left.apply( this, arguments );
2438
2439			$.ui.position.fit.left.apply( this, arguments );
2440
2441		},
2442
2443		top: function() {
2444
2445			$.ui.position.flip.top.apply( this, arguments );
2446
2447			$.ui.position.fit.top.apply( this, arguments );
2448
2449		}
2450
2451	}
2452
2453};
2454
2455
2456
2457} )();
2458
2459
2460
2461var position = $.ui.position;
2462
2463
2464
2465
2466
2467/*!
2468
2469 * jQuery UI :data 1.12.1
2470
2471 * http://jqueryui.com
vendor: 5,972 bytes, lines 2472-2932
2472
2473 *
2474
2475 * Copyright jQuery Foundation and other contributors
2476
2477 * Released under the MIT license.
2478
2479 * http://jquery.org/license
2480
2481 */
2482
2483
2484
2485//>>label: :data Selector
2486
2487//>>group: Core
2488
2489//>>description: Selects elements which have data stored under the specified key.
2490
2491//>>docs: http://api.jqueryui.com/data-selector/
2492
2493
2494
2495
2496
2497var data = $.extend( $.expr[ ":" ], {
2498
2499	data: $.expr.createPseudo ?
2500
2501		$.expr.createPseudo( function( dataName ) {
2502
2503			return function( elem ) {
2504
2505				return !!$.data( elem, dataName );
2506
2507			};
2508
2509		} ) :
2510
2511
2512
2513		// Support: jQuery <1.8
2514
2515		function( elem, i, match ) {
2516
2517			return !!$.data( elem, match[ 3 ] );
2518
2519		}
2520
2521} );
2522
2523
2524
2525/*!
2526
2527 * jQuery UI Disable Selection 1.12.1
2528
2529 * http://jqueryui.com
2530
2531 *
2532
2533 * Copyright jQuery Foundation and other contributors
2534
2535 * Released under the MIT license.
2536
2537 * http://jquery.org/license
2538
2539 */
2540
2541
2542
2543//>>label: disableSelection
2544
2545//>>group: Core
2546
2547//>>description: Disable selection of text content within the set of matched elements.
2548
2549//>>docs: http://api.jqueryui.com/disableSelection/
2550
2551
2552
2553// This file is deprecated
2554
2555
2556
2557
2558
2559var disableSelection = $.fn.extend( {
2560
2561	disableSelection: ( function() {
2562
2563		var eventType = "onselectstart" in document.createElement( "div" ) ?
2564
2565			"selectstart" :
2566
2567			"mousedown";
2568
2569
2570
2571		return function() {
2572
2573			return this.on( eventType + ".ui-disableSelection", function( event ) {
2574
2575				event.preventDefault();
2576
2577			} );
2578
2579		};
2580
2581	} )(),
2582
2583
2584
2585	enableSelection: function() {
2586
2587		return this.off( ".ui-disableSelection" );
2588
2589	}
2590
2591} );
2592
2593
2594
2595
2596
2597/*!
2598
2599 * jQuery UI Effects 1.12.1
2600
2601 * http://jqueryui.com
2602
2603 *
2604
2605 * Copyright jQuery Foundation and other contributors
2606
2607 * Released under the MIT license.
2608
2609 * http://jquery.org/license
2610
2611 */
2612
2613
2614
2615//>>label: Effects Core
2616
2617//>>group: Effects
2618
2619// jscs:disable maximumLineLength
2620
2621//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects.
2622
2623// jscs:enable maximumLineLength
2624
2625//>>docs: http://api.jqueryui.com/category/effects-core/
2626
2627//>>demos: http://jqueryui.com/effect/
2628
2629
2630
2631
2632
2633
2634
2635var dataSpace = "ui-effects-",
2636
2637	dataSpaceStyle = "ui-effects-style",
2638
2639	dataSpaceAnimated = "ui-effects-animated",
2640
2641
2642
2643	// Create a local jQuery because jQuery Color relies on it and the
2644
2645	// global may not exist with AMD and a custom build (#10199)
2646
2647	jQuery = $;
2648
2649
2650
2651$.effects = {
2652
2653	effect: {}
2654
2655};
2656
2657
2658
2659/*!
2660
2661 * jQuery Color Animations v2.1.2
2662
2663 * https://github.com/jquery/jquery-color
2664
2665 *
2666
2667 * Copyright 2014 jQuery Foundation and other contributors
2668
2669 * Released under the MIT license.
2670
2671 * http://jquery.org/license
2672
2673 *
2674
2675 * Date: Wed Jan 16 08:47:09 2013 -0600
2676
2677 */
2678
2679( function( jQuery, undefined ) {
2680
2681
2682
2683	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " +
2684
2685		"borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
2686
2687
2688
2689	// Plusequals test for += 100 -= 100
2690
2691	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
2692
2693
2694
2695	// A set of RE's that can match strings and generate color tuples.
2696
2697	stringParsers = [ {
2698
2699			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
2700
2701			parse: function( execResult ) {
2702
2703				return [
2704
2705					execResult[ 1 ],
2706
2707					execResult[ 2 ],
2708
2709					execResult[ 3 ],
2710
2711					execResult[ 4 ]
2712
2713				];
2714
2715			}
2716
2717		}, {
2718
2719			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
2720
2721			parse: function( execResult ) {
2722
2723				return [
2724
2725					execResult[ 1 ] * 2.55,
2726
2727					execResult[ 2 ] * 2.55,
2728
2729					execResult[ 3 ] * 2.55,
2730
2731					execResult[ 4 ]
2732
2733				];
2734
2735			}
2736
2737		}, {
2738
2739
2740
2741			// This regex ignores A-F because it's compared against an already lowercased string
2742
2743			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
2744
2745			parse: function( execResult ) {
2746
2747				return [
2748
2749					parseInt( execResult[ 1 ], 16 ),
2750
2751					parseInt( execResult[ 2 ], 16 ),
2752
2753					parseInt( execResult[ 3 ], 16 )
2754
2755				];
2756
2757			}
2758
2759		}, {
2760
2761
2762
2763			// This regex ignores A-F because it's compared against an already lowercased string
2764
2765			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
2766
2767			parse: function( execResult ) {
2768
2769				return [
2770
2771					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
2772
2773					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
2774
2775					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
2776
2777				];
2778
2779			}
2780
2781		}, {
2782
2783			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
2784
2785			space: "hsla",
2786
2787			parse: function( execResult ) {
2788
2789				return [
2790
2791					execResult[ 1 ],
2792
2793					execResult[ 2 ] / 100,
2794
2795					execResult[ 3 ] / 100,
2796
2797					execResult[ 4 ]
2798
2799				];
2800
2801			}
2802
2803		} ],
2804
2805
2806
2807	// JQuery.Color( )
2808
2809	color = jQuery.Color = function( color, green, blue, alpha ) {
2810
2811		return new jQuery.Color.fn.parse( color, green, blue, alpha );
2812
2813	},
2814
2815	spaces = {
2816
2817		rgba: {
2818
2819			props: {
2820
2821				red: {
2822
2823					idx: 0,
2824
2825					type: "byte"
2826
2827				},
2828
2829				green: {
2830
2831					idx: 1,
2832
2833					type: "byte"
2834
2835				},
2836
2837				blue: {
2838
2839					idx: 2,
2840
2841					type: "byte"
2842
2843				}
2844
2845			}
2846
2847		},
2848
2849
2850
2851		hsla: {
2852
2853			props: {
2854
2855				hue: {
2856
2857					idx: 0,
2858
2859					type: "degrees"
2860
2861				},
2862
2863				saturation: {
2864
2865					idx: 1,
2866
2867					type: "percent"
2868
2869				},
2870
2871				lightness: {
2872
2873					idx: 2,
2874
2875					type: "percent"
2876
2877				}
2878
2879			}
2880
2881		}
2882
2883	},
2884
2885	propTypes = {
2886
2887		"byte": {
2888
2889			floor: true,
2890
2891			max: 255
2892
2893		},
2894
2895		"percent": {
2896
2897			max: 1
2898
2899		},
2900
2901		"degrees": {
2902
2903			mod: 360,
2904
2905			floor: true
2906
2907		}
2908
2909	},
2910
2911	support = color.support = {},
2912
2913
2914
2915	// Element for support tests
2916
2917	supportElem = jQuery( "<p>" )[ 0 ],
2918
2919
2920
2921	// Colors = jQuery.Color.names
2922
2923	colors,
2924
2925
2926
2927	// Local aliases of functions called often
2928
2929	each = jQuery.each;
2930
2931
2932
vendor: 20,435 bytes, lines 2933-4398
2933// Determine rgba support immediately
2934
2935supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
2936
2937support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
2938
2939
2940
2941// Define cache name and alpha properties
2942
2943// for rgba and hsla spaces
2944
2945each( spaces, function( spaceName, space ) {
2946
2947	space.cache = "_" + spaceName;
2948
2949	space.props.alpha = {
2950
2951		idx: 3,
2952
2953		type: "percent",
2954
2955		def: 1
2956
2957	};
2958
2959} );
2960
2961
2962
2963function clamp( value, prop, allowEmpty ) {
2964
2965	var type = propTypes[ prop.type ] || {};
2966
2967
2968
2969	if ( value == null ) {
2970
2971		return ( allowEmpty || !prop.def ) ? null : prop.def;
2972
2973	}
2974
2975
2976
2977	// ~~ is an short way of doing floor for positive numbers
2978
2979	value = type.floor ? ~~value : parseFloat( value );
2980
2981
2982
2983	// IE will pass in empty strings as value for alpha,
2984
2985	// which will hit this case
2986
2987	if ( isNaN( value ) ) {
2988
2989		return prop.def;
2990
2991	}
2992
2993
2994
2995	if ( type.mod ) {
2996
2997
2998
2999		// We add mod before modding to make sure that negatives values
3000
3001		// get converted properly: -10 -> 350
3002
3003		return ( value + type.mod ) % type.mod;
3004
3005	}
3006
3007
3008
3009	// For now all property types without mod have min and max
3010
3011	return 0 > value ? 0 : type.max < value ? type.max : value;
3012
3013}
3014
3015
3016
3017function stringParse( string ) {
3018
3019	var inst = color(),
3020
3021		rgba = inst._rgba = [];
3022
3023
3024
3025	string = string.toLowerCase();
3026
3027
3028
3029	each( stringParsers, function( i, parser ) {
3030
3031		var parsed,
3032
3033			match = parser.re.exec( string ),
3034
3035			values = match && parser.parse( match ),
3036
3037			spaceName = parser.space || "rgba";
3038
3039
3040
3041		if ( values ) {
3042
3043			parsed = inst[ spaceName ]( values );
3044
3045
3046
3047			// If this was an rgba parse the assignment might happen twice
3048
3049			// oh well....
3050
3051			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
3052
3053			rgba = inst._rgba = parsed._rgba;
3054
3055
3056
3057			// Exit each( stringParsers ) here because we matched
3058
3059			return false;
3060
3061		}
3062
3063	} );
3064
3065
3066
3067	// Found a stringParser that handled it
3068
3069	if ( rgba.length ) {
3070
3071
3072
3073		// If this came from a parsed string, force "transparent" when alpha is 0
3074
3075		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
3076
3077		if ( rgba.join() === "0,0,0,0" ) {
3078
3079			jQuery.extend( rgba, colors.transparent );
3080
3081		}
3082
3083		return inst;
3084
3085	}
3086
3087
3088
3089	// Named colors
3090
3091	return colors[ string ];
3092
3093}
3094
3095
3096
3097color.fn = jQuery.extend( color.prototype, {
3098
3099	parse: function( red, green, blue, alpha ) {
3100
3101		if ( red === undefined ) {
3102
3103			this._rgba = [ null, null, null, null ];
3104
3105			return this;
3106
3107		}
3108
3109		if ( red.jquery || red.nodeType ) {
3110
3111			red = jQuery( red ).css( green );
3112
3113			green = undefined;
3114
3115		}
3116
3117
3118
3119		var inst = this,
3120
3121			type = jQuery.type( red ),
3122
3123			rgba = this._rgba = [];
3124
3125
3126
3127		// More than 1 argument specified - assume ( red, green, blue, alpha )
3128
3129		if ( green !== undefined ) {
3130
3131			red = [ red, green, blue, alpha ];
3132
3133			type = "array";
3134
3135		}
3136
3137
3138
3139		if ( type === "string" ) {
3140
3141			return this.parse( stringParse( red ) || colors._default );
3142
3143		}
3144
3145
3146
3147		if ( type === "array" ) {
3148
3149			each( spaces.rgba.props, function( key, prop ) {
3150
3151				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
3152
3153			} );
3154
3155			return this;
3156
3157		}
3158
3159
3160
3161		if ( type === "object" ) {
3162
3163			if ( red instanceof color ) {
3164
3165				each( spaces, function( spaceName, space ) {
3166
3167					if ( red[ space.cache ] ) {
3168
3169						inst[ space.cache ] = red[ space.cache ].slice();
3170
3171					}
3172
3173				} );
3174
3175			} else {
3176
3177				each( spaces, function( spaceName, space ) {
3178
3179					var cache = space.cache;
3180
3181					each( space.props, function( key, prop ) {
3182
3183
3184
3185						// If the cache doesn't exist, and we know how to convert
3186
3187						if ( !inst[ cache ] && space.to ) {
3188
3189
3190
3191							// If the value was null, we don't need to copy it
3192
3193							// if the key was alpha, we don't need to copy it either
3194
3195							if ( key === "alpha" || red[ key ] == null ) {
3196
3197								return;
3198
3199							}
3200
3201							inst[ cache ] = space.to( inst._rgba );
3202
3203						}
3204
3205
3206
3207						// This is the only case where we allow nulls for ALL properties.
3208
3209						// call clamp with alwaysAllowEmpty
3210
3211						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
3212
3213					} );
3214
3215
3216
3217					// Everything defined but alpha?
3218
3219					if ( inst[ cache ] &&
3220
3221							jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
3222
3223
3224
3225						// Use the default of 1
3226
3227						inst[ cache ][ 3 ] = 1;
3228
3229						if ( space.from ) {
3230
3231							inst._rgba = space.from( inst[ cache ] );
3232
3233						}
3234
3235					}
3236
3237				} );
3238
3239			}
3240
3241			return this;
3242
3243		}
3244
3245	},
3246
3247	is: function( compare ) {
3248
3249		var is = color( compare ),
3250
3251			same = true,
3252
3253			inst = this;
3254
3255
3256
3257		each( spaces, function( _, space ) {
3258
3259			var localCache,
3260
3261				isCache = is[ space.cache ];
3262
3263			if ( isCache ) {
3264
3265				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
3266
3267				each( space.props, function( _, prop ) {
3268
3269					if ( isCache[ prop.idx ] != null ) {
3270
3271						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
3272
3273						return same;
3274
3275					}
3276
3277				} );
3278
3279			}
3280
3281			return same;
3282
3283		} );
3284
3285		return same;
3286
3287	},
3288
3289	_space: function() {
3290
3291		var used = [],
3292
3293			inst = this;
3294
3295		each( spaces, function( spaceName, space ) {
3296
3297			if ( inst[ space.cache ] ) {
3298
3299				used.push( spaceName );
3300
3301			}
3302
3303		} );
3304
3305		return used.pop();
3306
3307	},
3308
3309	transition: function( other, distance ) {
3310
3311		var end = color( other ),
3312
3313			spaceName = end._space(),
3314
3315			space = spaces[ spaceName ],
3316
3317			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
3318
3319			start = startColor[ space.cache ] || space.to( startColor._rgba ),
3320
3321			result = start.slice();
3322
3323
3324
3325		end = end[ space.cache ];
3326
3327		each( space.props, function( key, prop ) {
3328
3329			var index = prop.idx,
3330
3331				startValue = start[ index ],
3332
3333				endValue = end[ index ],
3334
3335				type = propTypes[ prop.type ] || {};
3336
3337
3338
3339			// If null, don't override start value
3340
3341			if ( endValue === null ) {
3342
3343				return;
3344
3345			}
3346
3347
3348
3349			// If null - use end
3350
3351			if ( startValue === null ) {
3352
3353				result[ index ] = endValue;
3354
3355			} else {
3356
3357				if ( type.mod ) {
3358
3359					if ( endValue - startValue > type.mod / 2 ) {
3360
3361						startValue += type.mod;
3362
3363					} else if ( startValue - endValue > type.mod / 2 ) {
3364
3365						startValue -= type.mod;
3366
3367					}
3368
3369				}
3370
3371				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
3372
3373			}
3374
3375		} );
3376
3377		return this[ spaceName ]( result );
3378
3379	},
3380
3381	blend: function( opaque ) {
3382
3383
3384
3385		// If we are already opaque - return ourself
3386
3387		if ( this._rgba[ 3 ] === 1 ) {
3388
3389			return this;
3390
3391		}
3392
3393
3394
3395		var rgb = this._rgba.slice(),
3396
3397			a = rgb.pop(),
3398
3399			blend = color( opaque )._rgba;
3400
3401
3402
3403		return color( jQuery.map( rgb, function( v, i ) {
3404
3405			return ( 1 - a ) * blend[ i ] + a * v;
3406
3407		} ) );
3408
3409	},
3410
3411	toRgbaString: function() {
3412
3413		var prefix = "rgba(",
3414
3415			rgba = jQuery.map( this._rgba, function( v, i ) {
3416
3417				return v == null ? ( i > 2 ? 1 : 0 ) : v;
3418
3419			} );
3420
3421
3422
3423		if ( rgba[ 3 ] === 1 ) {
3424
3425			rgba.pop();
3426
3427			prefix = "rgb(";
3428
3429		}
3430
3431
3432
3433		return prefix + rgba.join() + ")";
3434
3435	},
3436
3437	toHslaString: function() {
3438
3439		var prefix = "hsla(",
3440
3441			hsla = jQuery.map( this.hsla(), function( v, i ) {
3442
3443				if ( v == null ) {
3444
3445					v = i > 2 ? 1 : 0;
3446
3447				}
3448
3449
3450
3451				// Catch 1 and 2
3452
3453				if ( i && i < 3 ) {
3454
3455					v = Math.round( v * 100 ) + "%";
3456
3457				}
3458
3459				return v;
3460
3461			} );
3462
3463
3464
3465		if ( hsla[ 3 ] === 1 ) {
3466
3467			hsla.pop();
3468
3469			prefix = "hsl(";
3470
3471		}
3472
3473		return prefix + hsla.join() + ")";
3474
3475	},
3476
3477	toHexString: function( includeAlpha ) {
3478
3479		var rgba = this._rgba.slice(),
3480
3481			alpha = rgba.pop();
3482
3483
3484
3485		if ( includeAlpha ) {
3486
3487			rgba.push( ~~( alpha * 255 ) );
3488
3489		}
3490
3491
3492
3493		return "#" + jQuery.map( rgba, function( v ) {
3494
3495
3496
3497			// Default to 0 when nulls exist
3498
3499			v = ( v || 0 ).toString( 16 );
3500
3501			return v.length === 1 ? "0" + v : v;
3502
3503		} ).join( "" );
3504
3505	},
3506
3507	toString: function() {
3508
3509		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
3510
3511	}
3512
3513} );
3514
3515color.fn.parse.prototype = color.fn;
3516
3517
3518
3519// Hsla conversions adapted from:
3520
3521// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
3522
3523
3524
3525function hue2rgb( p, q, h ) {
3526
3527	h = ( h + 1 ) % 1;
3528
3529	if ( h * 6 < 1 ) {
3530
3531		return p + ( q - p ) * h * 6;
3532
3533	}
3534
3535	if ( h * 2 < 1 ) {
3536
3537		return q;
3538
3539	}
3540
3541	if ( h * 3 < 2 ) {
3542
3543		return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
3544
3545	}
3546
3547	return p;
3548
3549}
3550
3551
3552
3553spaces.hsla.to = function( rgba ) {
3554
3555	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
3556
3557		return [ null, null, null, rgba[ 3 ] ];
3558
3559	}
3560
3561	var r = rgba[ 0 ] / 255,
3562
3563		g = rgba[ 1 ] / 255,
3564
3565		b = rgba[ 2 ] / 255,
3566
3567		a = rgba[ 3 ],
3568
3569		max = Math.max( r, g, b ),
3570
3571		min = Math.min( r, g, b ),
3572
3573		diff = max - min,
3574
3575		add = max + min,
3576
3577		l = add * 0.5,
3578
3579		h, s;
3580
3581
3582
3583	if ( min === max ) {
3584
3585		h = 0;
3586
3587	} else if ( r === max ) {
3588
3589		h = ( 60 * ( g - b ) / diff ) + 360;
3590
3591	} else if ( g === max ) {
3592
3593		h = ( 60 * ( b - r ) / diff ) + 120;
3594
3595	} else {
3596
3597		h = ( 60 * ( r - g ) / diff ) + 240;
3598
3599	}
3600
3601
3602
3603	// Chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
3604
3605	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
3606
3607	if ( diff === 0 ) {
3608
3609		s = 0;
3610
3611	} else if ( l <= 0.5 ) {
3612
3613		s = diff / add;
3614
3615	} else {
3616
3617		s = diff / ( 2 - add );
3618
3619	}
3620
3621	return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ];
3622
3623};
3624
3625
3626
3627spaces.hsla.from = function( hsla ) {
3628
3629	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
3630
3631		return [ null, null, null, hsla[ 3 ] ];
3632
3633	}
3634
3635	var h = hsla[ 0 ] / 360,
3636
3637		s = hsla[ 1 ],
3638
3639		l = hsla[ 2 ],
3640
3641		a = hsla[ 3 ],
3642
3643		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
3644
3645		p = 2 * l - q;
3646
3647
3648
3649	return [
3650
3651		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
3652
3653		Math.round( hue2rgb( p, q, h ) * 255 ),
3654
3655		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
3656
3657		a
3658
3659	];
3660
3661};
3662
3663
3664
3665each( spaces, function( spaceName, space ) {
3666
3667	var props = space.props,
3668
3669		cache = space.cache,
3670
3671		to = space.to,
3672
3673		from = space.from;
3674
3675
3676
3677	// Makes rgba() and hsla()
3678
3679	color.fn[ spaceName ] = function( value ) {
3680
3681
3682
3683		// Generate a cache for this space if it doesn't exist
3684
3685		if ( to && !this[ cache ] ) {
3686
3687			this[ cache ] = to( this._rgba );
3688
3689		}
3690
3691		if ( value === undefined ) {
3692
3693			return this[ cache ].slice();
3694
3695		}
3696
3697
3698
3699		var ret,
3700
3701			type = jQuery.type( value ),
3702
3703			arr = ( type === "array" || type === "object" ) ? value : arguments,
3704
3705			local = this[ cache ].slice();
3706
3707
3708
3709		each( props, function( key, prop ) {
3710
3711			var val = arr[ type === "object" ? key : prop.idx ];
3712
3713			if ( val == null ) {
3714
3715				val = local[ prop.idx ];
3716
3717			}
3718
3719			local[ prop.idx ] = clamp( val, prop );
3720
3721		} );
3722
3723
3724
3725		if ( from ) {
3726
3727			ret = color( from( local ) );
3728
3729			ret[ cache ] = local;
3730
3731			return ret;
3732
3733		} else {
3734
3735			return color( local );
3736
3737		}
3738
3739	};
3740
3741
3742
3743	// Makes red() green() blue() alpha() hue() saturation() lightness()
3744
3745	each( props, function( key, prop ) {
3746
3747
3748
3749		// Alpha is included in more than one space
3750
3751		if ( color.fn[ key ] ) {
3752
3753			return;
3754
3755		}
3756
3757		color.fn[ key ] = function( value ) {
3758
3759			var vtype = jQuery.type( value ),
3760
3761				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
3762
3763				local = this[ fn ](),
3764
3765				cur = local[ prop.idx ],
3766
3767				match;
3768
3769
3770
3771			if ( vtype === "undefined" ) {
3772
3773				return cur;
3774
3775			}
3776
3777
3778
3779			if ( vtype === "function" ) {
3780
3781				value = value.call( this, cur );
3782
3783				vtype = jQuery.type( value );
3784
3785			}
3786
3787			if ( value == null && prop.empty ) {
3788
3789				return this;
3790
3791			}
3792
3793			if ( vtype === "string" ) {
3794
3795				match = rplusequals.exec( value );
3796
3797				if ( match ) {
3798
3799					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
3800
3801				}
3802
3803			}
3804
3805			local[ prop.idx ] = value;
3806
3807			return this[ fn ]( local );
3808
3809		};
3810
3811	} );
3812
3813} );
3814
3815
3816
3817// Add cssHook and .fx.step function for each named hook.
3818
3819// accept a space separated string of properties
3820
3821color.hook = function( hook ) {
3822
3823	var hooks = hook.split( " " );
3824
3825	each( hooks, function( i, hook ) {
3826
3827		jQuery.cssHooks[ hook ] = {
3828
3829			set: function( elem, value ) {
3830
3831				var parsed, curElem,
3832
3833					backgroundColor = "";
3834
3835
3836
3837				if ( value !== "transparent" && ( jQuery.type( value ) !== "string" ||
3838
3839						( parsed = stringParse( value ) ) ) ) {
3840
3841					value = color( parsed || value );
3842
3843					if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
3844
3845						curElem = hook === "backgroundColor" ? elem.parentNode : elem;
3846
3847						while (
3848
3849							( backgroundColor === "" || backgroundColor === "transparent" ) &&
3850
3851							curElem && curElem.style
3852
3853						) {
3854
3855							try {
3856
3857								backgroundColor = jQuery.css( curElem, "backgroundColor" );
3858
3859								curElem = curElem.parentNode;
3860
3861							} catch ( e ) {
3862
3863							}
3864
3865						}
3866
3867
3868
3869						value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
3870
3871							backgroundColor :
3872
3873							"_default" );
3874
3875					}
3876
3877
3878
3879					value = value.toRgbaString();
3880
3881				}
3882
3883				try {
3884
3885					elem.style[ hook ] = value;
3886
3887				} catch ( e ) {
3888
3889
3890
3891					// Wrapped to prevent IE from throwing errors on "invalid" values like
3892
3893					// 'auto' or 'inherit'
3894
3895				}
3896
3897			}
3898
3899		};
3900
3901		jQuery.fx.step[ hook ] = function( fx ) {
3902
3903			if ( !fx.colorInit ) {
3904
3905				fx.start = color( fx.elem, hook );
3906
3907				fx.end = color( fx.end );
3908
3909				fx.colorInit = true;
3910
3911			}
3912
3913			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
3914
3915		};
3916
3917	} );
3918
3919
3920
3921};
3922
3923
3924
3925color.hook( stepHooks );
3926
3927
3928
3929jQuery.cssHooks.borderColor = {
3930
3931	expand: function( value ) {
3932
3933		var expanded = {};
3934
3935
3936
3937		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
3938
3939			expanded[ "border" + part + "Color" ] = value;
3940
3941		} );
3942
3943		return expanded;
3944
3945	}
3946
3947};
3948
3949
3950
3951// Basic color names only.
3952
3953// Usage of any of the other color names requires adding yourself or including
3954
3955// jquery.color.svg-names.js.
3956
3957colors = jQuery.Color.names = {
3958
3959
3960
3961	// 4.1. Basic color keywords
3962
3963	aqua: "#00ffff",
3964
3965	black: "#000000",
3966
3967	blue: "#0000ff",
3968
3969	fuchsia: "#ff00ff",
3970
3971	gray: "#808080",
3972
3973	green: "#008000",
3974
3975	lime: "#00ff00",
3976
3977	maroon: "#800000",
3978
3979	navy: "#000080",
3980
3981	olive: "#808000",
3982
3983	purple: "#800080",
3984
3985	red: "#ff0000",
3986
3987	silver: "#c0c0c0",
3988
3989	teal: "#008080",
3990
3991	white: "#ffffff",
3992
3993	yellow: "#ffff00",
3994
3995
3996
3997	// 4.2.3. "transparent" color keyword
3998
3999	transparent: [ null, null, null, 0 ],
4000
4001
4002
4003	_default: "#ffffff"
4004
4005};
4006
4007
4008
4009} )( jQuery );
4010
4011
4012
4013/******************************************************************************/
4014
4015/****************************** CLASS ANIMATIONS ******************************/
4016
4017/******************************************************************************/
4018
4019( function() {
4020
4021
4022
4023var classAnimationActions = [ "add", "remove", "toggle" ],
4024
4025	shorthandStyles = {
4026
4027		border: 1,
4028
4029		borderBottom: 1,
4030
4031		borderColor: 1,
4032
4033		borderLeft: 1,
4034
4035		borderRight: 1,
4036
4037		borderTop: 1,
4038
4039		borderWidth: 1,
4040
4041		margin: 1,
4042
4043		padding: 1
4044
4045	};
4046
4047
4048
4049$.each(
4050
4051	[ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ],
4052
4053	function( _, prop ) {
4054
4055		$.fx.step[ prop ] = function( fx ) {
4056
4057			if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
4058
4059				jQuery.style( fx.elem, prop, fx.end );
4060
4061				fx.setAttr = true;
4062
4063			}
4064
4065		};
4066
4067	}
4068
4069);
4070
4071
4072
4073function getElementStyles( elem ) {
4074
4075	var key, len,
4076
4077		style = elem.ownerDocument.defaultView ?
4078
4079			elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
4080
4081			elem.currentStyle,
4082
4083		styles = {};
4084
4085
4086
4087	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
4088
4089		len = style.length;
4090
4091		while ( len-- ) {
4092
4093			key = style[ len ];
4094
4095			if ( typeof style[ key ] === "string" ) {
4096
4097				styles[ $.camelCase( key ) ] = style[ key ];
4098
4099			}
4100
4101		}
4102
4103
4104
4105	// Support: Opera, IE <9
4106
4107	} else {
4108
4109		for ( key in style ) {
4110
4111			if ( typeof style[ key ] === "string" ) {
4112
4113				styles[ key ] = style[ key ];
4114
4115			}
4116
4117		}
4118
4119	}
4120
4121
4122
4123	return styles;
4124
4125}
4126
4127
4128
4129function styleDifference( oldStyle, newStyle ) {
4130
4131	var diff = {},
4132
4133		name, value;
4134
4135
4136
4137	for ( name in newStyle ) {
4138
4139		value = newStyle[ name ];
4140
4141		if ( oldStyle[ name ] !== value ) {
4142
4143			if ( !shorthandStyles[ name ] ) {
4144
4145				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
4146
4147					diff[ name ] = value;
4148
4149				}
4150
4151			}
4152
4153		}
4154
4155	}
4156
4157
4158
4159	return diff;
4160
4161}
4162
4163
4164
4165// Support: jQuery <1.8
4166
4167if ( !$.fn.addBack ) {
4168
4169	$.fn.addBack = function( selector ) {
4170
4171		return this.add( selector == null ?
4172
4173			this.prevObject : this.prevObject.filter( selector )
4174
4175		);
4176
4177	};
4178
4179}
4180
4181
4182
4183$.effects.animateClass = function( value, duration, easing, callback ) {
4184
4185	var o = $.speed( duration, easing, callback );
4186
4187
4188
4189	return this.queue( function() {
4190
4191		var animated = $( this ),
4192
4193			baseClass = animated.attr( "class" ) || "",
4194
4195			applyClassChange,
4196
4197			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
4198
4199
4200
4201		// Map the animated objects to store the original styles.
4202
4203		allAnimations = allAnimations.map( function() {
4204
4205			var el = $( this );
4206
4207			return {
4208
4209				el: el,
4210
4211				start: getElementStyles( this )
4212
4213			};
4214
4215		} );
4216
4217
4218
4219		// Apply class change
4220
4221		applyClassChange = function() {
4222
4223			$.each( classAnimationActions, function( i, action ) {
4224
4225				if ( value[ action ] ) {
4226
4227					animated[ action + "Class" ]( value[ action ] );
4228
4229				}
4230
4231			} );
4232
4233		};
4234
4235		applyClassChange();
4236
4237
4238
4239		// Map all animated objects again - calculate new styles and diff
4240
4241		allAnimations = allAnimations.map( function() {
4242
4243			this.end = getElementStyles( this.el[ 0 ] );
4244
4245			this.diff = styleDifference( this.start, this.end );
4246
4247			return this;
4248
4249		} );
4250
4251
4252
4253		// Apply original class
4254
4255		animated.attr( "class", baseClass );
4256
4257
4258
4259		// Map all animated objects again - this time collecting a promise
4260
4261		allAnimations = allAnimations.map( function() {
4262
4263			var styleInfo = this,
4264
4265				dfd = $.Deferred(),
4266
4267				opts = $.extend( {}, o, {
4268
4269					queue: false,
4270
4271					complete: function() {
4272
4273						dfd.resolve( styleInfo );
4274
4275					}
4276
4277				} );
4278
4279
4280
4281			this.el.animate( this.diff, opts );
4282
4283			return dfd.promise();
4284
4285		} );
4286
4287
4288
4289		// Once all animations have completed:
4290
4291		$.when.apply( $, allAnimations.get() ).done( function() {
4292
4293
4294
4295			// Set the final class
4296
4297			applyClassChange();
4298
4299
4300
4301			// For each animated element,
4302
4303			// clear all css properties that were animated
4304
4305			$.each( arguments, function() {
4306
4307				var el = this.el;
4308
4309				$.each( this.diff, function( key ) {
4310
4311					el.css( key, "" );
4312
4313				} );
4314
4315			} );
4316
4317
4318
4319			// This is guarnteed to be there if you use jQuery.speed()
4320
4321			// it also handles dequeuing the next anim...
4322
4323			o.complete.call( animated[ 0 ] );
4324
4325		} );
4326
4327	} );
4328
4329};
4330
4331
4332
4333$.fn.extend( {
4334
4335	addClass: ( function( orig ) {
4336
4337		return function( classNames, speed, easing, callback ) {
4338
4339			return speed ?
4340
4341				$.effects.animateClass.call( this,
4342
4343					{ add: classNames }, speed, easing, callback ) :
4344
4345				orig.apply( this, arguments );
4346
4347		};
4348
4349	} )( $.fn.addClass ),
4350
4351
4352
4353	removeClass: ( function( orig ) {
4354
4355		return function( classNames, speed, easing, callback ) {
4356
4357			return arguments.length > 1 ?
4358
4359				$.effects.animateClass.call( this,
4360
4361					{ remove: classNames }, speed, easing, callback ) :
4362
4363				orig.apply( this, arguments );
4364
4365		};
4366
4367	} )( $.fn.removeClass ),
4368
4369
4370
4371	toggleClass: ( function( orig ) {
4372
4373		return function( classNames, force, speed, easing, callback ) {
4374
4375			if ( typeof force === "boolean" || force === undefined ) {
4376
4377				if ( !speed ) {
4378
4379
4380
4381					// Without speed parameter
4382
4383					return orig.apply( this, arguments );
4384
4385				} else {
4386
4387					return $.effects.animateClass.call( this,
4388
4389						( force ? { add: classNames } : { remove: classNames } ),
4390
4391						speed, easing, callback );
4392
4393				}
4394
4395			} else {
4396
4397
4398
vendor: 4,376 bytes, lines 4399-4692
4399				// Without force parameter
4400
4401				return $.effects.animateClass.call( this,
4402
4403					{ toggle: classNames }, force, speed, easing );
4404
4405			}
4406
4407		};
4408
4409	} )( $.fn.toggleClass ),
4410
4411
4412
4413	switchClass: function( remove, add, speed, easing, callback ) {
4414
4415		return $.effects.animateClass.call( this, {
4416
4417			add: add,
4418
4419			remove: remove
4420
4421		}, speed, easing, callback );
4422
4423	}
4424
4425} );
4426
4427
4428
4429} )();
4430
4431
4432
4433/******************************************************************************/
4434
4435/*********************************** EFFECTS **********************************/
4436
4437/******************************************************************************/
4438
4439
4440
4441( function() {
4442
4443
4444
4445if ( $.expr && $.expr.filters && $.expr.filters.animated ) {
4446
4447	$.expr.filters.animated = ( function( orig ) {
4448
4449		return function( elem ) {
4450
4451			return !!$( elem ).data( dataSpaceAnimated ) || orig( elem );
4452
4453		};
4454
4455	} )( $.expr.filters.animated );
4456
4457}
4458
4459
4460
4461if ( $.uiBackCompat !== false ) {
4462
4463	$.extend( $.effects, {
4464
4465
4466
4467		// Saves a set of properties in a data storage
4468
4469		save: function( element, set ) {
4470
4471			var i = 0, length = set.length;
4472
4473			for ( ; i < length; i++ ) {
4474
4475				if ( set[ i ] !== null ) {
4476
4477					element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
4478
4479				}
4480
4481			}
4482
4483		},
4484
4485
4486
4487		// Restores a set of previously saved properties from a data storage
4488
4489		restore: function( element, set ) {
4490
4491			var val, i = 0, length = set.length;
4492
4493			for ( ; i < length; i++ ) {
4494
4495				if ( set[ i ] !== null ) {
4496
4497					val = element.data( dataSpace + set[ i ] );
4498
4499					element.css( set[ i ], val );
4500
4501				}
4502
4503			}
4504
4505		},
4506
4507
4508
4509		setMode: function( el, mode ) {
4510
4511			if ( mode === "toggle" ) {
4512
4513				mode = el.is( ":hidden" ) ? "show" : "hide";
4514
4515			}
4516
4517			return mode;
4518
4519		},
4520
4521
4522
4523		// Wraps the element around a wrapper that copies position properties
4524
4525		createWrapper: function( element ) {
4526
4527
4528
4529			// If the element is already wrapped, return it
4530
4531			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
4532
4533				return element.parent();
4534
4535			}
4536
4537
4538
4539			// Wrap the element
4540
4541			var props = {
4542
4543					width: element.outerWidth( true ),
4544
4545					height: element.outerHeight( true ),
4546
4547					"float": element.css( "float" )
4548
4549				},
4550
4551				wrapper = $( "<div></div>" )
4552
4553					.addClass( "ui-effects-wrapper" )
4554
4555					.css( {
4556
4557						fontSize: "100%",
4558
4559						background: "transparent",
4560
4561						border: "none",
4562
4563						margin: 0,
4564
4565						padding: 0
4566
4567					} ),
4568
4569
4570
4571				// Store the size in case width/height are defined in % - Fixes #5245
4572
4573				size = {
4574
4575					width: element.width(),
4576
4577					height: element.height()
4578
4579				},
4580
4581				active = document.activeElement;
4582
4583
4584
4585			// Support: Firefox
4586
4587			// Firefox incorrectly exposes anonymous content
4588
4589			// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
4590
4591			try {
4592
4593				active.id;
4594
4595			} catch ( e ) {
4596
4597				active = document.body;
4598
4599			}
4600
4601
4602
4603			element.wrap( wrapper );
4604
4605
4606
4607			// Fixes #7595 - Elements lose focus when wrapped.
4608
4609			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
4610
4611				$( active ).trigger( "focus" );
4612
4613			}
4614
4615
4616
4617			// Hotfix for jQuery 1.4 since some change in wrap() seems to actually
4618
4619			// lose the reference to the wrapped element
4620
4621			wrapper = element.parent();
4622
4623
4624
4625			// Transfer positioning properties to the wrapper
4626
4627			if ( element.css( "position" ) === "static" ) {
4628
4629				wrapper.css( { position: "relative" } );
4630
4631				element.css( { position: "relative" } );
4632
4633			} else {
4634
4635				$.extend( props, {
4636
4637					position: element.css( "position" ),
4638
4639					zIndex: element.css( "z-index" )
4640
4641				} );
4642
4643				$.each( [ "top", "left", "bottom", "right" ], function( i, pos ) {
4644
4645					props[ pos ] = element.css( pos );
4646
4647					if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
4648
4649						props[ pos ] = "auto";
4650
4651					}
4652
4653				} );
4654
4655				element.css( {
4656
4657					position: "relative",
4658
4659					top: 0,
4660
4661					left: 0,
4662
4663					right: "auto",
4664
4665					bottom: "auto"
4666
4667				} );
4668
4669			}
4670
4671			element.css( size );
4672
4673
4674
4675			return wrapper.css( props ).show();
4676
4677		},
4678
4679
4680
4681		removeWrapper: function( element ) {
4682
4683			var active = document.activeElement;
4684
4685
4686
4687			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
4688
4689				element.parent().replaceWith( element );
4690
4691
4692
vendor: 17,840 bytes, lines 4693-5963
4693				// Fixes #7595 - Elements lose focus when wrapped.
4694
4695				if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
4696
4697					$( active ).trigger( "focus" );
4698
4699				}
4700
4701			}
4702
4703
4704
4705			return element;
4706
4707		}
4708
4709	} );
4710
4711}
4712
4713
4714
4715$.extend( $.effects, {
4716
4717	version: "1.12.1",
4718
4719
4720
4721	define: function( name, mode, effect ) {
4722
4723		if ( !effect ) {
4724
4725			effect = mode;
4726
4727			mode = "effect";
4728
4729		}
4730
4731
4732
4733		$.effects.effect[ name ] = effect;
4734
4735		$.effects.effect[ name ].mode = mode;
4736
4737
4738
4739		return effect;
4740
4741	},
4742
4743
4744
4745	scaledDimensions: function( element, percent, direction ) {
4746
4747		if ( percent === 0 ) {
4748
4749			return {
4750
4751				height: 0,
4752
4753				width: 0,
4754
4755				outerHeight: 0,
4756
4757				outerWidth: 0
4758
4759			};
4760
4761		}
4762
4763
4764
4765		var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1,
4766
4767			y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1;
4768
4769
4770
4771		return {
4772
4773			height: element.height() * y,
4774
4775			width: element.width() * x,
4776
4777			outerHeight: element.outerHeight() * y,
4778
4779			outerWidth: element.outerWidth() * x
4780
4781		};
4782
4783
4784
4785	},
4786
4787
4788
4789	clipToBox: function( animation ) {
4790
4791		return {
4792
4793			width: animation.clip.right - animation.clip.left,
4794
4795			height: animation.clip.bottom - animation.clip.top,
4796
4797			left: animation.clip.left,
4798
4799			top: animation.clip.top
4800
4801		};
4802
4803	},
4804
4805
4806
4807	// Injects recently queued functions to be first in line (after "inprogress")
4808
4809	unshift: function( element, queueLength, count ) {
4810
4811		var queue = element.queue();
4812
4813
4814
4815		if ( queueLength > 1 ) {
4816
4817			queue.splice.apply( queue,
4818
4819				[ 1, 0 ].concat( queue.splice( queueLength, count ) ) );
4820
4821		}
4822
4823		element.dequeue();
4824
4825	},
4826
4827
4828
4829	saveStyle: function( element ) {
4830
4831		element.data( dataSpaceStyle, element[ 0 ].style.cssText );
4832
4833	},
4834
4835
4836
4837	restoreStyle: function( element ) {
4838
4839		element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || "";
4840
4841		element.removeData( dataSpaceStyle );
4842
4843	},
4844
4845
4846
4847	mode: function( element, mode ) {
4848
4849		var hidden = element.is( ":hidden" );
4850
4851
4852
4853		if ( mode === "toggle" ) {
4854
4855			mode = hidden ? "show" : "hide";
4856
4857		}
4858
4859		if ( hidden ? mode === "hide" : mode === "show" ) {
4860
4861			mode = "none";
4862
4863		}
4864
4865		return mode;
4866
4867	},
4868
4869
4870
4871	// Translates a [top,left] array into a baseline value
4872
4873	getBaseline: function( origin, original ) {
4874
4875		var y, x;
4876
4877
4878
4879		switch ( origin[ 0 ] ) {
4880
4881		case "top":
4882
4883			y = 0;
4884
4885			break;
4886
4887		case "middle":
4888
4889			y = 0.5;
4890
4891			break;
4892
4893		case "bottom":
4894
4895			y = 1;
4896
4897			break;
4898
4899		default:
4900
4901			y = origin[ 0 ] / original.height;
4902
4903		}
4904
4905
4906
4907		switch ( origin[ 1 ] ) {
4908
4909		case "left":
4910
4911			x = 0;
4912
4913			break;
4914
4915		case "center":
4916
4917			x = 0.5;
4918
4919			break;
4920
4921		case "right":
4922
4923			x = 1;
4924
4925			break;
4926
4927		default:
4928
4929			x = origin[ 1 ] / original.width;
4930
4931		}
4932
4933
4934
4935		return {
4936
4937			x: x,
4938
4939			y: y
4940
4941		};
4942
4943	},
4944
4945
4946
4947	// Creates a placeholder element so that the original element can be made absolute
4948
4949	createPlaceholder: function( element ) {
4950
4951		var placeholder,
4952
4953			cssPosition = element.css( "position" ),
4954
4955			position = element.position();
4956
4957
4958
4959		// Lock in margins first to account for form elements, which
4960
4961		// will change margin if you explicitly set height
4962
4963		// see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380
4964
4965		// Support: Safari
4966
4967		element.css( {
4968
4969			marginTop: element.css( "marginTop" ),
4970
4971			marginBottom: element.css( "marginBottom" ),
4972
4973			marginLeft: element.css( "marginLeft" ),
4974
4975			marginRight: element.css( "marginRight" )
4976
4977		} )
4978
4979		.outerWidth( element.outerWidth() )
4980
4981		.outerHeight( element.outerHeight() );
4982
4983
4984
4985		if ( /^(static|relative)/.test( cssPosition ) ) {
4986
4987			cssPosition = "absolute";
4988
4989
4990
4991			placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( {
4992
4993
4994
4995				// Convert inline to inline block to account for inline elements
4996
4997				// that turn to inline block based on content (like img)
4998
4999				display: /^(inline|ruby)/.test( element.css( "display" ) ) ?
5000
5001					"inline-block" :
5002
5003					"block",
5004
5005				visibility: "hidden",
5006
5007
5008
5009				// Margins need to be set to account for margin collapse
5010
5011				marginTop: element.css( "marginTop" ),
5012
5013				marginBottom: element.css( "marginBottom" ),
5014
5015				marginLeft: element.css( "marginLeft" ),
5016
5017				marginRight: element.css( "marginRight" ),
5018
5019				"float": element.css( "float" )
5020
5021			} )
5022
5023			.outerWidth( element.outerWidth() )
5024
5025			.outerHeight( element.outerHeight() )
5026
5027			.addClass( "ui-effects-placeholder" );
5028
5029
5030
5031			element.data( dataSpace + "placeholder", placeholder );
5032
5033		}
5034
5035
5036
5037		element.css( {
5038
5039			position: cssPosition,
5040
5041			left: position.left,
5042
5043			top: position.top
5044
5045		} );
5046
5047
5048
5049		return placeholder;
5050
5051	},
5052
5053
5054
5055	removePlaceholder: function( element ) {
5056
5057		var dataKey = dataSpace + "placeholder",
5058
5059				placeholder = element.data( dataKey );
5060
5061
5062
5063		if ( placeholder ) {
5064
5065			placeholder.remove();
5066
5067			element.removeData( dataKey );
5068
5069		}
5070
5071	},
5072
5073
5074
5075	// Removes a placeholder if it exists and restores
5076
5077	// properties that were modified during placeholder creation
5078
5079	cleanUp: function( element ) {
5080
5081		$.effects.restoreStyle( element );
5082
5083		$.effects.removePlaceholder( element );
5084
5085	},
5086
5087
5088
5089	setTransition: function( element, list, factor, value ) {
5090
5091		value = value || {};
5092
5093		$.each( list, function( i, x ) {
5094
5095			var unit = element.cssUnit( x );
5096
5097			if ( unit[ 0 ] > 0 ) {
5098
5099				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
5100
5101			}
5102
5103		} );
5104
5105		return value;
5106
5107	}
5108
5109} );
5110
5111
5112
5113// Return an effect options object for the given parameters:
5114
5115function _normalizeArguments( effect, options, speed, callback ) {
5116
5117
5118
5119	// Allow passing all options as the first parameter
5120
5121	if ( $.isPlainObject( effect ) ) {
5122
5123		options = effect;
5124
5125		effect = effect.effect;
5126
5127	}
5128
5129
5130
5131	// Convert to an object
5132
5133	effect = { effect: effect };
5134
5135
5136
5137	// Catch (effect, null, ...)
5138
5139	if ( options == null ) {
5140
5141		options = {};
5142
5143	}
5144
5145
5146
5147	// Catch (effect, callback)
5148
5149	if ( $.isFunction( options ) ) {
5150
5151		callback = options;
5152
5153		speed = null;
5154
5155		options = {};
5156
5157	}
5158
5159
5160
5161	// Catch (effect, speed, ?)
5162
5163	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
5164
5165		callback = speed;
5166
5167		speed = options;
5168
5169		options = {};
5170
5171	}
5172
5173
5174
5175	// Catch (effect, options, callback)
5176
5177	if ( $.isFunction( speed ) ) {
5178
5179		callback = speed;
5180
5181		speed = null;
5182
5183	}
5184
5185
5186
5187	// Add options to effect
5188
5189	if ( options ) {
5190
5191		$.extend( effect, options );
5192
5193	}
5194
5195
5196
5197	speed = speed || options.duration;
5198
5199	effect.duration = $.fx.off ? 0 :
5200
5201		typeof speed === "number" ? speed :
5202
5203		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
5204
5205		$.fx.speeds._default;
5206
5207
5208
5209	effect.complete = callback || options.complete;
5210
5211
5212
5213	return effect;
5214
5215}
5216
5217
5218
5219function standardAnimationOption( option ) {
5220
5221
5222
5223	// Valid standard speeds (nothing, number, named speed)
5224
5225	if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
5226
5227		return true;
5228
5229	}
5230
5231
5232
5233	// Invalid strings - treat as "normal" speed
5234
5235	if ( typeof option === "string" && !$.effects.effect[ option ] ) {
5236
5237		return true;
5238
5239	}
5240
5241
5242
5243	// Complete callback
5244
5245	if ( $.isFunction( option ) ) {
5246
5247		return true;
5248
5249	}
5250
5251
5252
5253	// Options hash (but not naming an effect)
5254
5255	if ( typeof option === "object" && !option.effect ) {
5256
5257		return true;
5258
5259	}
5260
5261
5262
5263	// Didn't match any standard API
5264
5265	return false;
5266
5267}
5268
5269
5270
5271$.fn.extend( {
5272
5273	effect: function( /* effect, options, speed, callback */ ) {
5274
5275		var args = _normalizeArguments.apply( this, arguments ),
5276
5277			effectMethod = $.effects.effect[ args.effect ],
5278
5279			defaultMode = effectMethod.mode,
5280
5281			queue = args.queue,
5282
5283			queueName = queue || "fx",
5284
5285			complete = args.complete,
5286
5287			mode = args.mode,
5288
5289			modes = [],
5290
5291			prefilter = function( next ) {
5292
5293				var el = $( this ),
5294
5295					normalizedMode = $.effects.mode( el, mode ) || defaultMode;
5296
5297
5298
5299				// Sentinel for duck-punching the :animated psuedo-selector
5300
5301				el.data( dataSpaceAnimated, true );
5302
5303
5304
5305				// Save effect mode for later use,
5306
5307				// we can't just call $.effects.mode again later,
5308
5309				// as the .show() below destroys the initial state
5310
5311				modes.push( normalizedMode );
5312
5313
5314
5315				// See $.uiBackCompat inside of run() for removal of defaultMode in 1.13
5316
5317				if ( defaultMode && ( normalizedMode === "show" ||
5318
5319						( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) {
5320
5321					el.show();
5322
5323				}
5324
5325
5326
5327				if ( !defaultMode || normalizedMode !== "none" ) {
5328
5329					$.effects.saveStyle( el );
5330
5331				}
5332
5333
5334
5335				if ( $.isFunction( next ) ) {
5336
5337					next();
5338
5339				}
5340
5341			};
5342
5343
5344
5345		if ( $.fx.off || !effectMethod ) {
5346
5347
5348
5349			// Delegate to the original method (e.g., .show()) if possible
5350
5351			if ( mode ) {
5352
5353				return this[ mode ]( args.duration, complete );
5354
5355			} else {
5356
5357				return this.each( function() {
5358
5359					if ( complete ) {
5360
5361						complete.call( this );
5362
5363					}
5364
5365				} );
5366
5367			}
5368
5369		}
5370
5371
5372
5373		function run( next ) {
5374
5375			var elem = $( this );
5376
5377
5378
5379			function cleanup() {
5380
5381				elem.removeData( dataSpaceAnimated );
5382
5383
5384
5385				$.effects.cleanUp( elem );
5386
5387
5388
5389				if ( args.mode === "hide" ) {
5390
5391					elem.hide();
5392
5393				}
5394
5395
5396
5397				done();
5398
5399			}
5400
5401
5402
5403			function done() {
5404
5405				if ( $.isFunction( complete ) ) {
5406
5407					complete.call( elem[ 0 ] );
5408
5409				}
5410
5411
5412
5413				if ( $.isFunction( next ) ) {
5414
5415					next();
5416
5417				}
5418
5419			}
5420
5421
5422
5423			// Override mode option on a per element basis,
5424
5425			// as toggle can be either show or hide depending on element state
5426
5427			args.mode = modes.shift();
5428
5429
5430
5431			if ( $.uiBackCompat !== false && !defaultMode ) {
5432
5433				if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
5434
5435
5436
5437					// Call the core method to track "olddisplay" properly
5438
5439					elem[ mode ]();
5440
5441					done();
5442
5443				} else {
5444
5445					effectMethod.call( elem[ 0 ], args, done );
5446
5447				}
5448
5449			} else {
5450
5451				if ( args.mode === "none" ) {
5452
5453
5454
5455					// Call the core method to track "olddisplay" properly
5456
5457					elem[ mode ]();
5458
5459					done();
5460
5461				} else {
5462
5463					effectMethod.call( elem[ 0 ], args, cleanup );
5464
5465				}
5466
5467			}
5468
5469		}
5470
5471
5472
5473		// Run prefilter on all elements first to ensure that
5474
5475		// any showing or hiding happens before placeholder creation,
5476
5477		// which ensures that any layout changes are correctly captured.
5478
5479		return queue === false ?
5480
5481			this.each( prefilter ).each( run ) :
5482
5483			this.queue( queueName, prefilter ).queue( queueName, run );
5484
5485	},
5486
5487
5488
5489	show: ( function( orig ) {
5490
5491		return function( option ) {
5492
5493			if ( standardAnimationOption( option ) ) {
5494
5495				return orig.apply( this, arguments );
5496
5497			} else {
5498
5499				var args = _normalizeArguments.apply( this, arguments );
5500
5501				args.mode = "show";
5502
5503				return this.effect.call( this, args );
5504
5505			}
5506
5507		};
5508
5509	} )( $.fn.show ),
5510
5511
5512
5513	hide: ( function( orig ) {
5514
5515		return function( option ) {
5516
5517			if ( standardAnimationOption( option ) ) {
5518
5519				return orig.apply( this, arguments );
5520
5521			} else {
5522
5523				var args = _normalizeArguments.apply( this, arguments );
5524
5525				args.mode = "hide";
5526
5527				return this.effect.call( this, args );
5528
5529			}
5530
5531		};
5532
5533	} )( $.fn.hide ),
5534
5535
5536
5537	toggle: ( function( orig ) {
5538
5539		return function( option ) {
5540
5541			if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
5542
5543				return orig.apply( this, arguments );
5544
5545			} else {
5546
5547				var args = _normalizeArguments.apply( this, arguments );
5548
5549				args.mode = "toggle";
5550
5551				return this.effect.call( this, args );
5552
5553			}
5554
5555		};
5556
5557	} )( $.fn.toggle ),
5558
5559
5560
5561	cssUnit: function( key ) {
5562
5563		var style = this.css( key ),
5564
5565			val = [];
5566
5567
5568
5569		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
5570
5571			if ( style.indexOf( unit ) > 0 ) {
5572
5573				val = [ parseFloat( style ), unit ];
5574
5575			}
5576
5577		} );
5578
5579		return val;
5580
5581	},
5582
5583
5584
5585	cssClip: function( clipObj ) {
5586
5587		if ( clipObj ) {
5588
5589			return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " +
5590
5591				clipObj.bottom + "px " + clipObj.left + "px)" );
5592
5593		}
5594
5595		return parseClip( this.css( "clip" ), this );
5596
5597	},
5598
5599
5600
5601	transfer: function( options, done ) {
5602
5603		var element = $( this ),
5604
5605			target = $( options.to ),
5606
5607			targetFixed = target.css( "position" ) === "fixed",
5608
5609			body = $( "body" ),
5610
5611			fixTop = targetFixed ? body.scrollTop() : 0,
5612
5613			fixLeft = targetFixed ? body.scrollLeft() : 0,
5614
5615			endPosition = target.offset(),
5616
5617			animation = {
5618
5619				top: endPosition.top - fixTop,
5620
5621				left: endPosition.left - fixLeft,
5622
5623				height: target.innerHeight(),
5624
5625				width: target.innerWidth()
5626
5627			},
5628
5629			startPosition = element.offset(),
5630
5631			transfer = $( "<div class='ui-effects-transfer'></div>" )
5632
5633				.appendTo( "body" )
5634
5635				.addClass( options.className )
5636
5637				.css( {
5638
5639					top: startPosition.top - fixTop,
5640
5641					left: startPosition.left - fixLeft,
5642
5643					height: element.innerHeight(),
5644
5645					width: element.innerWidth(),
5646
5647					position: targetFixed ? "fixed" : "absolute"
5648
5649				} )
5650
5651				.animate( animation, options.duration, options.easing, function() {
5652
5653					transfer.remove();
5654
5655					if ( $.isFunction( done ) ) {
5656
5657						done();
5658
5659					}
5660
5661				} );
5662
5663	}
5664
5665} );
5666
5667
5668
5669function parseClip( str, element ) {
5670
5671		var outerWidth = element.outerWidth(),
5672
5673			outerHeight = element.outerHeight(),
5674
5675			clipRegex = /^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/,
5676
5677			values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ];
5678
5679
5680
5681		return {
5682
5683			top: parseFloat( values[ 1 ] ) || 0,
5684
5685			right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ),
5686
5687			bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ),
5688
5689			left: parseFloat( values[ 4 ] ) || 0
5690
5691		};
5692
5693}
5694
5695
5696
5697$.fx.step.clip = function( fx ) {
5698
5699	if ( !fx.clipInit ) {
5700
5701		fx.start = $( fx.elem ).cssClip();
5702
5703		if ( typeof fx.end === "string" ) {
5704
5705			fx.end = parseClip( fx.end, fx.elem );
5706
5707		}
5708
5709		fx.clipInit = true;
5710
5711	}
5712
5713
5714
5715	$( fx.elem ).cssClip( {
5716
5717		top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top,
5718
5719		right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right,
5720
5721		bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom,
5722
5723		left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left
5724
5725	} );
5726
5727};
5728
5729
5730
5731} )();
5732
5733
5734
5735/******************************************************************************/
5736
5737/*********************************** EASING ***********************************/
5738
5739/******************************************************************************/
5740
5741
5742
5743( function() {
5744
5745
5746
5747// Based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
5748
5749
5750
5751var baseEasings = {};
5752
5753
5754
5755$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
5756
5757	baseEasings[ name ] = function( p ) {
5758
5759		return Math.pow( p, i + 2 );
5760
5761	};
5762
5763} );
5764
5765
5766
5767$.extend( baseEasings, {
5768
5769	Sine: function( p ) {
5770
5771		return 1 - Math.cos( p * Math.PI / 2 );
5772
5773	},
5774
5775	Circ: function( p ) {
5776
5777		return 1 - Math.sqrt( 1 - p * p );
5778
5779	},
5780
5781	Elastic: function( p ) {
5782
5783		return p === 0 || p === 1 ? p :
5784
5785			-Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );
5786
5787	},
5788
5789	Back: function( p ) {
5790
5791		return p * p * ( 3 * p - 2 );
5792
5793	},
5794
5795	Bounce: function( p ) {
5796
5797		var pow2,
5798
5799			bounce = 4;
5800
5801
5802
5803		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
5804
5805		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
5806
5807	}
5808
5809} );
5810
5811
5812
5813$.each( baseEasings, function( name, easeIn ) {
5814
5815	$.easing[ "easeIn" + name ] = easeIn;
5816
5817	$.easing[ "easeOut" + name ] = function( p ) {
5818
5819		return 1 - easeIn( 1 - p );
5820
5821	};
5822
5823	$.easing[ "easeInOut" + name ] = function( p ) {
5824
5825		return p < 0.5 ?
5826
5827			easeIn( p * 2 ) / 2 :
5828
5829			1 - easeIn( p * -2 + 2 ) / 2;
5830
5831	};
5832
5833} );
5834
5835
5836
5837} )();
5838
5839
5840
5841var effect = $.effects;
5842
5843
5844
5845
5846
5847/*!
5848
5849 * jQuery UI Effects Blind 1.12.1
5850
5851 * http://jqueryui.com
5852
5853 *
5854
5855 * Copyright jQuery Foundation and other contributors
5856
5857 * Released under the MIT license.
5858
5859 * http://jquery.org/license
5860
5861 */
5862
5863
5864
5865//>>label: Blind Effect
5866
5867//>>group: Effects
5868
5869//>>description: Blinds the element.
5870
5871//>>docs: http://api.jqueryui.com/blind-effect/
5872
5873//>>demos: http://jqueryui.com/effect/
5874
5875
5876
5877
5878
5879
5880
5881var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) {
5882
5883	var map = {
5884
5885			up: [ "bottom", "top" ],
5886
5887			vertical: [ "bottom", "top" ],
5888
5889			down: [ "top", "bottom" ],
5890
5891			left: [ "right", "left" ],
5892
5893			horizontal: [ "right", "left" ],
5894
5895			right: [ "left", "right" ]
5896
5897		},
5898
5899		element = $( this ),
5900
5901		direction = options.direction || "up",
5902
5903		start = element.cssClip(),
5904
5905		animate = { clip: $.extend( {}, start ) },
5906
5907		placeholder = $.effects.createPlaceholder( element );
5908
5909
5910
5911	animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ];
5912
5913
5914
5915	if ( options.mode === "show" ) {
5916
5917		element.cssClip( animate.clip );
5918
5919		if ( placeholder ) {
5920
5921			placeholder.css( $.effects.clipToBox( animate ) );
5922
5923		}
5924
5925
5926
5927		animate.clip = start;
5928
5929	}
5930
5931
5932
5933	if ( placeholder ) {
5934
5935		placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing );
5936
5937	}
5938
5939
5940
5941	element.animate( animate, {
5942
5943		queue: false,
5944
5945		duration: options.duration,
5946
5947		easing: options.easing,
5948
5949		complete: done
5950
5951	} );
5952
5953} );
5954
5955
5956
5957
5958
5959/*!
5960
5961 * jQuery UI Effects Bounce 1.12.1
5962
5963 * http://jqueryui.com
vendor: 11,402 bytes, lines 5964-6777
5964
5965 *
5966
5967 * Copyright jQuery Foundation and other contributors
5968
5969 * Released under the MIT license.
5970
5971 * http://jquery.org/license
5972
5973 */
5974
5975
5976
5977//>>label: Bounce Effect
5978
5979//>>group: Effects
5980
5981//>>description: Bounces an element horizontally or vertically n times.
5982
5983//>>docs: http://api.jqueryui.com/bounce-effect/
5984
5985//>>demos: http://jqueryui.com/effect/
5986
5987
5988
5989
5990
5991
5992
5993var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) {
5994
5995	var upAnim, downAnim, refValue,
5996
5997		element = $( this ),
5998
5999
6000
6001		// Defaults:
6002
6003		mode = options.mode,
6004
6005		hide = mode === "hide",
6006
6007		show = mode === "show",
6008
6009		direction = options.direction || "up",
6010
6011		distance = options.distance,
6012
6013		times = options.times || 5,
6014
6015
6016
6017		// Number of internal animations
6018
6019		anims = times * 2 + ( show || hide ? 1 : 0 ),
6020
6021		speed = options.duration / anims,
6022
6023		easing = options.easing,
6024
6025
6026
6027		// Utility:
6028
6029		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
6030
6031		motion = ( direction === "up" || direction === "left" ),
6032
6033		i = 0,
6034
6035
6036
6037		queuelen = element.queue().length;
6038
6039
6040
6041	$.effects.createPlaceholder( element );
6042
6043
6044
6045	refValue = element.css( ref );
6046
6047
6048
6049	// Default distance for the BIGGEST bounce is the outer Distance / 3
6050
6051	if ( !distance ) {
6052
6053		distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
6054
6055	}
6056
6057
6058
6059	if ( show ) {
6060
6061		downAnim = { opacity: 1 };
6062
6063		downAnim[ ref ] = refValue;
6064
6065
6066
6067		// If we are showing, force opacity 0 and set the initial position
6068
6069		// then do the "first" animation
6070
6071		element
6072
6073			.css( "opacity", 0 )
6074
6075			.css( ref, motion ? -distance * 2 : distance * 2 )
6076
6077			.animate( downAnim, speed, easing );
6078
6079	}
6080
6081
6082
6083	// Start at the smallest distance if we are hiding
6084
6085	if ( hide ) {
6086
6087		distance = distance / Math.pow( 2, times - 1 );
6088
6089	}
6090
6091
6092
6093	downAnim = {};
6094
6095	downAnim[ ref ] = refValue;
6096
6097
6098
6099	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
6100
6101	for ( ; i < times; i++ ) {
6102
6103		upAnim = {};
6104
6105		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
6106
6107
6108
6109		element
6110
6111			.animate( upAnim, speed, easing )
6112
6113			.animate( downAnim, speed, easing );
6114
6115
6116
6117		distance = hide ? distance * 2 : distance / 2;
6118
6119	}
6120
6121
6122
6123	// Last Bounce when Hiding
6124
6125	if ( hide ) {
6126
6127		upAnim = { opacity: 0 };
6128
6129		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
6130
6131
6132
6133		element.animate( upAnim, speed, easing );
6134
6135	}
6136
6137
6138
6139	element.queue( done );
6140
6141
6142
6143	$.effects.unshift( element, queuelen, anims + 1 );
6144
6145} );
6146
6147
6148
6149
6150
6151/*!
6152
6153 * jQuery UI Effects Clip 1.12.1
6154
6155 * http://jqueryui.com
6156
6157 *
6158
6159 * Copyright jQuery Foundation and other contributors
6160
6161 * Released under the MIT license.
6162
6163 * http://jquery.org/license
6164
6165 */
6166
6167
6168
6169//>>label: Clip Effect
6170
6171//>>group: Effects
6172
6173//>>description: Clips the element on and off like an old TV.
6174
6175//>>docs: http://api.jqueryui.com/clip-effect/
6176
6177//>>demos: http://jqueryui.com/effect/
6178
6179
6180
6181
6182
6183
6184
6185var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) {
6186
6187	var start,
6188
6189		animate = {},
6190
6191		element = $( this ),
6192
6193		direction = options.direction || "vertical",
6194
6195		both = direction === "both",
6196
6197		horizontal = both || direction === "horizontal",
6198
6199		vertical = both || direction === "vertical";
6200
6201
6202
6203	start = element.cssClip();
6204
6205	animate.clip = {
6206
6207		top: vertical ? ( start.bottom - start.top ) / 2 : start.top,
6208
6209		right: horizontal ? ( start.right - start.left ) / 2 : start.right,
6210
6211		bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom,
6212
6213		left: horizontal ? ( start.right - start.left ) / 2 : start.left
6214
6215	};
6216
6217
6218
6219	$.effects.createPlaceholder( element );
6220
6221
6222
6223	if ( options.mode === "show" ) {
6224
6225		element.cssClip( animate.clip );
6226
6227		animate.clip = start;
6228
6229	}
6230
6231
6232
6233	element.animate( animate, {
6234
6235		queue: false,
6236
6237		duration: options.duration,
6238
6239		easing: options.easing,
6240
6241		complete: done
6242
6243	} );
6244
6245
6246
6247} );
6248
6249
6250
6251
6252
6253/*!
6254
6255 * jQuery UI Effects Drop 1.12.1
6256
6257 * http://jqueryui.com
6258
6259 *
6260
6261 * Copyright jQuery Foundation and other contributors
6262
6263 * Released under the MIT license.
6264
6265 * http://jquery.org/license
6266
6267 */
6268
6269
6270
6271//>>label: Drop Effect
6272
6273//>>group: Effects
6274
6275//>>description: Moves an element in one direction and hides it at the same time.
6276
6277//>>docs: http://api.jqueryui.com/drop-effect/
6278
6279//>>demos: http://jqueryui.com/effect/
6280
6281
6282
6283
6284
6285
6286
6287var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) {
6288
6289
6290
6291	var distance,
6292
6293		element = $( this ),
6294
6295		mode = options.mode,
6296
6297		show = mode === "show",
6298
6299		direction = options.direction || "left",
6300
6301		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
6302
6303		motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=",
6304
6305		oppositeMotion = ( motion === "+=" ) ? "-=" : "+=",
6306
6307		animation = {
6308
6309			opacity: 0
6310
6311		};
6312
6313
6314
6315	$.effects.createPlaceholder( element );
6316
6317
6318
6319	distance = options.distance ||
6320
6321		element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
6322
6323
6324
6325	animation[ ref ] = motion + distance;
6326
6327
6328
6329	if ( show ) {
6330
6331		element.css( animation );
6332
6333
6334
6335		animation[ ref ] = oppositeMotion + distance;
6336
6337		animation.opacity = 1;
6338
6339	}
6340
6341
6342
6343	// Animate
6344
6345	element.animate( animation, {
6346
6347		queue: false,
6348
6349		duration: options.duration,
6350
6351		easing: options.easing,
6352
6353		complete: done
6354
6355	} );
6356
6357} );
6358
6359
6360
6361
6362
6363/*!
6364
6365 * jQuery UI Effects Explode 1.12.1
6366
6367 * http://jqueryui.com
6368
6369 *
6370
6371 * Copyright jQuery Foundation and other contributors
6372
6373 * Released under the MIT license.
6374
6375 * http://jquery.org/license
6376
6377 */
6378
6379
6380
6381//>>label: Explode Effect
6382
6383//>>group: Effects
6384
6385// jscs:disable maximumLineLength
6386
6387//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness.
6388
6389// jscs:enable maximumLineLength
6390
6391//>>docs: http://api.jqueryui.com/explode-effect/
6392
6393//>>demos: http://jqueryui.com/effect/
6394
6395
6396
6397
6398
6399
6400
6401var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) {
6402
6403
6404
6405	var i, j, left, top, mx, my,
6406
6407		rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3,
6408
6409		cells = rows,
6410
6411		element = $( this ),
6412
6413		mode = options.mode,
6414
6415		show = mode === "show",
6416
6417
6418
6419		// Show and then visibility:hidden the element before calculating offset
6420
6421		offset = element.show().css( "visibility", "hidden" ).offset(),
6422
6423
6424
6425		// Width and height of a piece
6426
6427		width = Math.ceil( element.outerWidth() / cells ),
6428
6429		height = Math.ceil( element.outerHeight() / rows ),
6430
6431		pieces = [];
6432
6433
6434
6435	// Children animate complete:
6436
6437	function childComplete() {
6438
6439		pieces.push( this );
6440
6441		if ( pieces.length === rows * cells ) {
6442
6443			animComplete();
6444
6445		}
6446
6447	}
6448
6449
6450
6451	// Clone the element for each row and cell.
6452
6453	for ( i = 0; i < rows; i++ ) { // ===>
6454
6455		top = offset.top + i * height;
6456
6457		my = i - ( rows - 1 ) / 2;
6458
6459
6460
6461		for ( j = 0; j < cells; j++ ) { // |||
6462
6463			left = offset.left + j * width;
6464
6465			mx = j - ( cells - 1 ) / 2;
6466
6467
6468
6469			// Create a clone of the now hidden main element that will be absolute positioned
6470
6471			// within a wrapper div off the -left and -top equal to size of our pieces
6472
6473			element
6474
6475				.clone()
6476
6477				.appendTo( "body" )
6478
6479				.wrap( "<div></div>" )
6480
6481				.css( {
6482
6483					position: "absolute",
6484
6485					visibility: "visible",
6486
6487					left: -j * width,
6488
6489					top: -i * height
6490
6491				} )
6492
6493
6494
6495				// Select the wrapper - make it overflow: hidden and absolute positioned based on
6496
6497				// where the original was located +left and +top equal to the size of pieces
6498
6499				.parent()
6500
6501					.addClass( "ui-effects-explode" )
6502
6503					.css( {
6504
6505						position: "absolute",
6506
6507						overflow: "hidden",
6508
6509						width: width,
6510
6511						height: height,
6512
6513						left: left + ( show ? mx * width : 0 ),
6514
6515						top: top + ( show ? my * height : 0 ),
6516
6517						opacity: show ? 0 : 1
6518
6519					} )
6520
6521					.animate( {
6522
6523						left: left + ( show ? 0 : mx * width ),
6524
6525						top: top + ( show ? 0 : my * height ),
6526
6527						opacity: show ? 1 : 0
6528
6529					}, options.duration || 500, options.easing, childComplete );
6530
6531		}
6532
6533	}
6534
6535
6536
6537	function animComplete() {
6538
6539		element.css( {
6540
6541			visibility: "visible"
6542
6543		} );
6544
6545		$( pieces ).remove();
6546
6547		done();
6548
6549	}
6550
6551} );
6552
6553
6554
6555
6556
6557/*!
6558
6559 * jQuery UI Effects Fade 1.12.1
6560
6561 * http://jqueryui.com
6562
6563 *
6564
6565 * Copyright jQuery Foundation and other contributors
6566
6567 * Released under the MIT license.
6568
6569 * http://jquery.org/license
6570
6571 */
6572
6573
6574
6575//>>label: Fade Effect
6576
6577//>>group: Effects
6578
6579//>>description: Fades the element.
6580
6581//>>docs: http://api.jqueryui.com/fade-effect/
6582
6583//>>demos: http://jqueryui.com/effect/
6584
6585
6586
6587
6588
6589
6590
6591var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) {
6592
6593	var show = options.mode === "show";
6594
6595
6596
6597	$( this )
6598
6599		.css( "opacity", show ? 0 : 1 )
6600
6601		.animate( {
6602
6603			opacity: show ? 1 : 0
6604
6605		}, {
6606
6607			queue: false,
6608
6609			duration: options.duration,
6610
6611			easing: options.easing,
6612
6613			complete: done
6614
6615		} );
6616
6617} );
6618
6619
6620
6621
6622
6623/*!
6624
6625 * jQuery UI Effects Fold 1.12.1
6626
6627 * http://jqueryui.com
6628
6629 *
6630
6631 * Copyright jQuery Foundation and other contributors
6632
6633 * Released under the MIT license.
6634
6635 * http://jquery.org/license
6636
6637 */
6638
6639
6640
6641//>>label: Fold Effect
6642
6643//>>group: Effects
6644
6645//>>description: Folds an element first horizontally and then vertically.
6646
6647//>>docs: http://api.jqueryui.com/fold-effect/
6648
6649//>>demos: http://jqueryui.com/effect/
6650
6651
6652
6653
6654
6655
6656
6657var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) {
6658
6659
6660
6661	// Create element
6662
6663	var element = $( this ),
6664
6665		mode = options.mode,
6666
6667		show = mode === "show",
6668
6669		hide = mode === "hide",
6670
6671		size = options.size || 15,
6672
6673		percent = /([0-9]+)%/.exec( size ),
6674
6675		horizFirst = !!options.horizFirst,
6676
6677		ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ],
6678
6679		duration = options.duration / 2,
6680
6681
6682
6683		placeholder = $.effects.createPlaceholder( element ),
6684
6685
6686
6687		start = element.cssClip(),
6688
6689		animation1 = { clip: $.extend( {}, start ) },
6690
6691		animation2 = { clip: $.extend( {}, start ) },
6692
6693
6694
6695		distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ],
6696
6697
6698
6699		queuelen = element.queue().length;
6700
6701
6702
6703	if ( percent ) {
6704
6705		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
6706
6707	}
6708
6709	animation1.clip[ ref[ 0 ] ] = size;
6710
6711	animation2.clip[ ref[ 0 ] ] = size;
6712
6713	animation2.clip[ ref[ 1 ] ] = 0;
6714
6715
6716
6717	if ( show ) {
6718
6719		element.cssClip( animation2.clip );
6720
6721		if ( placeholder ) {
6722
6723			placeholder.css( $.effects.clipToBox( animation2 ) );
6724
6725		}
6726
6727
6728
6729		animation2.clip = start;
6730
6731	}
6732
6733
6734
6735	// Animate
6736
6737	element
6738
6739		.queue( function( next ) {
6740
6741			if ( placeholder ) {
6742
6743				placeholder
6744
6745					.animate( $.effects.clipToBox( animation1 ), duration, options.easing )
6746
6747					.animate( $.effects.clipToBox( animation2 ), duration, options.easing );
6748
6749			}
6750
6751
6752
6753			next();
6754
6755		} )
6756
6757		.animate( animation1, duration, options.easing )
6758
6759		.animate( animation2, duration, options.easing )
6760
6761		.queue( done );
6762
6763
6764
6765	$.effects.unshift( element, queuelen, 4 );
6766
6767} );
6768
6769
6770
6771
6772
6773/*!
6774
6775 * jQuery UI Effects Highlight 1.12.1
6776
6777 * http://jqueryui.com
vendor: 6,689 bytes, lines 6778-7217
6778
6779 *
6780
6781 * Copyright jQuery Foundation and other contributors
6782
6783 * Released under the MIT license.
6784
6785 * http://jquery.org/license
6786
6787 */
6788
6789
6790
6791//>>label: Highlight Effect
6792
6793//>>group: Effects
6794
6795//>>description: Highlights the background of an element in a defined color for a custom duration.
6796
6797//>>docs: http://api.jqueryui.com/highlight-effect/
6798
6799//>>demos: http://jqueryui.com/effect/
6800
6801
6802
6803
6804
6805
6806
6807var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) {
6808
6809	var element = $( this ),
6810
6811		animation = {
6812
6813			backgroundColor: element.css( "backgroundColor" )
6814
6815		};
6816
6817
6818
6819	if ( options.mode === "hide" ) {
6820
6821		animation.opacity = 0;
6822
6823	}
6824
6825
6826
6827	$.effects.saveStyle( element );
6828
6829
6830
6831	element
6832
6833		.css( {
6834
6835			backgroundImage: "none",
6836
6837			backgroundColor: options.color || "#ffff99"
6838
6839		} )
6840
6841		.animate( animation, {
6842
6843			queue: false,
6844
6845			duration: options.duration,
6846
6847			easing: options.easing,
6848
6849			complete: done
6850
6851		} );
6852
6853} );
6854
6855
6856
6857
6858
6859/*!
6860
6861 * jQuery UI Effects Size 1.12.1
6862
6863 * http://jqueryui.com
6864
6865 *
6866
6867 * Copyright jQuery Foundation and other contributors
6868
6869 * Released under the MIT license.
6870
6871 * http://jquery.org/license
6872
6873 */
6874
6875
6876
6877//>>label: Size Effect
6878
6879//>>group: Effects
6880
6881//>>description: Resize an element to a specified width and height.
6882
6883//>>docs: http://api.jqueryui.com/size-effect/
6884
6885//>>demos: http://jqueryui.com/effect/
6886
6887
6888
6889
6890
6891
6892
6893var effectsEffectSize = $.effects.define( "size", function( options, done ) {
6894
6895
6896
6897	// Create element
6898
6899	var baseline, factor, temp,
6900
6901		element = $( this ),
6902
6903
6904
6905		// Copy for children
6906
6907		cProps = [ "fontSize" ],
6908
6909		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
6910
6911		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
6912
6913
6914
6915		// Set options
6916
6917		mode = options.mode,
6918
6919		restore = mode !== "effect",
6920
6921		scale = options.scale || "both",
6922
6923		origin = options.origin || [ "middle", "center" ],
6924
6925		position = element.css( "position" ),
6926
6927		pos = element.position(),
6928
6929		original = $.effects.scaledDimensions( element ),
6930
6931		from = options.from || original,
6932
6933		to = options.to || $.effects.scaledDimensions( element, 0 );
6934
6935
6936
6937	$.effects.createPlaceholder( element );
6938
6939
6940
6941	if ( mode === "show" ) {
6942
6943		temp = from;
6944
6945		from = to;
6946
6947		to = temp;
6948
6949	}
6950
6951
6952
6953	// Set scaling factor
6954
6955	factor = {
6956
6957		from: {
6958
6959			y: from.height / original.height,
6960
6961			x: from.width / original.width
6962
6963		},
6964
6965		to: {
6966
6967			y: to.height / original.height,
6968
6969			x: to.width / original.width
6970
6971		}
6972
6973	};
6974
6975
6976
6977	// Scale the css box
6978
6979	if ( scale === "box" || scale === "both" ) {
6980
6981
6982
6983		// Vertical props scaling
6984
6985		if ( factor.from.y !== factor.to.y ) {
6986
6987			from = $.effects.setTransition( element, vProps, factor.from.y, from );
6988
6989			to = $.effects.setTransition( element, vProps, factor.to.y, to );
6990
6991		}
6992
6993
6994
6995		// Horizontal props scaling
6996
6997		if ( factor.from.x !== factor.to.x ) {
6998
6999			from = $.effects.setTransition( element, hProps, factor.from.x, from );
7000
7001			to = $.effects.setTransition( element, hProps, factor.to.x, to );
7002
7003		}
7004
7005	}
7006
7007
7008
7009	// Scale the content
7010
7011	if ( scale === "content" || scale === "both" ) {
7012
7013
7014
7015		// Vertical props scaling
7016
7017		if ( factor.from.y !== factor.to.y ) {
7018
7019			from = $.effects.setTransition( element, cProps, factor.from.y, from );
7020
7021			to = $.effects.setTransition( element, cProps, factor.to.y, to );
7022
7023		}
7024
7025	}
7026
7027
7028
7029	// Adjust the position properties based on the provided origin points
7030
7031	if ( origin ) {
7032
7033		baseline = $.effects.getBaseline( origin, original );
7034
7035		from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top;
7036
7037		from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left;
7038
7039		to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top;
7040
7041		to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left;
7042
7043	}
7044
7045	element.css( from );
7046
7047
7048
7049	// Animate the children if desired
7050
7051	if ( scale === "content" || scale === "both" ) {
7052
7053
7054
7055		vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps );
7056
7057		hProps = hProps.concat( [ "marginLeft", "marginRight" ] );
7058
7059
7060
7061		// Only animate children with width attributes specified
7062
7063		// TODO: is this right? should we include anything with css width specified as well
7064
7065		element.find( "*[width]" ).each( function() {
7066
7067			var child = $( this ),
7068
7069				childOriginal = $.effects.scaledDimensions( child ),
7070
7071				childFrom = {
7072
7073					height: childOriginal.height * factor.from.y,
7074
7075					width: childOriginal.width * factor.from.x,
7076
7077					outerHeight: childOriginal.outerHeight * factor.from.y,
7078
7079					outerWidth: childOriginal.outerWidth * factor.from.x
7080
7081				},
7082
7083				childTo = {
7084
7085					height: childOriginal.height * factor.to.y,
7086
7087					width: childOriginal.width * factor.to.x,
7088
7089					outerHeight: childOriginal.height * factor.to.y,
7090
7091					outerWidth: childOriginal.width * factor.to.x
7092
7093				};
7094
7095
7096
7097			// Vertical props scaling
7098
7099			if ( factor.from.y !== factor.to.y ) {
7100
7101				childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom );
7102
7103				childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo );
7104
7105			}
7106
7107
7108
7109			// Horizontal props scaling
7110
7111			if ( factor.from.x !== factor.to.x ) {
7112
7113				childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom );
7114
7115				childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo );
7116
7117			}
7118
7119
7120
7121			if ( restore ) {
7122
7123				$.effects.saveStyle( child );
7124
7125			}
7126
7127
7128
7129			// Animate children
7130
7131			child.css( childFrom );
7132
7133			child.animate( childTo, options.duration, options.easing, function() {
7134
7135
7136
7137				// Restore children
7138
7139				if ( restore ) {
7140
7141					$.effects.restoreStyle( child );
7142
7143				}
7144
7145			} );
7146
7147		} );
7148
7149	}
7150
7151
7152
7153	// Animate
7154
7155	element.animate( to, {
7156
7157		queue: false,
7158
7159		duration: options.duration,
7160
7161		easing: options.easing,
7162
7163		complete: function() {
7164
7165
7166
7167			var offset = element.offset();
7168
7169
7170
7171			if ( to.opacity === 0 ) {
7172
7173				element.css( "opacity", from.opacity );
7174
7175			}
7176
7177
7178
7179			if ( !restore ) {
7180
7181				element
7182
7183					.css( "position", position === "static" ? "relative" : position )
7184
7185					.offset( offset );
7186
7187
7188
7189				// Need to save style here so that automatic style restoration
7190
7191				// doesn't restore to the original styles from before the animation.
7192
7193				$.effects.saveStyle( element );
7194
7195			}
7196
7197
7198
7199			done();
7200
7201		}
7202
7203	} );
7204
7205
7206
7207} );
7208
7209
7210
7211
7212
7213/*!
7214
7215 * jQuery UI Effects Scale 1.12.1
7216
7217 * http://jqueryui.com
vendor: 5,153 bytes, lines 7218-7573
7218
7219 *
7220
7221 * Copyright jQuery Foundation and other contributors
7222
7223 * Released under the MIT license.
7224
7225 * http://jquery.org/license
7226
7227 */
7228
7229
7230
7231//>>label: Scale Effect
7232
7233//>>group: Effects
7234
7235//>>description: Grows or shrinks an element and its content.
7236
7237//>>docs: http://api.jqueryui.com/scale-effect/
7238
7239//>>demos: http://jqueryui.com/effect/
7240
7241
7242
7243
7244
7245
7246
7247var effectsEffectScale = $.effects.define( "scale", function( options, done ) {
7248
7249
7250
7251	// Create element
7252
7253	var el = $( this ),
7254
7255		mode = options.mode,
7256
7257		percent = parseInt( options.percent, 10 ) ||
7258
7259			( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ),
7260
7261
7262
7263		newOptions = $.extend( true, {
7264
7265			from: $.effects.scaledDimensions( el ),
7266
7267			to: $.effects.scaledDimensions( el, percent, options.direction || "both" ),
7268
7269			origin: options.origin || [ "middle", "center" ]
7270
7271		}, options );
7272
7273
7274
7275	// Fade option to support puff
7276
7277	if ( options.fade ) {
7278
7279		newOptions.from.opacity = 1;
7280
7281		newOptions.to.opacity = 0;
7282
7283	}
7284
7285
7286
7287	$.effects.effect.size.call( this, newOptions, done );
7288
7289} );
7290
7291
7292
7293
7294
7295/*!
7296
7297 * jQuery UI Effects Puff 1.12.1
7298
7299 * http://jqueryui.com
7300
7301 *
7302
7303 * Copyright jQuery Foundation and other contributors
7304
7305 * Released under the MIT license.
7306
7307 * http://jquery.org/license
7308
7309 */
7310
7311
7312
7313//>>label: Puff Effect
7314
7315//>>group: Effects
7316
7317//>>description: Creates a puff effect by scaling the element up and hiding it at the same time.
7318
7319//>>docs: http://api.jqueryui.com/puff-effect/
7320
7321//>>demos: http://jqueryui.com/effect/
7322
7323
7324
7325
7326
7327
7328
7329var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) {
7330
7331	var newOptions = $.extend( true, {}, options, {
7332
7333		fade: true,
7334
7335		percent: parseInt( options.percent, 10 ) || 150
7336
7337	} );
7338
7339
7340
7341	$.effects.effect.scale.call( this, newOptions, done );
7342
7343} );
7344
7345
7346
7347
7348
7349/*!
7350
7351 * jQuery UI Effects Pulsate 1.12.1
7352
7353 * http://jqueryui.com
7354
7355 *
7356
7357 * Copyright jQuery Foundation and other contributors
7358
7359 * Released under the MIT license.
7360
7361 * http://jquery.org/license
7362
7363 */
7364
7365
7366
7367//>>label: Pulsate Effect
7368
7369//>>group: Effects
7370
7371//>>description: Pulsates an element n times by changing the opacity to zero and back.
7372
7373//>>docs: http://api.jqueryui.com/pulsate-effect/
7374
7375//>>demos: http://jqueryui.com/effect/
7376
7377
7378
7379
7380
7381
7382
7383var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) {
7384
7385	var element = $( this ),
7386
7387		mode = options.mode,
7388
7389		show = mode === "show",
7390
7391		hide = mode === "hide",
7392
7393		showhide = show || hide,
7394
7395
7396
7397		// Showing or hiding leaves off the "last" animation
7398
7399		anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
7400
7401		duration = options.duration / anims,
7402
7403		animateTo = 0,
7404
7405		i = 1,
7406
7407		queuelen = element.queue().length;
7408
7409
7410
7411	if ( show || !element.is( ":visible" ) ) {
7412
7413		element.css( "opacity", 0 ).show();
7414
7415		animateTo = 1;
7416
7417	}
7418
7419
7420
7421	// Anims - 1 opacity "toggles"
7422
7423	for ( ; i < anims; i++ ) {
7424
7425		element.animate( { opacity: animateTo }, duration, options.easing );
7426
7427		animateTo = 1 - animateTo;
7428
7429	}
7430
7431
7432
7433	element.animate( { opacity: animateTo }, duration, options.easing );
7434
7435
7436
7437	element.queue( done );
7438
7439
7440
7441	$.effects.unshift( element, queuelen, anims + 1 );
7442
7443} );
7444
7445
7446
7447
7448
7449/*!
7450
7451 * jQuery UI Effects Shake 1.12.1
7452
7453 * http://jqueryui.com
7454
7455 *
7456
7457 * Copyright jQuery Foundation and other contributors
7458
7459 * Released under the MIT license.
7460
7461 * http://jquery.org/license
7462
7463 */
7464
7465
7466
7467//>>label: Shake Effect
7468
7469//>>group: Effects
7470
7471//>>description: Shakes an element horizontally or vertically n times.
7472
7473//>>docs: http://api.jqueryui.com/shake-effect/
7474
7475//>>demos: http://jqueryui.com/effect/
7476
7477
7478
7479
7480
7481
7482
7483var effectsEffectShake = $.effects.define( "shake", function( options, done ) {
7484
7485
7486
7487	var i = 1,
7488
7489		element = $( this ),
7490
7491		direction = options.direction || "left",
7492
7493		distance = options.distance || 20,
7494
7495		times = options.times || 3,
7496
7497		anims = times * 2 + 1,
7498
7499		speed = Math.round( options.duration / anims ),
7500
7501		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
7502
7503		positiveMotion = ( direction === "up" || direction === "left" ),
7504
7505		animation = {},
7506
7507		animation1 = {},
7508
7509		animation2 = {},
7510
7511
7512
7513		queuelen = element.queue().length;
7514
7515
7516
7517	$.effects.createPlaceholder( element );
7518
7519
7520
7521	// Animation
7522
7523	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
7524
7525	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
7526
7527	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
7528
7529
7530
7531	// Animate
7532
7533	element.animate( animation, speed, options.easing );
7534
7535
7536
7537	// Shakes
7538
7539	for ( ; i < times; i++ ) {
7540
7541		element
7542
7543			.animate( animation1, speed, options.easing )
7544
7545			.animate( animation2, speed, options.easing );
7546
7547	}
7548
7549
7550
7551	element
7552
7553		.animate( animation1, speed, options.easing )
7554
7555		.animate( animation, speed / 2, options.easing )
7556
7557		.queue( done );
7558
7559
7560
7561	$.effects.unshift( element, queuelen, anims + 1 );
7562
7563} );
7564
7565
7566
7567
7568
7569/*!
7570
7571 * jQuery UI Effects Slide 1.12.1
7572
7573 * http://jqueryui.com
vendor: 5,125 bytes, lines 7574-7917
7574
7575 *
7576
7577 * Copyright jQuery Foundation and other contributors
7578
7579 * Released under the MIT license.
7580
7581 * http://jquery.org/license
7582
7583 */
7584
7585
7586
7587//>>label: Slide Effect
7588
7589//>>group: Effects
7590
7591//>>description: Slides an element in and out of the viewport.
7592
7593//>>docs: http://api.jqueryui.com/slide-effect/
7594
7595//>>demos: http://jqueryui.com/effect/
7596
7597
7598
7599
7600
7601
7602
7603var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) {
7604
7605	var startClip, startRef,
7606
7607		element = $( this ),
7608
7609		map = {
7610
7611			up: [ "bottom", "top" ],
7612
7613			down: [ "top", "bottom" ],
7614
7615			left: [ "right", "left" ],
7616
7617			right: [ "left", "right" ]
7618
7619		},
7620
7621		mode = options.mode,
7622
7623		direction = options.direction || "left",
7624
7625		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
7626
7627		positiveMotion = ( direction === "up" || direction === "left" ),
7628
7629		distance = options.distance ||
7630
7631			element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ),
7632
7633		animation = {};
7634
7635
7636
7637	$.effects.createPlaceholder( element );
7638
7639
7640
7641	startClip = element.cssClip();
7642
7643	startRef = element.position()[ ref ];
7644
7645
7646
7647	// Define hide animation
7648
7649	animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef;
7650
7651	animation.clip = element.cssClip();
7652
7653	animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ];
7654
7655
7656
7657	// Reverse the animation if we're showing
7658
7659	if ( mode === "show" ) {
7660
7661		element.cssClip( animation.clip );
7662
7663		element.css( ref, animation[ ref ] );
7664
7665		animation.clip = startClip;
7666
7667		animation[ ref ] = startRef;
7668
7669	}
7670
7671
7672
7673	// Actually animate
7674
7675	element.animate( animation, {
7676
7677		queue: false,
7678
7679		duration: options.duration,
7680
7681		easing: options.easing,
7682
7683		complete: done
7684
7685	} );
7686
7687} );
7688
7689
7690
7691
7692
7693/*!
7694
7695 * jQuery UI Effects Transfer 1.12.1
7696
7697 * http://jqueryui.com
7698
7699 *
7700
7701 * Copyright jQuery Foundation and other contributors
7702
7703 * Released under the MIT license.
7704
7705 * http://jquery.org/license
7706
7707 */
7708
7709
7710
7711//>>label: Transfer Effect
7712
7713//>>group: Effects
7714
7715//>>description: Displays a transfer effect from one element to another.
7716
7717//>>docs: http://api.jqueryui.com/transfer-effect/
7718
7719//>>demos: http://jqueryui.com/effect/
7720
7721
7722
7723
7724
7725
7726
7727var effect;
7728
7729if ( $.uiBackCompat !== false ) {
7730
7731	effect = $.effects.define( "transfer", function( options, done ) {
7732
7733		$( this ).transfer( options, done );
7734
7735	} );
7736
7737}
7738
7739var effectsEffectTransfer = effect;
7740
7741
7742
7743
7744
7745/*!
7746
7747 * jQuery UI Focusable 1.12.1
7748
7749 * http://jqueryui.com
7750
7751 *
7752
7753 * Copyright jQuery Foundation and other contributors
7754
7755 * Released under the MIT license.
7756
7757 * http://jquery.org/license
7758
7759 */
7760
7761
7762
7763//>>label: :focusable Selector
7764
7765//>>group: Core
7766
7767//>>description: Selects elements which can be focused.
7768
7769//>>docs: http://api.jqueryui.com/focusable-selector/
7770
7771
7772
7773
7774
7775
7776
7777// Selectors
7778
7779$.ui.focusable = function( element, hasTabindex ) {
7780
7781	var map, mapName, img, focusableIfVisible, fieldset,
7782
7783		nodeName = element.nodeName.toLowerCase();
7784
7785
7786
7787	if ( "area" === nodeName ) {
7788
7789		map = element.parentNode;
7790
7791		mapName = map.name;
7792
7793		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
7794
7795			return false;
7796
7797		}
7798
7799		img = $( "img[usemap='#" + mapName + "']" );
7800
7801		return img.length > 0 && img.is( ":visible" );
7802
7803	}
7804
7805
7806
7807	if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) {
7808
7809		focusableIfVisible = !element.disabled;
7810
7811
7812
7813		if ( focusableIfVisible ) {
7814
7815
7816
7817			// Form controls within a disabled fieldset are disabled.
7818
7819			// However, controls within the fieldset's legend do not get disabled.
7820
7821			// Since controls generally aren't placed inside legends, we skip
7822
7823			// this portion of the check.
7824
7825			fieldset = $( element ).closest( "fieldset" )[ 0 ];
7826
7827			if ( fieldset ) {
7828
7829				focusableIfVisible = !fieldset.disabled;
7830
7831			}
7832
7833		}
7834
7835	} else if ( "a" === nodeName ) {
7836
7837		focusableIfVisible = element.href || hasTabindex;
7838
7839	} else {
7840
7841		focusableIfVisible = hasTabindex;
7842
7843	}
7844
7845
7846
7847	return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) );
7848
7849};
7850
7851
7852
7853// Support: IE 8 only
7854
7855// IE 8 doesn't resolve inherit to visible/hidden for computed values
7856
7857function visible( element ) {
7858
7859	var visibility = element.css( "visibility" );
7860
7861	while ( visibility === "inherit" ) {
7862
7863		element = element.parent();
7864
7865		visibility = element.css( "visibility" );
7866
7867	}
7868
7869	return visibility !== "hidden";
7870
7871}
7872
7873
7874
7875$.extend( $.expr[ ":" ], {
7876
7877	focusable: function( element ) {
7878
7879		return $.ui.focusable( element, $.attr( element, "tabindex" ) != null );
7880
7881	}
7882
7883} );
7884
7885
7886
7887var focusable = $.ui.focusable;
7888
7889
7890
7891
7892
7893
7894
7895
7896
7897// Support: IE8 Only
7898
7899// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop
7900
7901// with a string, so we need to find the proper form.
7902
7903var form = $.fn.form = function() {
7904
7905	return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form );
7906
7907};
7908
7909
7910
7911
7912
7913/*!
7914
7915 * jQuery UI Form Reset Mixin 1.12.1
7916
7917 * http://jqueryui.com
vendor: 4,177 bytes, lines 7918-8198
7918
7919 *
7920
7921 * Copyright jQuery Foundation and other contributors
7922
7923 * Released under the MIT license.
7924
7925 * http://jquery.org/license
7926
7927 */
7928
7929
7930
7931//>>label: Form Reset Mixin
7932
7933//>>group: Core
7934
7935//>>description: Refresh input widgets when their form is reset
7936
7937//>>docs: http://api.jqueryui.com/form-reset-mixin/
7938
7939
7940
7941
7942
7943
7944
7945var formResetMixin = $.ui.formResetMixin = {
7946
7947	_formResetHandler: function() {
7948
7949		var form = $( this );
7950
7951
7952
7953		// Wait for the form reset to actually happen before refreshing
7954
7955		setTimeout( function() {
7956
7957			var instances = form.data( "ui-form-reset-instances" );
7958
7959			$.each( instances, function() {
7960
7961				this.refresh();
7962
7963			} );
7964
7965		} );
7966
7967	},
7968
7969
7970
7971	_bindFormResetHandler: function() {
7972
7973		this.form = this.element.form();
7974
7975		if ( !this.form.length ) {
7976
7977			return;
7978
7979		}
7980
7981
7982
7983		var instances = this.form.data( "ui-form-reset-instances" ) || [];
7984
7985		if ( !instances.length ) {
7986
7987
7988
7989			// We don't use _on() here because we use a single event handler per form
7990
7991			this.form.on( "reset.ui-form-reset", this._formResetHandler );
7992
7993		}
7994
7995		instances.push( this );
7996
7997		this.form.data( "ui-form-reset-instances", instances );
7998
7999	},
8000
8001
8002
8003	_unbindFormResetHandler: function() {
8004
8005		if ( !this.form.length ) {
8006
8007			return;
8008
8009		}
8010
8011
8012
8013		var instances = this.form.data( "ui-form-reset-instances" );
8014
8015		instances.splice( $.inArray( this, instances ), 1 );
8016
8017		if ( instances.length ) {
8018
8019			this.form.data( "ui-form-reset-instances", instances );
8020
8021		} else {
8022
8023			this.form
8024
8025				.removeData( "ui-form-reset-instances" )
8026
8027				.off( "reset.ui-form-reset" );
8028
8029		}
8030
8031	}
8032
8033};
8034
8035
8036
8037
8038
8039/*!
8040
8041 * jQuery UI Support for jQuery core 1.7.x 1.12.1
8042
8043 * http://jqueryui.com
8044
8045 *
8046
8047 * Copyright jQuery Foundation and other contributors
8048
8049 * Released under the MIT license.
8050
8051 * http://jquery.org/license
8052
8053 *
8054
8055 */
8056
8057
8058
8059//>>label: jQuery 1.7 Support
8060
8061//>>group: Core
8062
8063//>>description: Support version 1.7.x of jQuery core
8064
8065
8066
8067
8068
8069
8070
8071// Support: jQuery 1.7 only
8072
8073// Not a great way to check versions, but since we only support 1.7+ and only
8074
8075// need to detect <1.8, this is a simple check that should suffice. Checking
8076
8077// for "1.7." would be a bit safer, but the version string is 1.7, not 1.7.0
8078
8079// and we'll never reach 1.70.0 (if we do, we certainly won't be supporting
8080
8081// 1.7 anymore). See #11197 for why we're not using feature detection.
8082
8083if ( $.fn.jquery.substring( 0, 3 ) === "1.7" ) {
8084
8085
8086
8087	// Setters for .innerWidth(), .innerHeight(), .outerWidth(), .outerHeight()
8088
8089	// Unlike jQuery Core 1.8+, these only support numeric values to set the
8090
8091	// dimensions in pixels
8092
8093	$.each( [ "Width", "Height" ], function( i, name ) {
8094
8095		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
8096
8097			type = name.toLowerCase(),
8098
8099			orig = {
8100
8101				innerWidth: $.fn.innerWidth,
8102
8103				innerHeight: $.fn.innerHeight,
8104
8105				outerWidth: $.fn.outerWidth,
8106
8107				outerHeight: $.fn.outerHeight
8108
8109			};
8110
8111
8112
8113		function reduce( elem, size, border, margin ) {
8114
8115			$.each( side, function() {
8116
8117				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
8118
8119				if ( border ) {
8120
8121					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
8122
8123				}
8124
8125				if ( margin ) {
8126
8127					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
8128
8129				}
8130
8131			} );
8132
8133			return size;
8134
8135		}
8136
8137
8138
8139		$.fn[ "inner" + name ] = function( size ) {
8140
8141			if ( size === undefined ) {
8142
8143				return orig[ "inner" + name ].call( this );
8144
8145			}
8146
8147
8148
8149			return this.each( function() {
8150
8151				$( this ).css( type, reduce( this, size ) + "px" );
8152
8153			} );
8154
8155		};
8156
8157
8158
8159		$.fn[ "outer" + name ] = function( size, margin ) {
8160
8161			if ( typeof size !== "number" ) {
8162
8163				return orig[ "outer" + name ].call( this, size );
8164
8165			}
8166
8167
8168
8169			return this.each( function() {
8170
8171				$( this ).css( type, reduce( this, size, true, margin ) + "px" );
8172
8173			} );
8174
8175		};
8176
8177	} );
8178
8179
8180
8181	$.fn.addBack = function( selector ) {
8182
8183		return this.add( selector == null ?
8184
8185			this.prevObject : this.prevObject.filter( selector )
8186
8187		);
8188
8189	};
8190
8191}
8192
8193
8194
8195;
8196
8197/*!
8198
vendor: 4,373 bytes, lines 8199-8517
8199 * jQuery UI Keycode 1.12.1
8200
8201 * http://jqueryui.com
8202
8203 *
8204
8205 * Copyright jQuery Foundation and other contributors
8206
8207 * Released under the MIT license.
8208
8209 * http://jquery.org/license
8210
8211 */
8212
8213
8214
8215//>>label: Keycode
8216
8217//>>group: Core
8218
8219//>>description: Provide keycodes as keynames
8220
8221//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/
8222
8223
8224
8225
8226
8227var keycode = $.ui.keyCode = {
8228
8229	BACKSPACE: 8,
8230
8231	COMMA: 188,
8232
8233	DELETE: 46,
8234
8235	DOWN: 40,
8236
8237	END: 35,
8238
8239	ENTER: 13,
8240
8241	ESCAPE: 27,
8242
8243	HOME: 36,
8244
8245	LEFT: 37,
8246
8247	PAGE_DOWN: 34,
8248
8249	PAGE_UP: 33,
8250
8251	PERIOD: 190,
8252
8253	RIGHT: 39,
8254
8255	SPACE: 32,
8256
8257	TAB: 9,
8258
8259	UP: 38
8260
8261};
8262
8263
8264
8265
8266
8267
8268
8269
8270
8271// Internal use only
8272
8273var escapeSelector = $.ui.escapeSelector = ( function() {
8274
8275	var selectorEscape = /([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;
8276
8277	return function( selector ) {
8278
8279		return selector.replace( selectorEscape, "\\$1" );
8280
8281	};
8282
8283} )();
8284
8285
8286
8287
8288
8289/*!
8290
8291 * jQuery UI Labels 1.12.1
8292
8293 * http://jqueryui.com
8294
8295 *
8296
8297 * Copyright jQuery Foundation and other contributors
8298
8299 * Released under the MIT license.
8300
8301 * http://jquery.org/license
8302
8303 */
8304
8305
8306
8307//>>label: labels
8308
8309//>>group: Core
8310
8311//>>description: Find all the labels associated with a given input
8312
8313//>>docs: http://api.jqueryui.com/labels/
8314
8315
8316
8317
8318
8319
8320
8321var labels = $.fn.labels = function() {
8322
8323	var ancestor, selector, id, labels, ancestors;
8324
8325
8326
8327	// Check control.labels first
8328
8329	if ( this[ 0 ].labels && this[ 0 ].labels.length ) {
8330
8331		return this.pushStack( this[ 0 ].labels );
8332
8333	}
8334
8335
8336
8337	// Support: IE <= 11, FF <= 37, Android <= 2.3 only
8338
8339	// Above browsers do not support control.labels. Everything below is to support them
8340
8341	// as well as document fragments. control.labels does not work on document fragments
8342
8343	labels = this.eq( 0 ).parents( "label" );
8344
8345
8346
8347	// Look for the label based on the id
8348
8349	id = this.attr( "id" );
8350
8351	if ( id ) {
8352
8353
8354
8355		// We don't search against the document in case the element
8356
8357		// is disconnected from the DOM
8358
8359		ancestor = this.eq( 0 ).parents().last();
8360
8361
8362
8363		// Get a full set of top level ancestors
8364
8365		ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() );
8366
8367
8368
8369		// Create a selector for the label based on the id
8370
8371		selector = "label[for='" + $.ui.escapeSelector( id ) + "']";
8372
8373
8374
8375		labels = labels.add( ancestors.find( selector ).addBack( selector ) );
8376
8377
8378
8379	}
8380
8381
8382
8383	// Return whatever we have found for labels
8384
8385	return this.pushStack( labels );
8386
8387};
8388
8389
8390
8391
8392
8393/*!
8394
8395 * jQuery UI Scroll Parent 1.12.1
8396
8397 * http://jqueryui.com
8398
8399 *
8400
8401 * Copyright jQuery Foundation and other contributors
8402
8403 * Released under the MIT license.
8404
8405 * http://jquery.org/license
8406
8407 */
8408
8409
8410
8411//>>label: scrollParent
8412
8413//>>group: Core
8414
8415//>>description: Get the closest ancestor element that is scrollable.
8416
8417//>>docs: http://api.jqueryui.com/scrollParent/
8418
8419
8420
8421
8422
8423
8424
8425var scrollParent = $.fn.scrollParent = function( includeHidden ) {
8426
8427	var position = this.css( "position" ),
8428
8429		excludeStaticParent = position === "absolute",
8430
8431		overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
8432
8433		scrollParent = this.parents().filter( function() {
8434
8435			var parent = $( this );
8436
8437			if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
8438
8439				return false;
8440
8441			}
8442
8443			return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
8444
8445				parent.css( "overflow-x" ) );
8446
8447		} ).eq( 0 );
8448
8449
8450
8451	return position === "fixed" || !scrollParent.length ?
8452
8453		$( this[ 0 ].ownerDocument || document ) :
8454
8455		scrollParent;
8456
8457};
8458
8459
8460
8461
8462
8463/*!
8464
8465 * jQuery UI Tabbable 1.12.1
8466
8467 * http://jqueryui.com
8468
8469 *
8470
8471 * Copyright jQuery Foundation and other contributors
8472
8473 * Released under the MIT license.
8474
8475 * http://jquery.org/license
8476
8477 */
8478
8479
8480
8481//>>label: :tabbable Selector
8482
8483//>>group: Core
8484
8485//>>description: Selects elements which can be tabbed to.
8486
8487//>>docs: http://api.jqueryui.com/tabbable-selector/
8488
8489
8490
8491
8492
8493
8494
8495var tabbable = $.extend( $.expr[ ":" ], {
8496
8497	tabbable: function( element ) {
8498
8499		var tabIndex = $.attr( element, "tabindex" ),
8500
8501			hasTabindex = tabIndex != null;
8502
8503		return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex );
8504
8505	}
8506
8507} );
8508
8509
8510
8511
8512
8513/*!
8514
8515 * jQuery UI Unique ID 1.12.1
8516
8517 * http://jqueryui.com
vendor: 5,284 bytes, lines 8518-8928
8518
8519 *
8520
8521 * Copyright jQuery Foundation and other contributors
8522
8523 * Released under the MIT license.
8524
8525 * http://jquery.org/license
8526
8527 */
8528
8529
8530
8531//>>label: uniqueId
8532
8533//>>group: Core
8534
8535//>>description: Functions to generate and remove uniqueId's
8536
8537//>>docs: http://api.jqueryui.com/uniqueId/
8538
8539
8540
8541
8542
8543
8544
8545var uniqueId = $.fn.extend( {
8546
8547	uniqueId: ( function() {
8548
8549		var uuid = 0;
8550
8551
8552
8553		return function() {
8554
8555			return this.each( function() {
8556
8557				if ( !this.id ) {
8558
8559					this.id = "ui-id-" + ( ++uuid );
8560
8561				}
8562
8563			} );
8564
8565		};
8566
8567	} )(),
8568
8569
8570
8571	removeUniqueId: function() {
8572
8573		return this.each( function() {
8574
8575			if ( /^ui-id-\d+$/.test( this.id ) ) {
8576
8577				$( this ).removeAttr( "id" );
8578
8579			}
8580
8581		} );
8582
8583	}
8584
8585} );
8586
8587
8588
8589
8590
8591/*!
8592
8593 * jQuery UI Accordion 1.12.1
8594
8595 * http://jqueryui.com
8596
8597 *
8598
8599 * Copyright jQuery Foundation and other contributors
8600
8601 * Released under the MIT license.
8602
8603 * http://jquery.org/license
8604
8605 */
8606
8607
8608
8609//>>label: Accordion
8610
8611//>>group: Widgets
8612
8613// jscs:disable maximumLineLength
8614
8615//>>description: Displays collapsible content panels for presenting information in a limited amount of space.
8616
8617// jscs:enable maximumLineLength
8618
8619//>>docs: http://api.jqueryui.com/accordion/
8620
8621//>>demos: http://jqueryui.com/accordion/
8622
8623//>>css.structure: ../../themes/base/core.css
8624
8625//>>css.structure: ../../themes/base/accordion.css
8626
8627//>>css.theme: ../../themes/base/theme.css
8628
8629
8630
8631
8632
8633
8634
8635var widgetsAccordion = $.widget( "ui.accordion", {
8636
8637	version: "1.12.1",
8638
8639	options: {
8640
8641		active: 0,
8642
8643		animate: {},
8644
8645		classes: {
8646
8647			"ui-accordion-header": "ui-corner-top",
8648
8649			"ui-accordion-header-collapsed": "ui-corner-all",
8650
8651			"ui-accordion-content": "ui-corner-bottom"
8652
8653		},
8654
8655		collapsible: false,
8656
8657		event: "click",
8658
8659		header: "> li > :first-child, > :not(li):even",
8660
8661		heightStyle: "auto",
8662
8663		icons: {
8664
8665			activeHeader: "ui-icon-triangle-1-s",
8666
8667			header: "ui-icon-triangle-1-e"
8668
8669		},
8670
8671
8672
8673		// Callbacks
8674
8675		activate: null,
8676
8677		beforeActivate: null
8678
8679	},
8680
8681
8682
8683	hideProps: {
8684
8685		borderTopWidth: "hide",
8686
8687		borderBottomWidth: "hide",
8688
8689		paddingTop: "hide",
8690
8691		paddingBottom: "hide",
8692
8693		height: "hide"
8694
8695	},
8696
8697
8698
8699	showProps: {
8700
8701		borderTopWidth: "show",
8702
8703		borderBottomWidth: "show",
8704
8705		paddingTop: "show",
8706
8707		paddingBottom: "show",
8708
8709		height: "show"
8710
8711	},
8712
8713
8714
8715	_create: function() {
8716
8717		var options = this.options;
8718
8719
8720
8721		this.prevShow = this.prevHide = $();
8722
8723		this._addClass( "ui-accordion", "ui-widget ui-helper-reset" );
8724
8725		this.element.attr( "role", "tablist" );
8726
8727
8728
8729		// Don't allow collapsible: false and active: false / null
8730
8731		if ( !options.collapsible && ( options.active === false || options.active == null ) ) {
8732
8733			options.active = 0;
8734
8735		}
8736
8737
8738
8739		this._processPanels();
8740
8741
8742
8743		// handle negative values
8744
8745		if ( options.active < 0 ) {
8746
8747			options.active += this.headers.length;
8748
8749		}
8750
8751		this._refresh();
8752
8753	},
8754
8755
8756
8757	_getCreateEventData: function() {
8758
8759		return {
8760
8761			header: this.active,
8762
8763			panel: !this.active.length ? $() : this.active.next()
8764
8765		};
8766
8767	},
8768
8769
8770
8771	_createIcons: function() {
8772
8773		var icon, children,
8774
8775			icons = this.options.icons;
8776
8777
8778
8779		if ( icons ) {
8780
8781			icon = $( "<span>" );
8782
8783			this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header );
8784
8785			icon.prependTo( this.headers );
8786
8787			children = this.active.children( ".ui-accordion-header-icon" );
8788
8789			this._removeClass( children, icons.header )
8790
8791				._addClass( children, null, icons.activeHeader )
8792
8793				._addClass( this.headers, "ui-accordion-icons" );
8794
8795		}
8796
8797	},
8798
8799
8800
8801	_destroyIcons: function() {
8802
8803		this._removeClass( this.headers, "ui-accordion-icons" );
8804
8805		this.headers.children( ".ui-accordion-header-icon" ).remove();
8806
8807	},
8808
8809
8810
8811	_destroy: function() {
8812
8813		var contents;
8814
8815
8816
8817		// Clean up main element
8818
8819		this.element.removeAttr( "role" );
8820
8821
8822
8823		// Clean up headers
8824
8825		this.headers
8826
8827			.removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" )
8828
8829			.removeUniqueId();
8830
8831
8832
8833		this._destroyIcons();
8834
8835
8836
8837		// Clean up content panels
8838
8839		contents = this.headers.next()
8840
8841			.css( "display", "" )
8842
8843			.removeAttr( "role aria-hidden aria-labelledby" )
8844
8845			.removeUniqueId();
8846
8847
8848
8849		if ( this.options.heightStyle !== "content" ) {
8850
8851			contents.css( "height", "" );
8852
8853		}
8854
8855	},
8856
8857
8858
8859	_setOption: function( key, value ) {
8860
8861		if ( key === "active" ) {
8862
8863
8864
8865			// _activate() will handle invalid values and update this.options
8866
8867			this._activate( value );
8868
8869			return;
8870
8871		}
8872
8873
8874
8875		if ( key === "event" ) {
8876
8877			if ( this.options.event ) {
8878
8879				this._off( this.headers, this.options.event );
8880
8881			}
8882
8883			this._setupEvents( value );
8884
8885		}
8886
8887
8888
8889		this._super( key, value );
8890
8891
8892
8893		// Setting collapsible: false while collapsed; open first panel
8894
8895		if ( key === "collapsible" && !value && this.options.active === false ) {
8896
8897			this._activate( 0 );
8898
8899		}
8900
8901
8902
8903		if ( key === "icons" ) {
8904
8905			this._destroyIcons();
8906
8907			if ( value ) {
8908
8909				this._createIcons();
8910
8911			}
8912
8913		}
8914
8915	},
8916
8917
8918
8919	_setOptionDisabled: function( value ) {
8920
8921		this._super( value );
8922
8923
8924
8925		this.element.attr( "aria-disabled", value );
8926
8927
8928
vendor: 9,917 bytes, lines 8929-9584
8929		// Support: IE8 Only
8930
8931		// #5332 / #6059 - opacity doesn't cascade to positioned elements in IE
8932
8933		// so we need to add the disabled class to the headers and panels
8934
8935		this._toggleClass( null, "ui-state-disabled", !!value );
8936
8937		this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled",
8938
8939			!!value );
8940
8941	},
8942
8943
8944
8945	_keydown: function( event ) {
8946
8947		if ( event.altKey || event.ctrlKey ) {
8948
8949			return;
8950
8951		}
8952
8953
8954
8955		var keyCode = $.ui.keyCode,
8956
8957			length = this.headers.length,
8958
8959			currentIndex = this.headers.index( event.target ),
8960
8961			toFocus = false;
8962
8963
8964
8965		switch ( event.keyCode ) {
8966
8967		case keyCode.RIGHT:
8968
8969		case keyCode.DOWN:
8970
8971			toFocus = this.headers[ ( currentIndex + 1 ) % length ];
8972
8973			break;
8974
8975		case keyCode.LEFT:
8976
8977		case keyCode.UP:
8978
8979			toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
8980
8981			break;
8982
8983		case keyCode.SPACE:
8984
8985		case keyCode.ENTER:
8986
8987			this._eventHandler( event );
8988
8989			break;
8990
8991		case keyCode.HOME:
8992
8993			toFocus = this.headers[ 0 ];
8994
8995			break;
8996
8997		case keyCode.END:
8998
8999			toFocus = this.headers[ length - 1 ];
9000
9001			break;
9002
9003		}
9004
9005
9006
9007		if ( toFocus ) {
9008
9009			$( event.target ).attr( "tabIndex", -1 );
9010
9011			$( toFocus ).attr( "tabIndex", 0 );
9012
9013			$( toFocus ).trigger( "focus" );
9014
9015			event.preventDefault();
9016
9017		}
9018
9019	},
9020
9021
9022
9023	_panelKeyDown: function( event ) {
9024
9025		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
9026
9027			$( event.currentTarget ).prev().trigger( "focus" );
9028
9029		}
9030
9031	},
9032
9033
9034
9035	refresh: function() {
9036
9037		var options = this.options;
9038
9039		this._processPanels();
9040
9041
9042
9043		// Was collapsed or no panel
9044
9045		if ( ( options.active === false && options.collapsible === true ) ||
9046
9047				!this.headers.length ) {
9048
9049			options.active = false;
9050
9051			this.active = $();
9052
9053
9054
9055		// active false only when collapsible is true
9056
9057		} else if ( options.active === false ) {
9058
9059			this._activate( 0 );
9060
9061
9062
9063		// was active, but active panel is gone
9064
9065		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
9066
9067
9068
9069			// all remaining panel are disabled
9070
9071			if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) {
9072
9073				options.active = false;
9074
9075				this.active = $();
9076
9077
9078
9079			// activate previous panel
9080
9081			} else {
9082
9083				this._activate( Math.max( 0, options.active - 1 ) );
9084
9085			}
9086
9087
9088
9089		// was active, active panel still exists
9090
9091		} else {
9092
9093
9094
9095			// make sure active index is correct
9096
9097			options.active = this.headers.index( this.active );
9098
9099		}
9100
9101
9102
9103		this._destroyIcons();
9104
9105
9106
9107		this._refresh();
9108
9109	},
9110
9111
9112
9113	_processPanels: function() {
9114
9115		var prevHeaders = this.headers,
9116
9117			prevPanels = this.panels;
9118
9119
9120
9121		this.headers = this.element.find( this.options.header );
9122
9123		this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed",
9124
9125			"ui-state-default" );
9126
9127
9128
9129		this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide();
9130
9131		this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" );
9132
9133
9134
9135		// Avoid memory leaks (#10056)
9136
9137		if ( prevPanels ) {
9138
9139			this._off( prevHeaders.not( this.headers ) );
9140
9141			this._off( prevPanels.not( this.panels ) );
9142
9143		}
9144
9145	},
9146
9147
9148
9149	_refresh: function() {
9150
9151		var maxHeight,
9152
9153			options = this.options,
9154
9155			heightStyle = options.heightStyle,
9156
9157			parent = this.element.parent();
9158
9159
9160
9161		this.active = this._findActive( options.active );
9162
9163		this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" )
9164
9165			._removeClass( this.active, "ui-accordion-header-collapsed" );
9166
9167		this._addClass( this.active.next(), "ui-accordion-content-active" );
9168
9169		this.active.next().show();
9170
9171
9172
9173		this.headers
9174
9175			.attr( "role", "tab" )
9176
9177			.each( function() {
9178
9179				var header = $( this ),
9180
9181					headerId = header.uniqueId().attr( "id" ),
9182
9183					panel = header.next(),
9184
9185					panelId = panel.uniqueId().attr( "id" );
9186
9187				header.attr( "aria-controls", panelId );
9188
9189				panel.attr( "aria-labelledby", headerId );
9190
9191			} )
9192
9193			.next()
9194
9195				.attr( "role", "tabpanel" );
9196
9197
9198
9199		this.headers
9200
9201			.not( this.active )
9202
9203				.attr( {
9204
9205					"aria-selected": "false",
9206
9207					"aria-expanded": "false",
9208
9209					tabIndex: -1
9210
9211				} )
9212
9213				.next()
9214
9215					.attr( {
9216
9217						"aria-hidden": "true"
9218
9219					} )
9220
9221					.hide();
9222
9223
9224
9225		// Make sure at least one header is in the tab order
9226
9227		if ( !this.active.length ) {
9228
9229			this.headers.eq( 0 ).attr( "tabIndex", 0 );
9230
9231		} else {
9232
9233			this.active.attr( {
9234
9235				"aria-selected": "true",
9236
9237				"aria-expanded": "true",
9238
9239				tabIndex: 0
9240
9241			} )
9242
9243				.next()
9244
9245					.attr( {
9246
9247						"aria-hidden": "false"
9248
9249					} );
9250
9251		}
9252
9253
9254
9255		this._createIcons();
9256
9257
9258
9259		this._setupEvents( options.event );
9260
9261
9262
9263		if ( heightStyle === "fill" ) {
9264
9265			maxHeight = parent.height();
9266
9267			this.element.siblings( ":visible" ).each( function() {
9268
9269				var elem = $( this ),
9270
9271					position = elem.css( "position" );
9272
9273
9274
9275				if ( position === "absolute" || position === "fixed" ) {
9276
9277					return;
9278
9279				}
9280
9281				maxHeight -= elem.outerHeight( true );
9282
9283			} );
9284
9285
9286
9287			this.headers.each( function() {
9288
9289				maxHeight -= $( this ).outerHeight( true );
9290
9291			} );
9292
9293
9294
9295			this.headers.next()
9296
9297				.each( function() {
9298
9299					$( this ).height( Math.max( 0, maxHeight -
9300
9301						$( this ).innerHeight() + $( this ).height() ) );
9302
9303				} )
9304
9305				.css( "overflow", "auto" );
9306
9307		} else if ( heightStyle === "auto" ) {
9308
9309			maxHeight = 0;
9310
9311			this.headers.next()
9312
9313				.each( function() {
9314
9315					var isVisible = $( this ).is( ":visible" );
9316
9317					if ( !isVisible ) {
9318
9319						$( this ).show();
9320
9321					}
9322
9323					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
9324
9325					if ( !isVisible ) {
9326
9327						$( this ).hide();
9328
9329					}
9330
9331				} )
9332
9333				.height( maxHeight );
9334
9335		}
9336
9337	},
9338
9339
9340
9341	_activate: function( index ) {
9342
9343		var active = this._findActive( index )[ 0 ];
9344
9345
9346
9347		// Trying to activate the already active panel
9348
9349		if ( active === this.active[ 0 ] ) {
9350
9351			return;
9352
9353		}
9354
9355
9356
9357		// Trying to collapse, simulate a click on the currently active header
9358
9359		active = active || this.active[ 0 ];
9360
9361
9362
9363		this._eventHandler( {
9364
9365			target: active,
9366
9367			currentTarget: active,
9368
9369			preventDefault: $.noop
9370
9371		} );
9372
9373	},
9374
9375
9376
9377	_findActive: function( selector ) {
9378
9379		return typeof selector === "number" ? this.headers.eq( selector ) : $();
9380
9381	},
9382
9383
9384
9385	_setupEvents: function( event ) {
9386
9387		var events = {
9388
9389			keydown: "_keydown"
9390
9391		};
9392
9393		if ( event ) {
9394
9395			$.each( event.split( " " ), function( index, eventName ) {
9396
9397				events[ eventName ] = "_eventHandler";
9398
9399			} );
9400
9401		}
9402
9403
9404
9405		this._off( this.headers.add( this.headers.next() ) );
9406
9407		this._on( this.headers, events );
9408
9409		this._on( this.headers.next(), { keydown: "_panelKeyDown" } );
9410
9411		this._hoverable( this.headers );
9412
9413		this._focusable( this.headers );
9414
9415	},
9416
9417
9418
9419	_eventHandler: function( event ) {
9420
9421		var activeChildren, clickedChildren,
9422
9423			options = this.options,
9424
9425			active = this.active,
9426
9427			clicked = $( event.currentTarget ),
9428
9429			clickedIsActive = clicked[ 0 ] === active[ 0 ],
9430
9431			collapsing = clickedIsActive && options.collapsible,
9432
9433			toShow = collapsing ? $() : clicked.next(),
9434
9435			toHide = active.next(),
9436
9437			eventData = {
9438
9439				oldHeader: active,
9440
9441				oldPanel: toHide,
9442
9443				newHeader: collapsing ? $() : clicked,
9444
9445				newPanel: toShow
9446
9447			};
9448
9449
9450
9451		event.preventDefault();
9452
9453
9454
9455		if (
9456
9457
9458
9459				// click on active header, but not collapsible
9460
9461				( clickedIsActive && !options.collapsible ) ||
9462
9463
9464
9465				// allow canceling activation
9466
9467				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
9468
9469			return;
9470
9471		}
9472
9473
9474
9475		options.active = collapsing ? false : this.headers.index( clicked );
9476
9477
9478
9479		// When the call to ._toggle() comes after the class changes
9480
9481		// it causes a very odd bug in IE 8 (see #6720)
9482
9483		this.active = clickedIsActive ? $() : clicked;
9484
9485		this._toggle( eventData );
9486
9487
9488
9489		// Switch classes
9490
9491		// corner classes on the previously active header stay after the animation
9492
9493		this._removeClass( active, "ui-accordion-header-active", "ui-state-active" );
9494
9495		if ( options.icons ) {
9496
9497			activeChildren = active.children( ".ui-accordion-header-icon" );
9498
9499			this._removeClass( activeChildren, null, options.icons.activeHeader )
9500
9501				._addClass( activeChildren, null, options.icons.header );
9502
9503		}
9504
9505
9506
9507		if ( !clickedIsActive ) {
9508
9509			this._removeClass( clicked, "ui-accordion-header-collapsed" )
9510
9511				._addClass( clicked, "ui-accordion-header-active", "ui-state-active" );
9512
9513			if ( options.icons ) {
9514
9515				clickedChildren = clicked.children( ".ui-accordion-header-icon" );
9516
9517				this._removeClass( clickedChildren, null, options.icons.header )
9518
9519					._addClass( clickedChildren, null, options.icons.activeHeader );
9520
9521			}
9522
9523
9524
9525			this._addClass( clicked.next(), "ui-accordion-content-active" );
9526
9527		}
9528
9529	},
9530
9531
9532
9533	_toggle: function( data ) {
9534
9535		var toShow = data.newPanel,
9536
9537			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
9538
9539
9540
9541		// Handle activating a panel during the animation for another activation
9542
9543		this.prevShow.add( this.prevHide ).stop( true, true );
9544
9545		this.prevShow = toShow;
9546
9547		this.prevHide = toHide;
9548
9549
9550
9551		if ( this.options.animate ) {
9552
9553			this._animate( toShow, toHide, data );
9554
9555		} else {
9556
9557			toHide.hide();
9558
9559			toShow.show();
9560
9561			this._toggleComplete( data );
9562
9563		}
9564
9565
9566
9567		toHide.attr( {
9568
9569			"aria-hidden": "true"
9570
9571		} );
9572
9573		toHide.prev().attr( {
9574
9575			"aria-selected": "false",
9576
9577			"aria-expanded": "false"
9578
9579		} );
9580
9581
9582
9583		// if we're switching panels, remove the old header from the tab order
9584
vendor: 8,111 bytes, lines 9585-10125
9585		// if we're opening from collapsed state, remove the previous header from the tab order
9586
9587		// if we're collapsing, then keep the collapsing header in the tab order
9588
9589		if ( toShow.length && toHide.length ) {
9590
9591			toHide.prev().attr( {
9592
9593				"tabIndex": -1,
9594
9595				"aria-expanded": "false"
9596
9597			} );
9598
9599		} else if ( toShow.length ) {
9600
9601			this.headers.filter( function() {
9602
9603				return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
9604
9605			} )
9606
9607				.attr( "tabIndex", -1 );
9608
9609		}
9610
9611
9612
9613		toShow
9614
9615			.attr( "aria-hidden", "false" )
9616
9617			.prev()
9618
9619				.attr( {
9620
9621					"aria-selected": "true",
9622
9623					"aria-expanded": "true",
9624
9625					tabIndex: 0
9626
9627				} );
9628
9629	},
9630
9631
9632
9633	_animate: function( toShow, toHide, data ) {
9634
9635		var total, easing, duration,
9636
9637			that = this,
9638
9639			adjust = 0,
9640
9641			boxSizing = toShow.css( "box-sizing" ),
9642
9643			down = toShow.length &&
9644
9645				( !toHide.length || ( toShow.index() < toHide.index() ) ),
9646
9647			animate = this.options.animate || {},
9648
9649			options = down && animate.down || animate,
9650
9651			complete = function() {
9652
9653				that._toggleComplete( data );
9654
9655			};
9656
9657
9658
9659		if ( typeof options === "number" ) {
9660
9661			duration = options;
9662
9663		}
9664
9665		if ( typeof options === "string" ) {
9666
9667			easing = options;
9668
9669		}
9670
9671
9672
9673		// fall back from options to animation in case of partial down settings
9674
9675		easing = easing || options.easing || animate.easing;
9676
9677		duration = duration || options.duration || animate.duration;
9678
9679
9680
9681		if ( !toHide.length ) {
9682
9683			return toShow.animate( this.showProps, duration, easing, complete );
9684
9685		}
9686
9687		if ( !toShow.length ) {
9688
9689			return toHide.animate( this.hideProps, duration, easing, complete );
9690
9691		}
9692
9693
9694
9695		total = toShow.show().outerHeight();
9696
9697		toHide.animate( this.hideProps, {
9698
9699			duration: duration,
9700
9701			easing: easing,
9702
9703			step: function( now, fx ) {
9704
9705				fx.now = Math.round( now );
9706
9707			}
9708
9709		} );
9710
9711		toShow
9712
9713			.hide()
9714
9715			.animate( this.showProps, {
9716
9717				duration: duration,
9718
9719				easing: easing,
9720
9721				complete: complete,
9722
9723				step: function( now, fx ) {
9724
9725					fx.now = Math.round( now );
9726
9727					if ( fx.prop !== "height" ) {
9728
9729						if ( boxSizing === "content-box" ) {
9730
9731							adjust += fx.now;
9732
9733						}
9734
9735					} else if ( that.options.heightStyle !== "content" ) {
9736
9737						fx.now = Math.round( total - toHide.outerHeight() - adjust );
9738
9739						adjust = 0;
9740
9741					}
9742
9743				}
9744
9745			} );
9746
9747	},
9748
9749
9750
9751	_toggleComplete: function( data ) {
9752
9753		var toHide = data.oldPanel,
9754
9755			prev = toHide.prev();
9756
9757
9758
9759		this._removeClass( toHide, "ui-accordion-content-active" );
9760
9761		this._removeClass( prev, "ui-accordion-header-active" )
9762
9763			._addClass( prev, "ui-accordion-header-collapsed" );
9764
9765
9766
9767		// Work around for rendering bug in IE (#5421)
9768
9769		if ( toHide.length ) {
9770
9771			toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
9772
9773		}
9774
9775		this._trigger( "activate", null, data );
9776
9777	}
9778
9779} );
9780
9781
9782
9783
9784
9785
9786
9787var safeActiveElement = $.ui.safeActiveElement = function( document ) {
9788
9789	var activeElement;
9790
9791
9792
9793	// Support: IE 9 only
9794
9795	// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
9796
9797	try {
9798
9799		activeElement = document.activeElement;
9800
9801	} catch ( error ) {
9802
9803		activeElement = document.body;
9804
9805	}
9806
9807
9808
9809	// Support: IE 9 - 11 only
9810
9811	// IE may return null instead of an element
9812
9813	// Interestingly, this only seems to occur when NOT in an iframe
9814
9815	if ( !activeElement ) {
9816
9817		activeElement = document.body;
9818
9819	}
9820
9821
9822
9823	// Support: IE 11 only
9824
9825	// IE11 returns a seemingly empty object in some cases when accessing
9826
9827	// document.activeElement from an <iframe>
9828
9829	if ( !activeElement.nodeName ) {
9830
9831		activeElement = document.body;
9832
9833	}
9834
9835
9836
9837	return activeElement;
9838
9839};
9840
9841
9842
9843
9844
9845/*!
9846
9847 * jQuery UI Menu 1.12.1
9848
9849 * http://jqueryui.com
9850
9851 *
9852
9853 * Copyright jQuery Foundation and other contributors
9854
9855 * Released under the MIT license.
9856
9857 * http://jquery.org/license
9858
9859 */
9860
9861
9862
9863//>>label: Menu
9864
9865//>>group: Widgets
9866
9867//>>description: Creates nestable menus.
9868
9869//>>docs: http://api.jqueryui.com/menu/
9870
9871//>>demos: http://jqueryui.com/menu/
9872
9873//>>css.structure: ../../themes/base/core.css
9874
9875//>>css.structure: ../../themes/base/menu.css
9876
9877//>>css.theme: ../../themes/base/theme.css
9878
9879
9880
9881
9882
9883
9884
9885var widgetsMenu = $.widget( "ui.menu", {
9886
9887	version: "1.12.1",
9888
9889	defaultElement: "<ul>",
9890
9891	delay: 300,
9892
9893	options: {
9894
9895		icons: {
9896
9897			submenu: "ui-icon-caret-1-e"
9898
9899		},
9900
9901		items: "> *",
9902
9903		menus: "ul",
9904
9905		position: {
9906
9907			my: "left top",
9908
9909			at: "right top"
9910
9911		},
9912
9913		role: "menu",
9914
9915
9916
9917		// Callbacks
9918
9919		blur: null,
9920
9921		focus: null,
9922
9923		select: null
9924
9925	},
9926
9927
9928
9929	_create: function() {
9930
9931		this.activeMenu = this.element;
9932
9933
9934
9935		// Flag used to prevent firing of the click handler
9936
9937		// as the event bubbles up through nested menus
9938
9939		this.mouseHandled = false;
9940
9941		this.element
9942
9943			.uniqueId()
9944
9945			.attr( {
9946
9947				role: this.options.role,
9948
9949				tabIndex: 0
9950
9951			} );
9952
9953
9954
9955		this._addClass( "ui-menu", "ui-widget ui-widget-content" );
9956
9957		this._on( {
9958
9959
9960
9961			// Prevent focus from sticking to links inside menu after clicking
9962
9963			// them (focus should always stay on UL during navigation).
9964
9965			"mousedown .ui-menu-item": function( event ) {
9966
9967				event.preventDefault();
9968
9969			},
9970
9971			"click .ui-menu-item": function( event ) {
9972
9973				var target = $( event.target );
9974
9975				var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
9976
9977				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
9978
9979					this.select( event );
9980
9981
9982
9983					// Only set the mouseHandled flag if the event will bubble, see #9469.
9984
9985					if ( !event.isPropagationStopped() ) {
9986
9987						this.mouseHandled = true;
9988
9989					}
9990
9991
9992
9993					// Open submenu on click
9994
9995					if ( target.has( ".ui-menu" ).length ) {
9996
9997						this.expand( event );
9998
9999					} else if ( !this.element.is( ":focus" ) &&
10000
10001							active.closest( ".ui-menu" ).length ) {
10002
10003
10004
10005						// Redirect focus to the menu
10006
10007						this.element.trigger( "focus", [ true ] );
10008
10009
10010
10011						// If the active item is on the top level, let it stay active.
10012
10013						// Otherwise, blur the active item since it is no longer visible.
10014
10015						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
10016
10017							clearTimeout( this.timer );
10018
10019						}
10020
10021					}
10022
10023				}
10024
10025			},
10026
10027			"mouseenter .ui-menu-item": function( event ) {
10028
10029
10030
10031				// Ignore mouse events while typeahead is active, see #10458.
10032
10033				// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
10034
10035				// is over an item in the menu
10036
10037				if ( this.previousFilter ) {
10038
10039					return;
10040
10041				}
10042
10043
10044
10045				var actualTarget = $( event.target ).closest( ".ui-menu-item" ),
10046
10047					target = $( event.currentTarget );
10048
10049
10050
10051				// Ignore bubbled events on parent items, see #11641
10052
10053				if ( actualTarget[ 0 ] !== target[ 0 ] ) {
10054
10055					return;
10056
10057				}
10058
10059
10060
10061				// Remove ui-state-active class from siblings of the newly focused menu item
10062
10063				// to avoid a jump caused by adjacent elements both having a class with a border
10064
10065				this._removeClass( target.siblings().children( ".ui-state-active" ),
10066
10067					null, "ui-state-active" );
10068
10069				this.focus( event, target );
10070
10071			},
10072
10073			mouseleave: "collapseAll",
10074
10075			"mouseleave .ui-menu": "collapseAll",
10076
10077			focus: function( event, keepActiveItem ) {
10078
10079
10080
10081				// If there's already an active item, keep it active
10082
10083				// If not, activate the first item
10084
10085				var item = this.active || this.element.find( this.options.items ).eq( 0 );
10086
10087
10088
10089				if ( !keepActiveItem ) {
10090
10091					this.focus( event, item );
10092
10093				}
10094
10095			},
10096
10097			blur: function( event ) {
10098
10099				this._delay( function() {
10100
10101					var notContained = !$.contains(
10102
10103						this.element[ 0 ],
10104
10105						$.ui.safeActiveElement( this.document[ 0 ] )
10106
10107					);
10108
10109					if ( notContained ) {
10110
10111						this.collapseAll( event );
10112
10113					}
10114
10115				} );
10116
10117			},
10118
10119			keydown: "_keydown"
10120
10121		} );
10122
10123
10124
10125		this.refresh();
vendor: 4,731 bytes, lines 10126-10454
10126
10127
10128
10129		// Clicks outside of a menu collapse any open menus
10130
10131		this._on( this.document, {
10132
10133			click: function( event ) {
10134
10135				if ( this._closeOnDocumentClick( event ) ) {
10136
10137					this.collapseAll( event );
10138
10139				}
10140
10141
10142
10143				// Reset the mouseHandled flag
10144
10145				this.mouseHandled = false;
10146
10147			}
10148
10149		} );
10150
10151	},
10152
10153
10154
10155	_destroy: function() {
10156
10157		var items = this.element.find( ".ui-menu-item" )
10158
10159				.removeAttr( "role aria-disabled" ),
10160
10161			submenus = items.children( ".ui-menu-item-wrapper" )
10162
10163				.removeUniqueId()
10164
10165				.removeAttr( "tabIndex role aria-haspopup" );
10166
10167
10168
10169		// Destroy (sub)menus
10170
10171		this.element
10172
10173			.removeAttr( "aria-activedescendant" )
10174
10175			.find( ".ui-menu" ).addBack()
10176
10177				.removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " +
10178
10179					"tabIndex" )
10180
10181				.removeUniqueId()
10182
10183				.show();
10184
10185
10186
10187		submenus.children().each( function() {
10188
10189			var elem = $( this );
10190
10191			if ( elem.data( "ui-menu-submenu-caret" ) ) {
10192
10193				elem.remove();
10194
10195			}
10196
10197		} );
10198
10199	},
10200
10201
10202
10203	_keydown: function( event ) {
10204
10205		var match, prev, character, skip,
10206
10207			preventDefault = true;
10208
10209
10210
10211		switch ( event.keyCode ) {
10212
10213		case $.ui.keyCode.PAGE_UP:
10214
10215			this.previousPage( event );
10216
10217			break;
10218
10219		case $.ui.keyCode.PAGE_DOWN:
10220
10221			this.nextPage( event );
10222
10223			break;
10224
10225		case $.ui.keyCode.HOME:
10226
10227			this._move( "first", "first", event );
10228
10229			break;
10230
10231		case $.ui.keyCode.END:
10232
10233			this._move( "last", "last", event );
10234
10235			break;
10236
10237		case $.ui.keyCode.UP:
10238
10239			this.previous( event );
10240
10241			break;
10242
10243		case $.ui.keyCode.DOWN:
10244
10245			this.next( event );
10246
10247			break;
10248
10249		case $.ui.keyCode.LEFT:
10250
10251			this.collapse( event );
10252
10253			break;
10254
10255		case $.ui.keyCode.RIGHT:
10256
10257			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
10258
10259				this.expand( event );
10260
10261			}
10262
10263			break;
10264
10265		case $.ui.keyCode.ENTER:
10266
10267		case $.ui.keyCode.SPACE:
10268
10269			this._activate( event );
10270
10271			break;
10272
10273		case $.ui.keyCode.ESCAPE:
10274
10275			this.collapse( event );
10276
10277			break;
10278
10279		default:
10280
10281			preventDefault = false;
10282
10283			prev = this.previousFilter || "";
10284
10285			skip = false;
10286
10287
10288
10289			// Support number pad values
10290
10291			character = event.keyCode >= 96 && event.keyCode <= 105 ?
10292
10293				( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode );
10294
10295
10296
10297			clearTimeout( this.filterTimer );
10298
10299
10300
10301			if ( character === prev ) {
10302
10303				skip = true;
10304
10305			} else {
10306
10307				character = prev + character;
10308
10309			}
10310
10311
10312
10313			match = this._filterMenuItems( character );
10314
10315			match = skip && match.index( this.active.next() ) !== -1 ?
10316
10317				this.active.nextAll( ".ui-menu-item" ) :
10318
10319				match;
10320
10321
10322
10323			// If no matches on the current filter, reset to the last character pressed
10324
10325			// to move down the menu to the first item that starts with that character
10326
10327			if ( !match.length ) {
10328
10329				character = String.fromCharCode( event.keyCode );
10330
10331				match = this._filterMenuItems( character );
10332
10333			}
10334
10335
10336
10337			if ( match.length ) {
10338
10339				this.focus( event, match );
10340
10341				this.previousFilter = character;
10342
10343				this.filterTimer = this._delay( function() {
10344
10345					delete this.previousFilter;
10346
10347				}, 1000 );
10348
10349			} else {
10350
10351				delete this.previousFilter;
10352
10353			}
10354
10355		}
10356
10357
10358
10359		if ( preventDefault ) {
10360
10361			event.preventDefault();
10362
10363		}
10364
10365	},
10366
10367
10368
10369	_activate: function( event ) {
10370
10371		if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
10372
10373			if ( this.active.children( "[aria-haspopup='true']" ).length ) {
10374
10375				this.expand( event );
10376
10377			} else {
10378
10379				this.select( event );
10380
10381			}
10382
10383		}
10384
10385	},
10386
10387
10388
10389	refresh: function() {
10390
10391		var menus, items, newSubmenus, newItems, newWrappers,
10392
10393			that = this,
10394
10395			icon = this.options.icons.submenu,
10396
10397			submenus = this.element.find( this.options.menus );
10398
10399
10400
10401		this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length );
10402
10403
10404
10405		// Initialize nested menus
10406
10407		newSubmenus = submenus.filter( ":not(.ui-menu)" )
10408
10409			.hide()
10410
10411			.attr( {
10412
10413				role: this.options.role,
10414
10415				"aria-hidden": "true",
10416
10417				"aria-expanded": "false"
10418
10419			} )
10420
10421			.each( function() {
10422
10423				var menu = $( this ),
10424
10425					item = menu.prev(),
10426
10427					submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true );
10428
10429
10430
10431				that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon );
10432
10433				item
10434
10435					.attr( "aria-haspopup", "true" )
10436
10437					.prepend( submenuCaret );
10438
10439				menu.attr( "aria-labelledby", item.attr( "id" ) );
10440
10441			} );
10442
10443
10444
10445		this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" );
10446
10447
10448
10449		menus = submenus.add( this.element );
10450
10451		items = menus.find( this.options.items );
10452
10453
10454
vendor: 5,041 bytes, lines 10455-10780
10455		// Initialize menu-items containing spaces and/or dashes only as dividers
10456
10457		items.not( ".ui-menu-item" ).each( function() {
10458
10459			var item = $( this );
10460
10461			if ( that._isDivider( item ) ) {
10462
10463				that._addClass( item, "ui-menu-divider", "ui-widget-content" );
10464
10465			}
10466
10467		} );
10468
10469
10470
10471		// Don't refresh list items that are already adapted
10472
10473		newItems = items.not( ".ui-menu-item, .ui-menu-divider" );
10474
10475		newWrappers = newItems.children()
10476
10477			.not( ".ui-menu" )
10478
10479				.uniqueId()
10480
10481				.attr( {
10482
10483					tabIndex: -1,
10484
10485					role: this._itemRole()
10486
10487				} );
10488
10489		this._addClass( newItems, "ui-menu-item" )
10490
10491			._addClass( newWrappers, "ui-menu-item-wrapper" );
10492
10493
10494
10495		// Add aria-disabled attribute to any disabled menu item
10496
10497		items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
10498
10499
10500
10501		// If the active item has been removed, blur the menu
10502
10503		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
10504
10505			this.blur();
10506
10507		}
10508
10509	},
10510
10511
10512
10513	_itemRole: function() {
10514
10515		return {
10516
10517			menu: "menuitem",
10518
10519			listbox: "option"
10520
10521		}[ this.options.role ];
10522
10523	},
10524
10525
10526
10527	_setOption: function( key, value ) {
10528
10529		if ( key === "icons" ) {
10530
10531			var icons = this.element.find( ".ui-menu-icon" );
10532
10533			this._removeClass( icons, null, this.options.icons.submenu )
10534
10535				._addClass( icons, null, value.submenu );
10536
10537		}
10538
10539		this._super( key, value );
10540
10541	},
10542
10543
10544
10545	_setOptionDisabled: function( value ) {
10546
10547		this._super( value );
10548
10549
10550
10551		this.element.attr( "aria-disabled", String( value ) );
10552
10553		this._toggleClass( null, "ui-state-disabled", !!value );
10554
10555	},
10556
10557
10558
10559	focus: function( event, item ) {
10560
10561		var nested, focused, activeParent;
10562
10563		this.blur( event, event && event.type === "focus" );
10564
10565
10566
10567		this._scrollIntoView( item );
10568
10569
10570
10571		this.active = item.first();
10572
10573
10574
10575		focused = this.active.children( ".ui-menu-item-wrapper" );
10576
10577		this._addClass( focused, null, "ui-state-active" );
10578
10579
10580
10581		// Only update aria-activedescendant if there's a role
10582
10583		// otherwise we assume focus is managed elsewhere
10584
10585		if ( this.options.role ) {
10586
10587			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
10588
10589		}
10590
10591
10592
10593		// Highlight active parent menu item, if any
10594
10595		activeParent = this.active
10596
10597			.parent()
10598
10599				.closest( ".ui-menu-item" )
10600
10601					.children( ".ui-menu-item-wrapper" );
10602
10603		this._addClass( activeParent, null, "ui-state-active" );
10604
10605
10606
10607		if ( event && event.type === "keydown" ) {
10608
10609			this._close();
10610
10611		} else {
10612
10613			this.timer = this._delay( function() {
10614
10615				this._close();
10616
10617			}, this.delay );
10618
10619		}
10620
10621
10622
10623		nested = item.children( ".ui-menu" );
10624
10625		if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
10626
10627			this._startOpening( nested );
10628
10629		}
10630
10631		this.activeMenu = item.parent();
10632
10633
10634
10635		this._trigger( "focus", event, { item: item } );
10636
10637	},
10638
10639
10640
10641	_scrollIntoView: function( item ) {
10642
10643		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
10644
10645		if ( this._hasScroll() ) {
10646
10647			borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0;
10648
10649			paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0;
10650
10651			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
10652
10653			scroll = this.activeMenu.scrollTop();
10654
10655			elementHeight = this.activeMenu.height();
10656
10657			itemHeight = item.outerHeight();
10658
10659
10660
10661			if ( offset < 0 ) {
10662
10663				this.activeMenu.scrollTop( scroll + offset );
10664
10665			} else if ( offset + itemHeight > elementHeight ) {
10666
10667				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
10668
10669			}
10670
10671		}
10672
10673	},
10674
10675
10676
10677	blur: function( event, fromFocus ) {
10678
10679		if ( !fromFocus ) {
10680
10681			clearTimeout( this.timer );
10682
10683		}
10684
10685
10686
10687		if ( !this.active ) {
10688
10689			return;
10690
10691		}
10692
10693
10694
10695		this._removeClass( this.active.children( ".ui-menu-item-wrapper" ),
10696
10697			null, "ui-state-active" );
10698
10699
10700
10701		this._trigger( "blur", event, { item: this.active } );
10702
10703		this.active = null;
10704
10705	},
10706
10707
10708
10709	_startOpening: function( submenu ) {
10710
10711		clearTimeout( this.timer );
10712
10713
10714
10715		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
10716
10717		// shift in the submenu position when mousing over the caret icon
10718
10719		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
10720
10721			return;
10722
10723		}
10724
10725
10726
10727		this.timer = this._delay( function() {
10728
10729			this._close();
10730
10731			this._open( submenu );
10732
10733		}, this.delay );
10734
10735	},
10736
10737
10738
10739	_open: function( submenu ) {
10740
10741		var position = $.extend( {
10742
10743			of: this.active
10744
10745		}, this.options.position );
10746
10747
10748
10749		clearTimeout( this.timer );
10750
10751		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
10752
10753			.hide()
10754
10755			.attr( "aria-hidden", "true" );
10756
10757
10758
10759		submenu
10760
10761			.show()
10762
10763			.removeAttr( "aria-hidden" )
10764
10765			.attr( "aria-expanded", "true" )
10766
10767			.position( position );
10768
10769	},
10770
10771
10772
10773	collapseAll: function( event, all ) {
10774
10775		clearTimeout( this.timer );
10776
10777		this.timer = this._delay( function() {
10778
10779
10780
vendor: 39,620 bytes, lines 10781-13420
10781			// If we were passed an event, look for the submenu that contains the event
10782
10783			var currentMenu = all ? this.element :
10784
10785				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
10786
10787
10788
10789			// If we found no valid submenu ancestor, use the main menu to close all
10790
10791			// sub menus anyway
10792
10793			if ( !currentMenu.length ) {
10794
10795				currentMenu = this.element;
10796
10797			}
10798
10799
10800
10801			this._close( currentMenu );
10802
10803
10804
10805			this.blur( event );
10806
10807
10808
10809			// Work around active item staying active after menu is blurred
10810
10811			this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" );
10812
10813
10814
10815			this.activeMenu = currentMenu;
10816
10817		}, this.delay );
10818
10819	},
10820
10821
10822
10823	// With no arguments, closes the currently active menu - if nothing is active
10824
10825	// it closes all menus.  If passed an argument, it will search for menus BELOW
10826
10827	_close: function( startMenu ) {
10828
10829		if ( !startMenu ) {
10830
10831			startMenu = this.active ? this.active.parent() : this.element;
10832
10833		}
10834
10835
10836
10837		startMenu.find( ".ui-menu" )
10838
10839			.hide()
10840
10841			.attr( "aria-hidden", "true" )
10842
10843			.attr( "aria-expanded", "false" );
10844
10845	},
10846
10847
10848
10849	_closeOnDocumentClick: function( event ) {
10850
10851		return !$( event.target ).closest( ".ui-menu" ).length;
10852
10853	},
10854
10855
10856
10857	_isDivider: function( item ) {
10858
10859
10860
10861		// Match hyphen, em dash, en dash
10862
10863		return !/[^\-\u2014\u2013\s]/.test( item.text() );
10864
10865	},
10866
10867
10868
10869	collapse: function( event ) {
10870
10871		var newItem = this.active &&
10872
10873			this.active.parent().closest( ".ui-menu-item", this.element );
10874
10875		if ( newItem && newItem.length ) {
10876
10877			this._close();
10878
10879			this.focus( event, newItem );
10880
10881		}
10882
10883	},
10884
10885
10886
10887	expand: function( event ) {
10888
10889		var newItem = this.active &&
10890
10891			this.active
10892
10893				.children( ".ui-menu " )
10894
10895					.find( this.options.items )
10896
10897						.first();
10898
10899
10900
10901		if ( newItem && newItem.length ) {
10902
10903			this._open( newItem.parent() );
10904
10905
10906
10907			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
10908
10909			this._delay( function() {
10910
10911				this.focus( event, newItem );
10912
10913			} );
10914
10915		}
10916
10917	},
10918
10919
10920
10921	next: function( event ) {
10922
10923		this._move( "next", "first", event );
10924
10925	},
10926
10927
10928
10929	previous: function( event ) {
10930
10931		this._move( "prev", "last", event );
10932
10933	},
10934
10935
10936
10937	isFirstItem: function() {
10938
10939		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
10940
10941	},
10942
10943
10944
10945	isLastItem: function() {
10946
10947		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
10948
10949	},
10950
10951
10952
10953	_move: function( direction, filter, event ) {
10954
10955		var next;
10956
10957		if ( this.active ) {
10958
10959			if ( direction === "first" || direction === "last" ) {
10960
10961				next = this.active
10962
10963					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
10964
10965					.eq( -1 );
10966
10967			} else {
10968
10969				next = this.active
10970
10971					[ direction + "All" ]( ".ui-menu-item" )
10972
10973					.eq( 0 );
10974
10975			}
10976
10977		}
10978
10979		if ( !next || !next.length || !this.active ) {
10980
10981			next = this.activeMenu.find( this.options.items )[ filter ]();
10982
10983		}
10984
10985
10986
10987		this.focus( event, next );
10988
10989	},
10990
10991
10992
10993	nextPage: function( event ) {
10994
10995		var item, base, height;
10996
10997
10998
10999		if ( !this.active ) {
11000
11001			this.next( event );
11002
11003			return;
11004
11005		}
11006
11007		if ( this.isLastItem() ) {
11008
11009			return;
11010
11011		}
11012
11013		if ( this._hasScroll() ) {
11014
11015			base = this.active.offset().top;
11016
11017			height = this.element.height();
11018
11019			this.active.nextAll( ".ui-menu-item" ).each( function() {
11020
11021				item = $( this );
11022
11023				return item.offset().top - base - height < 0;
11024
11025			} );
11026
11027
11028
11029			this.focus( event, item );
11030
11031		} else {
11032
11033			this.focus( event, this.activeMenu.find( this.options.items )
11034
11035				[ !this.active ? "first" : "last" ]() );
11036
11037		}
11038
11039	},
11040
11041
11042
11043	previousPage: function( event ) {
11044
11045		var item, base, height;
11046
11047		if ( !this.active ) {
11048
11049			this.next( event );
11050
11051			return;
11052
11053		}
11054
11055		if ( this.isFirstItem() ) {
11056
11057			return;
11058
11059		}
11060
11061		if ( this._hasScroll() ) {
11062
11063			base = this.active.offset().top;
11064
11065			height = this.element.height();
11066
11067			this.active.prevAll( ".ui-menu-item" ).each( function() {
11068
11069				item = $( this );
11070
11071				return item.offset().top - base + height > 0;
11072
11073			} );
11074
11075
11076
11077			this.focus( event, item );
11078
11079		} else {
11080
11081			this.focus( event, this.activeMenu.find( this.options.items ).first() );
11082
11083		}
11084
11085	},
11086
11087
11088
11089	_hasScroll: function() {
11090
11091		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
11092
11093	},
11094
11095
11096
11097	select: function( event ) {
11098
11099
11100
11101		// TODO: It should never be possible to not have an active item at this
11102
11103		// point, but the tests don't trigger mouseenter before click.
11104
11105		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
11106
11107		var ui = { item: this.active };
11108
11109		if ( !this.active.has( ".ui-menu" ).length ) {
11110
11111			this.collapseAll( event, true );
11112
11113		}
11114
11115		this._trigger( "select", event, ui );
11116
11117	},
11118
11119
11120
11121	_filterMenuItems: function( character ) {
11122
11123		var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
11124
11125			regex = new RegExp( "^" + escapedCharacter, "i" );
11126
11127
11128
11129		return this.activeMenu
11130
11131			.find( this.options.items )
11132
11133
11134
11135				// Only match on items, not dividers or other content (#10571)
11136
11137				.filter( ".ui-menu-item" )
11138
11139					.filter( function() {
11140
11141						return regex.test(
11142
11143							$.trim( $( this ).children( ".ui-menu-item-wrapper" ).text() ) );
11144
11145					} );
11146
11147	}
11148
11149} );
11150
11151
11152
11153
11154
11155/*!
11156
11157 * jQuery UI Autocomplete 1.12.1
11158
11159 * http://jqueryui.com
11160
11161 *
11162
11163 * Copyright jQuery Foundation and other contributors
11164
11165 * Released under the MIT license.
11166
11167 * http://jquery.org/license
11168
11169 */
11170
11171
11172
11173//>>label: Autocomplete
11174
11175//>>group: Widgets
11176
11177//>>description: Lists suggested words as the user is typing.
11178
11179//>>docs: http://api.jqueryui.com/autocomplete/
11180
11181//>>demos: http://jqueryui.com/autocomplete/
11182
11183//>>css.structure: ../../themes/base/core.css
11184
11185//>>css.structure: ../../themes/base/autocomplete.css
11186
11187//>>css.theme: ../../themes/base/theme.css
11188
11189
11190
11191
11192
11193
11194
11195$.widget( "ui.autocomplete", {
11196
11197	version: "1.12.1",
11198
11199	defaultElement: "<input>",
11200
11201	options: {
11202
11203		appendTo: null,
11204
11205		autoFocus: false,
11206
11207		delay: 300,
11208
11209		minLength: 1,
11210
11211		position: {
11212
11213			my: "left top",
11214
11215			at: "left bottom",
11216
11217			collision: "none"
11218
11219		},
11220
11221		source: null,
11222
11223
11224
11225		// Callbacks
11226
11227		change: null,
11228
11229		close: null,
11230
11231		focus: null,
11232
11233		open: null,
11234
11235		response: null,
11236
11237		search: null,
11238
11239		select: null
11240
11241	},
11242
11243
11244
11245	requestIndex: 0,
11246
11247	pending: 0,
11248
11249
11250
11251	_create: function() {
11252
11253
11254
11255		// Some browsers only repeat keydown events, not keypress events,
11256
11257		// so we use the suppressKeyPress flag to determine if we've already
11258
11259		// handled the keydown event. #7269
11260
11261		// Unfortunately the code for & in keypress is the same as the up arrow,
11262
11263		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
11264
11265		// events when we know the keydown event was used to modify the
11266
11267		// search term. #7799
11268
11269		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
11270
11271			nodeName = this.element[ 0 ].nodeName.toLowerCase(),
11272
11273			isTextarea = nodeName === "textarea",
11274
11275			isInput = nodeName === "input";
11276
11277
11278
11279		// Textareas are always multi-line
11280
11281		// Inputs are always single-line, even if inside a contentEditable element
11282
11283		// IE also treats inputs as contentEditable
11284
11285		// All other element types are determined by whether or not they're contentEditable
11286
11287		this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element );
11288
11289
11290
11291		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
11292
11293		this.isNewMenu = true;
11294
11295
11296
11297		this._addClass( "ui-autocomplete-input" );
11298
11299		this.element.attr( "autocomplete", "off" );
11300
11301
11302
11303		this._on( this.element, {
11304
11305			keydown: function( event ) {
11306
11307				if ( this.element.prop( "readOnly" ) ) {
11308
11309					suppressKeyPress = true;
11310
11311					suppressInput = true;
11312
11313					suppressKeyPressRepeat = true;
11314
11315					return;
11316
11317				}
11318
11319
11320
11321				suppressKeyPress = false;
11322
11323				suppressInput = false;
11324
11325				suppressKeyPressRepeat = false;
11326
11327				var keyCode = $.ui.keyCode;
11328
11329				switch ( event.keyCode ) {
11330
11331				case keyCode.PAGE_UP:
11332
11333					suppressKeyPress = true;
11334
11335					this._move( "previousPage", event );
11336
11337					break;
11338
11339				case keyCode.PAGE_DOWN:
11340
11341					suppressKeyPress = true;
11342
11343					this._move( "nextPage", event );
11344
11345					break;
11346
11347				case keyCode.UP:
11348
11349					suppressKeyPress = true;
11350
11351					this._keyEvent( "previous", event );
11352
11353					break;
11354
11355				case keyCode.DOWN:
11356
11357					suppressKeyPress = true;
11358
11359					this._keyEvent( "next", event );
11360
11361					break;
11362
11363				case keyCode.ENTER:
11364
11365
11366
11367					// when menu is open and has focus
11368
11369					if ( this.menu.active ) {
11370
11371
11372
11373						// #6055 - Opera still allows the keypress to occur
11374
11375						// which causes forms to submit
11376
11377						suppressKeyPress = true;
11378
11379						event.preventDefault();
11380
11381						this.menu.select( event );
11382
11383					}
11384
11385					break;
11386
11387				case keyCode.TAB:
11388
11389					if ( this.menu.active ) {
11390
11391						this.menu.select( event );
11392
11393					}
11394
11395					break;
11396
11397				case keyCode.ESCAPE:
11398
11399					if ( this.menu.element.is( ":visible" ) ) {
11400
11401						if ( !this.isMultiLine ) {
11402
11403							this._value( this.term );
11404
11405						}
11406
11407						this.close( event );
11408
11409
11410
11411						// Different browsers have different default behavior for escape
11412
11413						// Single press can mean undo or clear
11414
11415						// Double press in IE means clear the whole form
11416
11417						event.preventDefault();
11418
11419					}
11420
11421					break;
11422
11423				default:
11424
11425					suppressKeyPressRepeat = true;
11426
11427
11428
11429					// search timeout should be triggered before the input value is changed
11430
11431					this._searchTimeout( event );
11432
11433					break;
11434
11435				}
11436
11437			},
11438
11439			keypress: function( event ) {
11440
11441				if ( suppressKeyPress ) {
11442
11443					suppressKeyPress = false;
11444
11445					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
11446
11447						event.preventDefault();
11448
11449					}
11450
11451					return;
11452
11453				}
11454
11455				if ( suppressKeyPressRepeat ) {
11456
11457					return;
11458
11459				}
11460
11461
11462
11463				// Replicate some key handlers to allow them to repeat in Firefox and Opera
11464
11465				var keyCode = $.ui.keyCode;
11466
11467				switch ( event.keyCode ) {
11468
11469				case keyCode.PAGE_UP:
11470
11471					this._move( "previousPage", event );
11472
11473					break;
11474
11475				case keyCode.PAGE_DOWN:
11476
11477					this._move( "nextPage", event );
11478
11479					break;
11480
11481				case keyCode.UP:
11482
11483					this._keyEvent( "previous", event );
11484
11485					break;
11486
11487				case keyCode.DOWN:
11488
11489					this._keyEvent( "next", event );
11490
11491					break;
11492
11493				}
11494
11495			},
11496
11497			input: function( event ) {
11498
11499				if ( suppressInput ) {
11500
11501					suppressInput = false;
11502
11503					event.preventDefault();
11504
11505					return;
11506
11507				}
11508
11509				this._searchTimeout( event );
11510
11511			},
11512
11513			focus: function() {
11514
11515				this.selectedItem = null;
11516
11517				this.previous = this._value();
11518
11519			},
11520
11521			blur: function( event ) {
11522
11523				if ( this.cancelBlur ) {
11524
11525					delete this.cancelBlur;
11526
11527					return;
11528
11529				}
11530
11531
11532
11533				clearTimeout( this.searching );
11534
11535				this.close( event );
11536
11537				this._change( event );
11538
11539			}
11540
11541		} );
11542
11543
11544
11545		this._initSource();
11546
11547		this.menu = $( "<ul>" )
11548
11549			.appendTo( this._appendTo() )
11550
11551			.menu( {
11552
11553
11554
11555				// disable ARIA support, the live region takes care of that
11556
11557				role: null
11558
11559			} )
11560
11561			.hide()
11562
11563			.menu( "instance" );
11564
11565
11566
11567		this._addClass( this.menu.element, "ui-autocomplete", "ui-front" );
11568
11569		this._on( this.menu.element, {
11570
11571			mousedown: function( event ) {
11572
11573
11574
11575				// prevent moving focus out of the text field
11576
11577				event.preventDefault();
11578
11579
11580
11581				// IE doesn't prevent moving focus even with event.preventDefault()
11582
11583				// so we set a flag to know when we should ignore the blur event
11584
11585				this.cancelBlur = true;
11586
11587				this._delay( function() {
11588
11589					delete this.cancelBlur;
11590
11591
11592
11593					// Support: IE 8 only
11594
11595					// Right clicking a menu item or selecting text from the menu items will
11596
11597					// result in focus moving out of the input. However, we've already received
11598
11599					// and ignored the blur event because of the cancelBlur flag set above. So
11600
11601					// we restore focus to ensure that the menu closes properly based on the user's
11602
11603					// next actions.
11604
11605					if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
11606
11607						this.element.trigger( "focus" );
11608
11609					}
11610
11611				} );
11612
11613			},
11614
11615			menufocus: function( event, ui ) {
11616
11617				var label, item;
11618
11619
11620
11621				// support: Firefox
11622
11623				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
11624
11625				if ( this.isNewMenu ) {
11626
11627					this.isNewMenu = false;
11628
11629					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
11630
11631						this.menu.blur();
11632
11633
11634
11635						this.document.one( "mousemove", function() {
11636
11637							$( event.target ).trigger( event.originalEvent );
11638
11639						} );
11640
11641
11642
11643						return;
11644
11645					}
11646
11647				}
11648
11649
11650
11651				item = ui.item.data( "ui-autocomplete-item" );
11652
11653				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
11654
11655
11656
11657					// use value to match what will end up in the input, if it was a key event
11658
11659					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
11660
11661						this._value( item.value );
11662
11663					}
11664
11665				}
11666
11667
11668
11669				// Announce the value in the liveRegion
11670
11671				label = ui.item.attr( "aria-label" ) || item.value;
11672
11673				if ( label && $.trim( label ).length ) {
11674
11675					this.liveRegion.children().hide();
11676
11677					$( "<div>" ).text( label ).appendTo( this.liveRegion );
11678
11679				}
11680
11681			},
11682
11683			menuselect: function( event, ui ) {
11684
11685				var item = ui.item.data( "ui-autocomplete-item" ),
11686
11687					previous = this.previous;
11688
11689
11690
11691				// Only trigger when focus was lost (click on menu)
11692
11693				if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
11694
11695					this.element.trigger( "focus" );
11696
11697					this.previous = previous;
11698
11699
11700
11701					// #6109 - IE triggers two focus events and the second
11702
11703					// is asynchronous, so we need to reset the previous
11704
11705					// term synchronously and asynchronously :-(
11706
11707					this._delay( function() {
11708
11709						this.previous = previous;
11710
11711						this.selectedItem = item;
11712
11713					} );
11714
11715				}
11716
11717
11718
11719				if ( false !== this._trigger( "select", event, { item: item } ) ) {
11720
11721					this._value( item.value );
11722
11723				}
11724
11725
11726
11727				// reset the term after the select event
11728
11729				// this allows custom select handling to work properly
11730
11731				this.term = this._value();
11732
11733
11734
11735				this.close( event );
11736
11737				this.selectedItem = item;
11738
11739			}
11740
11741		} );
11742
11743
11744
11745		this.liveRegion = $( "<div>", {
11746
11747			role: "status",
11748
11749			"aria-live": "assertive",
11750
11751			"aria-relevant": "additions"
11752
11753		} )
11754
11755			.appendTo( this.document[ 0 ].body );
11756
11757
11758
11759		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
11760
11761
11762
11763		// Turning off autocomplete prevents the browser from remembering the
11764
11765		// value when navigating through history, so we re-enable autocomplete
11766
11767		// if the page is unloaded before the widget is destroyed. #7790
11768
11769		this._on( this.window, {
11770
11771			beforeunload: function() {
11772
11773				this.element.removeAttr( "autocomplete" );
11774
11775			}
11776
11777		} );
11778
11779	},
11780
11781
11782
11783	_destroy: function() {
11784
11785		clearTimeout( this.searching );
11786
11787		this.element.removeAttr( "autocomplete" );
11788
11789		this.menu.element.remove();
11790
11791		this.liveRegion.remove();
11792
11793	},
11794
11795
11796
11797	_setOption: function( key, value ) {
11798
11799		this._super( key, value );
11800
11801		if ( key === "source" ) {
11802
11803			this._initSource();
11804
11805		}
11806
11807		if ( key === "appendTo" ) {
11808
11809			this.menu.element.appendTo( this._appendTo() );
11810
11811		}
11812
11813		if ( key === "disabled" && value && this.xhr ) {
11814
11815			this.xhr.abort();
11816
11817		}
11818
11819	},
11820
11821
11822
11823	_isEventTargetInWidget: function( event ) {
11824
11825		var menuElement = this.menu.element[ 0 ];
11826
11827
11828
11829		return event.target === this.element[ 0 ] ||
11830
11831			event.target === menuElement ||
11832
11833			$.contains( menuElement, event.target );
11834
11835	},
11836
11837
11838
11839	_closeOnClickOutside: function( event ) {
11840
11841		if ( !this._isEventTargetInWidget( event ) ) {
11842
11843			this.close();
11844
11845		}
11846
11847	},
11848
11849
11850
11851	_appendTo: function() {
11852
11853		var element = this.options.appendTo;
11854
11855
11856
11857		if ( element ) {
11858
11859			element = element.jquery || element.nodeType ?
11860
11861				$( element ) :
11862
11863				this.document.find( element ).eq( 0 );
11864
11865		}
11866
11867
11868
11869		if ( !element || !element[ 0 ] ) {
11870
11871			element = this.element.closest( ".ui-front, dialog" );
11872
11873		}
11874
11875
11876
11877		if ( !element.length ) {
11878
11879			element = this.document[ 0 ].body;
11880
11881		}
11882
11883
11884
11885		return element;
11886
11887	},
11888
11889
11890
11891	_initSource: function() {
11892
11893		var array, url,
11894
11895			that = this;
11896
11897		if ( $.isArray( this.options.source ) ) {
11898
11899			array = this.options.source;
11900
11901			this.source = function( request, response ) {
11902
11903				response( $.ui.autocomplete.filter( array, request.term ) );
11904
11905			};
11906
11907		} else if ( typeof this.options.source === "string" ) {
11908
11909			url = this.options.source;
11910
11911			this.source = function( request, response ) {
11912
11913				if ( that.xhr ) {
11914
11915					that.xhr.abort();
11916
11917				}
11918
11919				that.xhr = $.ajax( {
11920
11921					url: url,
11922
11923					data: request,
11924
11925					dataType: "json",
11926
11927					success: function( data ) {
11928
11929						response( data );
11930
11931					},
11932
11933					error: function() {
11934
11935						response( [] );
11936
11937					}
11938
11939				} );
11940
11941			};
11942
11943		} else {
11944
11945			this.source = this.options.source;
11946
11947		}
11948
11949	},
11950
11951
11952
11953	_searchTimeout: function( event ) {
11954
11955		clearTimeout( this.searching );
11956
11957		this.searching = this._delay( function() {
11958
11959
11960
11961			// Search if the value has changed, or if the user retypes the same value (see #7434)
11962
11963			var equalValues = this.term === this._value(),
11964
11965				menuVisible = this.menu.element.is( ":visible" ),
11966
11967				modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
11968
11969
11970
11971			if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
11972
11973				this.selectedItem = null;
11974
11975				this.search( null, event );
11976
11977			}
11978
11979		}, this.options.delay );
11980
11981	},
11982
11983
11984
11985	search: function( value, event ) {
11986
11987		value = value != null ? value : this._value();
11988
11989
11990
11991		// Always save the actual value, not the one passed as an argument
11992
11993		this.term = this._value();
11994
11995
11996
11997		if ( value.length < this.options.minLength ) {
11998
11999			return this.close( event );
12000
12001		}
12002
12003
12004
12005		if ( this._trigger( "search", event ) === false ) {
12006
12007			return;
12008
12009		}
12010
12011
12012
12013		return this._search( value );
12014
12015	},
12016
12017
12018
12019	_search: function( value ) {
12020
12021		this.pending++;
12022
12023		this._addClass( "ui-autocomplete-loading" );
12024
12025		this.cancelSearch = false;
12026
12027
12028
12029		this.source( { term: value }, this._response() );
12030
12031	},
12032
12033
12034
12035	_response: function() {
12036
12037		var index = ++this.requestIndex;
12038
12039
12040
12041		return $.proxy( function( content ) {
12042
12043			if ( index === this.requestIndex ) {
12044
12045				this.__response( content );
12046
12047			}
12048
12049
12050
12051			this.pending--;
12052
12053			if ( !this.pending ) {
12054
12055				this._removeClass( "ui-autocomplete-loading" );
12056
12057			}
12058
12059		}, this );
12060
12061	},
12062
12063
12064
12065	__response: function( content ) {
12066
12067		if ( content ) {
12068
12069			content = this._normalize( content );
12070
12071		}
12072
12073		this._trigger( "response", null, { content: content } );
12074
12075		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
12076
12077			this._suggest( content );
12078
12079			this._trigger( "open" );
12080
12081		} else {
12082
12083
12084
12085			// use ._close() instead of .close() so we don't cancel future searches
12086
12087			this._close();
12088
12089		}
12090
12091	},
12092
12093
12094
12095	close: function( event ) {
12096
12097		this.cancelSearch = true;
12098
12099		this._close( event );
12100
12101	},
12102
12103
12104
12105	_close: function( event ) {
12106
12107
12108
12109		// Remove the handler that closes the menu on outside clicks
12110
12111		this._off( this.document, "mousedown" );
12112
12113
12114
12115		if ( this.menu.element.is( ":visible" ) ) {
12116
12117			this.menu.element.hide();
12118
12119			this.menu.blur();
12120
12121			this.isNewMenu = true;
12122
12123			this._trigger( "close", event );
12124
12125		}
12126
12127	},
12128
12129
12130
12131	_change: function( event ) {
12132
12133		if ( this.previous !== this._value() ) {
12134
12135			this._trigger( "change", event, { item: this.selectedItem } );
12136
12137		}
12138
12139	},
12140
12141
12142
12143	_normalize: function( items ) {
12144
12145
12146
12147		// assume all items have the right format when the first item is complete
12148
12149		if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
12150
12151			return items;
12152
12153		}
12154
12155		return $.map( items, function( item ) {
12156
12157			if ( typeof item === "string" ) {
12158
12159				return {
12160
12161					label: item,
12162
12163					value: item
12164
12165				};
12166
12167			}
12168
12169			return $.extend( {}, item, {
12170
12171				label: item.label || item.value,
12172
12173				value: item.value || item.label
12174
12175			} );
12176
12177		} );
12178
12179	},
12180
12181
12182
12183	_suggest: function( items ) {
12184
12185		var ul = this.menu.element.empty();
12186
12187		this._renderMenu( ul, items );
12188
12189		this.isNewMenu = true;
12190
12191		this.menu.refresh();
12192
12193
12194
12195		// Size and position menu
12196
12197		ul.show();
12198
12199		this._resizeMenu();
12200
12201		ul.position( $.extend( {
12202
12203			of: this.element
12204
12205		}, this.options.position ) );
12206
12207
12208
12209		if ( this.options.autoFocus ) {
12210
12211			this.menu.next();
12212
12213		}
12214
12215
12216
12217		// Listen for interactions outside of the widget (#6642)
12218
12219		this._on( this.document, {
12220
12221			mousedown: "_closeOnClickOutside"
12222
12223		} );
12224
12225	},
12226
12227
12228
12229	_resizeMenu: function() {
12230
12231		var ul = this.menu.element;
12232
12233		ul.outerWidth( Math.max(
12234
12235
12236
12237			// Firefox wraps long text (possibly a rounding bug)
12238
12239			// so we add 1px to avoid the wrapping (#7513)
12240
12241			ul.width( "" ).outerWidth() + 1,
12242
12243			this.element.outerWidth()
12244
12245		) );
12246
12247	},
12248
12249
12250
12251	_renderMenu: function( ul, items ) {
12252
12253		var that = this;
12254
12255		$.each( items, function( index, item ) {
12256
12257			that._renderItemData( ul, item );
12258
12259		} );
12260
12261	},
12262
12263
12264
12265	_renderItemData: function( ul, item ) {
12266
12267		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
12268
12269	},
12270
12271
12272
12273	_renderItem: function( ul, item ) {
12274
12275		return $( "<li>" )
12276
12277			.append( $( "<div>" ).text( item.label ) )
12278
12279			.appendTo( ul );
12280
12281	},
12282
12283
12284
12285	_move: function( direction, event ) {
12286
12287		if ( !this.menu.element.is( ":visible" ) ) {
12288
12289			this.search( null, event );
12290
12291			return;
12292
12293		}
12294
12295		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
12296
12297				this.menu.isLastItem() && /^next/.test( direction ) ) {
12298
12299
12300
12301			if ( !this.isMultiLine ) {
12302
12303				this._value( this.term );
12304
12305			}
12306
12307
12308
12309			this.menu.blur();
12310
12311			return;
12312
12313		}
12314
12315		this.menu[ direction ]( event );
12316
12317	},
12318
12319
12320
12321	widget: function() {
12322
12323		return this.menu.element;
12324
12325	},
12326
12327
12328
12329	_value: function() {
12330
12331		return this.valueMethod.apply( this.element, arguments );
12332
12333	},
12334
12335
12336
12337	_keyEvent: function( keyEvent, event ) {
12338
12339		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
12340
12341			this._move( keyEvent, event );
12342
12343
12344
12345			// Prevents moving cursor to beginning/end of the text field in some browsers
12346
12347			event.preventDefault();
12348
12349		}
12350
12351	},
12352
12353
12354
12355	// Support: Chrome <=50
12356
12357	// We should be able to just use this.element.prop( "isContentEditable" )
12358
12359	// but hidden elements always report false in Chrome.
12360
12361	// https://code.google.com/p/chromium/issues/detail?id=313082
12362
12363	_isContentEditable: function( element ) {
12364
12365		if ( !element.length ) {
12366
12367			return false;
12368
12369		}
12370
12371
12372
12373		var editable = element.prop( "contentEditable" );
12374
12375
12376
12377		if ( editable === "inherit" ) {
12378
12379		  return this._isContentEditable( element.parent() );
12380
12381		}
12382
12383
12384
12385		return editable === "true";
12386
12387	}
12388
12389} );
12390
12391
12392
12393$.extend( $.ui.autocomplete, {
12394
12395	escapeRegex: function( value ) {
12396
12397		return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
12398
12399	},
12400
12401	filter: function( array, term ) {
12402
12403		var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
12404
12405		return $.grep( array, function( value ) {
12406
12407			return matcher.test( value.label || value.value || value );
12408
12409		} );
12410
12411	}
12412
12413} );
12414
12415
12416
12417// Live region extension, adding a `messages` option
12418
12419// NOTE: This is an experimental API. We are still investigating
12420
12421// a full solution for string manipulation and internationalization.
12422
12423$.widget( "ui.autocomplete", $.ui.autocomplete, {
12424
12425	options: {
12426
12427		messages: {
12428
12429			noResults: "No search results.",
12430
12431			results: function( amount ) {
12432
12433				return amount + ( amount > 1 ? " results are" : " result is" ) +
12434
12435					" available, use up and down arrow keys to navigate.";
12436
12437			}
12438
12439		}
12440
12441	},
12442
12443
12444
12445	__response: function( content ) {
12446
12447		var message;
12448
12449		this._superApply( arguments );
12450
12451		if ( this.options.disabled || this.cancelSearch ) {
12452
12453			return;
12454
12455		}
12456
12457		if ( content && content.length ) {
12458
12459			message = this.options.messages.results( content.length );
12460
12461		} else {
12462
12463			message = this.options.messages.noResults;
12464
12465		}
12466
12467		this.liveRegion.children().hide();
12468
12469		$( "<div>" ).text( message ).appendTo( this.liveRegion );
12470
12471	}
12472
12473} );
12474
12475
12476
12477var widgetsAutocomplete = $.ui.autocomplete;
12478
12479
12480
12481
12482
12483/*!
12484
12485 * jQuery UI Controlgroup 1.12.1
12486
12487 * http://jqueryui.com
12488
12489 *
12490
12491 * Copyright jQuery Foundation and other contributors
12492
12493 * Released under the MIT license.
12494
12495 * http://jquery.org/license
12496
12497 */
12498
12499
12500
12501//>>label: Controlgroup
12502
12503//>>group: Widgets
12504
12505//>>description: Visually groups form control widgets
12506
12507//>>docs: http://api.jqueryui.com/controlgroup/
12508
12509//>>demos: http://jqueryui.com/controlgroup/
12510
12511//>>css.structure: ../../themes/base/core.css
12512
12513//>>css.structure: ../../themes/base/controlgroup.css
12514
12515//>>css.theme: ../../themes/base/theme.css
12516
12517
12518
12519
12520
12521var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g;
12522
12523
12524
12525var widgetsControlgroup = $.widget( "ui.controlgroup", {
12526
12527	version: "1.12.1",
12528
12529	defaultElement: "<div>",
12530
12531	options: {
12532
12533		direction: "horizontal",
12534
12535		disabled: null,
12536
12537		onlyVisible: true,
12538
12539		items: {
12540
12541			"button": "input[type=button], input[type=submit], input[type=reset], button, a",
12542
12543			"controlgroupLabel": ".ui-controlgroup-label",
12544
12545			"checkboxradio": "input[type='checkbox'], input[type='radio']",
12546
12547			"selectmenu": "select",
12548
12549			"spinner": ".ui-spinner-input"
12550
12551		}
12552
12553	},
12554
12555
12556
12557	_create: function() {
12558
12559		this._enhance();
12560
12561	},
12562
12563
12564
12565	// To support the enhanced option in jQuery Mobile, we isolate DOM manipulation
12566
12567	_enhance: function() {
12568
12569		this.element.attr( "role", "toolbar" );
12570
12571		this.refresh();
12572
12573	},
12574
12575
12576
12577	_destroy: function() {
12578
12579		this._callChildMethod( "destroy" );
12580
12581		this.childWidgets.removeData( "ui-controlgroup-data" );
12582
12583		this.element.removeAttr( "role" );
12584
12585		if ( this.options.items.controlgroupLabel ) {
12586
12587			this.element
12588
12589				.find( this.options.items.controlgroupLabel )
12590
12591				.find( ".ui-controlgroup-label-contents" )
12592
12593				.contents().unwrap();
12594
12595		}
12596
12597	},
12598
12599
12600
12601	_initWidgets: function() {
12602
12603		var that = this,
12604
12605			childWidgets = [];
12606
12607
12608
12609		// First we iterate over each of the items options
12610
12611		$.each( this.options.items, function( widget, selector ) {
12612
12613			var labels;
12614
12615			var options = {};
12616
12617
12618
12619			// Make sure the widget has a selector set
12620
12621			if ( !selector ) {
12622
12623				return;
12624
12625			}
12626
12627
12628
12629			if ( widget === "controlgroupLabel" ) {
12630
12631				labels = that.element.find( selector );
12632
12633				labels.each( function() {
12634
12635					var element = $( this );
12636
12637
12638
12639					if ( element.children( ".ui-controlgroup-label-contents" ).length ) {
12640
12641						return;
12642
12643					}
12644
12645					element.contents()
12646
12647						.wrapAll( "<span class='ui-controlgroup-label-contents'></span>" );
12648
12649				} );
12650
12651				that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" );
12652
12653				childWidgets = childWidgets.concat( labels.get() );
12654
12655				return;
12656
12657			}
12658
12659
12660
12661			// Make sure the widget actually exists
12662
12663			if ( !$.fn[ widget ] ) {
12664
12665				return;
12666
12667			}
12668
12669
12670
12671			// We assume everything is in the middle to start because we can't determine
12672
12673			// first / last elements until all enhancments are done.
12674
12675			if ( that[ "_" + widget + "Options" ] ) {
12676
12677				options = that[ "_" + widget + "Options" ]( "middle" );
12678
12679			} else {
12680
12681				options = { classes: {} };
12682
12683			}
12684
12685
12686
12687			// Find instances of this widget inside controlgroup and init them
12688
12689			that.element
12690
12691				.find( selector )
12692
12693				.each( function() {
12694
12695					var element = $( this );
12696
12697					var instance = element[ widget ]( "instance" );
12698
12699
12700
12701					// We need to clone the default options for this type of widget to avoid
12702
12703					// polluting the variable options which has a wider scope than a single widget.
12704
12705					var instanceOptions = $.widget.extend( {}, options );
12706
12707
12708
12709					// If the button is the child of a spinner ignore it
12710
12711					// TODO: Find a more generic solution
12712
12713					if ( widget === "button" && element.parent( ".ui-spinner" ).length ) {
12714
12715						return;
12716
12717					}
12718
12719
12720
12721					// Create the widget if it doesn't exist
12722
12723					if ( !instance ) {
12724
12725						instance = element[ widget ]()[ widget ]( "instance" );
12726
12727					}
12728
12729					if ( instance ) {
12730
12731						instanceOptions.classes =
12732
12733							that._resolveClassesValues( instanceOptions.classes, instance );
12734
12735					}
12736
12737					element[ widget ]( instanceOptions );
12738
12739
12740
12741					// Store an instance of the controlgroup to be able to reference
12742
12743					// from the outermost element for changing options and refresh
12744
12745					var widgetElement = element[ widget ]( "widget" );
12746
12747					$.data( widgetElement[ 0 ], "ui-controlgroup-data",
12748
12749						instance ? instance : element[ widget ]( "instance" ) );
12750
12751
12752
12753					childWidgets.push( widgetElement[ 0 ] );
12754
12755				} );
12756
12757		} );
12758
12759
12760
12761		this.childWidgets = $( $.unique( childWidgets ) );
12762
12763		this._addClass( this.childWidgets, "ui-controlgroup-item" );
12764
12765	},
12766
12767
12768
12769	_callChildMethod: function( method ) {
12770
12771		this.childWidgets.each( function() {
12772
12773			var element = $( this ),
12774
12775				data = element.data( "ui-controlgroup-data" );
12776
12777			if ( data && data[ method ] ) {
12778
12779				data[ method ]();
12780
12781			}
12782
12783		} );
12784
12785	},
12786
12787
12788
12789	_updateCornerClass: function( element, position ) {
12790
12791		var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all";
12792
12793		var add = this._buildSimpleOptions( position, "label" ).classes.label;
12794
12795
12796
12797		this._removeClass( element, null, remove );
12798
12799		this._addClass( element, null, add );
12800
12801	},
12802
12803
12804
12805	_buildSimpleOptions: function( position, key ) {
12806
12807		var direction = this.options.direction === "vertical";
12808
12809		var result = {
12810
12811			classes: {}
12812
12813		};
12814
12815		result.classes[ key ] = {
12816
12817			"middle": "",
12818
12819			"first": "ui-corner-" + ( direction ? "top" : "left" ),
12820
12821			"last": "ui-corner-" + ( direction ? "bottom" : "right" ),
12822
12823			"only": "ui-corner-all"
12824
12825		}[ position ];
12826
12827
12828
12829		return result;
12830
12831	},
12832
12833
12834
12835	_spinnerOptions: function( position ) {
12836
12837		var options = this._buildSimpleOptions( position, "ui-spinner" );
12838
12839
12840
12841		options.classes[ "ui-spinner-up" ] = "";
12842
12843		options.classes[ "ui-spinner-down" ] = "";
12844
12845
12846
12847		return options;
12848
12849	},
12850
12851
12852
12853	_buttonOptions: function( position ) {
12854
12855		return this._buildSimpleOptions( position, "ui-button" );
12856
12857	},
12858
12859
12860
12861	_checkboxradioOptions: function( position ) {
12862
12863		return this._buildSimpleOptions( position, "ui-checkboxradio-label" );
12864
12865	},
12866
12867
12868
12869	_selectmenuOptions: function( position ) {
12870
12871		var direction = this.options.direction === "vertical";
12872
12873		return {
12874
12875			width: direction ? "auto" : false,
12876
12877			classes: {
12878
12879				middle: {
12880
12881					"ui-selectmenu-button-open": "",
12882
12883					"ui-selectmenu-button-closed": ""
12884
12885				},
12886
12887				first: {
12888
12889					"ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ),
12890
12891					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" )
12892
12893				},
12894
12895				last: {
12896
12897					"ui-selectmenu-button-open": direction ? "" : "ui-corner-tr",
12898
12899					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" )
12900
12901				},
12902
12903				only: {
12904
12905					"ui-selectmenu-button-open": "ui-corner-top",
12906
12907					"ui-selectmenu-button-closed": "ui-corner-all"
12908
12909				}
12910
12911
12912
12913			}[ position ]
12914
12915		};
12916
12917	},
12918
12919
12920
12921	_resolveClassesValues: function( classes, instance ) {
12922
12923		var result = {};
12924
12925		$.each( classes, function( key ) {
12926
12927			var current = instance.options.classes[ key ] || "";
12928
12929			current = $.trim( current.replace( controlgroupCornerRegex, "" ) );
12930
12931			result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " );
12932
12933		} );
12934
12935		return result;
12936
12937	},
12938
12939
12940
12941	_setOption: function( key, value ) {
12942
12943		if ( key === "direction" ) {
12944
12945			this._removeClass( "ui-controlgroup-" + this.options.direction );
12946
12947		}
12948
12949
12950
12951		this._super( key, value );
12952
12953		if ( key === "disabled" ) {
12954
12955			this._callChildMethod( value ? "disable" : "enable" );
12956
12957			return;
12958
12959		}
12960
12961
12962
12963		this.refresh();
12964
12965	},
12966
12967
12968
12969	refresh: function() {
12970
12971		var children,
12972
12973			that = this;
12974
12975
12976
12977		this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction );
12978
12979
12980
12981		if ( this.options.direction === "horizontal" ) {
12982
12983			this._addClass( null, "ui-helper-clearfix" );
12984
12985		}
12986
12987		this._initWidgets();
12988
12989
12990
12991		children = this.childWidgets;
12992
12993
12994
12995		// We filter here because we need to track all childWidgets not just the visible ones
12996
12997		if ( this.options.onlyVisible ) {
12998
12999			children = children.filter( ":visible" );
13000
13001		}
13002
13003
13004
13005		if ( children.length ) {
13006
13007
13008
13009			// We do this last because we need to make sure all enhancment is done
13010
13011			// before determining first and last
13012
13013			$.each( [ "first", "last" ], function( index, value ) {
13014
13015				var instance = children[ value ]().data( "ui-controlgroup-data" );
13016
13017
13018
13019				if ( instance && that[ "_" + instance.widgetName + "Options" ] ) {
13020
13021					var options = that[ "_" + instance.widgetName + "Options" ](
13022
13023						children.length === 1 ? "only" : value
13024
13025					);
13026
13027					options.classes = that._resolveClassesValues( options.classes, instance );
13028
13029					instance.element[ instance.widgetName ]( options );
13030
13031				} else {
13032
13033					that._updateCornerClass( children[ value ](), value );
13034
13035				}
13036
13037			} );
13038
13039
13040
13041			// Finally call the refresh method on each of the child widgets.
13042
13043			this._callChildMethod( "refresh" );
13044
13045		}
13046
13047	}
13048
13049} );
13050
13051
13052
13053/*!
13054
13055 * jQuery UI Checkboxradio 1.12.1
13056
13057 * http://jqueryui.com
13058
13059 *
13060
13061 * Copyright jQuery Foundation and other contributors
13062
13063 * Released under the MIT license.
13064
13065 * http://jquery.org/license
13066
13067 */
13068
13069
13070
13071//>>label: Checkboxradio
13072
13073//>>group: Widgets
13074
13075//>>description: Enhances a form with multiple themeable checkboxes or radio buttons.
13076
13077//>>docs: http://api.jqueryui.com/checkboxradio/
13078
13079//>>demos: http://jqueryui.com/checkboxradio/
13080
13081//>>css.structure: ../../themes/base/core.css
13082
13083//>>css.structure: ../../themes/base/button.css
13084
13085//>>css.structure: ../../themes/base/checkboxradio.css
13086
13087//>>css.theme: ../../themes/base/theme.css
13088
13089
13090
13091
13092
13093
13094
13095$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
13096
13097	version: "1.12.1",
13098
13099	options: {
13100
13101		disabled: null,
13102
13103		label: null,
13104
13105		icon: true,
13106
13107		classes: {
13108
13109			"ui-checkboxradio-label": "ui-corner-all",
13110
13111			"ui-checkboxradio-icon": "ui-corner-all"
13112
13113		}
13114
13115	},
13116
13117
13118
13119	_getCreateOptions: function() {
13120
13121		var disabled, labels;
13122
13123		var that = this;
13124
13125		var options = this._super() || {};
13126
13127
13128
13129		// We read the type here, because it makes more sense to throw a element type error first,
13130
13131		// rather then the error for lack of a label. Often if its the wrong type, it
13132
13133		// won't have a label (e.g. calling on a div, btn, etc)
13134
13135		this._readType();
13136
13137
13138
13139		labels = this.element.labels();
13140
13141
13142
13143		// If there are multiple labels, use the last one
13144
13145		this.label = $( labels[ labels.length - 1 ] );
13146
13147		if ( !this.label.length ) {
13148
13149			$.error( "No label found for checkboxradio widget" );
13150
13151		}
13152
13153
13154
13155		this.originalLabel = "";
13156
13157
13158
13159		// We need to get the label text but this may also need to make sure it does not contain the
13160
13161		// input itself.
13162
13163		this.label.contents().not( this.element[ 0 ] ).each( function() {
13164
13165
13166
13167			// The label contents could be text, html, or a mix. We concat each element to get a
13168
13169			// string representation of the label, without the input as part of it.
13170
13171			that.originalLabel += this.nodeType === 3 ? $( this ).text() : this.outerHTML;
13172
13173		} );
13174
13175
13176
13177		// Set the label option if we found label text
13178
13179		if ( this.originalLabel ) {
13180
13181			options.label = this.originalLabel;
13182
13183		}
13184
13185
13186
13187		disabled = this.element[ 0 ].disabled;
13188
13189		if ( disabled != null ) {
13190
13191			options.disabled = disabled;
13192
13193		}
13194
13195		return options;
13196
13197	},
13198
13199
13200
13201	_create: function() {
13202
13203		var checked = this.element[ 0 ].checked;
13204
13205
13206
13207		this._bindFormResetHandler();
13208
13209
13210
13211		if ( this.options.disabled == null ) {
13212
13213			this.options.disabled = this.element[ 0 ].disabled;
13214
13215		}
13216
13217
13218
13219		this._setOption( "disabled", this.options.disabled );
13220
13221		this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" );
13222
13223		this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" );
13224
13225
13226
13227		if ( this.type === "radio" ) {
13228
13229			this._addClass( this.label, "ui-checkboxradio-radio-label" );
13230
13231		}
13232
13233
13234
13235		if ( this.options.label && this.options.label !== this.originalLabel ) {
13236
13237			this._updateLabel();
13238
13239		} else if ( this.originalLabel ) {
13240
13241			this.options.label = this.originalLabel;
13242
13243		}
13244
13245
13246
13247		this._enhance();
13248
13249
13250
13251		if ( checked ) {
13252
13253			this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" );
13254
13255			if ( this.icon ) {
13256
13257				this._addClass( this.icon, null, "ui-state-hover" );
13258
13259			}
13260
13261		}
13262
13263
13264
13265		this._on( {
13266
13267			change: "_toggleClasses",
13268
13269			focus: function() {
13270
13271				this._addClass( this.label, null, "ui-state-focus ui-visual-focus" );
13272
13273			},
13274
13275			blur: function() {
13276
13277				this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" );
13278
13279			}
13280
13281		} );
13282
13283	},
13284
13285
13286
13287	_readType: function() {
13288
13289		var nodeName = this.element[ 0 ].nodeName.toLowerCase();
13290
13291		this.type = this.element[ 0 ].type;
13292
13293		if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) {
13294
13295			$.error( "Can't create checkboxradio on element.nodeName=" + nodeName +
13296
13297				" and element.type=" + this.type );
13298
13299		}
13300
13301	},
13302
13303
13304
13305	// Support jQuery Mobile enhanced option
13306
13307	_enhance: function() {
13308
13309		this._updateIcon( this.element[ 0 ].checked );
13310
13311	},
13312
13313
13314
13315	widget: function() {
13316
13317		return this.label;
13318
13319	},
13320
13321
13322
13323	_getRadioGroup: function() {
13324
13325		var group;
13326
13327		var name = this.element[ 0 ].name;
13328
13329		var nameSelector = "input[name='" + $.ui.escapeSelector( name ) + "']";
13330
13331
13332
13333		if ( !name ) {
13334
13335			return $( [] );
13336
13337		}
13338
13339
13340
13341		if ( this.form.length ) {
13342
13343			group = $( this.form[ 0 ].elements ).filter( nameSelector );
13344
13345		} else {
13346
13347
13348
13349			// Not inside a form, check all inputs that also are not inside a form
13350
13351			group = $( nameSelector ).filter( function() {
13352
13353				return $( this ).form().length === 0;
13354
13355			} );
13356
13357		}
13358
13359
13360
13361		return group.not( this.element );
13362
13363	},
13364
13365
13366
13367	_toggleClasses: function() {
13368
13369		var checked = this.element[ 0 ].checked;
13370
13371		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
13372
13373
13374
13375		if ( this.options.icon && this.type === "checkbox" ) {
13376
13377			this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked )
13378
13379				._toggleClass( this.icon, null, "ui-icon-blank", !checked );
13380
13381		}
13382
13383
13384
13385		if ( this.type === "radio" ) {
13386
13387			this._getRadioGroup()
13388
13389				.each( function() {
13390
13391					var instance = $( this ).checkboxradio( "instance" );
13392
13393
13394
13395					if ( instance ) {
13396
13397						instance._removeClass( instance.label,
13398
13399							"ui-checkboxradio-checked", "ui-state-active" );
13400
13401					}
13402
13403				} );
13404
13405		}
13406
13407	},
13408
13409
13410
13411	_destroy: function() {
13412
13413		this._unbindFormResetHandler();
13414
13415
13416
13417		if ( this.icon ) {
13418
13419			this.icon.remove();
13420
vendor: 9,105 bytes, lines 13421-14052
13421			this.iconSpace.remove();
13422
13423		}
13424
13425	},
13426
13427
13428
13429	_setOption: function( key, value ) {
13430
13431
13432
13433		// We don't allow the value to be set to nothing
13434
13435		if ( key === "label" && !value ) {
13436
13437			return;
13438
13439		}
13440
13441
13442
13443		this._super( key, value );
13444
13445
13446
13447		if ( key === "disabled" ) {
13448
13449			this._toggleClass( this.label, null, "ui-state-disabled", value );
13450
13451			this.element[ 0 ].disabled = value;
13452
13453
13454
13455			// Don't refresh when setting disabled
13456
13457			return;
13458
13459		}
13460
13461		this.refresh();
13462
13463	},
13464
13465
13466
13467	_updateIcon: function( checked ) {
13468
13469		var toAdd = "ui-icon ui-icon-background ";
13470
13471
13472
13473		if ( this.options.icon ) {
13474
13475			if ( !this.icon ) {
13476
13477				this.icon = $( "<span>" );
13478
13479				this.iconSpace = $( "<span> </span>" );
13480
13481				this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" );
13482
13483			}
13484
13485
13486
13487			if ( this.type === "checkbox" ) {
13488
13489				toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank";
13490
13491				this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" );
13492
13493			} else {
13494
13495				toAdd += "ui-icon-blank";
13496
13497			}
13498
13499			this._addClass( this.icon, "ui-checkboxradio-icon", toAdd );
13500
13501			if ( !checked ) {
13502
13503				this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" );
13504
13505			}
13506
13507			this.icon.prependTo( this.label ).after( this.iconSpace );
13508
13509		} else if ( this.icon !== undefined ) {
13510
13511			this.icon.remove();
13512
13513			this.iconSpace.remove();
13514
13515			delete this.icon;
13516
13517		}
13518
13519	},
13520
13521
13522
13523	_updateLabel: function() {
13524
13525
13526
13527		// Remove the contents of the label ( minus the icon, icon space, and input )
13528
13529		var contents = this.label.contents().not( this.element[ 0 ] );
13530
13531		if ( this.icon ) {
13532
13533			contents = contents.not( this.icon[ 0 ] );
13534
13535		}
13536
13537		if ( this.iconSpace ) {
13538
13539			contents = contents.not( this.iconSpace[ 0 ] );
13540
13541		}
13542
13543		contents.remove();
13544
13545
13546
13547		this.label.append( this.options.label );
13548
13549	},
13550
13551
13552
13553	refresh: function() {
13554
13555		var checked = this.element[ 0 ].checked,
13556
13557			isDisabled = this.element[ 0 ].disabled;
13558
13559
13560
13561		this._updateIcon( checked );
13562
13563		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
13564
13565		if ( this.options.label !== null ) {
13566
13567			this._updateLabel();
13568
13569		}
13570
13571
13572
13573		if ( isDisabled !== this.options.disabled ) {
13574
13575			this._setOptions( { "disabled": isDisabled } );
13576
13577		}
13578
13579	}
13580
13581
13582
13583} ] );
13584
13585
13586
13587var widgetsCheckboxradio = $.ui.checkboxradio;
13588
13589
13590
13591
13592
13593/*!
13594
13595 * jQuery UI Button 1.12.1
13596
13597 * http://jqueryui.com
13598
13599 *
13600
13601 * Copyright jQuery Foundation and other contributors
13602
13603 * Released under the MIT license.
13604
13605 * http://jquery.org/license
13606
13607 */
13608
13609
13610
13611//>>label: Button
13612
13613//>>group: Widgets
13614
13615//>>description: Enhances a form with themeable buttons.
13616
13617//>>docs: http://api.jqueryui.com/button/
13618
13619//>>demos: http://jqueryui.com/button/
13620
13621//>>css.structure: ../../themes/base/core.css
13622
13623//>>css.structure: ../../themes/base/button.css
13624
13625//>>css.theme: ../../themes/base/theme.css
13626
13627
13628
13629
13630
13631
13632
13633$.widget( "ui.button", {
13634
13635	version: "1.12.1",
13636
13637	defaultElement: "<button>",
13638
13639	options: {
13640
13641		classes: {
13642
13643			"ui-button": "ui-corner-all"
13644
13645		},
13646
13647		disabled: null,
13648
13649		icon: null,
13650
13651		iconPosition: "beginning",
13652
13653		label: null,
13654
13655		showLabel: true
13656
13657	},
13658
13659
13660
13661	_getCreateOptions: function() {
13662
13663		var disabled,
13664
13665
13666
13667			// This is to support cases like in jQuery Mobile where the base widget does have
13668
13669			// an implementation of _getCreateOptions
13670
13671			options = this._super() || {};
13672
13673
13674
13675		this.isInput = this.element.is( "input" );
13676
13677
13678
13679		disabled = this.element[ 0 ].disabled;
13680
13681		if ( disabled != null ) {
13682
13683			options.disabled = disabled;
13684
13685		}
13686
13687
13688
13689		this.originalLabel = this.isInput ? this.element.val() : this.element.html();
13690
13691		if ( this.originalLabel ) {
13692
13693			options.label = this.originalLabel;
13694
13695		}
13696
13697
13698
13699		return options;
13700
13701	},
13702
13703
13704
13705	_create: function() {
13706
13707		if ( !this.option.showLabel & !this.options.icon ) {
13708
13709			this.options.showLabel = true;
13710
13711		}
13712
13713
13714
13715		// We have to check the option again here even though we did in _getCreateOptions,
13716
13717		// because null may have been passed on init which would override what was set in
13718
13719		// _getCreateOptions
13720
13721		if ( this.options.disabled == null ) {
13722
13723			this.options.disabled = this.element[ 0 ].disabled || false;
13724
13725		}
13726
13727
13728
13729		this.hasTitle = !!this.element.attr( "title" );
13730
13731
13732
13733		// Check to see if the label needs to be set or if its already correct
13734
13735		if ( this.options.label && this.options.label !== this.originalLabel ) {
13736
13737			if ( this.isInput ) {
13738
13739				this.element.val( this.options.label );
13740
13741			} else {
13742
13743				this.element.html( this.options.label );
13744
13745			}
13746
13747		}
13748
13749		this._addClass( "ui-button", "ui-widget" );
13750
13751		this._setOption( "disabled", this.options.disabled );
13752
13753		this._enhance();
13754
13755
13756
13757		if ( this.element.is( "a" ) ) {
13758
13759			this._on( {
13760
13761				"keyup": function( event ) {
13762
13763					if ( event.keyCode === $.ui.keyCode.SPACE ) {
13764
13765						event.preventDefault();
13766
13767
13768
13769						// Support: PhantomJS <= 1.9, IE 8 Only
13770
13771						// If a native click is available use it so we actually cause navigation
13772
13773						// otherwise just trigger a click event
13774
13775						if ( this.element[ 0 ].click ) {
13776
13777							this.element[ 0 ].click();
13778
13779						} else {
13780
13781							this.element.trigger( "click" );
13782
13783						}
13784
13785					}
13786
13787				}
13788
13789			} );
13790
13791		}
13792
13793	},
13794
13795
13796
13797	_enhance: function() {
13798
13799		if ( !this.element.is( "button" ) ) {
13800
13801			this.element.attr( "role", "button" );
13802
13803		}
13804
13805
13806
13807		if ( this.options.icon ) {
13808
13809			this._updateIcon( "icon", this.options.icon );
13810
13811			this._updateTooltip();
13812
13813		}
13814
13815	},
13816
13817
13818
13819	_updateTooltip: function() {
13820
13821		this.title = this.element.attr( "title" );
13822
13823
13824
13825		if ( !this.options.showLabel && !this.title ) {
13826
13827			this.element.attr( "title", this.options.label );
13828
13829		}
13830
13831	},
13832
13833
13834
13835	_updateIcon: function( option, value ) {
13836
13837		var icon = option !== "iconPosition",
13838
13839			position = icon ? this.options.iconPosition : value,
13840
13841			displayBlock = position === "top" || position === "bottom";
13842
13843
13844
13845		// Create icon
13846
13847		if ( !this.icon ) {
13848
13849			this.icon = $( "<span>" );
13850
13851
13852
13853			this._addClass( this.icon, "ui-button-icon", "ui-icon" );
13854
13855
13856
13857			if ( !this.options.showLabel ) {
13858
13859				this._addClass( "ui-button-icon-only" );
13860
13861			}
13862
13863		} else if ( icon ) {
13864
13865
13866
13867			// If we are updating the icon remove the old icon class
13868
13869			this._removeClass( this.icon, null, this.options.icon );
13870
13871		}
13872
13873
13874
13875		// If we are updating the icon add the new icon class
13876
13877		if ( icon ) {
13878
13879			this._addClass( this.icon, null, value );
13880
13881		}
13882
13883
13884
13885		this._attachIcon( position );
13886
13887
13888
13889		// If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove
13890
13891		// the iconSpace if there is one.
13892
13893		if ( displayBlock ) {
13894
13895			this._addClass( this.icon, null, "ui-widget-icon-block" );
13896
13897			if ( this.iconSpace ) {
13898
13899				this.iconSpace.remove();
13900
13901			}
13902
13903		} else {
13904
13905
13906
13907			// Position is beginning or end so remove the ui-widget-icon-block class and add the
13908
13909			// space if it does not exist
13910
13911			if ( !this.iconSpace ) {
13912
13913				this.iconSpace = $( "<span> </span>" );
13914
13915				this._addClass( this.iconSpace, "ui-button-icon-space" );
13916
13917			}
13918
13919			this._removeClass( this.icon, null, "ui-wiget-icon-block" );
13920
13921			this._attachIconSpace( position );
13922
13923		}
13924
13925	},
13926
13927
13928
13929	_destroy: function() {
13930
13931		this.element.removeAttr( "role" );
13932
13933
13934
13935		if ( this.icon ) {
13936
13937			this.icon.remove();
13938
13939		}
13940
13941		if ( this.iconSpace ) {
13942
13943			this.iconSpace.remove();
13944
13945		}
13946
13947		if ( !this.hasTitle ) {
13948
13949			this.element.removeAttr( "title" );
13950
13951		}
13952
13953	},
13954
13955
13956
13957	_attachIconSpace: function( iconPosition ) {
13958
13959		this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace );
13960
13961	},
13962
13963
13964
13965	_attachIcon: function( iconPosition ) {
13966
13967		this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon );
13968
13969	},
13970
13971
13972
13973	_setOptions: function( options ) {
13974
13975		var newShowLabel = options.showLabel === undefined ?
13976
13977				this.options.showLabel :
13978
13979				options.showLabel,
13980
13981			newIcon = options.icon === undefined ? this.options.icon : options.icon;
13982
13983
13984
13985		if ( !newShowLabel && !newIcon ) {
13986
13987			options.showLabel = true;
13988
13989		}
13990
13991		this._super( options );
13992
13993	},
13994
13995
13996
13997	_setOption: function( key, value ) {
13998
13999		if ( key === "icon" ) {
14000
14001			if ( value ) {
14002
14003				this._updateIcon( key, value );
14004
14005			} else if ( this.icon ) {
14006
14007				this.icon.remove();
14008
14009				if ( this.iconSpace ) {
14010
14011					this.iconSpace.remove();
14012
14013				}
14014
14015			}
14016
14017		}
14018
14019
14020
14021		if ( key === "iconPosition" ) {
14022
14023			this._updateIcon( key, value );
14024
14025		}
14026
14027
14028
14029		// Make sure we can't end up with a button that has neither text nor icon
14030
14031		if ( key === "showLabel" ) {
14032
14033				this._toggleClass( "ui-button-icon-only", null, !value );
14034
14035				this._updateTooltip();
14036
14037		}
14038
14039
14040
14041		if ( key === "label" ) {
14042
14043			if ( this.isInput ) {
14044
14045				this.element.val( value );
14046
14047			} else {
14048
14049
14050
14051				// If there is an icon, append it, else nothing then append the value
14052
vendor: 4,209 bytes, lines 14053-14333
14053				// this avoids removal of the icon when setting label text
14054
14055				this.element.html( value );
14056
14057				if ( this.icon ) {
14058
14059					this._attachIcon( this.options.iconPosition );
14060
14061					this._attachIconSpace( this.options.iconPosition );
14062
14063				}
14064
14065			}
14066
14067		}
14068
14069
14070
14071		this._super( key, value );
14072
14073
14074
14075		if ( key === "disabled" ) {
14076
14077			this._toggleClass( null, "ui-state-disabled", value );
14078
14079			this.element[ 0 ].disabled = value;
14080
14081			if ( value ) {
14082
14083				this.element.blur();
14084
14085			}
14086
14087		}
14088
14089	},
14090
14091
14092
14093	refresh: function() {
14094
14095
14096
14097		// Make sure to only check disabled if its an element that supports this otherwise
14098
14099		// check for the disabled class to determine state
14100
14101		var isDisabled = this.element.is( "input, button" ) ?
14102
14103			this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" );
14104
14105
14106
14107		if ( isDisabled !== this.options.disabled ) {
14108
14109			this._setOptions( { disabled: isDisabled } );
14110
14111		}
14112
14113
14114
14115		this._updateTooltip();
14116
14117	}
14118
14119} );
14120
14121
14122
14123// DEPRECATED
14124
14125if ( $.uiBackCompat !== false ) {
14126
14127
14128
14129	// Text and Icons options
14130
14131	$.widget( "ui.button", $.ui.button, {
14132
14133		options: {
14134
14135			text: true,
14136
14137			icons: {
14138
14139				primary: null,
14140
14141				secondary: null
14142
14143			}
14144
14145		},
14146
14147
14148
14149		_create: function() {
14150
14151			if ( this.options.showLabel && !this.options.text ) {
14152
14153				this.options.showLabel = this.options.text;
14154
14155			}
14156
14157			if ( !this.options.showLabel && this.options.text ) {
14158
14159				this.options.text = this.options.showLabel;
14160
14161			}
14162
14163			if ( !this.options.icon && ( this.options.icons.primary ||
14164
14165					this.options.icons.secondary ) ) {
14166
14167				if ( this.options.icons.primary ) {
14168
14169					this.options.icon = this.options.icons.primary;
14170
14171				} else {
14172
14173					this.options.icon = this.options.icons.secondary;
14174
14175					this.options.iconPosition = "end";
14176
14177				}
14178
14179			} else if ( this.options.icon ) {
14180
14181				this.options.icons.primary = this.options.icon;
14182
14183			}
14184
14185			this._super();
14186
14187		},
14188
14189
14190
14191		_setOption: function( key, value ) {
14192
14193			if ( key === "text" ) {
14194
14195				this._super( "showLabel", value );
14196
14197				return;
14198
14199			}
14200
14201			if ( key === "showLabel" ) {
14202
14203				this.options.text = value;
14204
14205			}
14206
14207			if ( key === "icon" ) {
14208
14209				this.options.icons.primary = value;
14210
14211			}
14212
14213			if ( key === "icons" ) {
14214
14215				if ( value.primary ) {
14216
14217					this._super( "icon", value.primary );
14218
14219					this._super( "iconPosition", "beginning" );
14220
14221				} else if ( value.secondary ) {
14222
14223					this._super( "icon", value.secondary );
14224
14225					this._super( "iconPosition", "end" );
14226
14227				}
14228
14229			}
14230
14231			this._superApply( arguments );
14232
14233		}
14234
14235	} );
14236
14237
14238
14239	$.fn.button = ( function( orig ) {
14240
14241		return function() {
14242
14243			if ( !this.length || ( this.length && this[ 0 ].tagName !== "INPUT" ) ||
14244
14245					( this.length && this[ 0 ].tagName === "INPUT" && (
14246
14247						this.attr( "type" ) !== "checkbox" && this.attr( "type" ) !== "radio"
14248
14249					) ) ) {
14250
14251				return orig.apply( this, arguments );
14252
14253			}
14254
14255			if ( !$.ui.checkboxradio ) {
14256
14257				$.error( "Checkboxradio widget missing" );
14258
14259			}
14260
14261			if ( arguments.length === 0 ) {
14262
14263				return this.checkboxradio( {
14264
14265					"icon": false
14266
14267				} );
14268
14269			}
14270
14271			return this.checkboxradio.apply( this, arguments );
14272
14273		};
14274
14275	} )( $.fn.button );
14276
14277
14278
14279	$.fn.buttonset = function() {
14280
14281		if ( !$.ui.controlgroup ) {
14282
14283			$.error( "Controlgroup widget missing" );
14284
14285		}
14286
14287		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) {
14288
14289			return this.controlgroup.apply( this,
14290
14291				[ arguments[ 0 ], "items.button", arguments[ 2 ] ] );
14292
14293		}
14294
14295		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) {
14296
14297			return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] );
14298
14299		}
14300
14301		if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) {
14302
14303			arguments[ 0 ].items = {
14304
14305				button: arguments[ 0 ].items
14306
14307			};
14308
14309		}
14310
14311		return this.controlgroup.apply( this, arguments );
14312
14313	};
14314
14315}
14316
14317
14318
14319var widgetsButton = $.ui.button;
14320
14321
14322
14323
14324
14325// jscs:disable maximumLineLength
14326
14327/* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
14328
14329/*!
14330
14331 * jQuery UI Datepicker 1.12.1
14332
14333 * http://jqueryui.com
vendor: 4,729 bytes, lines 14334-14508
14334
14335 *
14336
14337 * Copyright jQuery Foundation and other contributors
14338
14339 * Released under the MIT license.
14340
14341 * http://jquery.org/license
14342
14343 */
14344
14345
14346
14347//>>label: Datepicker
14348
14349//>>group: Widgets
14350
14351//>>description: Displays a calendar from an input or inline for selecting dates.
14352
14353//>>docs: http://api.jqueryui.com/datepicker/
14354
14355//>>demos: http://jqueryui.com/datepicker/
14356
14357//>>css.structure: ../../themes/base/core.css
14358
14359//>>css.structure: ../../themes/base/datepicker.css
14360
14361//>>css.theme: ../../themes/base/theme.css
14362
14363
14364
14365
14366
14367
14368
14369$.extend( $.ui, { datepicker: { version: "1.12.1" } } );
14370
14371
14372
14373var datepicker_instActive;
14374
14375
14376
14377function datepicker_getZindex( elem ) {
14378
14379	var position, value;
14380
14381	while ( elem.length && elem[ 0 ] !== document ) {
14382
14383
14384
14385		// Ignore z-index if position is set to a value where z-index is ignored by the browser
14386
14387		// This makes behavior of this function consistent across browsers
14388
14389		// WebKit always returns auto if the element is positioned
14390
14391		position = elem.css( "position" );
14392
14393		if ( position === "absolute" || position === "relative" || position === "fixed" ) {
14394
14395
14396
14397			// IE returns 0 when zIndex is not specified
14398
14399			// other browsers return a string
14400
14401			// we ignore the case of nested elements with an explicit value of 0
14402
14403			// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
14404
14405			value = parseInt( elem.css( "zIndex" ), 10 );
14406
14407			if ( !isNaN( value ) && value !== 0 ) {
14408
14409				return value;
14410
14411			}
14412
14413		}
14414
14415		elem = elem.parent();
14416
14417	}
14418
14419
14420
14421	return 0;
14422
14423}
14424
14425/* Date picker manager.
14426
14427   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
14428
14429   Settings for (groups of) date pickers are maintained in an instance object,
14430
14431   allowing multiple different settings on the same page. */
14432
14433
14434
14435function Datepicker() {
14436
14437	this._curInst = null; // The current instance in use
14438
14439	this._keyEvent = false; // If the last event was a key event
14440
14441	this._disabledInputs = []; // List of date picker inputs that have been disabled
14442
14443	this._datepickerShowing = false; // True if the popup picker is showing , false if not
14444
14445	this._inDialog = false; // True if showing within a "dialog", false if not
14446
14447	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
14448
14449	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
14450
14451	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
14452
14453	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
14454
14455	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
14456
14457	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
14458
14459	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
14460
14461	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
14462
14463	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
14464
14465	this.regional = []; // Available regional settings, indexed by language code
14466
14467	this.regional[ "" ] = { // Default regional settings
14468
14469		closeText: "Done", // Display text for close link
14470
14471		prevText: "Prev", // Display text for previous month link
14472
14473		nextText: "Next", // Display text for next month link
14474
14475		currentText: "Today", // Display text for current month link
14476
14477		monthNames: [ "January","February","March","April","May","June",
14478
14479			"July","August","September","October","November","December" ], // Names of months for drop-down and formatting
14480
14481		monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting
14482
14483		dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting
14484
14485		dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting
14486
14487		dayNamesMin: [ "Su","Mo","Tu","We","Th","Fr","Sa" ], // Column headings for days starting at Sunday
14488
14489		weekHeader: "Wk", // Column header for week of the year
14490
14491		dateFormat: "mm/dd/yy", // See format options on parseDate
14492
14493		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
14494
14495		isRTL: false, // True if right-to-left language, false if left-to-right
14496
14497		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
14498
14499		yearSuffix: "" // Additional text to append to the year in the month headers
14500
14501	};
14502
14503	this._defaults = { // Global defaults for all the date picker instances
14504
14505		showOn: "focus", // "focus" for popup on focus,
14506
14507			// "button" for trigger button, or "both" for either
14508
vendor: 7,027 bytes, lines 14509-14774
14509		showAnim: "fadeIn", // Name of jQuery animation for popup
14510
14511		showOptions: {}, // Options for enhanced animations
14512
14513		defaultDate: null, // Used when field is blank: actual date,
14514
14515			// +/-number for offset from today, null for today
14516
14517		appendText: "", // Display text following the input box, e.g. showing the format
14518
14519		buttonText: "...", // Text for trigger button
14520
14521		buttonImage: "", // URL for trigger button image
14522
14523		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
14524
14525		hideIfNoPrevNext: false, // True to hide next/previous month links
14526
14527			// if not applicable, false to just disable them
14528
14529		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
14530
14531		gotoCurrent: false, // True if today link goes back to current selection instead
14532
14533		changeMonth: false, // True if month can be selected directly, false if only prev/next
14534
14535		changeYear: false, // True if year can be selected directly, false if only prev/next
14536
14537		yearRange: "c-10:c+10", // Range of years to display in drop-down,
14538
14539			// either relative to today's year (-nn:+nn), relative to currently displayed year
14540
14541			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
14542
14543		showOtherMonths: false, // True to show dates in other months, false to leave blank
14544
14545		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
14546
14547		showWeek: false, // True to show week of the year, false to not show it
14548
14549		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
14550
14551			// takes a Date and returns the number of the week for it
14552
14553		shortYearCutoff: "+10", // Short year values < this are in the current century,
14554
14555			// > this are in the previous century,
14556
14557			// string value starting with "+" for current year + value
14558
14559		minDate: null, // The earliest selectable date, or null for no limit
14560
14561		maxDate: null, // The latest selectable date, or null for no limit
14562
14563		duration: "fast", // Duration of display/closure
14564
14565		beforeShowDay: null, // Function that takes a date and returns an array with
14566
14567			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
14568
14569			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
14570
14571		beforeShow: null, // Function that takes an input field and
14572
14573			// returns a set of custom settings for the date picker
14574
14575		onSelect: null, // Define a callback function when a date is selected
14576
14577		onChangeMonthYear: null, // Define a callback function when the month or year is changed
14578
14579		onClose: null, // Define a callback function when the datepicker is closed
14580
14581		numberOfMonths: 1, // Number of months to show at a time
14582
14583		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
14584
14585		stepMonths: 1, // Number of months to step back/forward
14586
14587		stepBigMonths: 12, // Number of months to step back/forward for the big links
14588
14589		altField: "", // Selector for an alternate field to store selected dates into
14590
14591		altFormat: "", // The date format to use for the alternate field
14592
14593		constrainInput: true, // The input is constrained by the current date format
14594
14595		showButtonPanel: false, // True to show button panel, false to not show it
14596
14597		autoSize: false, // True to size the input for the date format, false to leave as is
14598
14599		disabled: false // The initial disabled state
14600
14601	};
14602
14603	$.extend( this._defaults, this.regional[ "" ] );
14604
14605	this.regional.en = $.extend( true, {}, this.regional[ "" ] );
14606
14607	this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
14608
14609	this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) );
14610
14611}
14612
14613
14614
14615$.extend( Datepicker.prototype, {
14616
14617	/* Class name added to elements to indicate already configured with a date picker. */
14618
14619	markerClassName: "hasDatepicker",
14620
14621
14622
14623	//Keep track of the maximum number of rows displayed (see #7043)
14624
14625	maxRows: 4,
14626
14627
14628
14629	// TODO rename to "widget" when switching to widget factory
14630
14631	_widgetDatepicker: function() {
14632
14633		return this.dpDiv;
14634
14635	},
14636
14637
14638
14639	/* Override the default settings for all instances of the date picker.
14640
14641	 * @param  settings  object - the new settings to use as defaults (anonymous object)
14642
14643	 * @return the manager object
14644
14645	 */
14646
14647	setDefaults: function( settings ) {
14648
14649		datepicker_extendRemove( this._defaults, settings || {} );
14650
14651		return this;
14652
14653	},
14654
14655
14656
14657	/* Attach the date picker to a jQuery selection.
14658
14659	 * @param  target	element - the target input field or division or span
14660
14661	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
14662
14663	 */
14664
14665	_attachDatepicker: function( target, settings ) {
14666
14667		var nodeName, inline, inst;
14668
14669		nodeName = target.nodeName.toLowerCase();
14670
14671		inline = ( nodeName === "div" || nodeName === "span" );
14672
14673		if ( !target.id ) {
14674
14675			this.uuid += 1;
14676
14677			target.id = "dp" + this.uuid;
14678
14679		}
14680
14681		inst = this._newInst( $( target ), inline );
14682
14683		inst.settings = $.extend( {}, settings || {} );
14684
14685		if ( nodeName === "input" ) {
14686
14687			this._connectDatepicker( target, inst );
14688
14689		} else if ( inline ) {
14690
14691			this._inlineDatepicker( target, inst );
14692
14693		}
14694
14695	},
14696
14697
14698
14699	/* Create a new instance object. */
14700
14701	_newInst: function( target, inline ) {
14702
14703		var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars
14704
14705		return { id: id, input: target, // associated target
14706
14707			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
14708
14709			drawMonth: 0, drawYear: 0, // month being drawn
14710
14711			inline: inline, // is datepicker inline or not
14712
14713			dpDiv: ( !inline ? this.dpDiv : // presentation div
14714
14715			datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) };
14716
14717	},
14718
14719
14720
14721	/* Attach the date picker to an input field. */
14722
14723	_connectDatepicker: function( target, inst ) {
14724
14725		var input = $( target );
14726
14727		inst.append = $( [] );
14728
14729		inst.trigger = $( [] );
14730
14731		if ( input.hasClass( this.markerClassName ) ) {
14732
14733			return;
14734
14735		}
14736
14737		this._attachments( input, inst );
14738
14739		input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ).
14740
14741			on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp );
14742
14743		this._autoSize( inst );
14744
14745		$.data( target, "datepicker", inst );
14746
14747
14748
14749		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
14750
14751		if ( inst.settings.disabled ) {
14752
14753			this._disableDatepicker( target );
14754
14755		}
14756
14757	},
14758
14759
14760
14761	/* Make attachments based on settings. */
14762
14763	_attachments: function( input, inst ) {
14764
14765		var showOn, buttonText, buttonImage,
14766
14767			appendText = this._get( inst, "appendText" ),
14768
14769			isRTL = this._get( inst, "isRTL" );
14770
14771
14772
14773		if ( inst.append ) {
14774
vendor: 6,508 bytes, lines 14775-15090
14775			inst.append.remove();
14776
14777		}
14778
14779		if ( appendText ) {
14780
14781			inst.append = $( "<span class='" + this._appendClass + "'>" + appendText + "</span>" );
14782
14783			input[ isRTL ? "before" : "after" ]( inst.append );
14784
14785		}
14786
14787
14788
14789		input.off( "focus", this._showDatepicker );
14790
14791
14792
14793		if ( inst.trigger ) {
14794
14795			inst.trigger.remove();
14796
14797		}
14798
14799
14800
14801		showOn = this._get( inst, "showOn" );
14802
14803		if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field
14804
14805			input.on( "focus", this._showDatepicker );
14806
14807		}
14808
14809		if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked
14810
14811			buttonText = this._get( inst, "buttonText" );
14812
14813			buttonImage = this._get( inst, "buttonImage" );
14814
14815			inst.trigger = $( this._get( inst, "buttonImageOnly" ) ?
14816
14817				$( "<img/>" ).addClass( this._triggerClass ).
14818
14819					attr( { src: buttonImage, alt: buttonText, title: buttonText } ) :
14820
14821				$( "<button type='button'></button>" ).addClass( this._triggerClass ).
14822
14823					html( !buttonImage ? buttonText : $( "<img/>" ).attr(
14824
14825					{ src:buttonImage, alt:buttonText, title:buttonText } ) ) );
14826
14827			input[ isRTL ? "before" : "after" ]( inst.trigger );
14828
14829			inst.trigger.on( "click", function() {
14830
14831				if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) {
14832
14833					$.datepicker._hideDatepicker();
14834
14835				} else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) {
14836
14837					$.datepicker._hideDatepicker();
14838
14839					$.datepicker._showDatepicker( input[ 0 ] );
14840
14841				} else {
14842
14843					$.datepicker._showDatepicker( input[ 0 ] );
14844
14845				}
14846
14847				return false;
14848
14849			} );
14850
14851		}
14852
14853	},
14854
14855
14856
14857	/* Apply the maximum length for the date format. */
14858
14859	_autoSize: function( inst ) {
14860
14861		if ( this._get( inst, "autoSize" ) && !inst.inline ) {
14862
14863			var findMax, max, maxI, i,
14864
14865				date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits
14866
14867				dateFormat = this._get( inst, "dateFormat" );
14868
14869
14870
14871			if ( dateFormat.match( /[DM]/ ) ) {
14872
14873				findMax = function( names ) {
14874
14875					max = 0;
14876
14877					maxI = 0;
14878
14879					for ( i = 0; i < names.length; i++ ) {
14880
14881						if ( names[ i ].length > max ) {
14882
14883							max = names[ i ].length;
14884
14885							maxI = i;
14886
14887						}
14888
14889					}
14890
14891					return maxI;
14892
14893				};
14894
14895				date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ?
14896
14897					"monthNames" : "monthNamesShort" ) ) ) );
14898
14899				date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ?
14900
14901					"dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() );
14902
14903			}
14904
14905			inst.input.attr( "size", this._formatDate( inst, date ).length );
14906
14907		}
14908
14909	},
14910
14911
14912
14913	/* Attach an inline date picker to a div. */
14914
14915	_inlineDatepicker: function( target, inst ) {
14916
14917		var divSpan = $( target );
14918
14919		if ( divSpan.hasClass( this.markerClassName ) ) {
14920
14921			return;
14922
14923		}
14924
14925		divSpan.addClass( this.markerClassName ).append( inst.dpDiv );
14926
14927		$.data( target, "datepicker", inst );
14928
14929		this._setDate( inst, this._getDefaultDate( inst ), true );
14930
14931		this._updateDatepicker( inst );
14932
14933		this._updateAlternate( inst );
14934
14935
14936
14937		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
14938
14939		if ( inst.settings.disabled ) {
14940
14941			this._disableDatepicker( target );
14942
14943		}
14944
14945
14946
14947		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
14948
14949		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
14950
14951		inst.dpDiv.css( "display", "block" );
14952
14953	},
14954
14955
14956
14957	/* Pop-up the date picker in a "dialog" box.
14958
14959	 * @param  input element - ignored
14960
14961	 * @param  date	string or Date - the initial date to display
14962
14963	 * @param  onSelect  function - the function to call when a date is selected
14964
14965	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
14966
14967	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
14968
14969	 *					event - with x/y coordinates or
14970
14971	 *					leave empty for default (screen centre)
14972
14973	 * @return the manager object
14974
14975	 */
14976
14977	_dialogDatepicker: function( input, date, onSelect, settings, pos ) {
14978
14979		var id, browserWidth, browserHeight, scrollX, scrollY,
14980
14981			inst = this._dialogInst; // internal instance
14982
14983
14984
14985		if ( !inst ) {
14986
14987			this.uuid += 1;
14988
14989			id = "dp" + this.uuid;
14990
14991			this._dialogInput = $( "<input type='text' id='" + id +
14992
14993				"' style='position: absolute; top: -100px; width: 0px;'/>" );
14994
14995			this._dialogInput.on( "keydown", this._doKeyDown );
14996
14997			$( "body" ).append( this._dialogInput );
14998
14999			inst = this._dialogInst = this._newInst( this._dialogInput, false );
15000
15001			inst.settings = {};
15002
15003			$.data( this._dialogInput[ 0 ], "datepicker", inst );
15004
15005		}
15006
15007		datepicker_extendRemove( inst.settings, settings || {} );
15008
15009		date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date );
15010
15011		this._dialogInput.val( date );
15012
15013
15014
15015		this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null );
15016
15017		if ( !this._pos ) {
15018
15019			browserWidth = document.documentElement.clientWidth;
15020
15021			browserHeight = document.documentElement.clientHeight;
15022
15023			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
15024
15025			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
15026
15027			this._pos = // should use actual width/height below
15028
15029				[ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ];
15030
15031		}
15032
15033
15034
15035		// Move input on screen for focus, but hidden behind dialog
15036
15037		this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" );
15038
15039		inst.settings.onSelect = onSelect;
15040
15041		this._inDialog = true;
15042
15043		this.dpDiv.addClass( this._dialogClass );
15044
15045		this._showDatepicker( this._dialogInput[ 0 ] );
15046
15047		if ( $.blockUI ) {
15048
15049			$.blockUI( this.dpDiv );
15050
15051		}
15052
15053		$.data( this._dialogInput[ 0 ], "datepicker", inst );
15054
15055		return this;
15056
15057	},
15058
15059
15060
15061	/* Detach a datepicker from its control.
15062
15063	 * @param  target	element - the target input field or division or span
15064
15065	 */
15066
15067	_destroyDatepicker: function( target ) {
15068
15069		var nodeName,
15070
15071			$target = $( target ),
15072
15073			inst = $.data( target, "datepicker" );
15074
15075
15076
15077		if ( !$target.hasClass( this.markerClassName ) ) {
15078
15079			return;
15080
15081		}
15082
15083
15084
15085		nodeName = target.nodeName.toLowerCase();
15086
15087		$.removeData( target, "datepicker" );
15088
15089		if ( nodeName === "input" ) {
15090
vendor: 12,793 bytes, lines 15091-15772
15091			inst.append.remove();
15092
15093			inst.trigger.remove();
15094
15095			$target.removeClass( this.markerClassName ).
15096
15097				off( "focus", this._showDatepicker ).
15098
15099				off( "keydown", this._doKeyDown ).
15100
15101				off( "keypress", this._doKeyPress ).
15102
15103				off( "keyup", this._doKeyUp );
15104
15105		} else if ( nodeName === "div" || nodeName === "span" ) {
15106
15107			$target.removeClass( this.markerClassName ).empty();
15108
15109		}
15110
15111
15112
15113		if ( datepicker_instActive === inst ) {
15114
15115			datepicker_instActive = null;
15116
15117		}
15118
15119	},
15120
15121
15122
15123	/* Enable the date picker to a jQuery selection.
15124
15125	 * @param  target	element - the target input field or division or span
15126
15127	 */
15128
15129	_enableDatepicker: function( target ) {
15130
15131		var nodeName, inline,
15132
15133			$target = $( target ),
15134
15135			inst = $.data( target, "datepicker" );
15136
15137
15138
15139		if ( !$target.hasClass( this.markerClassName ) ) {
15140
15141			return;
15142
15143		}
15144
15145
15146
15147		nodeName = target.nodeName.toLowerCase();
15148
15149		if ( nodeName === "input" ) {
15150
15151			target.disabled = false;
15152
15153			inst.trigger.filter( "button" ).
15154
15155				each( function() { this.disabled = false; } ).end().
15156
15157				filter( "img" ).css( { opacity: "1.0", cursor: "" } );
15158
15159		} else if ( nodeName === "div" || nodeName === "span" ) {
15160
15161			inline = $target.children( "." + this._inlineClass );
15162
15163			inline.children().removeClass( "ui-state-disabled" );
15164
15165			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
15166
15167				prop( "disabled", false );
15168
15169		}
15170
15171		this._disabledInputs = $.map( this._disabledInputs,
15172
15173			function( value ) { return ( value === target ? null : value ); } ); // delete entry
15174
15175	},
15176
15177
15178
15179	/* Disable the date picker to a jQuery selection.
15180
15181	 * @param  target	element - the target input field or division or span
15182
15183	 */
15184
15185	_disableDatepicker: function( target ) {
15186
15187		var nodeName, inline,
15188
15189			$target = $( target ),
15190
15191			inst = $.data( target, "datepicker" );
15192
15193
15194
15195		if ( !$target.hasClass( this.markerClassName ) ) {
15196
15197			return;
15198
15199		}
15200
15201
15202
15203		nodeName = target.nodeName.toLowerCase();
15204
15205		if ( nodeName === "input" ) {
15206
15207			target.disabled = true;
15208
15209			inst.trigger.filter( "button" ).
15210
15211				each( function() { this.disabled = true; } ).end().
15212
15213				filter( "img" ).css( { opacity: "0.5", cursor: "default" } );
15214
15215		} else if ( nodeName === "div" || nodeName === "span" ) {
15216
15217			inline = $target.children( "." + this._inlineClass );
15218
15219			inline.children().addClass( "ui-state-disabled" );
15220
15221			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
15222
15223				prop( "disabled", true );
15224
15225		}
15226
15227		this._disabledInputs = $.map( this._disabledInputs,
15228
15229			function( value ) { return ( value === target ? null : value ); } ); // delete entry
15230
15231		this._disabledInputs[ this._disabledInputs.length ] = target;
15232
15233	},
15234
15235
15236
15237	/* Is the first field in a jQuery collection disabled as a datepicker?
15238
15239	 * @param  target	element - the target input field or division or span
15240
15241	 * @return boolean - true if disabled, false if enabled
15242
15243	 */
15244
15245	_isDisabledDatepicker: function( target ) {
15246
15247		if ( !target ) {
15248
15249			return false;
15250
15251		}
15252
15253		for ( var i = 0; i < this._disabledInputs.length; i++ ) {
15254
15255			if ( this._disabledInputs[ i ] === target ) {
15256
15257				return true;
15258
15259			}
15260
15261		}
15262
15263		return false;
15264
15265	},
15266
15267
15268
15269	/* Retrieve the instance data for the target control.
15270
15271	 * @param  target  element - the target input field or division or span
15272
15273	 * @return  object - the associated instance data
15274
15275	 * @throws  error if a jQuery problem getting data
15276
15277	 */
15278
15279	_getInst: function( target ) {
15280
15281		try {
15282
15283			return $.data( target, "datepicker" );
15284
15285		}
15286
15287		catch ( err ) {
15288
15289			throw "Missing instance data for this datepicker";
15290
15291		}
15292
15293	},
15294
15295
15296
15297	/* Update or retrieve the settings for a date picker attached to an input field or division.
15298
15299	 * @param  target  element - the target input field or division or span
15300
15301	 * @param  name	object - the new settings to update or
15302
15303	 *				string - the name of the setting to change or retrieve,
15304
15305	 *				when retrieving also "all" for all instance settings or
15306
15307	 *				"defaults" for all global defaults
15308
15309	 * @param  value   any - the new value for the setting
15310
15311	 *				(omit if above is an object or to retrieve a value)
15312
15313	 */
15314
15315	_optionDatepicker: function( target, name, value ) {
15316
15317		var settings, date, minDate, maxDate,
15318
15319			inst = this._getInst( target );
15320
15321
15322
15323		if ( arguments.length === 2 && typeof name === "string" ) {
15324
15325			return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) :
15326
15327				( inst ? ( name === "all" ? $.extend( {}, inst.settings ) :
15328
15329				this._get( inst, name ) ) : null ) );
15330
15331		}
15332
15333
15334
15335		settings = name || {};
15336
15337		if ( typeof name === "string" ) {
15338
15339			settings = {};
15340
15341			settings[ name ] = value;
15342
15343		}
15344
15345
15346
15347		if ( inst ) {
15348
15349			if ( this._curInst === inst ) {
15350
15351				this._hideDatepicker();
15352
15353			}
15354
15355
15356
15357			date = this._getDateDatepicker( target, true );
15358
15359			minDate = this._getMinMaxDate( inst, "min" );
15360
15361			maxDate = this._getMinMaxDate( inst, "max" );
15362
15363			datepicker_extendRemove( inst.settings, settings );
15364
15365
15366
15367			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
15368
15369			if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) {
15370
15371				inst.settings.minDate = this._formatDate( inst, minDate );
15372
15373			}
15374
15375			if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) {
15376
15377				inst.settings.maxDate = this._formatDate( inst, maxDate );
15378
15379			}
15380
15381			if ( "disabled" in settings ) {
15382
15383				if ( settings.disabled ) {
15384
15385					this._disableDatepicker( target );
15386
15387				} else {
15388
15389					this._enableDatepicker( target );
15390
15391				}
15392
15393			}
15394
15395			this._attachments( $( target ), inst );
15396
15397			this._autoSize( inst );
15398
15399			this._setDate( inst, date );
15400
15401			this._updateAlternate( inst );
15402
15403			this._updateDatepicker( inst );
15404
15405		}
15406
15407	},
15408
15409
15410
15411	// Change method deprecated
15412
15413	_changeDatepicker: function( target, name, value ) {
15414
15415		this._optionDatepicker( target, name, value );
15416
15417	},
15418
15419
15420
15421	/* Redraw the date picker attached to an input field or division.
15422
15423	 * @param  target  element - the target input field or division or span
15424
15425	 */
15426
15427	_refreshDatepicker: function( target ) {
15428
15429		var inst = this._getInst( target );
15430
15431		if ( inst ) {
15432
15433			this._updateDatepicker( inst );
15434
15435		}
15436
15437	},
15438
15439
15440
15441	/* Set the dates for a jQuery selection.
15442
15443	 * @param  target element - the target input field or division or span
15444
15445	 * @param  date	Date - the new date
15446
15447	 */
15448
15449	_setDateDatepicker: function( target, date ) {
15450
15451		var inst = this._getInst( target );
15452
15453		if ( inst ) {
15454
15455			this._setDate( inst, date );
15456
15457			this._updateDatepicker( inst );
15458
15459			this._updateAlternate( inst );
15460
15461		}
15462
15463	},
15464
15465
15466
15467	/* Get the date(s) for the first entry in a jQuery selection.
15468
15469	 * @param  target element - the target input field or division or span
15470
15471	 * @param  noDefault boolean - true if no default date is to be used
15472
15473	 * @return Date - the current date
15474
15475	 */
15476
15477	_getDateDatepicker: function( target, noDefault ) {
15478
15479		var inst = this._getInst( target );
15480
15481		if ( inst && !inst.inline ) {
15482
15483			this._setDateFromField( inst, noDefault );
15484
15485		}
15486
15487		return ( inst ? this._getDate( inst ) : null );
15488
15489	},
15490
15491
15492
15493	/* Handle keystrokes. */
15494
15495	_doKeyDown: function( event ) {
15496
15497		var onSelect, dateStr, sel,
15498
15499			inst = $.datepicker._getInst( event.target ),
15500
15501			handled = true,
15502
15503			isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" );
15504
15505
15506
15507		inst._keyEvent = true;
15508
15509		if ( $.datepicker._datepickerShowing ) {
15510
15511			switch ( event.keyCode ) {
15512
15513				case 9: $.datepicker._hideDatepicker();
15514
15515						handled = false;
15516
15517						break; // hide on tab out
15518
15519				case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." +
15520
15521									$.datepicker._currentClass + ")", inst.dpDiv );
15522
15523						if ( sel[ 0 ] ) {
15524
15525							$.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] );
15526
15527						}
15528
15529
15530
15531						onSelect = $.datepicker._get( inst, "onSelect" );
15532
15533						if ( onSelect ) {
15534
15535							dateStr = $.datepicker._formatDate( inst );
15536
15537
15538
15539							// Trigger custom callback
15540
15541							onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );
15542
15543						} else {
15544
15545							$.datepicker._hideDatepicker();
15546
15547						}
15548
15549
15550
15551						return false; // don't submit the form
15552
15553				case 27: $.datepicker._hideDatepicker();
15554
15555						break; // hide on escape
15556
15557				case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
15558
15559							-$.datepicker._get( inst, "stepBigMonths" ) :
15560
15561							-$.datepicker._get( inst, "stepMonths" ) ), "M" );
15562
15563						break; // previous month/year on page up/+ ctrl
15564
15565				case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
15566
15567							+$.datepicker._get( inst, "stepBigMonths" ) :
15568
15569							+$.datepicker._get( inst, "stepMonths" ) ), "M" );
15570
15571						break; // next month/year on page down/+ ctrl
15572
15573				case 35: if ( event.ctrlKey || event.metaKey ) {
15574
15575							$.datepicker._clearDate( event.target );
15576
15577						}
15578
15579						handled = event.ctrlKey || event.metaKey;
15580
15581						break; // clear on ctrl or command +end
15582
15583				case 36: if ( event.ctrlKey || event.metaKey ) {
15584
15585							$.datepicker._gotoToday( event.target );
15586
15587						}
15588
15589						handled = event.ctrlKey || event.metaKey;
15590
15591						break; // current on ctrl or command +home
15592
15593				case 37: if ( event.ctrlKey || event.metaKey ) {
15594
15595							$.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" );
15596
15597						}
15598
15599						handled = event.ctrlKey || event.metaKey;
15600
15601
15602
15603						// -1 day on ctrl or command +left
15604
15605						if ( event.originalEvent.altKey ) {
15606
15607							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
15608
15609								-$.datepicker._get( inst, "stepBigMonths" ) :
15610
15611								-$.datepicker._get( inst, "stepMonths" ) ), "M" );
15612
15613						}
15614
15615
15616
15617						// next month/year on alt +left on Mac
15618
15619						break;
15620
15621				case 38: if ( event.ctrlKey || event.metaKey ) {
15622
15623							$.datepicker._adjustDate( event.target, -7, "D" );
15624
15625						}
15626
15627						handled = event.ctrlKey || event.metaKey;
15628
15629						break; // -1 week on ctrl or command +up
15630
15631				case 39: if ( event.ctrlKey || event.metaKey ) {
15632
15633							$.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" );
15634
15635						}
15636
15637						handled = event.ctrlKey || event.metaKey;
15638
15639
15640
15641						// +1 day on ctrl or command +right
15642
15643						if ( event.originalEvent.altKey ) {
15644
15645							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
15646
15647								+$.datepicker._get( inst, "stepBigMonths" ) :
15648
15649								+$.datepicker._get( inst, "stepMonths" ) ), "M" );
15650
15651						}
15652
15653
15654
15655						// next month/year on alt +right
15656
15657						break;
15658
15659				case 40: if ( event.ctrlKey || event.metaKey ) {
15660
15661							$.datepicker._adjustDate( event.target, +7, "D" );
15662
15663						}
15664
15665						handled = event.ctrlKey || event.metaKey;
15666
15667						break; // +1 week on ctrl or command +down
15668
15669				default: handled = false;
15670
15671			}
15672
15673		} else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home
15674
15675			$.datepicker._showDatepicker( this );
15676
15677		} else {
15678
15679			handled = false;
15680
15681		}
15682
15683
15684
15685		if ( handled ) {
15686
15687			event.preventDefault();
15688
15689			event.stopPropagation();
15690
15691		}
15692
15693	},
15694
15695
15696
15697	/* Filter entered characters - based on date format. */
15698
15699	_doKeyPress: function( event ) {
15700
15701		var chars, chr,
15702
15703			inst = $.datepicker._getInst( event.target );
15704
15705
15706
15707		if ( $.datepicker._get( inst, "constrainInput" ) ) {
15708
15709			chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) );
15710
15711			chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode );
15712
15713			return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 );
15714
15715		}
15716
15717	},
15718
15719
15720
15721	/* Synchronise manual entry and field/alternate field. */
15722
15723	_doKeyUp: function( event ) {
15724
15725		var date,
15726
15727			inst = $.datepicker._getInst( event.target );
15728
15729
15730
15731		if ( inst.input.val() !== inst.lastVal ) {
15732
15733			try {
15734
15735				date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
15736
15737					( inst.input ? inst.input.val() : null ),
15738
15739					$.datepicker._getFormatConfig( inst ) );
15740
15741
15742
15743				if ( date ) { // only if valid
15744
15745					$.datepicker._setDateFromField( inst );
15746
15747					$.datepicker._updateAlternate( inst );
15748
15749					$.datepicker._updateDatepicker( inst );
15750
15751				}
15752
15753			}
15754
15755			catch ( err ) {
15756
15757			}
15758
15759		}
15760
15761		return true;
15762
15763	},
15764
15765
15766
15767	/* Pop-up the date picker for a given input field.
15768
15769	 * If false returned from beforeShow event handler do not show.
15770
15771	 * @param  input  element - the input field attached to the date picker or
15772
vendor: 4,625 bytes, lines 15773-16016
15773	 *					event - if triggered by focus
15774
15775	 */
15776
15777	_showDatepicker: function( input ) {
15778
15779		input = input.target || input;
15780
15781		if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger
15782
15783			input = $( "input", input.parentNode )[ 0 ];
15784
15785		}
15786
15787
15788
15789		if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here
15790
15791			return;
15792
15793		}
15794
15795
15796
15797		var inst, beforeShow, beforeShowSettings, isFixed,
15798
15799			offset, showAnim, duration;
15800
15801
15802
15803		inst = $.datepicker._getInst( input );
15804
15805		if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) {
15806
15807			$.datepicker._curInst.dpDiv.stop( true, true );
15808
15809			if ( inst && $.datepicker._datepickerShowing ) {
15810
15811				$.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] );
15812
15813			}
15814
15815		}
15816
15817
15818
15819		beforeShow = $.datepicker._get( inst, "beforeShow" );
15820
15821		beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {};
15822
15823		if ( beforeShowSettings === false ) {
15824
15825			return;
15826
15827		}
15828
15829		datepicker_extendRemove( inst.settings, beforeShowSettings );
15830
15831
15832
15833		inst.lastVal = null;
15834
15835		$.datepicker._lastInput = input;
15836
15837		$.datepicker._setDateFromField( inst );
15838
15839
15840
15841		if ( $.datepicker._inDialog ) { // hide cursor
15842
15843			input.value = "";
15844
15845		}
15846
15847		if ( !$.datepicker._pos ) { // position below input
15848
15849			$.datepicker._pos = $.datepicker._findPos( input );
15850
15851			$.datepicker._pos[ 1 ] += input.offsetHeight; // add the height
15852
15853		}
15854
15855
15856
15857		isFixed = false;
15858
15859		$( input ).parents().each( function() {
15860
15861			isFixed |= $( this ).css( "position" ) === "fixed";
15862
15863			return !isFixed;
15864
15865		} );
15866
15867
15868
15869		offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] };
15870
15871		$.datepicker._pos = null;
15872
15873
15874
15875		//to avoid flashes on Firefox
15876
15877		inst.dpDiv.empty();
15878
15879
15880
15881		// determine sizing offscreen
15882
15883		inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } );
15884
15885		$.datepicker._updateDatepicker( inst );
15886
15887
15888
15889		// fix width for dynamic number of date pickers
15890
15891		// and adjust position before showing
15892
15893		offset = $.datepicker._checkOffset( inst, offset, isFixed );
15894
15895		inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ?
15896
15897			"static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none",
15898
15899			left: offset.left + "px", top: offset.top + "px" } );
15900
15901
15902
15903		if ( !inst.inline ) {
15904
15905			showAnim = $.datepicker._get( inst, "showAnim" );
15906
15907			duration = $.datepicker._get( inst, "duration" );
15908
15909			inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
15910
15911			$.datepicker._datepickerShowing = true;
15912
15913
15914
15915			if ( $.effects && $.effects.effect[ showAnim ] ) {
15916
15917				inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration );
15918
15919			} else {
15920
15921				inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null );
15922
15923			}
15924
15925
15926
15927			if ( $.datepicker._shouldFocusInput( inst ) ) {
15928
15929				inst.input.trigger( "focus" );
15930
15931			}
15932
15933
15934
15935			$.datepicker._curInst = inst;
15936
15937		}
15938
15939	},
15940
15941
15942
15943	/* Generate the date picker content. */
15944
15945	_updateDatepicker: function( inst ) {
15946
15947		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
15948
15949		datepicker_instActive = inst; // for delegate hover events
15950
15951		inst.dpDiv.empty().append( this._generateHTML( inst ) );
15952
15953		this._attachHandlers( inst );
15954
15955
15956
15957		var origyearshtml,
15958
15959			numMonths = this._getNumberOfMonths( inst ),
15960
15961			cols = numMonths[ 1 ],
15962
15963			width = 17,
15964
15965			activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
15966
15967
15968
15969		if ( activeCell.length > 0 ) {
15970
15971			datepicker_handleMouseover.apply( activeCell.get( 0 ) );
15972
15973		}
15974
15975
15976
15977		inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" );
15978
15979		if ( cols > 1 ) {
15980
15981			inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" );
15982
15983		}
15984
15985		inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) +
15986
15987			"Class" ]( "ui-datepicker-multi" );
15988
15989		inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) +
15990
15991			"Class" ]( "ui-datepicker-rtl" );
15992
15993
15994
15995		if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
15996
15997			inst.input.trigger( "focus" );
15998
15999		}
16000
16001
16002
16003		// Deffered render of the years select (to avoid flashes on Firefox)
16004
16005		if ( inst.yearshtml ) {
16006
16007			origyearshtml = inst.yearshtml;
16008
16009			setTimeout( function() {
16010
16011
16012
16013				//assure that inst.yearshtml didn't change.
16014
16015				if ( origyearshtml === inst.yearshtml && inst.yearshtml ) {
16016
vendor: 5,951 bytes, lines 16017-16330
16017					inst.dpDiv.find( "select.ui-datepicker-year:first" ).replaceWith( inst.yearshtml );
16018
16019				}
16020
16021				origyearshtml = inst.yearshtml = null;
16022
16023			}, 0 );
16024
16025		}
16026
16027	},
16028
16029
16030
16031	// #6694 - don't focus the input if it's already focused
16032
16033	// this breaks the change event in IE
16034
16035	// Support: IE and jQuery <1.9
16036
16037	_shouldFocusInput: function( inst ) {
16038
16039		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
16040
16041	},
16042
16043
16044
16045	/* Check positioning to remain on screen. */
16046
16047	_checkOffset: function( inst, offset, isFixed ) {
16048
16049		var dpWidth = inst.dpDiv.outerWidth(),
16050
16051			dpHeight = inst.dpDiv.outerHeight(),
16052
16053			inputWidth = inst.input ? inst.input.outerWidth() : 0,
16054
16055			inputHeight = inst.input ? inst.input.outerHeight() : 0,
16056
16057			viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ),
16058
16059			viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() );
16060
16061
16062
16063		offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 );
16064
16065		offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0;
16066
16067		offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0;
16068
16069
16070
16071		// Now check if datepicker is showing outside window viewport - move to a better place if so.
16072
16073		offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ?
16074
16075			Math.abs( offset.left + dpWidth - viewWidth ) : 0 );
16076
16077		offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ?
16078
16079			Math.abs( dpHeight + inputHeight ) : 0 );
16080
16081
16082
16083		return offset;
16084
16085	},
16086
16087
16088
16089	/* Find an object's position on the screen. */
16090
16091	_findPos: function( obj ) {
16092
16093		var position,
16094
16095			inst = this._getInst( obj ),
16096
16097			isRTL = this._get( inst, "isRTL" );
16098
16099
16100
16101		while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden( obj ) ) ) {
16102
16103			obj = obj[ isRTL ? "previousSibling" : "nextSibling" ];
16104
16105		}
16106
16107
16108
16109		position = $( obj ).offset();
16110
16111		return [ position.left, position.top ];
16112
16113	},
16114
16115
16116
16117	/* Hide the date picker from view.
16118
16119	 * @param  input  element - the input field attached to the date picker
16120
16121	 */
16122
16123	_hideDatepicker: function( input ) {
16124
16125		var showAnim, duration, postProcess, onClose,
16126
16127			inst = this._curInst;
16128
16129
16130
16131		if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) {
16132
16133			return;
16134
16135		}
16136
16137
16138
16139		if ( this._datepickerShowing ) {
16140
16141			showAnim = this._get( inst, "showAnim" );
16142
16143			duration = this._get( inst, "duration" );
16144
16145			postProcess = function() {
16146
16147				$.datepicker._tidyDialog( inst );
16148
16149			};
16150
16151
16152
16153			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
16154
16155			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
16156
16157				inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess );
16158
16159			} else {
16160
16161				inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" :
16162
16163					( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess );
16164
16165			}
16166
16167
16168
16169			if ( !showAnim ) {
16170
16171				postProcess();
16172
16173			}
16174
16175			this._datepickerShowing = false;
16176
16177
16178
16179			onClose = this._get( inst, "onClose" );
16180
16181			if ( onClose ) {
16182
16183				onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] );
16184
16185			}
16186
16187
16188
16189			this._lastInput = null;
16190
16191			if ( this._inDialog ) {
16192
16193				this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } );
16194
16195				if ( $.blockUI ) {
16196
16197					$.unblockUI();
16198
16199					$( "body" ).append( this.dpDiv );
16200
16201				}
16202
16203			}
16204
16205			this._inDialog = false;
16206
16207		}
16208
16209	},
16210
16211
16212
16213	/* Tidy up after a dialog display. */
16214
16215	_tidyDialog: function( inst ) {
16216
16217		inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" );
16218
16219	},
16220
16221
16222
16223	/* Close date picker if clicked elsewhere. */
16224
16225	_checkExternalClick: function( event ) {
16226
16227		if ( !$.datepicker._curInst ) {
16228
16229			return;
16230
16231		}
16232
16233
16234
16235		var $target = $( event.target ),
16236
16237			inst = $.datepicker._getInst( $target[ 0 ] );
16238
16239
16240
16241		if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId &&
16242
16243				$target.parents( "#" + $.datepicker._mainDivId ).length === 0 &&
16244
16245				!$target.hasClass( $.datepicker.markerClassName ) &&
16246
16247				!$target.closest( "." + $.datepicker._triggerClass ).length &&
16248
16249				$.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) ||
16250
16251			( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) {
16252
16253				$.datepicker._hideDatepicker();
16254
16255		}
16256
16257	},
16258
16259
16260
16261	/* Adjust one of the date sub-fields. */
16262
16263	_adjustDate: function( id, offset, period ) {
16264
16265		var target = $( id ),
16266
16267			inst = this._getInst( target[ 0 ] );
16268
16269
16270
16271		if ( this._isDisabledDatepicker( target[ 0 ] ) ) {
16272
16273			return;
16274
16275		}
16276
16277		this._adjustInstDate( inst, offset +
16278
16279			( period === "M" ? this._get( inst, "showCurrentAtPos" ) : 0 ), // undo positioning
16280
16281			period );
16282
16283		this._updateDatepicker( inst );
16284
16285	},
16286
16287
16288
16289	/* Action for current link. */
16290
16291	_gotoToday: function( id ) {
16292
16293		var date,
16294
16295			target = $( id ),
16296
16297			inst = this._getInst( target[ 0 ] );
16298
16299
16300
16301		if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) {
16302
16303			inst.selectedDay = inst.currentDay;
16304
16305			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
16306
16307			inst.drawYear = inst.selectedYear = inst.currentYear;
16308
16309		} else {
16310
16311			date = new Date();
16312
16313			inst.selectedDay = date.getDate();
16314
16315			inst.drawMonth = inst.selectedMonth = date.getMonth();
16316
16317			inst.drawYear = inst.selectedYear = date.getFullYear();
16318
16319		}
16320
16321		this._notifyChange( inst );
16322
16323		this._adjustDate( target );
16324
16325	},
16326
16327
16328
16329	/* Action for selecting a new month/year. */
16330
vendor: 4,966 bytes, lines 16331-16593
16331	_selectMonthYear: function( id, select, period ) {
16332
16333		var target = $( id ),
16334
16335			inst = this._getInst( target[ 0 ] );
16336
16337
16338
16339		inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] =
16340
16341		inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] =
16342
16343			parseInt( select.options[ select.selectedIndex ].value, 10 );
16344
16345
16346
16347		this._notifyChange( inst );
16348
16349		this._adjustDate( target );
16350
16351	},
16352
16353
16354
16355	/* Action for selecting a day. */
16356
16357	_selectDay: function( id, month, year, td ) {
16358
16359		var inst,
16360
16361			target = $( id );
16362
16363
16364
16365		if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) {
16366
16367			return;
16368
16369		}
16370
16371
16372
16373		inst = this._getInst( target[ 0 ] );
16374
16375		inst.selectedDay = inst.currentDay = $( "a", td ).html();
16376
16377		inst.selectedMonth = inst.currentMonth = month;
16378
16379		inst.selectedYear = inst.currentYear = year;
16380
16381		this._selectDate( id, this._formatDate( inst,
16382
16383			inst.currentDay, inst.currentMonth, inst.currentYear ) );
16384
16385	},
16386
16387
16388
16389	/* Erase the input field and hide the date picker. */
16390
16391	_clearDate: function( id ) {
16392
16393		var target = $( id );
16394
16395		this._selectDate( target, "" );
16396
16397	},
16398
16399
16400
16401	/* Update the input field with the selected date. */
16402
16403	_selectDate: function( id, dateStr ) {
16404
16405		var onSelect,
16406
16407			target = $( id ),
16408
16409			inst = this._getInst( target[ 0 ] );
16410
16411
16412
16413		dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) );
16414
16415		if ( inst.input ) {
16416
16417			inst.input.val( dateStr );
16418
16419		}
16420
16421		this._updateAlternate( inst );
16422
16423
16424
16425		onSelect = this._get( inst, "onSelect" );
16426
16427		if ( onSelect ) {
16428
16429			onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );  // trigger custom callback
16430
16431		} else if ( inst.input ) {
16432
16433			inst.input.trigger( "change" ); // fire the change event
16434
16435		}
16436
16437
16438
16439		if ( inst.inline ) {
16440
16441			this._updateDatepicker( inst );
16442
16443		} else {
16444
16445			this._hideDatepicker();
16446
16447			this._lastInput = inst.input[ 0 ];
16448
16449			if ( typeof( inst.input[ 0 ] ) !== "object" ) {
16450
16451				inst.input.trigger( "focus" ); // restore focus
16452
16453			}
16454
16455			this._lastInput = null;
16456
16457		}
16458
16459	},
16460
16461
16462
16463	/* Update any alternate field to synchronise with the main field. */
16464
16465	_updateAlternate: function( inst ) {
16466
16467		var altFormat, date, dateStr,
16468
16469			altField = this._get( inst, "altField" );
16470
16471
16472
16473		if ( altField ) { // update alternate field too
16474
16475			altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" );
16476
16477			date = this._getDate( inst );
16478
16479			dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) );
16480
16481			$( altField ).val( dateStr );
16482
16483		}
16484
16485	},
16486
16487
16488
16489	/* Set as beforeShowDay function to prevent selection of weekends.
16490
16491	 * @param  date  Date - the date to customise
16492
16493	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
16494
16495	 */
16496
16497	noWeekends: function( date ) {
16498
16499		var day = date.getDay();
16500
16501		return [ ( day > 0 && day < 6 ), "" ];
16502
16503	},
16504
16505
16506
16507	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
16508
16509	 * @param  date  Date - the date to get the week for
16510
16511	 * @return  number - the number of the week within the year that contains this date
16512
16513	 */
16514
16515	iso8601Week: function( date ) {
16516
16517		var time,
16518
16519			checkDate = new Date( date.getTime() );
16520
16521
16522
16523		// Find Thursday of this week starting on Monday
16524
16525		checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) );
16526
16527
16528
16529		time = checkDate.getTime();
16530
16531		checkDate.setMonth( 0 ); // Compare with Jan 1
16532
16533		checkDate.setDate( 1 );
16534
16535		return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1;
16536
16537	},
16538
16539
16540
16541	/* Parse a string value into a date object.
16542
16543	 * See formatDate below for the possible formats.
16544
16545	 *
16546
16547	 * @param  format string - the expected format of the date
16548
16549	 * @param  value string - the date in the above format
16550
16551	 * @param  settings Object - attributes include:
16552
16553	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
16554
16555	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
16556
16557	 *					dayNames		string[7] - names of the days from Sunday (optional)
16558
16559	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
16560
16561	 *					monthNames		string[12] - names of the months (optional)
16562
16563	 * @return  Date - the extracted date value or null if value is blank
16564
16565	 */
16566
16567	parseDate: function( format, value, settings ) {
16568
16569		if ( format == null || value == null ) {
16570
16571			throw "Invalid arguments";
16572
16573		}
16574
16575
16576
16577		value = ( typeof value === "object" ? value.toString() : value + "" );
16578
16579		if ( value === "" ) {
16580
16581			return null;
16582
16583		}
16584
16585
16586
16587		var iFormat, dim, extra,
16588
16589			iValue = 0,
16590
16591			shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff,
16592
16593			shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp 
vendor: 14,461 bytes, lines 16593-17457
16593:
16594
16595				new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ),
16596
16597			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
16598
16599			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
16600
16601			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
16602
16603			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
16604
16605			year = -1,
16606
16607			month = -1,
16608
16609			day = -1,
16610
16611			doy = -1,
16612
16613			literal = false,
16614
16615			date,
16616
16617
16618
16619			// Check whether a format character is doubled
16620
16621			lookAhead = function( match ) {
16622
16623				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
16624
16625				if ( matches ) {
16626
16627					iFormat++;
16628
16629				}
16630
16631				return matches;
16632
16633			},
16634
16635
16636
16637			// Extract a number from the string value
16638
16639			getNumber = function( match ) {
16640
16641				var isDoubled = lookAhead( match ),
16642
16643					size = ( match === "@" ? 14 : ( match === "!" ? 20 :
16644
16645					( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ),
16646
16647					minSize = ( match === "y" ? size : 1 ),
16648
16649					digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ),
16650
16651					num = value.substring( iValue ).match( digits );
16652
16653				if ( !num ) {
16654
16655					throw "Missing number at position " + iValue;
16656
16657				}
16658
16659				iValue += num[ 0 ].length;
16660
16661				return parseInt( num[ 0 ], 10 );
16662
16663			},
16664
16665
16666
16667			// Extract a name from the string value and convert to an index
16668
16669			getName = function( match, shortNames, longNames ) {
16670
16671				var index = -1,
16672
16673					names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) {
16674
16675						return [ [ k, v ] ];
16676
16677					} ).sort( function( a, b ) {
16678
16679						return -( a[ 1 ].length - b[ 1 ].length );
16680
16681					} );
16682
16683
16684
16685				$.each( names, function( i, pair ) {
16686
16687					var name = pair[ 1 ];
16688
16689					if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) {
16690
16691						index = pair[ 0 ];
16692
16693						iValue += name.length;
16694
16695						return false;
16696
16697					}
16698
16699				} );
16700
16701				if ( index !== -1 ) {
16702
16703					return index + 1;
16704
16705				} else {
16706
16707					throw "Unknown name at position " + iValue;
16708
16709				}
16710
16711			},
16712
16713
16714
16715			// Confirm that a literal character matches the string value
16716
16717			checkLiteral = function() {
16718
16719				if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) {
16720
16721					throw "Unexpected literal at position " + iValue;
16722
16723				}
16724
16725				iValue++;
16726
16727			};
16728
16729
16730
16731		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
16732
16733			if ( literal ) {
16734
16735				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
16736
16737					literal = false;
16738
16739				} else {
16740
16741					checkLiteral();
16742
16743				}
16744
16745			} else {
16746
16747				switch ( format.charAt( iFormat ) ) {
16748
16749					case "d":
16750
16751						day = getNumber( "d" );
16752
16753						break;
16754
16755					case "D":
16756
16757						getName( "D", dayNamesShort, dayNames );
16758
16759						break;
16760
16761					case "o":
16762
16763						doy = getNumber( "o" );
16764
16765						break;
16766
16767					case "m":
16768
16769						month = getNumber( "m" );
16770
16771						break;
16772
16773					case "M":
16774
16775						month = getName( "M", monthNamesShort, monthNames );
16776
16777						break;
16778
16779					case "y":
16780
16781						year = getNumber( "y" );
16782
16783						break;
16784
16785					case "@":
16786
16787						date = new Date( getNumber( "@" ) );
16788
16789						year = date.getFullYear();
16790
16791						month = date.getMonth() + 1;
16792
16793						day = date.getDate();
16794
16795						break;
16796
16797					case "!":
16798
16799						date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 );
16800
16801						year = date.getFullYear();
16802
16803						month = date.getMonth() + 1;
16804
16805						day = date.getDate();
16806
16807						break;
16808
16809					case "'":
16810
16811						if ( lookAhead( "'" ) ) {
16812
16813							checkLiteral();
16814
16815						} else {
16816
16817							literal = true;
16818
16819						}
16820
16821						break;
16822
16823					default:
16824
16825						checkLiteral();
16826
16827				}
16828
16829			}
16830
16831		}
16832
16833
16834
16835		if ( iValue < value.length ) {
16836
16837			extra = value.substr( iValue );
16838
16839			if ( !/^\s+/.test( extra ) ) {
16840
16841				throw "Extra/unparsed characters found in date: " + extra;
16842
16843			}
16844
16845		}
16846
16847
16848
16849		if ( year === -1 ) {
16850
16851			year = new Date().getFullYear();
16852
16853		} else if ( year < 100 ) {
16854
16855			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
16856
16857				( year <= shortYearCutoff ? 0 : -100 );
16858
16859		}
16860
16861
16862
16863		if ( doy > -1 ) {
16864
16865			month = 1;
16866
16867			day = doy;
16868
16869			do {
16870
16871				dim = this._getDaysInMonth( year, month - 1 );
16872
16873				if ( day <= dim ) {
16874
16875					break;
16876
16877				}
16878
16879				month++;
16880
16881				day -= dim;
16882
16883			} while ( true );
16884
16885		}
16886
16887
16888
16889		date = this._daylightSavingAdjust( new Date( year, month - 1, day ) );
16890
16891		if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) {
16892
16893			throw "Invalid date"; // E.g. 31/02/00
16894
16895		}
16896
16897		return date;
16898
16899	},
16900
16901
16902
16903	/* Standard date formats. */
16904
16905	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
16906
16907	COOKIE: "D, dd M yy",
16908
16909	ISO_8601: "yy-mm-dd",
16910
16911	RFC_822: "D, d M y",
16912
16913	RFC_850: "DD, dd-M-y",
16914
16915	RFC_1036: "D, d M y",
16916
16917	RFC_1123: "D, d M yy",
16918
16919	RFC_2822: "D, d M yy",
16920
16921	RSS: "D, d M y", // RFC 822
16922
16923	TICKS: "!",
16924
16925	TIMESTAMP: "@",
16926
16927	W3C: "yy-mm-dd", // ISO 8601
16928
16929
16930
16931	_ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) +
16932
16933		Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ),
16934
16935
16936
16937	/* Format a date object into a string value.
16938
16939	 * The format can be combinations of the following:
16940
16941	 * d  - day of month (no leading zero)
16942
16943	 * dd - day of month (two digit)
16944
16945	 * o  - day of year (no leading zeros)
16946
16947	 * oo - day of year (three digit)
16948
16949	 * D  - day name short
16950
16951	 * DD - day name long
16952
16953	 * m  - month of year (no leading zero)
16954
16955	 * mm - month of year (two digit)
16956
16957	 * M  - month name short
16958
16959	 * MM - month name long
16960
16961	 * y  - year (two digit)
16962
16963	 * yy - year (four digit)
16964
16965	 * @ - Unix timestamp (ms since 01/01/1970)
16966
16967	 * ! - Windows ticks (100ns since 01/01/0001)
16968
16969	 * "..." - literal text
16970
16971	 * '' - single quote
16972
16973	 *
16974
16975	 * @param  format string - the desired format of the date
16976
16977	 * @param  date Date - the date value to format
16978
16979	 * @param  settings Object - attributes include:
16980
16981	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
16982
16983	 *					dayNames		string[7] - names of the days from Sunday (optional)
16984
16985	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
16986
16987	 *					monthNames		string[12] - names of the months (optional)
16988
16989	 * @return  string - the date in the above format
16990
16991	 */
16992
16993	formatDate: function( format, date, settings ) {
16994
16995		if ( !date ) {
16996
16997			return "";
16998
16999		}
17000
17001
17002
17003		var iFormat,
17004
17005			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
17006
17007			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
17008
17009			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
17010
17011			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
17012
17013
17014
17015			// Check whether a format character is doubled
17016
17017			lookAhead = function( match ) {
17018
17019				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
17020
17021				if ( matches ) {
17022
17023					iFormat++;
17024
17025				}
17026
17027				return matches;
17028
17029			},
17030
17031
17032
17033			// Format a number, with leading zero if necessary
17034
17035			formatNumber = function( match, value, len ) {
17036
17037				var num = "" + value;
17038
17039				if ( lookAhead( match ) ) {
17040
17041					while ( num.length < len ) {
17042
17043						num = "0" + num;
17044
17045					}
17046
17047				}
17048
17049				return num;
17050
17051			},
17052
17053
17054
17055			// Format a name, short or long as requested
17056
17057			formatName = function( match, value, shortNames, longNames ) {
17058
17059				return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] );
17060
17061			},
17062
17063			output = "",
17064
17065			literal = false;
17066
17067
17068
17069		if ( date ) {
17070
17071			for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
17072
17073				if ( literal ) {
17074
17075					if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
17076
17077						literal = false;
17078
17079					} else {
17080
17081						output += format.charAt( iFormat );
17082
17083					}
17084
17085				} else {
17086
17087					switch ( format.charAt( iFormat ) ) {
17088
17089						case "d":
17090
17091							output += formatNumber( "d", date.getDate(), 2 );
17092
17093							break;
17094
17095						case "D":
17096
17097							output += formatName( "D", date.getDay(), dayNamesShort, dayNames );
17098
17099							break;
17100
17101						case "o":
17102
17103							output += formatNumber( "o",
17104
17105								Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 );
17106
17107							break;
17108
17109						case "m":
17110
17111							output += formatNumber( "m", date.getMonth() + 1, 2 );
17112
17113							break;
17114
17115						case "M":
17116
17117							output += formatName( "M", date.getMonth(), monthNamesShort, monthNames );
17118
17119							break;
17120
17121						case "y":
17122
17123							output += ( lookAhead( "y" ) ? date.getFullYear() :
17124
17125								( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 );
17126
17127							break;
17128
17129						case "@":
17130
17131							output += date.getTime();
17132
17133							break;
17134
17135						case "!":
17136
17137							output += date.getTime() * 10000 + this._ticksTo1970;
17138
17139							break;
17140
17141						case "'":
17142
17143							if ( lookAhead( "'" ) ) {
17144
17145								output += "'";
17146
17147							} else {
17148
17149								literal = true;
17150
17151							}
17152
17153							break;
17154
17155						default:
17156
17157							output += format.charAt( iFormat );
17158
17159					}
17160
17161				}
17162
17163			}
17164
17165		}
17166
17167		return output;
17168
17169	},
17170
17171
17172
17173	/* Extract all possible characters from the date format. */
17174
17175	_possibleChars: function( format ) {
17176
17177		var iFormat,
17178
17179			chars = "",
17180
17181			literal = false,
17182
17183
17184
17185			// Check whether a format character is doubled
17186
17187			lookAhead = function( match ) {
17188
17189				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
17190
17191				if ( matches ) {
17192
17193					iFormat++;
17194
17195				}
17196
17197				return matches;
17198
17199			};
17200
17201
17202
17203		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
17204
17205			if ( literal ) {
17206
17207				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
17208
17209					literal = false;
17210
17211				} else {
17212
17213					chars += format.charAt( iFormat );
17214
17215				}
17216
17217			} else {
17218
17219				switch ( format.charAt( iFormat ) ) {
17220
17221					case "d": case "m": case "y": case "@":
17222
17223						chars += "0123456789";
17224
17225						break;
17226
17227					case "D": case "M":
17228
17229						return null; // Accept anything
17230
17231					case "'":
17232
17233						if ( lookAhead( "'" ) ) {
17234
17235							chars += "'";
17236
17237						} else {
17238
17239							literal = true;
17240
17241						}
17242
17243						break;
17244
17245					default:
17246
17247						chars += format.charAt( iFormat );
17248
17249				}
17250
17251			}
17252
17253		}
17254
17255		return chars;
17256
17257	},
17258
17259
17260
17261	/* Get a setting value, defaulting if necessary. */
17262
17263	_get: function( inst, name ) {
17264
17265		return inst.settings[ name ] !== undefined ?
17266
17267			inst.settings[ name ] : this._defaults[ name ];
17268
17269	},
17270
17271
17272
17273	/* Parse existing date and initialise date picker. */
17274
17275	_setDateFromField: function( inst, noDefault ) {
17276
17277		if ( inst.input.val() === inst.lastVal ) {
17278
17279			return;
17280
17281		}
17282
17283
17284
17285		var dateFormat = this._get( inst, "dateFormat" ),
17286
17287			dates = inst.lastVal = inst.input ? inst.input.val() : null,
17288
17289			defaultDate = this._getDefaultDate( inst ),
17290
17291			date = defaultDate,
17292
17293			settings = this._getFormatConfig( inst );
17294
17295
17296
17297		try {
17298
17299			date = this.parseDate( dateFormat, dates, settings ) || defaultDate;
17300
17301		} catch ( event ) {
17302
17303			dates = ( noDefault ? "" : dates );
17304
17305		}
17306
17307		inst.selectedDay = date.getDate();
17308
17309		inst.drawMonth = inst.selectedMonth = date.getMonth();
17310
17311		inst.drawYear = inst.selectedYear = date.getFullYear();
17312
17313		inst.currentDay = ( dates ? date.getDate() : 0 );
17314
17315		inst.currentMonth = ( dates ? date.getMonth() : 0 );
17316
17317		inst.currentYear = ( dates ? date.getFullYear() : 0 );
17318
17319		this._adjustInstDate( inst );
17320
17321	},
17322
17323
17324
17325	/* Retrieve the default date shown on opening. */
17326
17327	_getDefaultDate: function( inst ) {
17328
17329		return this._restrictMinMax( inst,
17330
17331			this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) );
17332
17333	},
17334
17335
17336
17337	/* A date may be specified as an exact value or a relative one. */
17338
17339	_determineDate: function( inst, date, defaultDate ) {
17340
17341		var offsetNumeric = function( offset ) {
17342
17343				var date = new Date();
17344
17345				date.setDate( date.getDate() + offset );
17346
17347				return date;
17348
17349			},
17350
17351			offsetString = function( offset ) {
17352
17353				try {
17354
17355					return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
17356
17357						offset, $.datepicker._getFormatConfig( inst ) );
17358
17359				}
17360
17361				catch ( e ) {
17362
17363
17364
17365					// Ignore
17366
17367				}
17368
17369
17370
17371				var date = ( offset.toLowerCase().match( /^c/ ) ?
17372
17373					$.datepicker._getDate( inst ) : null ) || new Date(),
17374
17375					year = date.getFullYear(),
17376
17377					month = date.getMonth(),
17378
17379					day = date.getDate(),
17380
17381					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
17382
17383					matches = pattern.exec( offset );
17384
17385
17386
17387				while ( matches ) {
17388
17389					switch ( matches[ 2 ] || "d" ) {
17390
17391						case "d" : case "D" :
17392
17393							day += parseInt( matches[ 1 ], 10 ); break;
17394
17395						case "w" : case "W" :
17396
17397							day += parseInt( matches[ 1 ], 10 ) * 7; break;
17398
17399						case "m" : case "M" :
17400
17401							month += parseInt( matches[ 1 ], 10 );
17402
17403							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
17404
17405							break;
17406
17407						case "y": case "Y" :
17408
17409							year += parseInt( matches[ 1 ], 10 );
17410
17411							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
17412
17413							break;
17414
17415					}
17416
17417					matches = pattern.exec( offset );
17418
17419				}
17420
17421				return new Date( year, month, day );
17422
17423			},
17424
17425			newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) :
17426
17427				( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) );
17428
17429
17430
17431		newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate );
17432
17433		if ( newDate ) {
17434
17435			newDate.setHours( 0 );
17436
17437			newDate.setMinutes( 0 );
17438
17439			newDate.setSeconds( 0 );
17440
17441			newDate.setMilliseconds( 0 );
17442
17443		}
17444
17445		return this._daylightSavingAdjust( newDate );
17446
17447	},
17448
17449
17450
17451	/* Handle switch to/from daylight saving.
17452
17453	 * Hours may be non-zero on daylight saving cut-over:
17454
17455	 * > 12 when midnight changeover, but then cannot generate
17456
17457	 * midnight datetime, so jump to 1AM, otherwise reset.
vendor: 25,812 bytes, lines 17458-18551
17458
17459	 * @param  date  (Date) the date to check
17460
17461	 * @return  (Date) the corrected date
17462
17463	 */
17464
17465	_daylightSavingAdjust: function( date ) {
17466
17467		if ( !date ) {
17468
17469			return null;
17470
17471		}
17472
17473		date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 );
17474
17475		return date;
17476
17477	},
17478
17479
17480
17481	/* Set the date(s) directly. */
17482
17483	_setDate: function( inst, date, noChange ) {
17484
17485		var clear = !date,
17486
17487			origMonth = inst.selectedMonth,
17488
17489			origYear = inst.selectedYear,
17490
17491			newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) );
17492
17493
17494
17495		inst.selectedDay = inst.currentDay = newDate.getDate();
17496
17497		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
17498
17499		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
17500
17501		if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) {
17502
17503			this._notifyChange( inst );
17504
17505		}
17506
17507		this._adjustInstDate( inst );
17508
17509		if ( inst.input ) {
17510
17511			inst.input.val( clear ? "" : this._formatDate( inst ) );
17512
17513		}
17514
17515	},
17516
17517
17518
17519	/* Retrieve the date(s) directly. */
17520
17521	_getDate: function( inst ) {
17522
17523		var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null :
17524
17525			this._daylightSavingAdjust( new Date(
17526
17527			inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
17528
17529			return startDate;
17530
17531	},
17532
17533
17534
17535	/* Attach the onxxx handlers.  These are declared statically so
17536
17537	 * they work with static code transformers like Caja.
17538
17539	 */
17540
17541	_attachHandlers: function( inst ) {
17542
17543		var stepMonths = this._get( inst, "stepMonths" ),
17544
17545			id = "#" + inst.id.replace( /\\\\/g, "\\" );
17546
17547		inst.dpDiv.find( "[data-handler]" ).map( function() {
17548
17549			var handler = {
17550
17551				prev: function() {
17552
17553					$.datepicker._adjustDate( id, -stepMonths, "M" );
17554
17555				},
17556
17557				next: function() {
17558
17559					$.datepicker._adjustDate( id, +stepMonths, "M" );
17560
17561				},
17562
17563				hide: function() {
17564
17565					$.datepicker._hideDatepicker();
17566
17567				},
17568
17569				today: function() {
17570
17571					$.datepicker._gotoToday( id );
17572
17573				},
17574
17575				selectDay: function() {
17576
17577					$.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this );
17578
17579					return false;
17580
17581				},
17582
17583				selectMonth: function() {
17584
17585					$.datepicker._selectMonthYear( id, this, "M" );
17586
17587					return false;
17588
17589				},
17590
17591				selectYear: function() {
17592
17593					$.datepicker._selectMonthYear( id, this, "Y" );
17594
17595					return false;
17596
17597				}
17598
17599			};
17600
17601			$( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] );
17602
17603		} );
17604
17605	},
17606
17607
17608
17609	/* Generate the HTML for the current state of the date picker. */
17610
17611	_generateHTML: function( inst ) {
17612
17613		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
17614
17615			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
17616
17617			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
17618
17619			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
17620
17621			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
17622
17623			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
17624
17625			tempDate = new Date(),
17626
17627			today = this._daylightSavingAdjust(
17628
17629				new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time
17630
17631			isRTL = this._get( inst, "isRTL" ),
17632
17633			showButtonPanel = this._get( inst, "showButtonPanel" ),
17634
17635			hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ),
17636
17637			navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ),
17638
17639			numMonths = this._getNumberOfMonths( inst ),
17640
17641			showCurrentAtPos = this._get( inst, "showCurrentAtPos" ),
17642
17643			stepMonths = this._get( inst, "stepMonths" ),
17644
17645			isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ),
17646
17647			currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) :
17648
17649				new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ),
17650
17651			minDate = this._getMinMaxDate( inst, "min" ),
17652
17653			maxDate = this._getMinMaxDate( inst, "max" ),
17654
17655			drawMonth = inst.drawMonth - showCurrentAtPos,
17656
17657			drawYear = inst.drawYear;
17658
17659
17660
17661		if ( drawMonth < 0 ) {
17662
17663			drawMonth += 12;
17664
17665			drawYear--;
17666
17667		}
17668
17669		if ( maxDate ) {
17670
17671			maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(),
17672
17673				maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) );
17674
17675			maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw );
17676
17677			while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) {
17678
17679				drawMonth--;
17680
17681				if ( drawMonth < 0 ) {
17682
17683					drawMonth = 11;
17684
17685					drawYear--;
17686
17687				}
17688
17689			}
17690
17691		}
17692
17693		inst.drawMonth = drawMonth;
17694
17695		inst.drawYear = drawYear;
17696
17697
17698
17699		prevText = this._get( inst, "prevText" );
17700
17701		prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText,
17702
17703			this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ),
17704
17705			this._getFormatConfig( inst ) ) );
17706
17707
17708
17709		prev = ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ?
17710
17711			"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
17712
17713			" title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" :
17714
17715			( 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>" ) );
17716
17717
17718
17719		nextText = this._get( inst, "nextText" );
17720
17721		nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText,
17722
17723			this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ),
17724
17725			this._getFormatConfig( inst ) ) );
17726
17727
17728
17729		next = ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ?
17730
17731			"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
17732
17733			" title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" :
17734
17735			( 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>" ) );
17736
17737
17738
17739		currentText = this._get( inst, "currentText" );
17740
17741		gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today );
17742
17743		currentText = ( !navigationAsDateFormat ? currentText :
17744
17745			this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) );
17746
17747
17748
17749		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'>" +
17750
17751			this._get( inst, "closeText" ) + "</button>" : "" );
17752
17753
17754
17755		buttonPanel = ( showButtonPanel ) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + ( isRTL ? controls : "" ) +
17756
17757			( 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'" +
17758
17759			">" + currentText + "</button>" : "" ) + ( isRTL ? "" : controls ) + "</div>" : "";
17760
17761
17762
17763		firstDay = parseInt( this._get( inst, "firstDay" ), 10 );
17764
17765		firstDay = ( isNaN( firstDay ) ? 0 : firstDay );
17766
17767
17768
17769		showWeek = this._get( inst, "showWeek" );
17770
17771		dayNames = this._get( inst, "dayNames" );
17772
17773		dayNamesMin = this._get( inst, "dayNamesMin" );
17774
17775		monthNames = this._get( inst, "monthNames" );
17776
17777		monthNamesShort = this._get( inst, "monthNamesShort" );
17778
17779		beforeShowDay = this._get( inst, "beforeShowDay" );
17780
17781		showOtherMonths = this._get( inst, "showOtherMonths" );
17782
17783		selectOtherMonths = this._get( inst, "selectOtherMonths" );
17784
17785		defaultDate = this._getDefaultDate( inst );
17786
17787		html = "";
17788
17789
17790
17791		for ( row = 0; row < numMonths[ 0 ]; row++ ) {
17792
17793			group = "";
17794
17795			this.maxRows = 4;
17796
17797			for ( col = 0; col < numMonths[ 1 ]; col++ ) {
17798
17799				selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) );
17800
17801				cornerClass = " ui-corner-all";
17802
17803				calender = "";
17804
17805				if ( isMultiMonth ) {
17806
17807					calender += "<div class='ui-datepicker-group";
17808
17809					if ( numMonths[ 1 ] > 1 ) {
17810
17811						switch ( col ) {
17812
17813							case 0: calender += " ui-datepicker-group-first";
17814
17815								cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break;
17816
17817							case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last";
17818
17819								cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break;
17820
17821							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
17822
17823						}
17824
17825					}
17826
17827					calender += "'>";
17828
17829				}
17830
17831				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
17832
17833					( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) +
17834
17835					( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) +
17836
17837					this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate,
17838
17839					row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers
17840
17841					"</div><table class='ui-datepicker-calendar'><thead>" +
17842
17843					"<tr>";
17844
17845				thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" );
17846
17847				for ( dow = 0; dow < 7; dow++ ) { // days of the week
17848
17849					day = ( dow + firstDay ) % 7;
17850
17851					thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" +
17852
17853						"<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>";
17854
17855				}
17856
17857				calender += thead + "</tr></thead><tbody>";
17858
17859				daysInMonth = this._getDaysInMonth( drawYear, drawMonth );
17860
17861				if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) {
17862
17863					inst.selectedDay = Math.min( inst.selectedDay, daysInMonth );
17864
17865				}
17866
17867				leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7;
17868
17869				curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate
17870
17871				numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043)
17872
17873				this.maxRows = numRows;
17874
17875				printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) );
17876
17877				for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows
17878
17879					calender += "<tr>";
17880
17881					tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
17882
17883						this._get( inst, "calculateWeek" )( printDate ) + "</td>" );
17884
17885					for ( dow = 0; dow < 7; dow++ ) { // create date picker days
17886
17887						daySettings = ( beforeShowDay ?
17888
17889							beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] );
17890
17891						otherMonth = ( printDate.getMonth() !== drawMonth );
17892
17893						unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] ||
17894
17895							( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate );
17896
17897						tbody += "<td class='" +
17898
17899							( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends
17900
17901							( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months
17902
17903							( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key
17904
17905							( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ?
17906
17907
17908
17909							// or defaultDate is current printedDate and defaultDate is selectedDate
17910
17911							" " + this._dayOverClass : "" ) + // highlight selected day
17912
17913							( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) +  // highlight unselectable days
17914
17915							( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates
17916
17917							( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day
17918
17919							( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different)
17920
17921							( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "&#39;" ) + "'" : "" ) + // cell title
17922
17923							( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions
17924
17925							( otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
17926
17927							( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
17928
17929							( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) +
17930
17931							( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day
17932
17933							( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months
17934
17935							"' href='#'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date
17936
17937						printDate.setDate( printDate.getDate() + 1 );
17938
17939						printDate = this._daylightSavingAdjust( printDate );
17940
17941					}
17942
17943					calender += tbody + "</tr>";
17944
17945				}
17946
17947				drawMonth++;
17948
17949				if ( drawMonth > 11 ) {
17950
17951					drawMonth = 0;
17952
17953					drawYear++;
17954
17955				}
17956
17957				calender += "</tbody></table>" + ( isMultiMonth ? "</div>" +
17958
17959							( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" );
17960
17961				group += calender;
17962
17963			}
17964
17965			html += group;
17966
17967		}
17968
17969		html += buttonPanel;
17970
17971		inst._keyEvent = false;
17972
17973		return html;
17974
17975	},
17976
17977
17978
17979	/* Generate the month and year header. */
17980
17981	_generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate,
17982
17983			secondary, monthNames, monthNamesShort ) {
17984
17985
17986
17987		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
17988
17989			changeMonth = this._get( inst, "changeMonth" ),
17990
17991			changeYear = this._get( inst, "changeYear" ),
17992
17993			showMonthAfterYear = this._get( inst, "showMonthAfterYear" ),
17994
17995			html = "<div class='ui-datepicker-title'>",
17996
17997			monthHtml = "";
17998
17999
18000
18001		// Month selection
18002
18003		if ( secondary || !changeMonth ) {
18004
18005			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>";
18006
18007		} else {
18008
18009			inMinYear = ( minDate && minDate.getFullYear() === drawYear );
18010
18011			inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear );
18012
18013			monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
18014
18015			for ( month = 0; month < 12; month++ ) {
18016
18017				if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) {
18018
18019					monthHtml += "<option value='" + month + "'" +
18020
18021						( month === drawMonth ? " selected='selected'" : "" ) +
18022
18023						">" + monthNamesShort[ month ] + "</option>";
18024
18025				}
18026
18027			}
18028
18029			monthHtml += "</select>";
18030
18031		}
18032
18033
18034
18035		if ( !showMonthAfterYear ) {
18036
18037			html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" );
18038
18039		}
18040
18041
18042
18043		// Year selection
18044
18045		if ( !inst.yearshtml ) {
18046
18047			inst.yearshtml = "";
18048
18049			if ( secondary || !changeYear ) {
18050
18051				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
18052
18053			} else {
18054
18055
18056
18057				// determine range of years to display
18058
18059				years = this._get( inst, "yearRange" ).split( ":" );
18060
18061				thisYear = new Date().getFullYear();
18062
18063				determineYear = function( value ) {
18064
18065					var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) :
18066
18067						( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) :
18068
18069						parseInt( value, 10 ) ) );
18070
18071					return ( isNaN( year ) ? thisYear : year );
18072
18073				};
18074
18075				year = determineYear( years[ 0 ] );
18076
18077				endYear = Math.max( year, determineYear( years[ 1 ] || "" ) );
18078
18079				year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year );
18080
18081				endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear );
18082
18083				inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
18084
18085				for ( ; year <= endYear; year++ ) {
18086
18087					inst.yearshtml += "<option value='" + year + "'" +
18088
18089						( year === drawYear ? " selected='selected'" : "" ) +
18090
18091						">" + year + "</option>";
18092
18093				}
18094
18095				inst.yearshtml += "</select>";
18096
18097
18098
18099				html += inst.yearshtml;
18100
18101				inst.yearshtml = null;
18102
18103			}
18104
18105		}
18106
18107
18108
18109		html += this._get( inst, "yearSuffix" );
18110
18111		if ( showMonthAfterYear ) {
18112
18113			html += ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" ) + monthHtml;
18114
18115		}
18116
18117		html += "</div>"; // Close datepicker_header
18118
18119		return html;
18120
18121	},
18122
18123
18124
18125	/* Adjust one of the date sub-fields. */
18126
18127	_adjustInstDate: function( inst, offset, period ) {
18128
18129		var year = inst.selectedYear + ( period === "Y" ? offset : 0 ),
18130
18131			month = inst.selectedMonth + ( period === "M" ? offset : 0 ),
18132
18133			day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ),
18134
18135			date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) );
18136
18137
18138
18139		inst.selectedDay = date.getDate();
18140
18141		inst.drawMonth = inst.selectedMonth = date.getMonth();
18142
18143		inst.drawYear = inst.selectedYear = date.getFullYear();
18144
18145		if ( period === "M" || period === "Y" ) {
18146
18147			this._notifyChange( inst );
18148
18149		}
18150
18151	},
18152
18153
18154
18155	/* Ensure a date is within any min/max bounds. */
18156
18157	_restrictMinMax: function( inst, date ) {
18158
18159		var minDate = this._getMinMaxDate( inst, "min" ),
18160
18161			maxDate = this._getMinMaxDate( inst, "max" ),
18162
18163			newDate = ( minDate && date < minDate ? minDate : date );
18164
18165		return ( maxDate && newDate > maxDate ? maxDate : newDate );
18166
18167	},
18168
18169
18170
18171	/* Notify change of month/year. */
18172
18173	_notifyChange: function( inst ) {
18174
18175		var onChange = this._get( inst, "onChangeMonthYear" );
18176
18177		if ( onChange ) {
18178
18179			onChange.apply( ( inst.input ? inst.input[ 0 ] : null ),
18180
18181				[ inst.selectedYear, inst.selectedMonth + 1, inst ] );
18182
18183		}
18184
18185	},
18186
18187
18188
18189	/* Determine the number of months to show. */
18190
18191	_getNumberOfMonths: function( inst ) {
18192
18193		var numMonths = this._get( inst, "numberOfMonths" );
18194
18195		return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) );
18196
18197	},
18198
18199
18200
18201	/* Determine the current maximum date - ensure no time components are set. */
18202
18203	_getMinMaxDate: function( inst, minMax ) {
18204
18205		return this._determineDate( inst, this._get( inst, minMax + "Date" ), null );
18206
18207	},
18208
18209
18210
18211	/* Find the number of days in a given month. */
18212
18213	_getDaysInMonth: function( year, month ) {
18214
18215		return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate();
18216
18217	},
18218
18219
18220
18221	/* Find the day of the week of the first of a month. */
18222
18223	_getFirstDayOfMonth: function( year, month ) {
18224
18225		return new Date( year, month, 1 ).getDay();
18226
18227	},
18228
18229
18230
18231	/* Determines if we should allow a "next/prev" month display change. */
18232
18233	_canAdjustMonth: function( inst, offset, curYear, curMonth ) {
18234
18235		var numMonths = this._getNumberOfMonths( inst ),
18236
18237			date = this._daylightSavingAdjust( new Date( curYear,
18238
18239			curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) );
18240
18241
18242
18243		if ( offset < 0 ) {
18244
18245			date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) );
18246
18247		}
18248
18249		return this._isInRange( inst, date );
18250
18251	},
18252
18253
18254
18255	/* Is the given date in the accepted range? */
18256
18257	_isInRange: function( inst, date ) {
18258
18259		var yearSplit, currentYear,
18260
18261			minDate = this._getMinMaxDate( inst, "min" ),
18262
18263			maxDate = this._getMinMaxDate( inst, "max" ),
18264
18265			minYear = null,
18266
18267			maxYear = null,
18268
18269			years = this._get( inst, "yearRange" );
18270
18271			if ( years ) {
18272
18273				yearSplit = years.split( ":" );
18274
18275				currentYear = new Date().getFullYear();
18276
18277				minYear = parseInt( yearSplit[ 0 ], 10 );
18278
18279				maxYear = parseInt( yearSplit[ 1 ], 10 );
18280
18281				if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) {
18282
18283					minYear += currentYear;
18284
18285				}
18286
18287				if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) {
18288
18289					maxYear += currentYear;
18290
18291				}
18292
18293			}
18294
18295
18296
18297		return ( ( !minDate || date.getTime() >= minDate.getTime() ) &&
18298
18299			( !maxDate || date.getTime() <= maxDate.getTime() ) &&
18300
18301			( !minYear || date.getFullYear() >= minYear ) &&
18302
18303			( !maxYear || date.getFullYear() <= maxYear ) );
18304
18305	},
18306
18307
18308
18309	/* Provide the configuration settings for formatting/parsing. */
18310
18311	_getFormatConfig: function( inst ) {
18312
18313		var shortYearCutoff = this._get( inst, "shortYearCutoff" );
18314
18315		shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff :
18316
18317			new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) );
18318
18319		return { shortYearCutoff: shortYearCutoff,
18320
18321			dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ),
18322
18323			monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) };
18324
18325	},
18326
18327
18328
18329	/* Format the given date for display. */
18330
18331	_formatDate: function( inst, day, month, year ) {
18332
18333		if ( !day ) {
18334
18335			inst.currentDay = inst.selectedDay;
18336
18337			inst.currentMonth = inst.selectedMonth;
18338
18339			inst.currentYear = inst.selectedYear;
18340
18341		}
18342
18343		var date = ( day ? ( typeof day === "object" ? day :
18344
18345			this._daylightSavingAdjust( new Date( year, month, day ) ) ) :
18346
18347			this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
18348
18349		return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) );
18350
18351	}
18352
18353} );
18354
18355
18356
18357/*
18358
18359 * Bind hover events for datepicker elements.
18360
18361 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
18362
18363 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
18364
18365 */
18366
18367function datepicker_bindHover( dpDiv ) {
18368
18369	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
18370
18371	return dpDiv.on( "mouseout", selector, function() {
18372
18373			$( this ).removeClass( "ui-state-hover" );
18374
18375			if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
18376
18377				$( this ).removeClass( "ui-datepicker-prev-hover" );
18378
18379			}
18380
18381			if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
18382
18383				$( this ).removeClass( "ui-datepicker-next-hover" );
18384
18385			}
18386
18387		} )
18388
18389		.on( "mouseover", selector, datepicker_handleMouseover );
18390
18391}
18392
18393
18394
18395function datepicker_handleMouseover() {
18396
18397	if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) {
18398
18399		$( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" );
18400
18401		$( this ).addClass( "ui-state-hover" );
18402
18403		if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
18404
18405			$( this ).addClass( "ui-datepicker-prev-hover" );
18406
18407		}
18408
18409		if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
18410
18411			$( this ).addClass( "ui-datepicker-next-hover" );
18412
18413		}
18414
18415	}
18416
18417}
18418
18419
18420
18421/* jQuery extend now ignores nulls! */
18422
18423function datepicker_extendRemove( target, props ) {
18424
18425	$.extend( target, props );
18426
18427	for ( var name in props ) {
18428
18429		if ( props[ name ] == null ) {
18430
18431			target[ name ] = props[ name ];
18432
18433		}
18434
18435	}
18436
18437	return target;
18438
18439}
18440
18441
18442
18443/* Invoke the datepicker functionality.
18444
18445   @param  options  string - a command, optionally followed by additional parameters or
18446
18447					Object - settings for attaching new datepicker functionality
18448
18449   @return  jQuery object */
18450
18451$.fn.datepicker = function( options ) {
18452
18453
18454
18455	/* Verify an empty collection wasn't passed - Fixes #6976 */
18456
18457	if ( !this.length ) {
18458
18459		return this;
18460
18461	}
18462
18463
18464
18465	/* Initialise the date picker. */
18466
18467	if ( !$.datepicker.initialized ) {
18468
18469		$( document ).on( "mousedown", $.datepicker._checkExternalClick );
18470
18471		$.datepicker.initialized = true;
18472
18473	}
18474
18475
18476
18477	/* Append datepicker main container to body if not exist. */
18478
18479	if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) {
18480
18481		$( "body" ).append( $.datepicker.dpDiv );
18482
18483	}
18484
18485
18486
18487	var otherArgs = Array.prototype.slice.call( arguments, 1 );
18488
18489	if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) {
18490
18491		return $.datepicker[ "_" + options + "Datepicker" ].
18492
18493			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
18494
18495	}
18496
18497	if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) {
18498
18499		return $.datepicker[ "_" + options + "Datepicker" ].
18500
18501			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
18502
18503	}
18504
18505	return this.each( function() {
18506
18507		typeof options === "string" ?
18508
18509			$.datepicker[ "_" + options + "Datepicker" ].
18510
18511				apply( $.datepicker, [ this ].concat( otherArgs ) ) :
18512
18513			$.datepicker._attachDatepicker( this, options );
18514
18515	} );
18516
18517};
18518
18519
18520
18521$.datepicker = new Datepicker(); // singleton instance
18522
18523$.datepicker.initialized = false;
18524
18525$.datepicker.uuid = new Date().getTime();
18526
18527$.datepicker.version = "1.12.1";
18528
18529
18530
18531var widgetsDatepicker = $.datepicker;
18532
18533
18534
18535
18536
18537
18538
18539
18540
18541// This file is deprecated
18542
18543var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
18544
18545
18546
18547/*!
18548
18549 * jQuery UI Mouse 1.12.1
18550
18551 * http://jqueryui.com
vendor: 4,203 bytes, lines 18552-18818
18552
18553 *
18554
18555 * Copyright jQuery Foundation and other contributors
18556
18557 * Released under the MIT license.
18558
18559 * http://jquery.org/license
18560
18561 */
18562
18563
18564
18565//>>label: Mouse
18566
18567//>>group: Widgets
18568
18569//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
18570
18571//>>docs: http://api.jqueryui.com/mouse/
18572
18573
18574
18575
18576
18577
18578
18579var mouseHandled = false;
18580
18581$( document ).on( "mouseup", function() {
18582
18583	mouseHandled = false;
18584
18585} );
18586
18587
18588
18589var widgetsMouse = $.widget( "ui.mouse", {
18590
18591	version: "1.12.1",
18592
18593	options: {
18594
18595		cancel: "input, textarea, button, select, option",
18596
18597		distance: 1,
18598
18599		delay: 0
18600
18601	},
18602
18603	_mouseInit: function() {
18604
18605		var that = this;
18606
18607
18608
18609		this.element
18610
18611			.on( "mousedown." + this.widgetName, function( event ) {
18612
18613				return that._mouseDown( event );
18614
18615			} )
18616
18617			.on( "click." + this.widgetName, function( event ) {
18618
18619				if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
18620
18621					$.removeData( event.target, that.widgetName + ".preventClickEvent" );
18622
18623					event.stopImmediatePropagation();
18624
18625					return false;
18626
18627				}
18628
18629			} );
18630
18631
18632
18633		this.started = false;
18634
18635	},
18636
18637
18638
18639	// TODO: make sure destroying one instance of mouse doesn't mess with
18640
18641	// other instances of mouse
18642
18643	_mouseDestroy: function() {
18644
18645		this.element.off( "." + this.widgetName );
18646
18647		if ( this._mouseMoveDelegate ) {
18648
18649			this.document
18650
18651				.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
18652
18653				.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
18654
18655		}
18656
18657	},
18658
18659
18660
18661	_mouseDown: function( event ) {
18662
18663
18664
18665		// don't let more than one widget handle mouseStart
18666
18667		if ( mouseHandled ) {
18668
18669			return;
18670
18671		}
18672
18673
18674
18675		this._mouseMoved = false;
18676
18677
18678
18679		// We may have missed mouseup (out of window)
18680
18681		( this._mouseStarted && this._mouseUp( event ) );
18682
18683
18684
18685		this._mouseDownEvent = event;
18686
18687
18688
18689		var that = this,
18690
18691			btnIsLeft = ( event.which === 1 ),
18692
18693
18694
18695			// event.target.nodeName works around a bug in IE 8 with
18696
18697			// disabled inputs (#7620)
18698
18699			elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
18700
18701				$( event.target ).closest( this.options.cancel ).length : false );
18702
18703		if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
18704
18705			return true;
18706
18707		}
18708
18709
18710
18711		this.mouseDelayMet = !this.options.delay;
18712
18713		if ( !this.mouseDelayMet ) {
18714
18715			this._mouseDelayTimer = setTimeout( function() {
18716
18717				that.mouseDelayMet = true;
18718
18719			}, this.options.delay );
18720
18721		}
18722
18723
18724
18725		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
18726
18727			this._mouseStarted = ( this._mouseStart( event ) !== false );
18728
18729			if ( !this._mouseStarted ) {
18730
18731				event.preventDefault();
18732
18733				return true;
18734
18735			}
18736
18737		}
18738
18739
18740
18741		// Click event may never have fired (Gecko & Opera)
18742
18743		if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
18744
18745			$.removeData( event.target, this.widgetName + ".preventClickEvent" );
18746
18747		}
18748
18749
18750
18751		// These delegates are required to keep context
18752
18753		this._mouseMoveDelegate = function( event ) {
18754
18755			return that._mouseMove( event );
18756
18757		};
18758
18759		this._mouseUpDelegate = function( event ) {
18760
18761			return that._mouseUp( event );
18762
18763		};
18764
18765
18766
18767		this.document
18768
18769			.on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
18770
18771			.on( "mouseup." + this.widgetName, this._mouseUpDelegate );
18772
18773
18774
18775		event.preventDefault();
18776
18777
18778
18779		mouseHandled = true;
18780
18781		return true;
18782
18783	},
18784
18785
18786
18787	_mouseMove: function( event ) {
18788
18789
18790
18791		// Only check for mouseups outside the document if you've moved inside the document
18792
18793		// at least once. This prevents the firing of mouseup in the case of IE<9, which will
18794
18795		// fire a mousemove event if content is placed under the cursor. See #7778
18796
18797		// Support: IE <9
18798
18799		if ( this._mouseMoved ) {
18800
18801
18802
18803			// IE mouseup check - mouseup happened when mouse was out of window
18804
18805			if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
18806
18807					!event.button ) {
18808
18809				return this._mouseUp( event );
18810
18811
18812
18813			// Iframe mouseup check - mouseup occurred in another document
18814
18815			} else if ( !event.which ) {
18816
18817
18818
vendor: 16,038 bytes, lines 18819-19916
18819				// Support: Safari <=8 - 9
18820
18821				// Safari sets which to 0 if you press any of the following keys
18822
18823				// during a drag (#14461)
18824
18825				if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
18826
18827						event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
18828
18829					this.ignoreMissingWhich = true;
18830
18831				} else if ( !this.ignoreMissingWhich ) {
18832
18833					return this._mouseUp( event );
18834
18835				}
18836
18837			}
18838
18839		}
18840
18841
18842
18843		if ( event.which || event.button ) {
18844
18845			this._mouseMoved = true;
18846
18847		}
18848
18849
18850
18851		if ( this._mouseStarted ) {
18852
18853			this._mouseDrag( event );
18854
18855			return event.preventDefault();
18856
18857		}
18858
18859
18860
18861		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
18862
18863			this._mouseStarted =
18864
18865				( this._mouseStart( this._mouseDownEvent, event ) !== false );
18866
18867			( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) );
18868
18869		}
18870
18871
18872
18873		return !this._mouseStarted;
18874
18875	},
18876
18877
18878
18879	_mouseUp: function( event ) {
18880
18881		this.document
18882
18883			.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
18884
18885			.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
18886
18887
18888
18889		if ( this._mouseStarted ) {
18890
18891			this._mouseStarted = false;
18892
18893
18894
18895			if ( event.target === this._mouseDownEvent.target ) {
18896
18897				$.data( event.target, this.widgetName + ".preventClickEvent", true );
18898
18899			}
18900
18901
18902
18903			this._mouseStop( event );
18904
18905		}
18906
18907
18908
18909		if ( this._mouseDelayTimer ) {
18910
18911			clearTimeout( this._mouseDelayTimer );
18912
18913			delete this._mouseDelayTimer;
18914
18915		}
18916
18917
18918
18919		this.ignoreMissingWhich = false;
18920
18921		mouseHandled = false;
18922
18923		event.preventDefault();
18924
18925	},
18926
18927
18928
18929	_mouseDistanceMet: function( event ) {
18930
18931		return ( Math.max(
18932
18933				Math.abs( this._mouseDownEvent.pageX - event.pageX ),
18934
18935				Math.abs( this._mouseDownEvent.pageY - event.pageY )
18936
18937			) >= this.options.distance
18938
18939		);
18940
18941	},
18942
18943
18944
18945	_mouseDelayMet: function( /* event */ ) {
18946
18947		return this.mouseDelayMet;
18948
18949	},
18950
18951
18952
18953	// These are placeholder methods, to be overriden by extending plugin
18954
18955	_mouseStart: function( /* event */ ) {},
18956
18957	_mouseDrag: function( /* event */ ) {},
18958
18959	_mouseStop: function( /* event */ ) {},
18960
18961	_mouseCapture: function( /* event */ ) { return true; }
18962
18963} );
18964
18965
18966
18967
18968
18969
18970
18971
18972
18973// $.ui.plugin is deprecated. Use $.widget() extensions instead.
18974
18975var plugin = $.ui.plugin = {
18976
18977	add: function( module, option, set ) {
18978
18979		var i,
18980
18981			proto = $.ui[ module ].prototype;
18982
18983		for ( i in set ) {
18984
18985			proto.plugins[ i ] = proto.plugins[ i ] || [];
18986
18987			proto.plugins[ i ].push( [ option, set[ i ] ] );
18988
18989		}
18990
18991	},
18992
18993	call: function( instance, name, args, allowDisconnected ) {
18994
18995		var i,
18996
18997			set = instance.plugins[ name ];
18998
18999
19000
19001		if ( !set ) {
19002
19003			return;
19004
19005		}
19006
19007
19008
19009		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
19010
19011				instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
19012
19013			return;
19014
19015		}
19016
19017
19018
19019		for ( i = 0; i < set.length; i++ ) {
19020
19021			if ( instance.options[ set[ i ][ 0 ] ] ) {
19022
19023				set[ i ][ 1 ].apply( instance.element, args );
19024
19025			}
19026
19027		}
19028
19029	}
19030
19031};
19032
19033
19034
19035
19036
19037
19038
19039var safeBlur = $.ui.safeBlur = function( element ) {
19040
19041
19042
19043	// Support: IE9 - 10 only
19044
19045	// If the <body> is blurred, IE will switch windows, see #9420
19046
19047	if ( element && element.nodeName.toLowerCase() !== "body" ) {
19048
19049		$( element ).trigger( "blur" );
19050
19051	}
19052
19053};
19054
19055
19056
19057
19058
19059/*!
19060
19061 * jQuery UI Draggable 1.12.1
19062
19063 * http://jqueryui.com
19064
19065 *
19066
19067 * Copyright jQuery Foundation and other contributors
19068
19069 * Released under the MIT license.
19070
19071 * http://jquery.org/license
19072
19073 */
19074
19075
19076
19077//>>label: Draggable
19078
19079//>>group: Interactions
19080
19081//>>description: Enables dragging functionality for any element.
19082
19083//>>docs: http://api.jqueryui.com/draggable/
19084
19085//>>demos: http://jqueryui.com/draggable/
19086
19087//>>css.structure: ../../themes/base/draggable.css
19088
19089
19090
19091
19092
19093
19094
19095$.widget( "ui.draggable", $.ui.mouse, {
19096
19097	version: "1.12.1",
19098
19099	widgetEventPrefix: "drag",
19100
19101	options: {
19102
19103		addClasses: true,
19104
19105		appendTo: "parent",
19106
19107		axis: false,
19108
19109		connectToSortable: false,
19110
19111		containment: false,
19112
19113		cursor: "auto",
19114
19115		cursorAt: false,
19116
19117		grid: false,
19118
19119		handle: false,
19120
19121		helper: "original",
19122
19123		iframeFix: false,
19124
19125		opacity: false,
19126
19127		refreshPositions: false,
19128
19129		revert: false,
19130
19131		revertDuration: 500,
19132
19133		scope: "default",
19134
19135		scroll: true,
19136
19137		scrollSensitivity: 20,
19138
19139		scrollSpeed: 20,
19140
19141		snap: false,
19142
19143		snapMode: "both",
19144
19145		snapTolerance: 20,
19146
19147		stack: false,
19148
19149		zIndex: false,
19150
19151
19152
19153		// Callbacks
19154
19155		drag: null,
19156
19157		start: null,
19158
19159		stop: null
19160
19161	},
19162
19163	_create: function() {
19164
19165
19166
19167		if ( this.options.helper === "original" ) {
19168
19169			this._setPositionRelative();
19170
19171		}
19172
19173		if ( this.options.addClasses ) {
19174
19175			this._addClass( "ui-draggable" );
19176
19177		}
19178
19179		this._setHandleClassName();
19180
19181
19182
19183		this._mouseInit();
19184
19185	},
19186
19187
19188
19189	_setOption: function( key, value ) {
19190
19191		this._super( key, value );
19192
19193		if ( key === "handle" ) {
19194
19195			this._removeHandleClassName();
19196
19197			this._setHandleClassName();
19198
19199		}
19200
19201	},
19202
19203
19204
19205	_destroy: function() {
19206
19207		if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
19208
19209			this.destroyOnClear = true;
19210
19211			return;
19212
19213		}
19214
19215		this._removeHandleClassName();
19216
19217		this._mouseDestroy();
19218
19219	},
19220
19221
19222
19223	_mouseCapture: function( event ) {
19224
19225		var o = this.options;
19226
19227
19228
19229		// Among others, prevent a drag on a resizable-handle
19230
19231		if ( this.helper || o.disabled ||
19232
19233				$( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
19234
19235			return false;
19236
19237		}
19238
19239
19240
19241		//Quit if we're not on a valid handle
19242
19243		this.handle = this._getHandle( event );
19244
19245		if ( !this.handle ) {
19246
19247			return false;
19248
19249		}
19250
19251
19252
19253		this._blurActiveElement( event );
19254
19255
19256
19257		this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
19258
19259
19260
19261		return true;
19262
19263
19264
19265	},
19266
19267
19268
19269	_blockFrames: function( selector ) {
19270
19271		this.iframeBlocks = this.document.find( selector ).map( function() {
19272
19273			var iframe = $( this );
19274
19275
19276
19277			return $( "<div>" )
19278
19279				.css( "position", "absolute" )
19280
19281				.appendTo( iframe.parent() )
19282
19283				.outerWidth( iframe.outerWidth() )
19284
19285				.outerHeight( iframe.outerHeight() )
19286
19287				.offset( iframe.offset() )[ 0 ];
19288
19289		} );
19290
19291	},
19292
19293
19294
19295	_unblockFrames: function() {
19296
19297		if ( this.iframeBlocks ) {
19298
19299			this.iframeBlocks.remove();
19300
19301			delete this.iframeBlocks;
19302
19303		}
19304
19305	},
19306
19307
19308
19309	_blurActiveElement: function( event ) {
19310
19311		var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
19312
19313			target = $( event.target );
19314
19315
19316
19317		// Don't blur if the event occurred on an element that is within
19318
19319		// the currently focused element
19320
19321		// See #10527, #12472
19322
19323		if ( target.closest( activeElement ).length ) {
19324
19325			return;
19326
19327		}
19328
19329
19330
19331		// Blur any element that currently has focus, see #4261
19332
19333		$.ui.safeBlur( activeElement );
19334
19335	},
19336
19337
19338
19339	_mouseStart: function( event ) {
19340
19341
19342
19343		var o = this.options;
19344
19345
19346
19347		//Create and append the visible helper
19348
19349		this.helper = this._createHelper( event );
19350
19351
19352
19353		this._addClass( this.helper, "ui-draggable-dragging" );
19354
19355
19356
19357		//Cache the helper size
19358
19359		this._cacheHelperProportions();
19360
19361
19362
19363		//If ddmanager is used for droppables, set the global draggable
19364
19365		if ( $.ui.ddmanager ) {
19366
19367			$.ui.ddmanager.current = this;
19368
19369		}
19370
19371
19372
19373		/*
19374
19375		 * - Position generation -
19376
19377		 * This block generates everything position related - it's the core of draggables.
19378
19379		 */
19380
19381
19382
19383		//Cache the margins of the original element
19384
19385		this._cacheMargins();
19386
19387
19388
19389		//Store the helper's css position
19390
19391		this.cssPosition = this.helper.css( "position" );
19392
19393		this.scrollParent = this.helper.scrollParent( true );
19394
19395		this.offsetParent = this.helper.offsetParent();
19396
19397		this.hasFixedAncestor = this.helper.parents().filter( function() {
19398
19399				return $( this ).css( "position" ) === "fixed";
19400
19401			} ).length > 0;
19402
19403
19404
19405		//The element's absolute position on the page minus margins
19406
19407		this.positionAbs = this.element.offset();
19408
19409		this._refreshOffsets( event );
19410
19411
19412
19413		//Generate the original position
19414
19415		this.originalPosition = this.position = this._generatePosition( event, false );
19416
19417		this.originalPageX = event.pageX;
19418
19419		this.originalPageY = event.pageY;
19420
19421
19422
19423		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
19424
19425		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
19426
19427
19428
19429		//Set a containment if given in the options
19430
19431		this._setContainment();
19432
19433
19434
19435		//Trigger event + callbacks
19436
19437		if ( this._trigger( "start", event ) === false ) {
19438
19439			this._clear();
19440
19441			return false;
19442
19443		}
19444
19445
19446
19447		//Recache the helper size
19448
19449		this._cacheHelperProportions();
19450
19451
19452
19453		//Prepare the droppable offsets
19454
19455		if ( $.ui.ddmanager && !o.dropBehaviour ) {
19456
19457			$.ui.ddmanager.prepareOffsets( this, event );
19458
19459		}
19460
19461
19462
19463		// Execute the drag once - this causes the helper not to be visible before getting its
19464
19465		// correct position
19466
19467		this._mouseDrag( event, true );
19468
19469
19470
19471		// If the ddmanager is used for droppables, inform the manager that dragging has started
19472
19473		// (see #5003)
19474
19475		if ( $.ui.ddmanager ) {
19476
19477			$.ui.ddmanager.dragStart( this, event );
19478
19479		}
19480
19481
19482
19483		return true;
19484
19485	},
19486
19487
19488
19489	_refreshOffsets: function( event ) {
19490
19491		this.offset = {
19492
19493			top: this.positionAbs.top - this.margins.top,
19494
19495			left: this.positionAbs.left - this.margins.left,
19496
19497			scroll: false,
19498
19499			parent: this._getParentOffset(),
19500
19501			relative: this._getRelativeOffset()
19502
19503		};
19504
19505
19506
19507		this.offset.click = {
19508
19509			left: event.pageX - this.offset.left,
19510
19511			top: event.pageY - this.offset.top
19512
19513		};
19514
19515	},
19516
19517
19518
19519	_mouseDrag: function( event, noPropagation ) {
19520
19521
19522
19523		// reset any necessary cached properties (see #5009)
19524
19525		if ( this.hasFixedAncestor ) {
19526
19527			this.offset.parent = this._getParentOffset();
19528
19529		}
19530
19531
19532
19533		//Compute the helpers position
19534
19535		this.position = this._generatePosition( event, true );
19536
19537		this.positionAbs = this._convertPositionTo( "absolute" );
19538
19539
19540
19541		//Call plugins and callbacks and use the resulting position if something is returned
19542
19543		if ( !noPropagation ) {
19544
19545			var ui = this._uiHash();
19546
19547			if ( this._trigger( "drag", event, ui ) === false ) {
19548
19549				this._mouseUp( new $.Event( "mouseup", event ) );
19550
19551				return false;
19552
19553			}
19554
19555			this.position = ui.position;
19556
19557		}
19558
19559
19560
19561		this.helper[ 0 ].style.left = this.position.left + "px";
19562
19563		this.helper[ 0 ].style.top = this.position.top + "px";
19564
19565
19566
19567		if ( $.ui.ddmanager ) {
19568
19569			$.ui.ddmanager.drag( this, event );
19570
19571		}
19572
19573
19574
19575		return false;
19576
19577	},
19578
19579
19580
19581	_mouseStop: function( event ) {
19582
19583
19584
19585		//If we are using droppables, inform the manager about the drop
19586
19587		var that = this,
19588
19589			dropped = false;
19590
19591		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
19592
19593			dropped = $.ui.ddmanager.drop( this, event );
19594
19595		}
19596
19597
19598
19599		//if a drop comes from outside (a sortable)
19600
19601		if ( this.dropped ) {
19602
19603			dropped = this.dropped;
19604
19605			this.dropped = false;
19606
19607		}
19608
19609
19610
19611		if ( ( this.options.revert === "invalid" && !dropped ) ||
19612
19613				( this.options.revert === "valid" && dropped ) ||
19614
19615				this.options.revert === true || ( $.isFunction( this.options.revert ) &&
19616
19617				this.options.revert.call( this.element, dropped ) )
19618
19619		) {
19620
19621			$( this.helper ).animate(
19622
19623				this.originalPosition,
19624
19625				parseInt( this.options.revertDuration, 10 ),
19626
19627				function() {
19628
19629					if ( that._trigger( "stop", event ) !== false ) {
19630
19631						that._clear();
19632
19633					}
19634
19635				}
19636
19637			);
19638
19639		} else {
19640
19641			if ( this._trigger( "stop", event ) !== false ) {
19642
19643				this._clear();
19644
19645			}
19646
19647		}
19648
19649
19650
19651		return false;
19652
19653	},
19654
19655
19656
19657	_mouseUp: function( event ) {
19658
19659		this._unblockFrames();
19660
19661
19662
19663		// If the ddmanager is used for droppables, inform the manager that dragging has stopped
19664
19665		// (see #5003)
19666
19667		if ( $.ui.ddmanager ) {
19668
19669			$.ui.ddmanager.dragStop( this, event );
19670
19671		}
19672
19673
19674
19675		// Only need to focus if the event occurred on the draggable itself, see #10527
19676
19677		if ( this.handleElement.is( event.target ) ) {
19678
19679
19680
19681			// The interaction is over; whether or not the click resulted in a drag,
19682
19683			// focus the element
19684
19685			this.element.trigger( "focus" );
19686
19687		}
19688
19689
19690
19691		return $.ui.mouse.prototype._mouseUp.call( this, event );
19692
19693	},
19694
19695
19696
19697	cancel: function() {
19698
19699
19700
19701		if ( this.helper.is( ".ui-draggable-dragging" ) ) {
19702
19703			this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
19704
19705		} else {
19706
19707			this._clear();
19708
19709		}
19710
19711
19712
19713		return this;
19714
19715
19716
19717	},
19718
19719
19720
19721	_getHandle: function( event ) {
19722
19723		return this.options.handle ?
19724
19725			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
19726
19727			true;
19728
19729	},
19730
19731
19732
19733	_setHandleClassName: function() {
19734
19735		this.handleElement = this.options.handle ?
19736
19737			this.element.find( this.options.handle ) : this.element;
19738
19739		this._addClass( this.handleElement, "ui-draggable-handle" );
19740
19741	},
19742
19743
19744
19745	_removeHandleClassName: function() {
19746
19747		this._removeClass( this.handleElement, "ui-draggable-handle" );
19748
19749	},
19750
19751
19752
19753	_createHelper: function( event ) {
19754
19755
19756
19757		var o = this.options,
19758
19759			helperIsFunction = $.isFunction( o.helper ),
19760
19761			helper = helperIsFunction ?
19762
19763				$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
19764
19765				( o.helper === "clone" ?
19766
19767					this.element.clone().removeAttr( "id" ) :
19768
19769					this.element );
19770
19771
19772
19773		if ( !helper.parents( "body" ).length ) {
19774
19775			helper.appendTo( ( o.appendTo === "parent" ?
19776
19777				this.element[ 0 ].parentNode :
19778
19779				o.appendTo ) );
19780
19781		}
19782
19783
19784
19785		// Http://bugs.jqueryui.com/ticket/9446
19786
19787		// a helper function can return the original element
19788
19789		// which wouldn't have been set to relative in _create
19790
19791		if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
19792
19793			this._setPositionRelative();
19794
19795		}
19796
19797
19798
19799		if ( helper[ 0 ] !== this.element[ 0 ] &&
19800
19801				!( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
19802
19803			helper.css( "position", "absolute" );
19804
19805		}
19806
19807
19808
19809		return helper;
19810
19811
19812
19813	},
19814
19815
19816
19817	_setPositionRelative: function() {
19818
19819		if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
19820
19821			this.element[ 0 ].style.position = "relative";
19822
19823		}
19824
19825	},
19826
19827
19828
19829	_adjustOffsetFromHelper: function( obj ) {
19830
19831		if ( typeof obj === "string" ) {
19832
19833			obj = obj.split( " " );
19834
19835		}
19836
19837		if ( $.isArray( obj ) ) {
19838
19839			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
19840
19841		}
19842
19843		if ( "left" in obj ) {
19844
19845			this.offset.click.left = obj.left + this.margins.left;
19846
19847		}
19848
19849		if ( "right" in obj ) {
19850
19851			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
19852
19853		}
19854
19855		if ( "top" in obj ) {
19856
19857			this.offset.click.top = obj.top + this.margins.top;
19858
19859		}
19860
19861		if ( "bottom" in obj ) {
19862
19863			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
19864
19865		}
19866
19867	},
19868
19869
19870
19871	_isRootNode: function( element ) {
19872
19873		return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
19874
19875	},
19876
19877
19878
19879	_getParentOffset: function() {
19880
19881
19882
19883		//Get the offsetParent and cache its position
19884
19885		var po = this.offsetParent.offset(),
19886
19887			document = this.document[ 0 ];
19888
19889
19890
19891		// This is a special case where we need to modify a offset calculated on start, since the
19892
19893		// following happened:
19894
19895		// 1. The position of the helper is absolute, so it's position is calculated based on the
19896
19897		// next positioned parent
19898
19899		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
19900
19901		// the document, which means that the scroll is included in the initial calculation of the
19902
19903		// offset of the parent, and never recalculated upon drag
19904
19905		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
19906
19907				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
19908
19909			po.left += this.scrollParent.scrollLeft();
19910
19911			po.top += this.scrollParent.scrollTop();
19912
19913		}
19914
19915
19916
vendor: 14,014 bytes, lines 19917-20774
19917		if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
19918
19919			po = { top: 0, left: 0 };
19920
19921		}
19922
19923
19924
19925		return {
19926
19927			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
19928
19929			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
19930
19931		};
19932
19933
19934
19935	},
19936
19937
19938
19939	_getRelativeOffset: function() {
19940
19941		if ( this.cssPosition !== "relative" ) {
19942
19943			return { top: 0, left: 0 };
19944
19945		}
19946
19947
19948
19949		var p = this.element.position(),
19950
19951			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
19952
19953
19954
19955		return {
19956
19957			top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
19958
19959				( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
19960
19961			left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
19962
19963				( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
19964
19965		};
19966
19967
19968
19969	},
19970
19971
19972
19973	_cacheMargins: function() {
19974
19975		this.margins = {
19976
19977			left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
19978
19979			top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
19980
19981			right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
19982
19983			bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
19984
19985		};
19986
19987	},
19988
19989
19990
19991	_cacheHelperProportions: function() {
19992
19993		this.helperProportions = {
19994
19995			width: this.helper.outerWidth(),
19996
19997			height: this.helper.outerHeight()
19998
19999		};
20000
20001	},
20002
20003
20004
20005	_setContainment: function() {
20006
20007
20008
20009		var isUserScrollable, c, ce,
20010
20011			o = this.options,
20012
20013			document = this.document[ 0 ];
20014
20015
20016
20017		this.relativeContainer = null;
20018
20019
20020
20021		if ( !o.containment ) {
20022
20023			this.containment = null;
20024
20025			return;
20026
20027		}
20028
20029
20030
20031		if ( o.containment === "window" ) {
20032
20033			this.containment = [
20034
20035				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
20036
20037				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
20038
20039				$( window ).scrollLeft() + $( window ).width() -
20040
20041					this.helperProportions.width - this.margins.left,
20042
20043				$( window ).scrollTop() +
20044
20045					( $( window ).height() || document.body.parentNode.scrollHeight ) -
20046
20047					this.helperProportions.height - this.margins.top
20048
20049			];
20050
20051			return;
20052
20053		}
20054
20055
20056
20057		if ( o.containment === "document" ) {
20058
20059			this.containment = [
20060
20061				0,
20062
20063				0,
20064
20065				$( document ).width() - this.helperProportions.width - this.margins.left,
20066
20067				( $( document ).height() || document.body.parentNode.scrollHeight ) -
20068
20069					this.helperProportions.height - this.margins.top
20070
20071			];
20072
20073			return;
20074
20075		}
20076
20077
20078
20079		if ( o.containment.constructor === Array ) {
20080
20081			this.containment = o.containment;
20082
20083			return;
20084
20085		}
20086
20087
20088
20089		if ( o.containment === "parent" ) {
20090
20091			o.containment = this.helper[ 0 ].parentNode;
20092
20093		}
20094
20095
20096
20097		c = $( o.containment );
20098
20099		ce = c[ 0 ];
20100
20101
20102
20103		if ( !ce ) {
20104
20105			return;
20106
20107		}
20108
20109
20110
20111		isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
20112
20113
20114
20115		this.containment = [
20116
20117			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
20118
20119				( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
20120
20121			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
20122
20123				( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
20124
20125			( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
20126
20127				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
20128
20129				( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
20130
20131				this.helperProportions.width -
20132
20133				this.margins.left -
20134
20135				this.margins.right,
20136
20137			( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
20138
20139				( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
20140
20141				( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
20142
20143				this.helperProportions.height -
20144
20145				this.margins.top -
20146
20147				this.margins.bottom
20148
20149		];
20150
20151		this.relativeContainer = c;
20152
20153	},
20154
20155
20156
20157	_convertPositionTo: function( d, pos ) {
20158
20159
20160
20161		if ( !pos ) {
20162
20163			pos = this.position;
20164
20165		}
20166
20167
20168
20169		var mod = d === "absolute" ? 1 : -1,
20170
20171			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
20172
20173
20174
20175		return {
20176
20177			top: (
20178
20179
20180
20181				// The absolute mouse position
20182
20183				pos.top	+
20184
20185
20186
20187				// Only for relative positioned nodes: Relative offset from element to offset parent
20188
20189				this.offset.relative.top * mod +
20190
20191
20192
20193				// The offsetParent's offset without borders (offset + border)
20194
20195				this.offset.parent.top * mod -
20196
20197				( ( this.cssPosition === "fixed" ?
20198
20199					-this.offset.scroll.top :
20200
20201					( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
20202
20203			),
20204
20205			left: (
20206
20207
20208
20209				// The absolute mouse position
20210
20211				pos.left +
20212
20213
20214
20215				// Only for relative positioned nodes: Relative offset from element to offset parent
20216
20217				this.offset.relative.left * mod +
20218
20219
20220
20221				// The offsetParent's offset without borders (offset + border)
20222
20223				this.offset.parent.left * mod	-
20224
20225				( ( this.cssPosition === "fixed" ?
20226
20227					-this.offset.scroll.left :
20228
20229					( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
20230
20231			)
20232
20233		};
20234
20235
20236
20237	},
20238
20239
20240
20241	_generatePosition: function( event, constrainPosition ) {
20242
20243
20244
20245		var containment, co, top, left,
20246
20247			o = this.options,
20248
20249			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
20250
20251			pageX = event.pageX,
20252
20253			pageY = event.pageY;
20254
20255
20256
20257		// Cache the scroll
20258
20259		if ( !scrollIsRootNode || !this.offset.scroll ) {
20260
20261			this.offset.scroll = {
20262
20263				top: this.scrollParent.scrollTop(),
20264
20265				left: this.scrollParent.scrollLeft()
20266
20267			};
20268
20269		}
20270
20271
20272
20273		/*
20274
20275		 * - Position constraining -
20276
20277		 * Constrain the position to a mix of grid, containment.
20278
20279		 */
20280
20281
20282
20283		// If we are not dragging yet, we won't check for options
20284
20285		if ( constrainPosition ) {
20286
20287			if ( this.containment ) {
20288
20289				if ( this.relativeContainer ) {
20290
20291					co = this.relativeContainer.offset();
20292
20293					containment = [
20294
20295						this.containment[ 0 ] + co.left,
20296
20297						this.containment[ 1 ] + co.top,
20298
20299						this.containment[ 2 ] + co.left,
20300
20301						this.containment[ 3 ] + co.top
20302
20303					];
20304
20305				} else {
20306
20307					containment = this.containment;
20308
20309				}
20310
20311
20312
20313				if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
20314
20315					pageX = containment[ 0 ] + this.offset.click.left;
20316
20317				}
20318
20319				if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
20320
20321					pageY = containment[ 1 ] + this.offset.click.top;
20322
20323				}
20324
20325				if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
20326
20327					pageX = containment[ 2 ] + this.offset.click.left;
20328
20329				}
20330
20331				if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
20332
20333					pageY = containment[ 3 ] + this.offset.click.top;
20334
20335				}
20336
20337			}
20338
20339
20340
20341			if ( o.grid ) {
20342
20343
20344
20345				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid
20346
20347				// argument errors in IE (see ticket #6950)
20348
20349				top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
20350
20351					this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
20352
20353				pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
20354
20355					top - this.offset.click.top > containment[ 3 ] ) ?
20356
20357						top :
20358
20359						( ( top - this.offset.click.top >= containment[ 1 ] ) ?
20360
20361							top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
20362
20363
20364
20365				left = o.grid[ 0 ] ? this.originalPageX +
20366
20367					Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
20368
20369					this.originalPageX;
20370
20371				pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
20372
20373					left - this.offset.click.left > containment[ 2 ] ) ?
20374
20375						left :
20376
20377						( ( left - this.offset.click.left >= containment[ 0 ] ) ?
20378
20379							left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
20380
20381			}
20382
20383
20384
20385			if ( o.axis === "y" ) {
20386
20387				pageX = this.originalPageX;
20388
20389			}
20390
20391
20392
20393			if ( o.axis === "x" ) {
20394
20395				pageY = this.originalPageY;
20396
20397			}
20398
20399		}
20400
20401
20402
20403		return {
20404
20405			top: (
20406
20407
20408
20409				// The absolute mouse position
20410
20411				pageY -
20412
20413
20414
20415				// Click offset (relative to the element)
20416
20417				this.offset.click.top -
20418
20419
20420
20421				// Only for relative positioned nodes: Relative offset from element to offset parent
20422
20423				this.offset.relative.top -
20424
20425
20426
20427				// The offsetParent's offset without borders (offset + border)
20428
20429				this.offset.parent.top +
20430
20431				( this.cssPosition === "fixed" ?
20432
20433					-this.offset.scroll.top :
20434
20435					( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
20436
20437			),
20438
20439			left: (
20440
20441
20442
20443				// The absolute mouse position
20444
20445				pageX -
20446
20447
20448
20449				// Click offset (relative to the element)
20450
20451				this.offset.click.left -
20452
20453
20454
20455				// Only for relative positioned nodes: Relative offset from element to offset parent
20456
20457				this.offset.relative.left -
20458
20459
20460
20461				// The offsetParent's offset without borders (offset + border)
20462
20463				this.offset.parent.left +
20464
20465				( this.cssPosition === "fixed" ?
20466
20467					-this.offset.scroll.left :
20468
20469					( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
20470
20471			)
20472
20473		};
20474
20475
20476
20477	},
20478
20479
20480
20481	_clear: function() {
20482
20483		this._removeClass( this.helper, "ui-draggable-dragging" );
20484
20485		if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
20486
20487			this.helper.remove();
20488
20489		}
20490
20491		this.helper = null;
20492
20493		this.cancelHelperRemoval = false;
20494
20495		if ( this.destroyOnClear ) {
20496
20497			this.destroy();
20498
20499		}
20500
20501	},
20502
20503
20504
20505	// From now on bulk stuff - mainly helpers
20506
20507
20508
20509	_trigger: function( type, event, ui ) {
20510
20511		ui = ui || this._uiHash();
20512
20513		$.ui.plugin.call( this, type, [ event, ui, this ], true );
20514
20515
20516
20517		// Absolute position and offset (see #6884 ) have to be recalculated after plugins
20518
20519		if ( /^(drag|start|stop)/.test( type ) ) {
20520
20521			this.positionAbs = this._convertPositionTo( "absolute" );
20522
20523			ui.offset = this.positionAbs;
20524
20525		}
20526
20527		return $.Widget.prototype._trigger.call( this, type, event, ui );
20528
20529	},
20530
20531
20532
20533	plugins: {},
20534
20535
20536
20537	_uiHash: function() {
20538
20539		return {
20540
20541			helper: this.helper,
20542
20543			position: this.position,
20544
20545			originalPosition: this.originalPosition,
20546
20547			offset: this.positionAbs
20548
20549		};
20550
20551	}
20552
20553
20554
20555} );
20556
20557
20558
20559$.ui.plugin.add( "draggable", "connectToSortable", {
20560
20561	start: function( event, ui, draggable ) {
20562
20563		var uiSortable = $.extend( {}, ui, {
20564
20565			item: draggable.element
20566
20567		} );
20568
20569
20570
20571		draggable.sortables = [];
20572
20573		$( draggable.options.connectToSortable ).each( function() {
20574
20575			var sortable = $( this ).sortable( "instance" );
20576
20577
20578
20579			if ( sortable && !sortable.options.disabled ) {
20580
20581				draggable.sortables.push( sortable );
20582
20583
20584
20585				// RefreshPositions is called at drag start to refresh the containerCache
20586
20587				// which is used in drag. This ensures it's initialized and synchronized
20588
20589				// with any changes that might have happened on the page since initialization.
20590
20591				sortable.refreshPositions();
20592
20593				sortable._trigger( "activate", event, uiSortable );
20594
20595			}
20596
20597		} );
20598
20599	},
20600
20601	stop: function( event, ui, draggable ) {
20602
20603		var uiSortable = $.extend( {}, ui, {
20604
20605			item: draggable.element
20606
20607		} );
20608
20609
20610
20611		draggable.cancelHelperRemoval = false;
20612
20613
20614
20615		$.each( draggable.sortables, function() {
20616
20617			var sortable = this;
20618
20619
20620
20621			if ( sortable.isOver ) {
20622
20623				sortable.isOver = 0;
20624
20625
20626
20627				// Allow this sortable to handle removing the helper
20628
20629				draggable.cancelHelperRemoval = true;
20630
20631				sortable.cancelHelperRemoval = false;
20632
20633
20634
20635				// Use _storedCSS To restore properties in the sortable,
20636
20637				// as this also handles revert (#9675) since the draggable
20638
20639				// may have modified them in unexpected ways (#8809)
20640
20641				sortable._storedCSS = {
20642
20643					position: sortable.placeholder.css( "position" ),
20644
20645					top: sortable.placeholder.css( "top" ),
20646
20647					left: sortable.placeholder.css( "left" )
20648
20649				};
20650
20651
20652
20653				sortable._mouseStop( event );
20654
20655
20656
20657				// Once drag has ended, the sortable should return to using
20658
20659				// its original helper, not the shared helper from draggable
20660
20661				sortable.options.helper = sortable.options._helper;
20662
20663			} else {
20664
20665
20666
20667				// Prevent this Sortable from removing the helper.
20668
20669				// However, don't set the draggable to remove the helper
20670
20671				// either as another connected Sortable may yet handle the removal.
20672
20673				sortable.cancelHelperRemoval = true;
20674
20675
20676
20677				sortable._trigger( "deactivate", event, uiSortable );
20678
20679			}
20680
20681		} );
20682
20683	},
20684
20685	drag: function( event, ui, draggable ) {
20686
20687		$.each( draggable.sortables, function() {
20688
20689			var innermostIntersecting = false,
20690
20691				sortable = this;
20692
20693
20694
20695			// Copy over variables that sortable's _intersectsWith uses
20696
20697			sortable.positionAbs = draggable.positionAbs;
20698
20699			sortable.helperProportions = draggable.helperProportions;
20700
20701			sortable.offset.click = draggable.offset.click;
20702
20703
20704
20705			if ( sortable._intersectsWith( sortable.containerCache ) ) {
20706
20707				innermostIntersecting = true;
20708
20709
20710
20711				$.each( draggable.sortables, function() {
20712
20713
20714
20715					// Copy over variables that sortable's _intersectsWith uses
20716
20717					this.positionAbs = draggable.positionAbs;
20718
20719					this.helperProportions = draggable.helperProportions;
20720
20721					this.offset.click = draggable.offset.click;
20722
20723
20724
20725					if ( this !== sortable &&
20726
20727							this._intersectsWith( this.containerCache ) &&
20728
20729							$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
20730
20731						innermostIntersecting = false;
20732
20733					}
20734
20735
20736
20737					return innermostIntersecting;
20738
20739				} );
20740
20741			}
20742
20743
20744
20745			if ( innermostIntersecting ) {
20746
20747
20748
20749				// If it intersects, we use a little isOver variable and set it once,
20750
20751				// so that the move-in stuff gets fired only once.
20752
20753				if ( !sortable.isOver ) {
20754
20755					sortable.isOver = 1;
20756
20757
20758
20759					// Store draggable's parent in case we need to reappend to it later.
20760
20761					draggable._parent = ui.helper.parent();
20762
20763
20764
20765					sortable.currentItem = ui.helper
20766
20767						.appendTo( sortable.element )
20768
20769						.data( "ui-sortable-item", true );
20770
20771
20772
20773					// Store helper option to later restore it
20774
vendor: 12,177 bytes, lines 20775-21523
20775					sortable.options._helper = sortable.options.helper;
20776
20777
20778
20779					sortable.options.helper = function() {
20780
20781						return ui.helper[ 0 ];
20782
20783					};
20784
20785
20786
20787					// Fire the start events of the sortable with our passed browser event,
20788
20789					// and our own helper (so it doesn't create a new one)
20790
20791					event.target = sortable.currentItem[ 0 ];
20792
20793					sortable._mouseCapture( event, true );
20794
20795					sortable._mouseStart( event, true, true );
20796
20797
20798
20799					// Because the browser event is way off the new appended portlet,
20800
20801					// modify necessary variables to reflect the changes
20802
20803					sortable.offset.click.top = draggable.offset.click.top;
20804
20805					sortable.offset.click.left = draggable.offset.click.left;
20806
20807					sortable.offset.parent.left -= draggable.offset.parent.left -
20808
20809						sortable.offset.parent.left;
20810
20811					sortable.offset.parent.top -= draggable.offset.parent.top -
20812
20813						sortable.offset.parent.top;
20814
20815
20816
20817					draggable._trigger( "toSortable", event );
20818
20819
20820
20821					// Inform draggable that the helper is in a valid drop zone,
20822
20823					// used solely in the revert option to handle "valid/invalid".
20824
20825					draggable.dropped = sortable.element;
20826
20827
20828
20829					// Need to refreshPositions of all sortables in the case that
20830
20831					// adding to one sortable changes the location of the other sortables (#9675)
20832
20833					$.each( draggable.sortables, function() {
20834
20835						this.refreshPositions();
20836
20837					} );
20838
20839
20840
20841					// Hack so receive/update callbacks work (mostly)
20842
20843					draggable.currentItem = draggable.element;
20844
20845					sortable.fromOutside = draggable;
20846
20847				}
20848
20849
20850
20851				if ( sortable.currentItem ) {
20852
20853					sortable._mouseDrag( event );
20854
20855
20856
20857					// Copy the sortable's position because the draggable's can potentially reflect
20858
20859					// a relative position, while sortable is always absolute, which the dragged
20860
20861					// element has now become. (#8809)
20862
20863					ui.position = sortable.position;
20864
20865				}
20866
20867			} else {
20868
20869
20870
20871				// If it doesn't intersect with the sortable, and it intersected before,
20872
20873				// we fake the drag stop of the sortable, but make sure it doesn't remove
20874
20875				// the helper by using cancelHelperRemoval.
20876
20877				if ( sortable.isOver ) {
20878
20879
20880
20881					sortable.isOver = 0;
20882
20883					sortable.cancelHelperRemoval = true;
20884
20885
20886
20887					// Calling sortable's mouseStop would trigger a revert,
20888
20889					// so revert must be temporarily false until after mouseStop is called.
20890
20891					sortable.options._revert = sortable.options.revert;
20892
20893					sortable.options.revert = false;
20894
20895
20896
20897					sortable._trigger( "out", event, sortable._uiHash( sortable ) );
20898
20899					sortable._mouseStop( event, true );
20900
20901
20902
20903					// Restore sortable behaviors that were modfied
20904
20905					// when the draggable entered the sortable area (#9481)
20906
20907					sortable.options.revert = sortable.options._revert;
20908
20909					sortable.options.helper = sortable.options._helper;
20910
20911
20912
20913					if ( sortable.placeholder ) {
20914
20915						sortable.placeholder.remove();
20916
20917					}
20918
20919
20920
20921					// Restore and recalculate the draggable's offset considering the sortable
20922
20923					// may have modified them in unexpected ways. (#8809, #10669)
20924
20925					ui.helper.appendTo( draggable._parent );
20926
20927					draggable._refreshOffsets( event );
20928
20929					ui.position = draggable._generatePosition( event, true );
20930
20931
20932
20933					draggable._trigger( "fromSortable", event );
20934
20935
20936
20937					// Inform draggable that the helper is no longer in a valid drop zone
20938
20939					draggable.dropped = false;
20940
20941
20942
20943					// Need to refreshPositions of all sortables just in case removing
20944
20945					// from one sortable changes the location of other sortables (#9675)
20946
20947					$.each( draggable.sortables, function() {
20948
20949						this.refreshPositions();
20950
20951					} );
20952
20953				}
20954
20955			}
20956
20957		} );
20958
20959	}
20960
20961} );
20962
20963
20964
20965$.ui.plugin.add( "draggable", "cursor", {
20966
20967	start: function( event, ui, instance ) {
20968
20969		var t = $( "body" ),
20970
20971			o = instance.options;
20972
20973
20974
20975		if ( t.css( "cursor" ) ) {
20976
20977			o._cursor = t.css( "cursor" );
20978
20979		}
20980
20981		t.css( "cursor", o.cursor );
20982
20983	},
20984
20985	stop: function( event, ui, instance ) {
20986
20987		var o = instance.options;
20988
20989		if ( o._cursor ) {
20990
20991			$( "body" ).css( "cursor", o._cursor );
20992
20993		}
20994
20995	}
20996
20997} );
20998
20999
21000
21001$.ui.plugin.add( "draggable", "opacity", {
21002
21003	start: function( event, ui, instance ) {
21004
21005		var t = $( ui.helper ),
21006
21007			o = instance.options;
21008
21009		if ( t.css( "opacity" ) ) {
21010
21011			o._opacity = t.css( "opacity" );
21012
21013		}
21014
21015		t.css( "opacity", o.opacity );
21016
21017	},
21018
21019	stop: function( event, ui, instance ) {
21020
21021		var o = instance.options;
21022
21023		if ( o._opacity ) {
21024
21025			$( ui.helper ).css( "opacity", o._opacity );
21026
21027		}
21028
21029	}
21030
21031} );
21032
21033
21034
21035$.ui.plugin.add( "draggable", "scroll", {
21036
21037	start: function( event, ui, i ) {
21038
21039		if ( !i.scrollParentNotHidden ) {
21040
21041			i.scrollParentNotHidden = i.helper.scrollParent( false );
21042
21043		}
21044
21045
21046
21047		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
21048
21049				i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
21050
21051			i.overflowOffset = i.scrollParentNotHidden.offset();
21052
21053		}
21054
21055	},
21056
21057	drag: function( event, ui, i  ) {
21058
21059
21060
21061		var o = i.options,
21062
21063			scrolled = false,
21064
21065			scrollParent = i.scrollParentNotHidden[ 0 ],
21066
21067			document = i.document[ 0 ];
21068
21069
21070
21071		if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
21072
21073			if ( !o.axis || o.axis !== "x" ) {
21074
21075				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
21076
21077						o.scrollSensitivity ) {
21078
21079					scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
21080
21081				} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
21082
21083					scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
21084
21085				}
21086
21087			}
21088
21089
21090
21091			if ( !o.axis || o.axis !== "y" ) {
21092
21093				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
21094
21095						o.scrollSensitivity ) {
21096
21097					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
21098
21099				} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
21100
21101					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
21102
21103				}
21104
21105			}
21106
21107
21108
21109		} else {
21110
21111
21112
21113			if ( !o.axis || o.axis !== "x" ) {
21114
21115				if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
21116
21117					scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
21118
21119				} else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
21120
21121						o.scrollSensitivity ) {
21122
21123					scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
21124
21125				}
21126
21127			}
21128
21129
21130
21131			if ( !o.axis || o.axis !== "y" ) {
21132
21133				if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
21134
21135					scrolled = $( document ).scrollLeft(
21136
21137						$( document ).scrollLeft() - o.scrollSpeed
21138
21139					);
21140
21141				} else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
21142
21143						o.scrollSensitivity ) {
21144
21145					scrolled = $( document ).scrollLeft(
21146
21147						$( document ).scrollLeft() + o.scrollSpeed
21148
21149					);
21150
21151				}
21152
21153			}
21154
21155
21156
21157		}
21158
21159
21160
21161		if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
21162
21163			$.ui.ddmanager.prepareOffsets( i, event );
21164
21165		}
21166
21167
21168
21169	}
21170
21171} );
21172
21173
21174
21175$.ui.plugin.add( "draggable", "snap", {
21176
21177	start: function( event, ui, i ) {
21178
21179
21180
21181		var o = i.options;
21182
21183
21184
21185		i.snapElements = [];
21186
21187
21188
21189		$( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
21190
21191			.each( function() {
21192
21193				var $t = $( this ),
21194
21195					$o = $t.offset();
21196
21197				if ( this !== i.element[ 0 ] ) {
21198
21199					i.snapElements.push( {
21200
21201						item: this,
21202
21203						width: $t.outerWidth(), height: $t.outerHeight(),
21204
21205						top: $o.top, left: $o.left
21206
21207					} );
21208
21209				}
21210
21211			} );
21212
21213
21214
21215	},
21216
21217	drag: function( event, ui, inst ) {
21218
21219
21220
21221		var ts, bs, ls, rs, l, r, t, b, i, first,
21222
21223			o = inst.options,
21224
21225			d = o.snapTolerance,
21226
21227			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
21228
21229			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
21230
21231
21232
21233		for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
21234
21235
21236
21237			l = inst.snapElements[ i ].left - inst.margins.left;
21238
21239			r = l + inst.snapElements[ i ].width;
21240
21241			t = inst.snapElements[ i ].top - inst.margins.top;
21242
21243			b = t + inst.snapElements[ i ].height;
21244
21245
21246
21247			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
21248
21249					!$.contains( inst.snapElements[ i ].item.ownerDocument,
21250
21251					inst.snapElements[ i ].item ) ) {
21252
21253				if ( inst.snapElements[ i ].snapping ) {
21254
21255					( inst.options.snap.release &&
21256
21257						inst.options.snap.release.call(
21258
21259							inst.element,
21260
21261							event,
21262
21263							$.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
21264
21265						) );
21266
21267				}
21268
21269				inst.snapElements[ i ].snapping = false;
21270
21271				continue;
21272
21273			}
21274
21275
21276
21277			if ( o.snapMode !== "inner" ) {
21278
21279				ts = Math.abs( t - y2 ) <= d;
21280
21281				bs = Math.abs( b - y1 ) <= d;
21282
21283				ls = Math.abs( l - x2 ) <= d;
21284
21285				rs = Math.abs( r - x1 ) <= d;
21286
21287				if ( ts ) {
21288
21289					ui.position.top = inst._convertPositionTo( "relative", {
21290
21291						top: t - inst.helperProportions.height,
21292
21293						left: 0
21294
21295					} ).top;
21296
21297				}
21298
21299				if ( bs ) {
21300
21301					ui.position.top = inst._convertPositionTo( "relative", {
21302
21303						top: b,
21304
21305						left: 0
21306
21307					} ).top;
21308
21309				}
21310
21311				if ( ls ) {
21312
21313					ui.position.left = inst._convertPositionTo( "relative", {
21314
21315						top: 0,
21316
21317						left: l - inst.helperProportions.width
21318
21319					} ).left;
21320
21321				}
21322
21323				if ( rs ) {
21324
21325					ui.position.left = inst._convertPositionTo( "relative", {
21326
21327						top: 0,
21328
21329						left: r
21330
21331					} ).left;
21332
21333				}
21334
21335			}
21336
21337
21338
21339			first = ( ts || bs || ls || rs );
21340
21341
21342
21343			if ( o.snapMode !== "outer" ) {
21344
21345				ts = Math.abs( t - y1 ) <= d;
21346
21347				bs = Math.abs( b - y2 ) <= d;
21348
21349				ls = Math.abs( l - x1 ) <= d;
21350
21351				rs = Math.abs( r - x2 ) <= d;
21352
21353				if ( ts ) {
21354
21355					ui.position.top = inst._convertPositionTo( "relative", {
21356
21357						top: t,
21358
21359						left: 0
21360
21361					} ).top;
21362
21363				}
21364
21365				if ( bs ) {
21366
21367					ui.position.top = inst._convertPositionTo( "relative", {
21368
21369						top: b - inst.helperProportions.height,
21370
21371						left: 0
21372
21373					} ).top;
21374
21375				}
21376
21377				if ( ls ) {
21378
21379					ui.position.left = inst._convertPositionTo( "relative", {
21380
21381						top: 0,
21382
21383						left: l
21384
21385					} ).left;
21386
21387				}
21388
21389				if ( rs ) {
21390
21391					ui.position.left = inst._convertPositionTo( "relative", {
21392
21393						top: 0,
21394
21395						left: r - inst.helperProportions.width
21396
21397					} ).left;
21398
21399				}
21400
21401			}
21402
21403
21404
21405			if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
21406
21407				( inst.options.snap.snap &&
21408
21409					inst.options.snap.snap.call(
21410
21411						inst.element,
21412
21413						event,
21414
21415						$.extend( inst._uiHash(), {
21416
21417							snapItem: inst.snapElements[ i ].item
21418
21419						} ) ) );
21420
21421			}
21422
21423			inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
21424
21425
21426
21427		}
21428
21429
21430
21431	}
21432
21433} );
21434
21435
21436
21437$.ui.plugin.add( "draggable", "stack", {
21438
21439	start: function( event, ui, instance ) {
21440
21441		var min,
21442
21443			o = instance.options,
21444
21445			group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
21446
21447				return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
21448
21449					( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
21450
21451			} );
21452
21453
21454
21455		if ( !group.length ) { return; }
21456
21457
21458
21459		min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
21460
21461		$( group ).each( function( i ) {
21462
21463			$( this ).css( "zIndex", min + i );
21464
21465		} );
21466
21467		this.css( "zIndex", ( min + group.length ) );
21468
21469	}
21470
21471} );
21472
21473
21474
21475$.ui.plugin.add( "draggable", "zIndex", {
21476
21477	start: function( event, ui, instance ) {
21478
21479		var t = $( ui.helper ),
21480
21481			o = instance.options;
21482
21483
21484
21485		if ( t.css( "zIndex" ) ) {
21486
21487			o._zIndex = t.css( "zIndex" );
21488
21489		}
21490
21491		t.css( "zIndex", o.zIndex );
21492
21493	},
21494
21495	stop: function( event, ui, instance ) {
21496
21497		var o = instance.options;
21498
21499
21500
21501		if ( o._zIndex ) {
21502
21503			$( ui.helper ).css( "zIndex", o._zIndex );
21504
21505		}
21506
21507	}
21508
21509} );
21510
21511
21512
21513var widgetsDraggable = $.ui.draggable;
21514
21515
21516
21517
21518
21519/*!
21520
21521 * jQuery UI Resizable 1.12.1
21522
21523 * http://jqueryui.com
vendor: 7,492 bytes, lines 21524-22082
21524
21525 *
21526
21527 * Copyright jQuery Foundation and other contributors
21528
21529 * Released under the MIT license.
21530
21531 * http://jquery.org/license
21532
21533 */
21534
21535
21536
21537//>>label: Resizable
21538
21539//>>group: Interactions
21540
21541//>>description: Enables resize functionality for any element.
21542
21543//>>docs: http://api.jqueryui.com/resizable/
21544
21545//>>demos: http://jqueryui.com/resizable/
21546
21547//>>css.structure: ../../themes/base/core.css
21548
21549//>>css.structure: ../../themes/base/resizable.css
21550
21551//>>css.theme: ../../themes/base/theme.css
21552
21553
21554
21555
21556
21557
21558
21559$.widget( "ui.resizable", $.ui.mouse, {
21560
21561	version: "1.12.1",
21562
21563	widgetEventPrefix: "resize",
21564
21565	options: {
21566
21567		alsoResize: false,
21568
21569		animate: false,
21570
21571		animateDuration: "slow",
21572
21573		animateEasing: "swing",
21574
21575		aspectRatio: false,
21576
21577		autoHide: false,
21578
21579		classes: {
21580
21581			"ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se"
21582
21583		},
21584
21585		containment: false,
21586
21587		ghost: false,
21588
21589		grid: false,
21590
21591		handles: "e,s,se",
21592
21593		helper: false,
21594
21595		maxHeight: null,
21596
21597		maxWidth: null,
21598
21599		minHeight: 10,
21600
21601		minWidth: 10,
21602
21603
21604
21605		// See #7960
21606
21607		zIndex: 90,
21608
21609
21610
21611		// Callbacks
21612
21613		resize: null,
21614
21615		start: null,
21616
21617		stop: null
21618
21619	},
21620
21621
21622
21623	_num: function( value ) {
21624
21625		return parseFloat( value ) || 0;
21626
21627	},
21628
21629
21630
21631	_isNumber: function( value ) {
21632
21633		return !isNaN( parseFloat( value ) );
21634
21635	},
21636
21637
21638
21639	_hasScroll: function( el, a ) {
21640
21641
21642
21643		if ( $( el ).css( "overflow" ) === "hidden" ) {
21644
21645			return false;
21646
21647		}
21648
21649
21650
21651		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
21652
21653			has = false;
21654
21655
21656
21657		if ( el[ scroll ] > 0 ) {
21658
21659			return true;
21660
21661		}
21662
21663
21664
21665		// TODO: determine which cases actually cause this to happen
21666
21667		// if the element doesn't have the scroll set, see if it's possible to
21668
21669		// set the scroll
21670
21671		el[ scroll ] = 1;
21672
21673		has = ( el[ scroll ] > 0 );
21674
21675		el[ scroll ] = 0;
21676
21677		return has;
21678
21679	},
21680
21681
21682
21683	_create: function() {
21684
21685
21686
21687		var margins,
21688
21689			o = this.options,
21690
21691			that = this;
21692
21693		this._addClass( "ui-resizable" );
21694
21695
21696
21697		$.extend( this, {
21698
21699			_aspectRatio: !!( o.aspectRatio ),
21700
21701			aspectRatio: o.aspectRatio,
21702
21703			originalElement: this.element,
21704
21705			_proportionallyResizeElements: [],
21706
21707			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
21708
21709		} );
21710
21711
21712
21713		// Wrap the element if it cannot hold child nodes
21714
21715		if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) {
21716
21717
21718
21719			this.element.wrap(
21720
21721				$( "<div class='ui-wrapper' style='overflow: hidden;'></div>" ).css( {
21722
21723					position: this.element.css( "position" ),
21724
21725					width: this.element.outerWidth(),
21726
21727					height: this.element.outerHeight(),
21728
21729					top: this.element.css( "top" ),
21730
21731					left: this.element.css( "left" )
21732
21733				} )
21734
21735			);
21736
21737
21738
21739			this.element = this.element.parent().data(
21740
21741				"ui-resizable", this.element.resizable( "instance" )
21742
21743			);
21744
21745
21746
21747			this.elementIsWrapper = true;
21748
21749
21750
21751			margins = {
21752
21753				marginTop: this.originalElement.css( "marginTop" ),
21754
21755				marginRight: this.originalElement.css( "marginRight" ),
21756
21757				marginBottom: this.originalElement.css( "marginBottom" ),
21758
21759				marginLeft: this.originalElement.css( "marginLeft" )
21760
21761			};
21762
21763
21764
21765			this.element.css( margins );
21766
21767			this.originalElement.css( "margin", 0 );
21768
21769
21770
21771			// support: Safari
21772
21773			// Prevent Safari textarea resize
21774
21775			this.originalResizeStyle = this.originalElement.css( "resize" );
21776
21777			this.originalElement.css( "resize", "none" );
21778
21779
21780
21781			this._proportionallyResizeElements.push( this.originalElement.css( {
21782
21783				position: "static",
21784
21785				zoom: 1,
21786
21787				display: "block"
21788
21789			} ) );
21790
21791
21792
21793			// Support: IE9
21794
21795			// avoid IE jump (hard set the margin)
21796
21797			this.originalElement.css( margins );
21798
21799
21800
21801			this._proportionallyResize();
21802
21803		}
21804
21805
21806
21807		this._setupHandles();
21808
21809
21810
21811		if ( o.autoHide ) {
21812
21813			$( this.element )
21814
21815				.on( "mouseenter", function() {
21816
21817					if ( o.disabled ) {
21818
21819						return;
21820
21821					}
21822
21823					that._removeClass( "ui-resizable-autohide" );
21824
21825					that._handles.show();
21826
21827				} )
21828
21829				.on( "mouseleave", function() {
21830
21831					if ( o.disabled ) {
21832
21833						return;
21834
21835					}
21836
21837					if ( !that.resizing ) {
21838
21839						that._addClass( "ui-resizable-autohide" );
21840
21841						that._handles.hide();
21842
21843					}
21844
21845				} );
21846
21847		}
21848
21849
21850
21851		this._mouseInit();
21852
21853	},
21854
21855
21856
21857	_destroy: function() {
21858
21859
21860
21861		this._mouseDestroy();
21862
21863
21864
21865		var wrapper,
21866
21867			_destroy = function( exp ) {
21868
21869				$( exp )
21870
21871					.removeData( "resizable" )
21872
21873					.removeData( "ui-resizable" )
21874
21875					.off( ".resizable" )
21876
21877					.find( ".ui-resizable-handle" )
21878
21879						.remove();
21880
21881			};
21882
21883
21884
21885		// TODO: Unwrap at same DOM position
21886
21887		if ( this.elementIsWrapper ) {
21888
21889			_destroy( this.element );
21890
21891			wrapper = this.element;
21892
21893			this.originalElement.css( {
21894
21895				position: wrapper.css( "position" ),
21896
21897				width: wrapper.outerWidth(),
21898
21899				height: wrapper.outerHeight(),
21900
21901				top: wrapper.css( "top" ),
21902
21903				left: wrapper.css( "left" )
21904
21905			} ).insertAfter( wrapper );
21906
21907			wrapper.remove();
21908
21909		}
21910
21911
21912
21913		this.originalElement.css( "resize", this.originalResizeStyle );
21914
21915		_destroy( this.originalElement );
21916
21917
21918
21919		return this;
21920
21921	},
21922
21923
21924
21925	_setOption: function( key, value ) {
21926
21927		this._super( key, value );
21928
21929
21930
21931		switch ( key ) {
21932
21933		case "handles":
21934
21935			this._removeHandles();
21936
21937			this._setupHandles();
21938
21939			break;
21940
21941		default:
21942
21943			break;
21944
21945		}
21946
21947	},
21948
21949
21950
21951	_setupHandles: function() {
21952
21953		var o = this.options, handle, i, n, hname, axis, that = this;
21954
21955		this.handles = o.handles ||
21956
21957			( !$( ".ui-resizable-handle", this.element ).length ?
21958
21959				"e,s,se" : {
21960
21961					n: ".ui-resizable-n",
21962
21963					e: ".ui-resizable-e",
21964
21965					s: ".ui-resizable-s",
21966
21967					w: ".ui-resizable-w",
21968
21969					se: ".ui-resizable-se",
21970
21971					sw: ".ui-resizable-sw",
21972
21973					ne: ".ui-resizable-ne",
21974
21975					nw: ".ui-resizable-nw"
21976
21977				} );
21978
21979
21980
21981		this._handles = $();
21982
21983		if ( this.handles.constructor === String ) {
21984
21985
21986
21987			if ( this.handles === "all" ) {
21988
21989				this.handles = "n,e,s,w,se,sw,ne,nw";
21990
21991			}
21992
21993
21994
21995			n = this.handles.split( "," );
21996
21997			this.handles = {};
21998
21999
22000
22001			for ( i = 0; i < n.length; i++ ) {
22002
22003
22004
22005				handle = $.trim( n[ i ] );
22006
22007				hname = "ui-resizable-" + handle;
22008
22009				axis = $( "<div>" );
22010
22011				this._addClass( axis, "ui-resizable-handle " + hname );
22012
22013
22014
22015				axis.css( { zIndex: o.zIndex } );
22016
22017
22018
22019				this.handles[ handle ] = ".ui-resizable-" + handle;
22020
22021				this.element.append( axis );
22022
22023			}
22024
22025
22026
22027		}
22028
22029
22030
22031		this._renderAxis = function( target ) {
22032
22033
22034
22035			var i, axis, padPos, padWrapper;
22036
22037
22038
22039			target = target || this.element;
22040
22041
22042
22043			for ( i in this.handles ) {
22044
22045
22046
22047				if ( this.handles[ i ].constructor === String ) {
22048
22049					this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show();
22050
22051				} else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
22052
22053					this.handles[ i ] = $( this.handles[ i ] );
22054
22055					this._on( this.handles[ i ], { "mousedown": that._mouseDown } );
22056
22057				}
22058
22059
22060
22061				if ( this.elementIsWrapper &&
22062
22063						this.originalElement[ 0 ]
22064
22065							.nodeName
22066
22067							.match( /^(textarea|input|select|button)$/i ) ) {
22068
22069					axis = $( this.handles[ i ], this.element );
22070
22071
22072
22073					padWrapper = /sw|ne|nw|se|n|s/.test( i ) ?
22074
22075						axis.outerHeight() :
22076
22077						axis.outerWidth();
22078
22079
22080
22081					padPos = [ "padding",
22082
vendor: 5,040 bytes, lines 22083-22444
22083						/ne|nw|n/.test( i ) ? "Top" :
22084
22085						/se|sw|s/.test( i ) ? "Bottom" :
22086
22087						/^e$/.test( i ) ? "Right" : "Left" ].join( "" );
22088
22089
22090
22091					target.css( padPos, padWrapper );
22092
22093
22094
22095					this._proportionallyResize();
22096
22097				}
22098
22099
22100
22101				this._handles = this._handles.add( this.handles[ i ] );
22102
22103			}
22104
22105		};
22106
22107
22108
22109		// TODO: make renderAxis a prototype function
22110
22111		this._renderAxis( this.element );
22112
22113
22114
22115		this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
22116
22117		this._handles.disableSelection();
22118
22119
22120
22121		this._handles.on( "mouseover", function() {
22122
22123			if ( !that.resizing ) {
22124
22125				if ( this.className ) {
22126
22127					axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i );
22128
22129				}
22130
22131				that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se";
22132
22133			}
22134
22135		} );
22136
22137
22138
22139		if ( o.autoHide ) {
22140
22141			this._handles.hide();
22142
22143			this._addClass( "ui-resizable-autohide" );
22144
22145		}
22146
22147	},
22148
22149
22150
22151	_removeHandles: function() {
22152
22153		this._handles.remove();
22154
22155	},
22156
22157
22158
22159	_mouseCapture: function( event ) {
22160
22161		var i, handle,
22162
22163			capture = false;
22164
22165
22166
22167		for ( i in this.handles ) {
22168
22169			handle = $( this.handles[ i ] )[ 0 ];
22170
22171			if ( handle === event.target || $.contains( handle, event.target ) ) {
22172
22173				capture = true;
22174
22175			}
22176
22177		}
22178
22179
22180
22181		return !this.options.disabled && capture;
22182
22183	},
22184
22185
22186
22187	_mouseStart: function( event ) {
22188
22189
22190
22191		var curleft, curtop, cursor,
22192
22193			o = this.options,
22194
22195			el = this.element;
22196
22197
22198
22199		this.resizing = true;
22200
22201
22202
22203		this._renderProxy();
22204
22205
22206
22207		curleft = this._num( this.helper.css( "left" ) );
22208
22209		curtop = this._num( this.helper.css( "top" ) );
22210
22211
22212
22213		if ( o.containment ) {
22214
22215			curleft += $( o.containment ).scrollLeft() || 0;
22216
22217			curtop += $( o.containment ).scrollTop() || 0;
22218
22219		}
22220
22221
22222
22223		this.offset = this.helper.offset();
22224
22225		this.position = { left: curleft, top: curtop };
22226
22227
22228
22229		this.size = this._helper ? {
22230
22231				width: this.helper.width(),
22232
22233				height: this.helper.height()
22234
22235			} : {
22236
22237				width: el.width(),
22238
22239				height: el.height()
22240
22241			};
22242
22243
22244
22245		this.originalSize = this._helper ? {
22246
22247				width: el.outerWidth(),
22248
22249				height: el.outerHeight()
22250
22251			} : {
22252
22253				width: el.width(),
22254
22255				height: el.height()
22256
22257			};
22258
22259
22260
22261		this.sizeDiff = {
22262
22263			width: el.outerWidth() - el.width(),
22264
22265			height: el.outerHeight() - el.height()
22266
22267		};
22268
22269
22270
22271		this.originalPosition = { left: curleft, top: curtop };
22272
22273		this.originalMousePosition = { left: event.pageX, top: event.pageY };
22274
22275
22276
22277		this.aspectRatio = ( typeof o.aspectRatio === "number" ) ?
22278
22279			o.aspectRatio :
22280
22281			( ( this.originalSize.width / this.originalSize.height ) || 1 );
22282
22283
22284
22285		cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" );
22286
22287		$( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor );
22288
22289
22290
22291		this._addClass( "ui-resizable-resizing" );
22292
22293		this._propagate( "start", event );
22294
22295		return true;
22296
22297	},
22298
22299
22300
22301	_mouseDrag: function( event ) {
22302
22303
22304
22305		var data, props,
22306
22307			smp = this.originalMousePosition,
22308
22309			a = this.axis,
22310
22311			dx = ( event.pageX - smp.left ) || 0,
22312
22313			dy = ( event.pageY - smp.top ) || 0,
22314
22315			trigger = this._change[ a ];
22316
22317
22318
22319		this._updatePrevProperties();
22320
22321
22322
22323		if ( !trigger ) {
22324
22325			return false;
22326
22327		}
22328
22329
22330
22331		data = trigger.apply( this, [ event, dx, dy ] );
22332
22333
22334
22335		this._updateVirtualBoundaries( event.shiftKey );
22336
22337		if ( this._aspectRatio || event.shiftKey ) {
22338
22339			data = this._updateRatio( data, event );
22340
22341		}
22342
22343
22344
22345		data = this._respectSize( data, event );
22346
22347
22348
22349		this._updateCache( data );
22350
22351
22352
22353		this._propagate( "resize", event );
22354
22355
22356
22357		props = this._applyChanges();
22358
22359
22360
22361		if ( !this._helper && this._proportionallyResizeElements.length ) {
22362
22363			this._proportionallyResize();
22364
22365		}
22366
22367
22368
22369		if ( !$.isEmptyObject( props ) ) {
22370
22371			this._updatePrevProperties();
22372
22373			this._trigger( "resize", event, this.ui() );
22374
22375			this._applyChanges();
22376
22377		}
22378
22379
22380
22381		return false;
22382
22383	},
22384
22385
22386
22387	_mouseStop: function( event ) {
22388
22389
22390
22391		this.resizing = false;
22392
22393		var pr, ista, soffseth, soffsetw, s, left, top,
22394
22395			o = this.options, that = this;
22396
22397
22398
22399		if ( this._helper ) {
22400
22401
22402
22403			pr = this._proportionallyResizeElements;
22404
22405			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName );
22406
22407			soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height;
22408
22409			soffsetw = ista ? 0 : that.sizeDiff.width;
22410
22411
22412
22413			s = {
22414
22415				width: ( that.helper.width()  - soffsetw ),
22416
22417				height: ( that.helper.height() - soffseth )
22418
22419			};
22420
22421			left = ( parseFloat( that.element.css( "left" ) ) +
22422
22423				( that.position.left - that.originalPosition.left ) ) || null;
22424
22425			top = ( parseFloat( that.element.css( "top" ) ) +
22426
22427				( that.position.top - that.originalPosition.top ) ) || null;
22428
22429
22430
22431			if ( !o.animate ) {
22432
22433				this.element.css( $.extend( s, { top: top, left: left } ) );
22434
22435			}
22436
22437
22438
22439			that.helper.height( that.size.height );
22440
22441			that.helper.width( that.size.width );
22442
22443
22444
vendor: 18,026 bytes, lines 22445-23704
22445			if ( this._helper && !o.animate ) {
22446
22447				this._proportionallyResize();
22448
22449			}
22450
22451		}
22452
22453
22454
22455		$( "body" ).css( "cursor", "auto" );
22456
22457
22458
22459		this._removeClass( "ui-resizable-resizing" );
22460
22461
22462
22463		this._propagate( "stop", event );
22464
22465
22466
22467		if ( this._helper ) {
22468
22469			this.helper.remove();
22470
22471		}
22472
22473
22474
22475		return false;
22476
22477
22478
22479	},
22480
22481
22482
22483	_updatePrevProperties: function() {
22484
22485		this.prevPosition = {
22486
22487			top: this.position.top,
22488
22489			left: this.position.left
22490
22491		};
22492
22493		this.prevSize = {
22494
22495			width: this.size.width,
22496
22497			height: this.size.height
22498
22499		};
22500
22501	},
22502
22503
22504
22505	_applyChanges: function() {
22506
22507		var props = {};
22508
22509
22510
22511		if ( this.position.top !== this.prevPosition.top ) {
22512
22513			props.top = this.position.top + "px";
22514
22515		}
22516
22517		if ( this.position.left !== this.prevPosition.left ) {
22518
22519			props.left = this.position.left + "px";
22520
22521		}
22522
22523		if ( this.size.width !== this.prevSize.width ) {
22524
22525			props.width = this.size.width + "px";
22526
22527		}
22528
22529		if ( this.size.height !== this.prevSize.height ) {
22530
22531			props.height = this.size.height + "px";
22532
22533		}
22534
22535
22536
22537		this.helper.css( props );
22538
22539
22540
22541		return props;
22542
22543	},
22544
22545
22546
22547	_updateVirtualBoundaries: function( forceAspectRatio ) {
22548
22549		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
22550
22551			o = this.options;
22552
22553
22554
22555		b = {
22556
22557			minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0,
22558
22559			maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity,
22560
22561			minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0,
22562
22563			maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity
22564
22565		};
22566
22567
22568
22569		if ( this._aspectRatio || forceAspectRatio ) {
22570
22571			pMinWidth = b.minHeight * this.aspectRatio;
22572
22573			pMinHeight = b.minWidth / this.aspectRatio;
22574
22575			pMaxWidth = b.maxHeight * this.aspectRatio;
22576
22577			pMaxHeight = b.maxWidth / this.aspectRatio;
22578
22579
22580
22581			if ( pMinWidth > b.minWidth ) {
22582
22583				b.minWidth = pMinWidth;
22584
22585			}
22586
22587			if ( pMinHeight > b.minHeight ) {
22588
22589				b.minHeight = pMinHeight;
22590
22591			}
22592
22593			if ( pMaxWidth < b.maxWidth ) {
22594
22595				b.maxWidth = pMaxWidth;
22596
22597			}
22598
22599			if ( pMaxHeight < b.maxHeight ) {
22600
22601				b.maxHeight = pMaxHeight;
22602
22603			}
22604
22605		}
22606
22607		this._vBoundaries = b;
22608
22609	},
22610
22611
22612
22613	_updateCache: function( data ) {
22614
22615		this.offset = this.helper.offset();
22616
22617		if ( this._isNumber( data.left ) ) {
22618
22619			this.position.left = data.left;
22620
22621		}
22622
22623		if ( this._isNumber( data.top ) ) {
22624
22625			this.position.top = data.top;
22626
22627		}
22628
22629		if ( this._isNumber( data.height ) ) {
22630
22631			this.size.height = data.height;
22632
22633		}
22634
22635		if ( this._isNumber( data.width ) ) {
22636
22637			this.size.width = data.width;
22638
22639		}
22640
22641	},
22642
22643
22644
22645	_updateRatio: function( data ) {
22646
22647
22648
22649		var cpos = this.position,
22650
22651			csize = this.size,
22652
22653			a = this.axis;
22654
22655
22656
22657		if ( this._isNumber( data.height ) ) {
22658
22659			data.width = ( data.height * this.aspectRatio );
22660
22661		} else if ( this._isNumber( data.width ) ) {
22662
22663			data.height = ( data.width / this.aspectRatio );
22664
22665		}
22666
22667
22668
22669		if ( a === "sw" ) {
22670
22671			data.left = cpos.left + ( csize.width - data.width );
22672
22673			data.top = null;
22674
22675		}
22676
22677		if ( a === "nw" ) {
22678
22679			data.top = cpos.top + ( csize.height - data.height );
22680
22681			data.left = cpos.left + ( csize.width - data.width );
22682
22683		}
22684
22685
22686
22687		return data;
22688
22689	},
22690
22691
22692
22693	_respectSize: function( data ) {
22694
22695
22696
22697		var o = this._vBoundaries,
22698
22699			a = this.axis,
22700
22701			ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ),
22702
22703			ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ),
22704
22705			isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ),
22706
22707			isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ),
22708
22709			dw = this.originalPosition.left + this.originalSize.width,
22710
22711			dh = this.originalPosition.top + this.originalSize.height,
22712
22713			cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a );
22714
22715		if ( isminw ) {
22716
22717			data.width = o.minWidth;
22718
22719		}
22720
22721		if ( isminh ) {
22722
22723			data.height = o.minHeight;
22724
22725		}
22726
22727		if ( ismaxw ) {
22728
22729			data.width = o.maxWidth;
22730
22731		}
22732
22733		if ( ismaxh ) {
22734
22735			data.height = o.maxHeight;
22736
22737		}
22738
22739
22740
22741		if ( isminw && cw ) {
22742
22743			data.left = dw - o.minWidth;
22744
22745		}
22746
22747		if ( ismaxw && cw ) {
22748
22749			data.left = dw - o.maxWidth;
22750
22751		}
22752
22753		if ( isminh && ch ) {
22754
22755			data.top = dh - o.minHeight;
22756
22757		}
22758
22759		if ( ismaxh && ch ) {
22760
22761			data.top = dh - o.maxHeight;
22762
22763		}
22764
22765
22766
22767		// Fixing jump error on top/left - bug #2330
22768
22769		if ( !data.width && !data.height && !data.left && data.top ) {
22770
22771			data.top = null;
22772
22773		} else if ( !data.width && !data.height && !data.top && data.left ) {
22774
22775			data.left = null;
22776
22777		}
22778
22779
22780
22781		return data;
22782
22783	},
22784
22785
22786
22787	_getPaddingPlusBorderDimensions: function( element ) {
22788
22789		var i = 0,
22790
22791			widths = [],
22792
22793			borders = [
22794
22795				element.css( "borderTopWidth" ),
22796
22797				element.css( "borderRightWidth" ),
22798
22799				element.css( "borderBottomWidth" ),
22800
22801				element.css( "borderLeftWidth" )
22802
22803			],
22804
22805			paddings = [
22806
22807				element.css( "paddingTop" ),
22808
22809				element.css( "paddingRight" ),
22810
22811				element.css( "paddingBottom" ),
22812
22813				element.css( "paddingLeft" )
22814
22815			];
22816
22817
22818
22819		for ( ; i < 4; i++ ) {
22820
22821			widths[ i ] = ( parseFloat( borders[ i ] ) || 0 );
22822
22823			widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 );
22824
22825		}
22826
22827
22828
22829		return {
22830
22831			height: widths[ 0 ] + widths[ 2 ],
22832
22833			width: widths[ 1 ] + widths[ 3 ]
22834
22835		};
22836
22837	},
22838
22839
22840
22841	_proportionallyResize: function() {
22842
22843
22844
22845		if ( !this._proportionallyResizeElements.length ) {
22846
22847			return;
22848
22849		}
22850
22851
22852
22853		var prel,
22854
22855			i = 0,
22856
22857			element = this.helper || this.element;
22858
22859
22860
22861		for ( ; i < this._proportionallyResizeElements.length; i++ ) {
22862
22863
22864
22865			prel = this._proportionallyResizeElements[ i ];
22866
22867
22868
22869			// TODO: Seems like a bug to cache this.outerDimensions
22870
22871			// considering that we are in a loop.
22872
22873			if ( !this.outerDimensions ) {
22874
22875				this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
22876
22877			}
22878
22879
22880
22881			prel.css( {
22882
22883				height: ( element.height() - this.outerDimensions.height ) || 0,
22884
22885				width: ( element.width() - this.outerDimensions.width ) || 0
22886
22887			} );
22888
22889
22890
22891		}
22892
22893
22894
22895	},
22896
22897
22898
22899	_renderProxy: function() {
22900
22901
22902
22903		var el = this.element, o = this.options;
22904
22905		this.elementOffset = el.offset();
22906
22907
22908
22909		if ( this._helper ) {
22910
22911
22912
22913			this.helper = this.helper || $( "<div style='overflow:hidden;'></div>" );
22914
22915
22916
22917			this._addClass( this.helper, this._helper );
22918
22919			this.helper.css( {
22920
22921				width: this.element.outerWidth(),
22922
22923				height: this.element.outerHeight(),
22924
22925				position: "absolute",
22926
22927				left: this.elementOffset.left + "px",
22928
22929				top: this.elementOffset.top + "px",
22930
22931				zIndex: ++o.zIndex //TODO: Don't modify option
22932
22933			} );
22934
22935
22936
22937			this.helper
22938
22939				.appendTo( "body" )
22940
22941				.disableSelection();
22942
22943
22944
22945		} else {
22946
22947			this.helper = this.element;
22948
22949		}
22950
22951
22952
22953	},
22954
22955
22956
22957	_change: {
22958
22959		e: function( event, dx ) {
22960
22961			return { width: this.originalSize.width + dx };
22962
22963		},
22964
22965		w: function( event, dx ) {
22966
22967			var cs = this.originalSize, sp = this.originalPosition;
22968
22969			return { left: sp.left + dx, width: cs.width - dx };
22970
22971		},
22972
22973		n: function( event, dx, dy ) {
22974
22975			var cs = this.originalSize, sp = this.originalPosition;
22976
22977			return { top: sp.top + dy, height: cs.height - dy };
22978
22979		},
22980
22981		s: function( event, dx, dy ) {
22982
22983			return { height: this.originalSize.height + dy };
22984
22985		},
22986
22987		se: function( event, dx, dy ) {
22988
22989			return $.extend( this._change.s.apply( this, arguments ),
22990
22991				this._change.e.apply( this, [ event, dx, dy ] ) );
22992
22993		},
22994
22995		sw: function( event, dx, dy ) {
22996
22997			return $.extend( this._change.s.apply( this, arguments ),
22998
22999				this._change.w.apply( this, [ event, dx, dy ] ) );
23000
23001		},
23002
23003		ne: function( event, dx, dy ) {
23004
23005			return $.extend( this._change.n.apply( this, arguments ),
23006
23007				this._change.e.apply( this, [ event, dx, dy ] ) );
23008
23009		},
23010
23011		nw: function( event, dx, dy ) {
23012
23013			return $.extend( this._change.n.apply( this, arguments ),
23014
23015				this._change.w.apply( this, [ event, dx, dy ] ) );
23016
23017		}
23018
23019	},
23020
23021
23022
23023	_propagate: function( n, event ) {
23024
23025		$.ui.plugin.call( this, n, [ event, this.ui() ] );
23026
23027		( n !== "resize" && this._trigger( n, event, this.ui() ) );
23028
23029	},
23030
23031
23032
23033	plugins: {},
23034
23035
23036
23037	ui: function() {
23038
23039		return {
23040
23041			originalElement: this.originalElement,
23042
23043			element: this.element,
23044
23045			helper: this.helper,
23046
23047			position: this.position,
23048
23049			size: this.size,
23050
23051			originalSize: this.originalSize,
23052
23053			originalPosition: this.originalPosition
23054
23055		};
23056
23057	}
23058
23059
23060
23061} );
23062
23063
23064
23065/*
23066
23067 * Resizable Extensions
23068
23069 */
23070
23071
23072
23073$.ui.plugin.add( "resizable", "animate", {
23074
23075
23076
23077	stop: function( event ) {
23078
23079		var that = $( this ).resizable( "instance" ),
23080
23081			o = that.options,
23082
23083			pr = that._proportionallyResizeElements,
23084
23085			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ),
23086
23087			soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height,
23088
23089			soffsetw = ista ? 0 : that.sizeDiff.width,
23090
23091			style = {
23092
23093				width: ( that.size.width - soffsetw ),
23094
23095				height: ( that.size.height - soffseth )
23096
23097			},
23098
23099			left = ( parseFloat( that.element.css( "left" ) ) +
23100
23101				( that.position.left - that.originalPosition.left ) ) || null,
23102
23103			top = ( parseFloat( that.element.css( "top" ) ) +
23104
23105				( that.position.top - that.originalPosition.top ) ) || null;
23106
23107
23108
23109		that.element.animate(
23110
23111			$.extend( style, top && left ? { top: top, left: left } : {} ), {
23112
23113				duration: o.animateDuration,
23114
23115				easing: o.animateEasing,
23116
23117				step: function() {
23118
23119
23120
23121					var data = {
23122
23123						width: parseFloat( that.element.css( "width" ) ),
23124
23125						height: parseFloat( that.element.css( "height" ) ),
23126
23127						top: parseFloat( that.element.css( "top" ) ),
23128
23129						left: parseFloat( that.element.css( "left" ) )
23130
23131					};
23132
23133
23134
23135					if ( pr && pr.length ) {
23136
23137						$( pr[ 0 ] ).css( { width: data.width, height: data.height } );
23138
23139					}
23140
23141
23142
23143					// Propagating resize, and updating values for each animation step
23144
23145					that._updateCache( data );
23146
23147					that._propagate( "resize", event );
23148
23149
23150
23151				}
23152
23153			}
23154
23155		);
23156
23157	}
23158
23159
23160
23161} );
23162
23163
23164
23165$.ui.plugin.add( "resizable", "containment", {
23166
23167
23168
23169	start: function() {
23170
23171		var element, p, co, ch, cw, width, height,
23172
23173			that = $( this ).resizable( "instance" ),
23174
23175			o = that.options,
23176
23177			el = that.element,
23178
23179			oc = o.containment,
23180
23181			ce = ( oc instanceof $ ) ?
23182
23183				oc.get( 0 ) :
23184
23185				( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
23186
23187
23188
23189		if ( !ce ) {
23190
23191			return;
23192
23193		}
23194
23195
23196
23197		that.containerElement = $( ce );
23198
23199
23200
23201		if ( /document/.test( oc ) || oc === document ) {
23202
23203			that.containerOffset = {
23204
23205				left: 0,
23206
23207				top: 0
23208
23209			};
23210
23211			that.containerPosition = {
23212
23213				left: 0,
23214
23215				top: 0
23216
23217			};
23218
23219
23220
23221			that.parentData = {
23222
23223				element: $( document ),
23224
23225				left: 0,
23226
23227				top: 0,
23228
23229				width: $( document ).width(),
23230
23231				height: $( document ).height() || document.body.parentNode.scrollHeight
23232
23233			};
23234
23235		} else {
23236
23237			element = $( ce );
23238
23239			p = [];
23240
23241			$( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) {
23242
23243				p[ i ] = that._num( element.css( "padding" + name ) );
23244
23245			} );
23246
23247
23248
23249			that.containerOffset = element.offset();
23250
23251			that.containerPosition = element.position();
23252
23253			that.containerSize = {
23254
23255				height: ( element.innerHeight() - p[ 3 ] ),
23256
23257				width: ( element.innerWidth() - p[ 1 ] )
23258
23259			};
23260
23261
23262
23263			co = that.containerOffset;
23264
23265			ch = that.containerSize.height;
23266
23267			cw = that.containerSize.width;
23268
23269			width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
23270
23271			height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
23272
23273
23274
23275			that.parentData = {
23276
23277				element: ce,
23278
23279				left: co.left,
23280
23281				top: co.top,
23282
23283				width: width,
23284
23285				height: height
23286
23287			};
23288
23289		}
23290
23291	},
23292
23293
23294
23295	resize: function( event ) {
23296
23297		var woset, hoset, isParent, isOffsetRelative,
23298
23299			that = $( this ).resizable( "instance" ),
23300
23301			o = that.options,
23302
23303			co = that.containerOffset,
23304
23305			cp = that.position,
23306
23307			pRatio = that._aspectRatio || event.shiftKey,
23308
23309			cop = {
23310
23311				top: 0,
23312
23313				left: 0
23314
23315			},
23316
23317			ce = that.containerElement,
23318
23319			continueResize = true;
23320
23321
23322
23323		if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
23324
23325			cop = co;
23326
23327		}
23328
23329
23330
23331		if ( cp.left < ( that._helper ? co.left : 0 ) ) {
23332
23333			that.size.width = that.size.width +
23334
23335				( that._helper ?
23336
23337					( that.position.left - co.left ) :
23338
23339					( that.position.left - cop.left ) );
23340
23341
23342
23343			if ( pRatio ) {
23344
23345				that.size.height = that.size.width / that.aspectRatio;
23346
23347				continueResize = false;
23348
23349			}
23350
23351			that.position.left = o.helper ? co.left : 0;
23352
23353		}
23354
23355
23356
23357		if ( cp.top < ( that._helper ? co.top : 0 ) ) {
23358
23359			that.size.height = that.size.height +
23360
23361				( that._helper ?
23362
23363					( that.position.top - co.top ) :
23364
23365					that.position.top );
23366
23367
23368
23369			if ( pRatio ) {
23370
23371				that.size.width = that.size.height * that.aspectRatio;
23372
23373				continueResize = false;
23374
23375			}
23376
23377			that.position.top = that._helper ? co.top : 0;
23378
23379		}
23380
23381
23382
23383		isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
23384
23385		isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
23386
23387
23388
23389		if ( isParent && isOffsetRelative ) {
23390
23391			that.offset.left = that.parentData.left + that.position.left;
23392
23393			that.offset.top = that.parentData.top + that.position.top;
23394
23395		} else {
23396
23397			that.offset.left = that.element.offset().left;
23398
23399			that.offset.top = that.element.offset().top;
23400
23401		}
23402
23403
23404
23405		woset = Math.abs( that.sizeDiff.width +
23406
23407			( that._helper ?
23408
23409				that.offset.left - cop.left :
23410
23411				( that.offset.left - co.left ) ) );
23412
23413
23414
23415		hoset = Math.abs( that.sizeDiff.height +
23416
23417			( that._helper ?
23418
23419				that.offset.top - cop.top :
23420
23421				( that.offset.top - co.top ) ) );
23422
23423
23424
23425		if ( woset + that.size.width >= that.parentData.width ) {
23426
23427			that.size.width = that.parentData.width - woset;
23428
23429			if ( pRatio ) {
23430
23431				that.size.height = that.size.width / that.aspectRatio;
23432
23433				continueResize = false;
23434
23435			}
23436
23437		}
23438
23439
23440
23441		if ( hoset + that.size.height >= that.parentData.height ) {
23442
23443			that.size.height = that.parentData.height - hoset;
23444
23445			if ( pRatio ) {
23446
23447				that.size.width = that.size.height * that.aspectRatio;
23448
23449				continueResize = false;
23450
23451			}
23452
23453		}
23454
23455
23456
23457		if ( !continueResize ) {
23458
23459			that.position.left = that.prevPosition.left;
23460
23461			that.position.top = that.prevPosition.top;
23462
23463			that.size.width = that.prevSize.width;
23464
23465			that.size.height = that.prevSize.height;
23466
23467		}
23468
23469	},
23470
23471
23472
23473	stop: function() {
23474
23475		var that = $( this ).resizable( "instance" ),
23476
23477			o = that.options,
23478
23479			co = that.containerOffset,
23480
23481			cop = that.containerPosition,
23482
23483			ce = that.containerElement,
23484
23485			helper = $( that.helper ),
23486
23487			ho = helper.offset(),
23488
23489			w = helper.outerWidth() - that.sizeDiff.width,
23490
23491			h = helper.outerHeight() - that.sizeDiff.height;
23492
23493
23494
23495		if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
23496
23497			$( this ).css( {
23498
23499				left: ho.left - cop.left - co.left,
23500
23501				width: w,
23502
23503				height: h
23504
23505			} );
23506
23507		}
23508
23509
23510
23511		if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
23512
23513			$( this ).css( {
23514
23515				left: ho.left - cop.left - co.left,
23516
23517				width: w,
23518
23519				height: h
23520
23521			} );
23522
23523		}
23524
23525	}
23526
23527} );
23528
23529
23530
23531$.ui.plugin.add( "resizable", "alsoResize", {
23532
23533
23534
23535	start: function() {
23536
23537		var that = $( this ).resizable( "instance" ),
23538
23539			o = that.options;
23540
23541
23542
23543		$( o.alsoResize ).each( function() {
23544
23545			var el = $( this );
23546
23547			el.data( "ui-resizable-alsoresize", {
23548
23549				width: parseFloat( el.width() ), height: parseFloat( el.height() ),
23550
23551				left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
23552
23553			} );
23554
23555		} );
23556
23557	},
23558
23559
23560
23561	resize: function( event, ui ) {
23562
23563		var that = $( this ).resizable( "instance" ),
23564
23565			o = that.options,
23566
23567			os = that.originalSize,
23568
23569			op = that.originalPosition,
23570
23571			delta = {
23572
23573				height: ( that.size.height - os.height ) || 0,
23574
23575				width: ( that.size.width - os.width ) || 0,
23576
23577				top: ( that.position.top - op.top ) || 0,
23578
23579				left: ( that.position.left - op.left ) || 0
23580
23581			};
23582
23583
23584
23585			$( o.alsoResize ).each( function() {
23586
23587				var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {},
23588
23589					css = el.parents( ui.originalElement[ 0 ] ).length ?
23590
23591							[ "width", "height" ] :
23592
23593							[ "width", "height", "top", "left" ];
23594
23595
23596
23597				$.each( css, function( i, prop ) {
23598
23599					var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 );
23600
23601					if ( sum && sum >= 0 ) {
23602
23603						style[ prop ] = sum || null;
23604
23605					}
23606
23607				} );
23608
23609
23610
23611				el.css( style );
23612
23613			} );
23614
23615	},
23616
23617
23618
23619	stop: function() {
23620
23621		$( this ).removeData( "ui-resizable-alsoresize" );
23622
23623	}
23624
23625} );
23626
23627
23628
23629$.ui.plugin.add( "resizable", "ghost", {
23630
23631
23632
23633	start: function() {
23634
23635
23636
23637		var that = $( this ).resizable( "instance" ), cs = that.size;
23638
23639
23640
23641		that.ghost = that.originalElement.clone();
23642
23643		that.ghost.css( {
23644
23645			opacity: 0.25,
23646
23647			display: "block",
23648
23649			position: "relative",
23650
23651			height: cs.height,
23652
23653			width: cs.width,
23654
23655			margin: 0,
23656
23657			left: 0,
23658
23659			top: 0
23660
23661		} );
23662
23663
23664
23665		that._addClass( that.ghost, "ui-resizable-ghost" );
23666
23667
23668
23669		// DEPRECATED
23670
23671		// TODO: remove after 1.12
23672
23673		if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) {
23674
23675
23676
23677			// Ghost option
23678
23679			that.ghost.addClass( this.options.ghost );
23680
23681		}
23682
23683
23684
23685		that.ghost.appendTo( that.helper );
23686
23687
23688
23689	},
23690
23691
23692
23693	resize: function() {
23694
23695		var that = $( this ).resizable( "instance" );
23696
23697		if ( that.ghost ) {
23698
23699			that.ghost.css( {
23700
23701				position: "relative",
23702
23703				height: that.size.height,
23704
vendor: 5,375 bytes, lines 23705-24116
23705				width: that.size.width
23706
23707			} );
23708
23709		}
23710
23711	},
23712
23713
23714
23715	stop: function() {
23716
23717		var that = $( this ).resizable( "instance" );
23718
23719		if ( that.ghost && that.helper ) {
23720
23721			that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) );
23722
23723		}
23724
23725	}
23726
23727
23728
23729} );
23730
23731
23732
23733$.ui.plugin.add( "resizable", "grid", {
23734
23735
23736
23737	resize: function() {
23738
23739		var outerDimensions,
23740
23741			that = $( this ).resizable( "instance" ),
23742
23743			o = that.options,
23744
23745			cs = that.size,
23746
23747			os = that.originalSize,
23748
23749			op = that.originalPosition,
23750
23751			a = that.axis,
23752
23753			grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
23754
23755			gridX = ( grid[ 0 ] || 1 ),
23756
23757			gridY = ( grid[ 1 ] || 1 ),
23758
23759			ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX,
23760
23761			oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY,
23762
23763			newWidth = os.width + ox,
23764
23765			newHeight = os.height + oy,
23766
23767			isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ),
23768
23769			isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ),
23770
23771			isMinWidth = o.minWidth && ( o.minWidth > newWidth ),
23772
23773			isMinHeight = o.minHeight && ( o.minHeight > newHeight );
23774
23775
23776
23777		o.grid = grid;
23778
23779
23780
23781		if ( isMinWidth ) {
23782
23783			newWidth += gridX;
23784
23785		}
23786
23787		if ( isMinHeight ) {
23788
23789			newHeight += gridY;
23790
23791		}
23792
23793		if ( isMaxWidth ) {
23794
23795			newWidth -= gridX;
23796
23797		}
23798
23799		if ( isMaxHeight ) {
23800
23801			newHeight -= gridY;
23802
23803		}
23804
23805
23806
23807		if ( /^(se|s|e)$/.test( a ) ) {
23808
23809			that.size.width = newWidth;
23810
23811			that.size.height = newHeight;
23812
23813		} else if ( /^(ne)$/.test( a ) ) {
23814
23815			that.size.width = newWidth;
23816
23817			that.size.height = newHeight;
23818
23819			that.position.top = op.top - oy;
23820
23821		} else if ( /^(sw)$/.test( a ) ) {
23822
23823			that.size.width = newWidth;
23824
23825			that.size.height = newHeight;
23826
23827			that.position.left = op.left - ox;
23828
23829		} else {
23830
23831			if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) {
23832
23833				outerDimensions = that._getPaddingPlusBorderDimensions( this );
23834
23835			}
23836
23837
23838
23839			if ( newHeight - gridY > 0 ) {
23840
23841				that.size.height = newHeight;
23842
23843				that.position.top = op.top - oy;
23844
23845			} else {
23846
23847				newHeight = gridY - outerDimensions.height;
23848
23849				that.size.height = newHeight;
23850
23851				that.position.top = op.top + os.height - newHeight;
23852
23853			}
23854
23855			if ( newWidth - gridX > 0 ) {
23856
23857				that.size.width = newWidth;
23858
23859				that.position.left = op.left - ox;
23860
23861			} else {
23862
23863				newWidth = gridX - outerDimensions.width;
23864
23865				that.size.width = newWidth;
23866
23867				that.position.left = op.left + os.width - newWidth;
23868
23869			}
23870
23871		}
23872
23873	}
23874
23875
23876
23877} );
23878
23879
23880
23881var widgetsResizable = $.ui.resizable;
23882
23883
23884
23885
23886
23887/*!
23888
23889 * jQuery UI Dialog 1.12.1
23890
23891 * http://jqueryui.com
23892
23893 *
23894
23895 * Copyright jQuery Foundation and other contributors
23896
23897 * Released under the MIT license.
23898
23899 * http://jquery.org/license
23900
23901 */
23902
23903
23904
23905//>>label: Dialog
23906
23907//>>group: Widgets
23908
23909//>>description: Displays customizable dialog windows.
23910
23911//>>docs: http://api.jqueryui.com/dialog/
23912
23913//>>demos: http://jqueryui.com/dialog/
23914
23915//>>css.structure: ../../themes/base/core.css
23916
23917//>>css.structure: ../../themes/base/dialog.css
23918
23919//>>css.theme: ../../themes/base/theme.css
23920
23921
23922
23923
23924
23925
23926
23927$.widget( "ui.dialog", {
23928
23929	version: "1.12.1",
23930
23931	options: {
23932
23933		appendTo: "body",
23934
23935		autoOpen: true,
23936
23937		buttons: [],
23938
23939		classes: {
23940
23941			"ui-dialog": "ui-corner-all",
23942
23943			"ui-dialog-titlebar": "ui-corner-all"
23944
23945		},
23946
23947		closeOnEscape: true,
23948
23949		closeText: "Close",
23950
23951		draggable: true,
23952
23953		hide: null,
23954
23955		height: "auto",
23956
23957		maxHeight: null,
23958
23959		maxWidth: null,
23960
23961		minHeight: 150,
23962
23963		minWidth: 150,
23964
23965		modal: false,
23966
23967		position: {
23968
23969			my: "center",
23970
23971			at: "center",
23972
23973			of: window,
23974
23975			collision: "fit",
23976
23977
23978
23979			// Ensure the titlebar is always visible
23980
23981			using: function( pos ) {
23982
23983				var topOffset = $( this ).css( pos ).offset().top;
23984
23985				if ( topOffset < 0 ) {
23986
23987					$( this ).css( "top", pos.top - topOffset );
23988
23989				}
23990
23991			}
23992
23993		},
23994
23995		resizable: true,
23996
23997		show: null,
23998
23999		title: null,
24000
24001		width: 300,
24002
24003
24004
24005		// Callbacks
24006
24007		beforeClose: null,
24008
24009		close: null,
24010
24011		drag: null,
24012
24013		dragStart: null,
24014
24015		dragStop: null,
24016
24017		focus: null,
24018
24019		open: null,
24020
24021		resize: null,
24022
24023		resizeStart: null,
24024
24025		resizeStop: null
24026
24027	},
24028
24029
24030
24031	sizeRelatedOptions: {
24032
24033		buttons: true,
24034
24035		height: true,
24036
24037		maxHeight: true,
24038
24039		maxWidth: true,
24040
24041		minHeight: true,
24042
24043		minWidth: true,
24044
24045		width: true
24046
24047	},
24048
24049
24050
24051	resizableRelatedOptions: {
24052
24053		maxHeight: true,
24054
24055		maxWidth: true,
24056
24057		minHeight: true,
24058
24059		minWidth: true
24060
24061	},
24062
24063
24064
24065	_create: function() {
24066
24067		this.originalCss = {
24068
24069			display: this.element[ 0 ].style.display,
24070
24071			width: this.element[ 0 ].style.width,
24072
24073			minHeight: this.element[ 0 ].style.minHeight,
24074
24075			maxHeight: this.element[ 0 ].style.maxHeight,
24076
24077			height: this.element[ 0 ].style.height
24078
24079		};
24080
24081		this.originalPosition = {
24082
24083			parent: this.element.parent(),
24084
24085			index: this.element.parent().children().index( this.element )
24086
24087		};
24088
24089		this.originalTitle = this.element.attr( "title" );
24090
24091		if ( this.options.title == null && this.originalTitle != null ) {
24092
24093			this.options.title = this.originalTitle;
24094
24095		}
24096
24097
24098
24099		// Dialogs can't be disabled
24100
24101		if ( this.options.disabled ) {
24102
24103			this.options.disabled = false;
24104
24105		}
24106
24107
24108
24109		this._createWrapper();
24110
24111
24112
24113		this.element
24114
24115			.show()
24116
vendor: 36,777 bytes, lines 24117-26683
24117			.removeAttr( "title" )
24118
24119			.appendTo( this.uiDialog );
24120
24121
24122
24123		this._addClass( "ui-dialog-content", "ui-widget-content" );
24124
24125
24126
24127		this._createTitlebar();
24128
24129		this._createButtonPane();
24130
24131
24132
24133		if ( this.options.draggable && $.fn.draggable ) {
24134
24135			this._makeDraggable();
24136
24137		}
24138
24139		if ( this.options.resizable && $.fn.resizable ) {
24140
24141			this._makeResizable();
24142
24143		}
24144
24145
24146
24147		this._isOpen = false;
24148
24149
24150
24151		this._trackFocus();
24152
24153	},
24154
24155
24156
24157	_init: function() {
24158
24159		if ( this.options.autoOpen ) {
24160
24161			this.open();
24162
24163		}
24164
24165	},
24166
24167
24168
24169	_appendTo: function() {
24170
24171		var element = this.options.appendTo;
24172
24173		if ( element && ( element.jquery || element.nodeType ) ) {
24174
24175			return $( element );
24176
24177		}
24178
24179		return this.document.find( element || "body" ).eq( 0 );
24180
24181	},
24182
24183
24184
24185	_destroy: function() {
24186
24187		var next,
24188
24189			originalPosition = this.originalPosition;
24190
24191
24192
24193		this._untrackInstance();
24194
24195		this._destroyOverlay();
24196
24197
24198
24199		this.element
24200
24201			.removeUniqueId()
24202
24203			.css( this.originalCss )
24204
24205
24206
24207			// Without detaching first, the following becomes really slow
24208
24209			.detach();
24210
24211
24212
24213		this.uiDialog.remove();
24214
24215
24216
24217		if ( this.originalTitle ) {
24218
24219			this.element.attr( "title", this.originalTitle );
24220
24221		}
24222
24223
24224
24225		next = originalPosition.parent.children().eq( originalPosition.index );
24226
24227
24228
24229		// Don't try to place the dialog next to itself (#8613)
24230
24231		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
24232
24233			next.before( this.element );
24234
24235		} else {
24236
24237			originalPosition.parent.append( this.element );
24238
24239		}
24240
24241	},
24242
24243
24244
24245	widget: function() {
24246
24247		return this.uiDialog;
24248
24249	},
24250
24251
24252
24253	disable: $.noop,
24254
24255	enable: $.noop,
24256
24257
24258
24259	close: function( event ) {
24260
24261		var that = this;
24262
24263
24264
24265		if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
24266
24267			return;
24268
24269		}
24270
24271
24272
24273		this._isOpen = false;
24274
24275		this._focusedElement = null;
24276
24277		this._destroyOverlay();
24278
24279		this._untrackInstance();
24280
24281
24282
24283		if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) {
24284
24285
24286
24287			// Hiding a focused element doesn't trigger blur in WebKit
24288
24289			// so in case we have nothing to focus on, explicitly blur the active element
24290
24291			// https://bugs.webkit.org/show_bug.cgi?id=47182
24292
24293			$.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) );
24294
24295		}
24296
24297
24298
24299		this._hide( this.uiDialog, this.options.hide, function() {
24300
24301			that._trigger( "close", event );
24302
24303		} );
24304
24305	},
24306
24307
24308
24309	isOpen: function() {
24310
24311		return this._isOpen;
24312
24313	},
24314
24315
24316
24317	moveToTop: function() {
24318
24319		this._moveToTop();
24320
24321	},
24322
24323
24324
24325	_moveToTop: function( event, silent ) {
24326
24327		var moved = false,
24328
24329			zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() {
24330
24331				return +$( this ).css( "z-index" );
24332
24333			} ).get(),
24334
24335			zIndexMax = Math.max.apply( null, zIndices );
24336
24337
24338
24339		if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
24340
24341			this.uiDialog.css( "z-index", zIndexMax + 1 );
24342
24343			moved = true;
24344
24345		}
24346
24347
24348
24349		if ( moved && !silent ) {
24350
24351			this._trigger( "focus", event );
24352
24353		}
24354
24355		return moved;
24356
24357	},
24358
24359
24360
24361	open: function() {
24362
24363		var that = this;
24364
24365		if ( this._isOpen ) {
24366
24367			if ( this._moveToTop() ) {
24368
24369				this._focusTabbable();
24370
24371			}
24372
24373			return;
24374
24375		}
24376
24377
24378
24379		this._isOpen = true;
24380
24381		this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
24382
24383
24384
24385		this._size();
24386
24387		this._position();
24388
24389		this._createOverlay();
24390
24391		this._moveToTop( null, true );
24392
24393
24394
24395		// Ensure the overlay is moved to the top with the dialog, but only when
24396
24397		// opening. The overlay shouldn't move after the dialog is open so that
24398
24399		// modeless dialogs opened after the modal dialog stack properly.
24400
24401		if ( this.overlay ) {
24402
24403			this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
24404
24405		}
24406
24407
24408
24409		this._show( this.uiDialog, this.options.show, function() {
24410
24411			that._focusTabbable();
24412
24413			that._trigger( "focus" );
24414
24415		} );
24416
24417
24418
24419		// Track the dialog immediately upon openening in case a focus event
24420
24421		// somehow occurs outside of the dialog before an element inside the
24422
24423		// dialog is focused (#10152)
24424
24425		this._makeFocusTarget();
24426
24427
24428
24429		this._trigger( "open" );
24430
24431	},
24432
24433
24434
24435	_focusTabbable: function() {
24436
24437
24438
24439		// Set focus to the first match:
24440
24441		// 1. An element that was focused previously
24442
24443		// 2. First element inside the dialog matching [autofocus]
24444
24445		// 3. Tabbable element inside the content element
24446
24447		// 4. Tabbable element inside the buttonpane
24448
24449		// 5. The close button
24450
24451		// 6. The dialog itself
24452
24453		var hasFocus = this._focusedElement;
24454
24455		if ( !hasFocus ) {
24456
24457			hasFocus = this.element.find( "[autofocus]" );
24458
24459		}
24460
24461		if ( !hasFocus.length ) {
24462
24463			hasFocus = this.element.find( ":tabbable" );
24464
24465		}
24466
24467		if ( !hasFocus.length ) {
24468
24469			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
24470
24471		}
24472
24473		if ( !hasFocus.length ) {
24474
24475			hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
24476
24477		}
24478
24479		if ( !hasFocus.length ) {
24480
24481			hasFocus = this.uiDialog;
24482
24483		}
24484
24485		hasFocus.eq( 0 ).trigger( "focus" );
24486
24487	},
24488
24489
24490
24491	_keepFocus: function( event ) {
24492
24493		function checkFocus() {
24494
24495			var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
24496
24497				isActive = this.uiDialog[ 0 ] === activeElement ||
24498
24499					$.contains( this.uiDialog[ 0 ], activeElement );
24500
24501			if ( !isActive ) {
24502
24503				this._focusTabbable();
24504
24505			}
24506
24507		}
24508
24509		event.preventDefault();
24510
24511		checkFocus.call( this );
24512
24513
24514
24515		// support: IE
24516
24517		// IE <= 8 doesn't prevent moving focus even with event.preventDefault()
24518
24519		// so we check again later
24520
24521		this._delay( checkFocus );
24522
24523	},
24524
24525
24526
24527	_createWrapper: function() {
24528
24529		this.uiDialog = $( "<div>" )
24530
24531			.hide()
24532
24533			.attr( {
24534
24535
24536
24537				// Setting tabIndex makes the div focusable
24538
24539				tabIndex: -1,
24540
24541				role: "dialog"
24542
24543			} )
24544
24545			.appendTo( this._appendTo() );
24546
24547
24548
24549		this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" );
24550
24551		this._on( this.uiDialog, {
24552
24553			keydown: function( event ) {
24554
24555				if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
24556
24557						event.keyCode === $.ui.keyCode.ESCAPE ) {
24558
24559					event.preventDefault();
24560
24561					this.close( event );
24562
24563					return;
24564
24565				}
24566
24567
24568
24569				// Prevent tabbing out of dialogs
24570
24571				if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
24572
24573					return;
24574
24575				}
24576
24577				var tabbables = this.uiDialog.find( ":tabbable" ),
24578
24579					first = tabbables.filter( ":first" ),
24580
24581					last = tabbables.filter( ":last" );
24582
24583
24584
24585				if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) &&
24586
24587						!event.shiftKey ) {
24588
24589					this._delay( function() {
24590
24591						first.trigger( "focus" );
24592
24593					} );
24594
24595					event.preventDefault();
24596
24597				} else if ( ( event.target === first[ 0 ] ||
24598
24599						event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) {
24600
24601					this._delay( function() {
24602
24603						last.trigger( "focus" );
24604
24605					} );
24606
24607					event.preventDefault();
24608
24609				}
24610
24611			},
24612
24613			mousedown: function( event ) {
24614
24615				if ( this._moveToTop( event ) ) {
24616
24617					this._focusTabbable();
24618
24619				}
24620
24621			}
24622
24623		} );
24624
24625
24626
24627		// We assume that any existing aria-describedby attribute means
24628
24629		// that the dialog content is marked up properly
24630
24631		// otherwise we brute force the content as the description
24632
24633		if ( !this.element.find( "[aria-describedby]" ).length ) {
24634
24635			this.uiDialog.attr( {
24636
24637				"aria-describedby": this.element.uniqueId().attr( "id" )
24638
24639			} );
24640
24641		}
24642
24643	},
24644
24645
24646
24647	_createTitlebar: function() {
24648
24649		var uiDialogTitle;
24650
24651
24652
24653		this.uiDialogTitlebar = $( "<div>" );
24654
24655		this._addClass( this.uiDialogTitlebar,
24656
24657			"ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" );
24658
24659		this._on( this.uiDialogTitlebar, {
24660
24661			mousedown: function( event ) {
24662
24663
24664
24665				// Don't prevent click on close button (#8838)
24666
24667				// Focusing a dialog that is partially scrolled out of view
24668
24669				// causes the browser to scroll it into view, preventing the click event
24670
24671				if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
24672
24673
24674
24675					// Dialog isn't getting focus when dragging (#8063)
24676
24677					this.uiDialog.trigger( "focus" );
24678
24679				}
24680
24681			}
24682
24683		} );
24684
24685
24686
24687		// Support: IE
24688
24689		// Use type="button" to prevent enter keypresses in textboxes from closing the
24690
24691		// dialog in IE (#9312)
24692
24693		this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
24694
24695			.button( {
24696
24697				label: $( "<a>" ).text( this.options.closeText ).html(),
24698
24699				icon: "ui-icon-closethick",
24700
24701				showLabel: false
24702
24703			} )
24704
24705			.appendTo( this.uiDialogTitlebar );
24706
24707
24708
24709		this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" );
24710
24711		this._on( this.uiDialogTitlebarClose, {
24712
24713			click: function( event ) {
24714
24715				event.preventDefault();
24716
24717				this.close( event );
24718
24719			}
24720
24721		} );
24722
24723
24724
24725		uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar );
24726
24727		this._addClass( uiDialogTitle, "ui-dialog-title" );
24728
24729		this._title( uiDialogTitle );
24730
24731
24732
24733		this.uiDialogTitlebar.prependTo( this.uiDialog );
24734
24735
24736
24737		this.uiDialog.attr( {
24738
24739			"aria-labelledby": uiDialogTitle.attr( "id" )
24740
24741		} );
24742
24743	},
24744
24745
24746
24747	_title: function( title ) {
24748
24749		if ( this.options.title ) {
24750
24751			title.text( this.options.title );
24752
24753		} else {
24754
24755			title.html( "&#160;" );
24756
24757		}
24758
24759	},
24760
24761
24762
24763	_createButtonPane: function() {
24764
24765		this.uiDialogButtonPane = $( "<div>" );
24766
24767		this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane",
24768
24769			"ui-widget-content ui-helper-clearfix" );
24770
24771
24772
24773		this.uiButtonSet = $( "<div>" )
24774
24775			.appendTo( this.uiDialogButtonPane );
24776
24777		this._addClass( this.uiButtonSet, "ui-dialog-buttonset" );
24778
24779
24780
24781		this._createButtons();
24782
24783	},
24784
24785
24786
24787	_createButtons: function() {
24788
24789		var that = this,
24790
24791			buttons = this.options.buttons;
24792
24793
24794
24795		// If we already have a button pane, remove it
24796
24797		this.uiDialogButtonPane.remove();
24798
24799		this.uiButtonSet.empty();
24800
24801
24802
24803		if ( $.isEmptyObject( buttons ) || ( $.isArray( buttons ) && !buttons.length ) ) {
24804
24805			this._removeClass( this.uiDialog, "ui-dialog-buttons" );
24806
24807			return;
24808
24809		}
24810
24811
24812
24813		$.each( buttons, function( name, props ) {
24814
24815			var click, buttonOptions;
24816
24817			props = $.isFunction( props ) ?
24818
24819				{ click: props, text: name } :
24820
24821				props;
24822
24823
24824
24825			// Default to a non-submitting button
24826
24827			props = $.extend( { type: "button" }, props );
24828
24829
24830
24831			// Change the context for the click callback to be the main element
24832
24833			click = props.click;
24834
24835			buttonOptions = {
24836
24837				icon: props.icon,
24838
24839				iconPosition: props.iconPosition,
24840
24841				showLabel: props.showLabel,
24842
24843
24844
24845				// Deprecated options
24846
24847				icons: props.icons,
24848
24849				text: props.text
24850
24851			};
24852
24853
24854
24855			delete props.click;
24856
24857			delete props.icon;
24858
24859			delete props.iconPosition;
24860
24861			delete props.showLabel;
24862
24863
24864
24865			// Deprecated options
24866
24867			delete props.icons;
24868
24869			if ( typeof props.text === "boolean" ) {
24870
24871				delete props.text;
24872
24873			}
24874
24875
24876
24877			$( "<button></button>", props )
24878
24879				.button( buttonOptions )
24880
24881				.appendTo( that.uiButtonSet )
24882
24883				.on( "click", function() {
24884
24885					click.apply( that.element[ 0 ], arguments );
24886
24887				} );
24888
24889		} );
24890
24891		this._addClass( this.uiDialog, "ui-dialog-buttons" );
24892
24893		this.uiDialogButtonPane.appendTo( this.uiDialog );
24894
24895	},
24896
24897
24898
24899	_makeDraggable: function() {
24900
24901		var that = this,
24902
24903			options = this.options;
24904
24905
24906
24907		function filteredUi( ui ) {
24908
24909			return {
24910
24911				position: ui.position,
24912
24913				offset: ui.offset
24914
24915			};
24916
24917		}
24918
24919
24920
24921		this.uiDialog.draggable( {
24922
24923			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
24924
24925			handle: ".ui-dialog-titlebar",
24926
24927			containment: "document",
24928
24929			start: function( event, ui ) {
24930
24931				that._addClass( $( this ), "ui-dialog-dragging" );
24932
24933				that._blockFrames();
24934
24935				that._trigger( "dragStart", event, filteredUi( ui ) );
24936
24937			},
24938
24939			drag: function( event, ui ) {
24940
24941				that._trigger( "drag", event, filteredUi( ui ) );
24942
24943			},
24944
24945			stop: function( event, ui ) {
24946
24947				var left = ui.offset.left - that.document.scrollLeft(),
24948
24949					top = ui.offset.top - that.document.scrollTop();
24950
24951
24952
24953				options.position = {
24954
24955					my: "left top",
24956
24957					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
24958
24959						"top" + ( top >= 0 ? "+" : "" ) + top,
24960
24961					of: that.window
24962
24963				};
24964
24965				that._removeClass( $( this ), "ui-dialog-dragging" );
24966
24967				that._unblockFrames();
24968
24969				that._trigger( "dragStop", event, filteredUi( ui ) );
24970
24971			}
24972
24973		} );
24974
24975	},
24976
24977
24978
24979	_makeResizable: function() {
24980
24981		var that = this,
24982
24983			options = this.options,
24984
24985			handles = options.resizable,
24986
24987
24988
24989			// .ui-resizable has position: relative defined in the stylesheet
24990
24991			// but dialogs have to use absolute or fixed positioning
24992
24993			position = this.uiDialog.css( "position" ),
24994
24995			resizeHandles = typeof handles === "string" ?
24996
24997				handles :
24998
24999				"n,e,s,w,se,sw,ne,nw";
25000
25001
25002
25003		function filteredUi( ui ) {
25004
25005			return {
25006
25007				originalPosition: ui.originalPosition,
25008
25009				originalSize: ui.originalSize,
25010
25011				position: ui.position,
25012
25013				size: ui.size
25014
25015			};
25016
25017		}
25018
25019
25020
25021		this.uiDialog.resizable( {
25022
25023			cancel: ".ui-dialog-content",
25024
25025			containment: "document",
25026
25027			alsoResize: this.element,
25028
25029			maxWidth: options.maxWidth,
25030
25031			maxHeight: options.maxHeight,
25032
25033			minWidth: options.minWidth,
25034
25035			minHeight: this._minHeight(),
25036
25037			handles: resizeHandles,
25038
25039			start: function( event, ui ) {
25040
25041				that._addClass( $( this ), "ui-dialog-resizing" );
25042
25043				that._blockFrames();
25044
25045				that._trigger( "resizeStart", event, filteredUi( ui ) );
25046
25047			},
25048
25049			resize: function( event, ui ) {
25050
25051				that._trigger( "resize", event, filteredUi( ui ) );
25052
25053			},
25054
25055			stop: function( event, ui ) {
25056
25057				var offset = that.uiDialog.offset(),
25058
25059					left = offset.left - that.document.scrollLeft(),
25060
25061					top = offset.top - that.document.scrollTop();
25062
25063
25064
25065				options.height = that.uiDialog.height();
25066
25067				options.width = that.uiDialog.width();
25068
25069				options.position = {
25070
25071					my: "left top",
25072
25073					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
25074
25075						"top" + ( top >= 0 ? "+" : "" ) + top,
25076
25077					of: that.window
25078
25079				};
25080
25081				that._removeClass( $( this ), "ui-dialog-resizing" );
25082
25083				that._unblockFrames();
25084
25085				that._trigger( "resizeStop", event, filteredUi( ui ) );
25086
25087			}
25088
25089		} )
25090
25091			.css( "position", position );
25092
25093	},
25094
25095
25096
25097	_trackFocus: function() {
25098
25099		this._on( this.widget(), {
25100
25101			focusin: function( event ) {
25102
25103				this._makeFocusTarget();
25104
25105				this._focusedElement = $( event.target );
25106
25107			}
25108
25109		} );
25110
25111	},
25112
25113
25114
25115	_makeFocusTarget: function() {
25116
25117		this._untrackInstance();
25118
25119		this._trackingInstances().unshift( this );
25120
25121	},
25122
25123
25124
25125	_untrackInstance: function() {
25126
25127		var instances = this._trackingInstances(),
25128
25129			exists = $.inArray( this, instances );
25130
25131		if ( exists !== -1 ) {
25132
25133			instances.splice( exists, 1 );
25134
25135		}
25136
25137	},
25138
25139
25140
25141	_trackingInstances: function() {
25142
25143		var instances = this.document.data( "ui-dialog-instances" );
25144
25145		if ( !instances ) {
25146
25147			instances = [];
25148
25149			this.document.data( "ui-dialog-instances", instances );
25150
25151		}
25152
25153		return instances;
25154
25155	},
25156
25157
25158
25159	_minHeight: function() {
25160
25161		var options = this.options;
25162
25163
25164
25165		return options.height === "auto" ?
25166
25167			options.minHeight :
25168
25169			Math.min( options.minHeight, options.height );
25170
25171	},
25172
25173
25174
25175	_position: function() {
25176
25177
25178
25179		// Need to show the dialog to get the actual offset in the position plugin
25180
25181		var isVisible = this.uiDialog.is( ":visible" );
25182
25183		if ( !isVisible ) {
25184
25185			this.uiDialog.show();
25186
25187		}
25188
25189		this.uiDialog.position( this.options.position );
25190
25191		if ( !isVisible ) {
25192
25193			this.uiDialog.hide();
25194
25195		}
25196
25197	},
25198
25199
25200
25201	_setOptions: function( options ) {
25202
25203		var that = this,
25204
25205			resize = false,
25206
25207			resizableOptions = {};
25208
25209
25210
25211		$.each( options, function( key, value ) {
25212
25213			that._setOption( key, value );
25214
25215
25216
25217			if ( key in that.sizeRelatedOptions ) {
25218
25219				resize = true;
25220
25221			}
25222
25223			if ( key in that.resizableRelatedOptions ) {
25224
25225				resizableOptions[ key ] = value;
25226
25227			}
25228
25229		} );
25230
25231
25232
25233		if ( resize ) {
25234
25235			this._size();
25236
25237			this._position();
25238
25239		}
25240
25241		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
25242
25243			this.uiDialog.resizable( "option", resizableOptions );
25244
25245		}
25246
25247	},
25248
25249
25250
25251	_setOption: function( key, value ) {
25252
25253		var isDraggable, isResizable,
25254
25255			uiDialog = this.uiDialog;
25256
25257
25258
25259		if ( key === "disabled" ) {
25260
25261			return;
25262
25263		}
25264
25265
25266
25267		this._super( key, value );
25268
25269
25270
25271		if ( key === "appendTo" ) {
25272
25273			this.uiDialog.appendTo( this._appendTo() );
25274
25275		}
25276
25277
25278
25279		if ( key === "buttons" ) {
25280
25281			this._createButtons();
25282
25283		}
25284
25285
25286
25287		if ( key === "closeText" ) {
25288
25289			this.uiDialogTitlebarClose.button( {
25290
25291
25292
25293				// Ensure that we always pass a string
25294
25295				label: $( "<a>" ).text( "" + this.options.closeText ).html()
25296
25297			} );
25298
25299		}
25300
25301
25302
25303		if ( key === "draggable" ) {
25304
25305			isDraggable = uiDialog.is( ":data(ui-draggable)" );
25306
25307			if ( isDraggable && !value ) {
25308
25309				uiDialog.draggable( "destroy" );
25310
25311			}
25312
25313
25314
25315			if ( !isDraggable && value ) {
25316
25317				this._makeDraggable();
25318
25319			}
25320
25321		}
25322
25323
25324
25325		if ( key === "position" ) {
25326
25327			this._position();
25328
25329		}
25330
25331
25332
25333		if ( key === "resizable" ) {
25334
25335
25336
25337			// currently resizable, becoming non-resizable
25338
25339			isResizable = uiDialog.is( ":data(ui-resizable)" );
25340
25341			if ( isResizable && !value ) {
25342
25343				uiDialog.resizable( "destroy" );
25344
25345			}
25346
25347
25348
25349			// Currently resizable, changing handles
25350
25351			if ( isResizable && typeof value === "string" ) {
25352
25353				uiDialog.resizable( "option", "handles", value );
25354
25355			}
25356
25357
25358
25359			// Currently non-resizable, becoming resizable
25360
25361			if ( !isResizable && value !== false ) {
25362
25363				this._makeResizable();
25364
25365			}
25366
25367		}
25368
25369
25370
25371		if ( key === "title" ) {
25372
25373			this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
25374
25375		}
25376
25377	},
25378
25379
25380
25381	_size: function() {
25382
25383
25384
25385		// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
25386
25387		// divs will both have width and height set, so we need to reset them
25388
25389		var nonContentHeight, minContentHeight, maxContentHeight,
25390
25391			options = this.options;
25392
25393
25394
25395		// Reset content sizing
25396
25397		this.element.show().css( {
25398
25399			width: "auto",
25400
25401			minHeight: 0,
25402
25403			maxHeight: "none",
25404
25405			height: 0
25406
25407		} );
25408
25409
25410
25411		if ( options.minWidth > options.width ) {
25412
25413			options.width = options.minWidth;
25414
25415		}
25416
25417
25418
25419		// Reset wrapper sizing
25420
25421		// determine the height of all the non-content elements
25422
25423		nonContentHeight = this.uiDialog.css( {
25424
25425			height: "auto",
25426
25427			width: options.width
25428
25429		} )
25430
25431			.outerHeight();
25432
25433		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
25434
25435		maxContentHeight = typeof options.maxHeight === "number" ?
25436
25437			Math.max( 0, options.maxHeight - nonContentHeight ) :
25438
25439			"none";
25440
25441
25442
25443		if ( options.height === "auto" ) {
25444
25445			this.element.css( {
25446
25447				minHeight: minContentHeight,
25448
25449				maxHeight: maxContentHeight,
25450
25451				height: "auto"
25452
25453			} );
25454
25455		} else {
25456
25457			this.element.height( Math.max( 0, options.height - nonContentHeight ) );
25458
25459		}
25460
25461
25462
25463		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
25464
25465			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
25466
25467		}
25468
25469	},
25470
25471
25472
25473	_blockFrames: function() {
25474
25475		this.iframeBlocks = this.document.find( "iframe" ).map( function() {
25476
25477			var iframe = $( this );
25478
25479
25480
25481			return $( "<div>" )
25482
25483				.css( {
25484
25485					position: "absolute",
25486
25487					width: iframe.outerWidth(),
25488
25489					height: iframe.outerHeight()
25490
25491				} )
25492
25493				.appendTo( iframe.parent() )
25494
25495				.offset( iframe.offset() )[ 0 ];
25496
25497		} );
25498
25499	},
25500
25501
25502
25503	_unblockFrames: function() {
25504
25505		if ( this.iframeBlocks ) {
25506
25507			this.iframeBlocks.remove();
25508
25509			delete this.iframeBlocks;
25510
25511		}
25512
25513	},
25514
25515
25516
25517	_allowInteraction: function( event ) {
25518
25519		if ( $( event.target ).closest( ".ui-dialog" ).length ) {
25520
25521			return true;
25522
25523		}
25524
25525
25526
25527		// TODO: Remove hack when datepicker implements
25528
25529		// the .ui-front logic (#8989)
25530
25531		return !!$( event.target ).closest( ".ui-datepicker" ).length;
25532
25533	},
25534
25535
25536
25537	_createOverlay: function() {
25538
25539		if ( !this.options.modal ) {
25540
25541			return;
25542
25543		}
25544
25545
25546
25547		// We use a delay in case the overlay is created from an
25548
25549		// event that we're going to be cancelling (#2804)
25550
25551		var isOpening = true;
25552
25553		this._delay( function() {
25554
25555			isOpening = false;
25556
25557		} );
25558
25559
25560
25561		if ( !this.document.data( "ui-dialog-overlays" ) ) {
25562
25563
25564
25565			// Prevent use of anchors and inputs
25566
25567			// Using _on() for an event handler shared across many instances is
25568
25569			// safe because the dialogs stack and must be closed in reverse order
25570
25571			this._on( this.document, {
25572
25573				focusin: function( event ) {
25574
25575					if ( isOpening ) {
25576
25577						return;
25578
25579					}
25580
25581
25582
25583					if ( !this._allowInteraction( event ) ) {
25584
25585						event.preventDefault();
25586
25587						this._trackingInstances()[ 0 ]._focusTabbable();
25588
25589					}
25590
25591				}
25592
25593			} );
25594
25595		}
25596
25597
25598
25599		this.overlay = $( "<div>" )
25600
25601			.appendTo( this._appendTo() );
25602
25603
25604
25605		this._addClass( this.overlay, null, "ui-widget-overlay ui-front" );
25606
25607		this._on( this.overlay, {
25608
25609			mousedown: "_keepFocus"
25610
25611		} );
25612
25613		this.document.data( "ui-dialog-overlays",
25614
25615			( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 );
25616
25617	},
25618
25619
25620
25621	_destroyOverlay: function() {
25622
25623		if ( !this.options.modal ) {
25624
25625			return;
25626
25627		}
25628
25629
25630
25631		if ( this.overlay ) {
25632
25633			var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
25634
25635
25636
25637			if ( !overlays ) {
25638
25639				this._off( this.document, "focusin" );
25640
25641				this.document.removeData( "ui-dialog-overlays" );
25642
25643			} else {
25644
25645				this.document.data( "ui-dialog-overlays", overlays );
25646
25647			}
25648
25649
25650
25651			this.overlay.remove();
25652
25653			this.overlay = null;
25654
25655		}
25656
25657	}
25658
25659} );
25660
25661
25662
25663// DEPRECATED
25664
25665// TODO: switch return back to widget declaration at top of file when this is removed
25666
25667if ( $.uiBackCompat !== false ) {
25668
25669
25670
25671	// Backcompat for dialogClass option
25672
25673	$.widget( "ui.dialog", $.ui.dialog, {
25674
25675		options: {
25676
25677			dialogClass: ""
25678
25679		},
25680
25681		_createWrapper: function() {
25682
25683			this._super();
25684
25685			this.uiDialog.addClass( this.options.dialogClass );
25686
25687		},
25688
25689		_setOption: function( key, value ) {
25690
25691			if ( key === "dialogClass" ) {
25692
25693				this.uiDialog
25694
25695					.removeClass( this.options.dialogClass )
25696
25697					.addClass( value );
25698
25699			}
25700
25701			this._superApply( arguments );
25702
25703		}
25704
25705	} );
25706
25707}
25708
25709
25710
25711var widgetsDialog = $.ui.dialog;
25712
25713
25714
25715
25716
25717/*!
25718
25719 * jQuery UI Droppable 1.12.1
25720
25721 * http://jqueryui.com
25722
25723 *
25724
25725 * Copyright jQuery Foundation and other contributors
25726
25727 * Released under the MIT license.
25728
25729 * http://jquery.org/license
25730
25731 */
25732
25733
25734
25735//>>label: Droppable
25736
25737//>>group: Interactions
25738
25739//>>description: Enables drop targets for draggable elements.
25740
25741//>>docs: http://api.jqueryui.com/droppable/
25742
25743//>>demos: http://jqueryui.com/droppable/
25744
25745
25746
25747
25748
25749
25750
25751$.widget( "ui.droppable", {
25752
25753	version: "1.12.1",
25754
25755	widgetEventPrefix: "drop",
25756
25757	options: {
25758
25759		accept: "*",
25760
25761		addClasses: true,
25762
25763		greedy: false,
25764
25765		scope: "default",
25766
25767		tolerance: "intersect",
25768
25769
25770
25771		// Callbacks
25772
25773		activate: null,
25774
25775		deactivate: null,
25776
25777		drop: null,
25778
25779		out: null,
25780
25781		over: null
25782
25783	},
25784
25785	_create: function() {
25786
25787
25788
25789		var proportions,
25790
25791			o = this.options,
25792
25793			accept = o.accept;
25794
25795
25796
25797		this.isover = false;
25798
25799		this.isout = true;
25800
25801
25802
25803		this.accept = $.isFunction( accept ) ? accept : function( d ) {
25804
25805			return d.is( accept );
25806
25807		};
25808
25809
25810
25811		this.proportions = function( /* valueToWrite */ ) {
25812
25813			if ( arguments.length ) {
25814
25815
25816
25817				// Store the droppable's proportions
25818
25819				proportions = arguments[ 0 ];
25820
25821			} else {
25822
25823
25824
25825				// Retrieve or derive the droppable's proportions
25826
25827				return proportions ?
25828
25829					proportions :
25830
25831					proportions = {
25832
25833						width: this.element[ 0 ].offsetWidth,
25834
25835						height: this.element[ 0 ].offsetHeight
25836
25837					};
25838
25839			}
25840
25841		};
25842
25843
25844
25845		this._addToManager( o.scope );
25846
25847
25848
25849		o.addClasses && this._addClass( "ui-droppable" );
25850
25851
25852
25853	},
25854
25855
25856
25857	_addToManager: function( scope ) {
25858
25859
25860
25861		// Add the reference and positions to the manager
25862
25863		$.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
25864
25865		$.ui.ddmanager.droppables[ scope ].push( this );
25866
25867	},
25868
25869
25870
25871	_splice: function( drop ) {
25872
25873		var i = 0;
25874
25875		for ( ; i < drop.length; i++ ) {
25876
25877			if ( drop[ i ] === this ) {
25878
25879				drop.splice( i, 1 );
25880
25881			}
25882
25883		}
25884
25885	},
25886
25887
25888
25889	_destroy: function() {
25890
25891		var drop = $.ui.ddmanager.droppables[ this.options.scope ];
25892
25893
25894
25895		this._splice( drop );
25896
25897	},
25898
25899
25900
25901	_setOption: function( key, value ) {
25902
25903
25904
25905		if ( key === "accept" ) {
25906
25907			this.accept = $.isFunction( value ) ? value : function( d ) {
25908
25909				return d.is( value );
25910
25911			};
25912
25913		} else if ( key === "scope" ) {
25914
25915			var drop = $.ui.ddmanager.droppables[ this.options.scope ];
25916
25917
25918
25919			this._splice( drop );
25920
25921			this._addToManager( value );
25922
25923		}
25924
25925
25926
25927		this._super( key, value );
25928
25929	},
25930
25931
25932
25933	_activate: function( event ) {
25934
25935		var draggable = $.ui.ddmanager.current;
25936
25937
25938
25939		this._addActiveClass();
25940
25941		if ( draggable ) {
25942
25943			this._trigger( "activate", event, this.ui( draggable ) );
25944
25945		}
25946
25947	},
25948
25949
25950
25951	_deactivate: function( event ) {
25952
25953		var draggable = $.ui.ddmanager.current;
25954
25955
25956
25957		this._removeActiveClass();
25958
25959		if ( draggable ) {
25960
25961			this._trigger( "deactivate", event, this.ui( draggable ) );
25962
25963		}
25964
25965	},
25966
25967
25968
25969	_over: function( event ) {
25970
25971
25972
25973		var draggable = $.ui.ddmanager.current;
25974
25975
25976
25977		// Bail if draggable and droppable are same element
25978
25979		if ( !draggable || ( draggable.currentItem ||
25980
25981				draggable.element )[ 0 ] === this.element[ 0 ] ) {
25982
25983			return;
25984
25985		}
25986
25987
25988
25989		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
25990
25991				draggable.element ) ) ) {
25992
25993			this._addHoverClass();
25994
25995			this._trigger( "over", event, this.ui( draggable ) );
25996
25997		}
25998
25999
26000
26001	},
26002
26003
26004
26005	_out: function( event ) {
26006
26007
26008
26009		var draggable = $.ui.ddmanager.current;
26010
26011
26012
26013		// Bail if draggable and droppable are same element
26014
26015		if ( !draggable || ( draggable.currentItem ||
26016
26017				draggable.element )[ 0 ] === this.element[ 0 ] ) {
26018
26019			return;
26020
26021		}
26022
26023
26024
26025		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
26026
26027				draggable.element ) ) ) {
26028
26029			this._removeHoverClass();
26030
26031			this._trigger( "out", event, this.ui( draggable ) );
26032
26033		}
26034
26035
26036
26037	},
26038
26039
26040
26041	_drop: function( event, custom ) {
26042
26043
26044
26045		var draggable = custom || $.ui.ddmanager.current,
26046
26047			childrenIntersection = false;
26048
26049
26050
26051		// Bail if draggable and droppable are same element
26052
26053		if ( !draggable || ( draggable.currentItem ||
26054
26055				draggable.element )[ 0 ] === this.element[ 0 ] ) {
26056
26057			return false;
26058
26059		}
26060
26061
26062
26063		this.element
26064
26065			.find( ":data(ui-droppable)" )
26066
26067			.not( ".ui-draggable-dragging" )
26068
26069			.each( function() {
26070
26071				var inst = $( this ).droppable( "instance" );
26072
26073				if (
26074
26075					inst.options.greedy &&
26076
26077					!inst.options.disabled &&
26078
26079					inst.options.scope === draggable.options.scope &&
26080
26081					inst.accept.call(
26082
26083						inst.element[ 0 ], ( draggable.currentItem || draggable.element )
26084
26085					) &&
26086
26087					intersect(
26088
26089						draggable,
26090
26091						$.extend( inst, { offset: inst.element.offset() } ),
26092
26093						inst.options.tolerance, event
26094
26095					)
26096
26097				) {
26098
26099					childrenIntersection = true;
26100
26101					return false; }
26102
26103			} );
26104
26105		if ( childrenIntersection ) {
26106
26107			return false;
26108
26109		}
26110
26111
26112
26113		if ( this.accept.call( this.element[ 0 ],
26114
26115				( draggable.currentItem || draggable.element ) ) ) {
26116
26117			this._removeActiveClass();
26118
26119			this._removeHoverClass();
26120
26121
26122
26123			this._trigger( "drop", event, this.ui( draggable ) );
26124
26125			return this.element;
26126
26127		}
26128
26129
26130
26131		return false;
26132
26133
26134
26135	},
26136
26137
26138
26139	ui: function( c ) {
26140
26141		return {
26142
26143			draggable: ( c.currentItem || c.element ),
26144
26145			helper: c.helper,
26146
26147			position: c.position,
26148
26149			offset: c.positionAbs
26150
26151		};
26152
26153	},
26154
26155
26156
26157	// Extension points just to make backcompat sane and avoid duplicating logic
26158
26159	// TODO: Remove in 1.13 along with call to it below
26160
26161	_addHoverClass: function() {
26162
26163		this._addClass( "ui-droppable-hover" );
26164
26165	},
26166
26167
26168
26169	_removeHoverClass: function() {
26170
26171		this._removeClass( "ui-droppable-hover" );
26172
26173	},
26174
26175
26176
26177	_addActiveClass: function() {
26178
26179		this._addClass( "ui-droppable-active" );
26180
26181	},
26182
26183
26184
26185	_removeActiveClass: function() {
26186
26187		this._removeClass( "ui-droppable-active" );
26188
26189	}
26190
26191} );
26192
26193
26194
26195var intersect = $.ui.intersect = ( function() {
26196
26197	function isOverAxis( x, reference, size ) {
26198
26199		return ( x >= reference ) && ( x < ( reference + size ) );
26200
26201	}
26202
26203
26204
26205	return function( draggable, droppable, toleranceMode, event ) {
26206
26207
26208
26209		if ( !droppable.offset ) {
26210
26211			return false;
26212
26213		}
26214
26215
26216
26217		var x1 = ( draggable.positionAbs ||
26218
26219				draggable.position.absolute ).left + draggable.margins.left,
26220
26221			y1 = ( draggable.positionAbs ||
26222
26223				draggable.position.absolute ).top + draggable.margins.top,
26224
26225			x2 = x1 + draggable.helperProportions.width,
26226
26227			y2 = y1 + draggable.helperProportions.height,
26228
26229			l = droppable.offset.left,
26230
26231			t = droppable.offset.top,
26232
26233			r = l + droppable.proportions().width,
26234
26235			b = t + droppable.proportions().height;
26236
26237
26238
26239		switch ( toleranceMode ) {
26240
26241		case "fit":
26242
26243			return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
26244
26245		case "intersect":
26246
26247			return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
26248
26249				x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
26250
26251				t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
26252
26253				y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
26254
26255		case "pointer":
26256
26257			return isOverAxis( event.pageY, t, droppable.proportions().height ) &&
26258
26259				isOverAxis( event.pageX, l, droppable.proportions().width );
26260
26261		case "touch":
26262
26263			return (
26264
26265				( y1 >= t && y1 <= b ) || // Top edge touching
26266
26267				( y2 >= t && y2 <= b ) || // Bottom edge touching
26268
26269				( y1 < t && y2 > b ) // Surrounded vertically
26270
26271			) && (
26272
26273				( x1 >= l && x1 <= r ) || // Left edge touching
26274
26275				( x2 >= l && x2 <= r ) || // Right edge touching
26276
26277				( x1 < l && x2 > r ) // Surrounded horizontally
26278
26279			);
26280
26281		default:
26282
26283			return false;
26284
26285		}
26286
26287	};
26288
26289} )();
26290
26291
26292
26293/*
26294
26295	This manager tracks offsets of draggables and droppables
26296
26297*/
26298
26299$.ui.ddmanager = {
26300
26301	current: null,
26302
26303	droppables: { "default": [] },
26304
26305	prepareOffsets: function( t, event ) {
26306
26307
26308
26309		var i, j,
26310
26311			m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
26312
26313			type = event ? event.type : null, // workaround for #2317
26314
26315			list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
26316
26317
26318
26319		droppablesLoop: for ( i = 0; i < m.length; i++ ) {
26320
26321
26322
26323			// No disabled and non-accepted
26324
26325			if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ],
26326
26327					( t.currentItem || t.element ) ) ) ) {
26328
26329				continue;
26330
26331			}
26332
26333
26334
26335			// Filter out elements in the current dragged item
26336
26337			for ( j = 0; j < list.length; j++ ) {
26338
26339				if ( list[ j ] === m[ i ].element[ 0 ] ) {
26340
26341					m[ i ].proportions().height = 0;
26342
26343					continue droppablesLoop;
26344
26345				}
26346
26347			}
26348
26349
26350
26351			m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
26352
26353			if ( !m[ i ].visible ) {
26354
26355				continue;
26356
26357			}
26358
26359
26360
26361			// Activate the droppable if used directly from draggables
26362
26363			if ( type === "mousedown" ) {
26364
26365				m[ i ]._activate.call( m[ i ], event );
26366
26367			}
26368
26369
26370
26371			m[ i ].offset = m[ i ].element.offset();
26372
26373			m[ i ].proportions( {
26374
26375				width: m[ i ].element[ 0 ].offsetWidth,
26376
26377				height: m[ i ].element[ 0 ].offsetHeight
26378
26379			} );
26380
26381
26382
26383		}
26384
26385
26386
26387	},
26388
26389	drop: function( draggable, event ) {
26390
26391
26392
26393		var dropped = false;
26394
26395
26396
26397		// Create a copy of the droppables in case the list changes during the drop (#9116)
26398
26399		$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
26400
26401
26402
26403			if ( !this.options ) {
26404
26405				return;
26406
26407			}
26408
26409			if ( !this.options.disabled && this.visible &&
26410
26411					intersect( draggable, this, this.options.tolerance, event ) ) {
26412
26413				dropped = this._drop.call( this, event ) || dropped;
26414
26415			}
26416
26417
26418
26419			if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ],
26420
26421					( draggable.currentItem || draggable.element ) ) ) {
26422
26423				this.isout = true;
26424
26425				this.isover = false;
26426
26427				this._deactivate.call( this, event );
26428
26429			}
26430
26431
26432
26433		} );
26434
26435		return dropped;
26436
26437
26438
26439	},
26440
26441	dragStart: function( draggable, event ) {
26442
26443
26444
26445		// Listen for scrolling so that if the dragging causes scrolling the position of the
26446
26447		// droppables can be recalculated (see #5003)
26448
26449		draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() {
26450
26451			if ( !draggable.options.refreshPositions ) {
26452
26453				$.ui.ddmanager.prepareOffsets( draggable, event );
26454
26455			}
26456
26457		} );
26458
26459	},
26460
26461	drag: function( draggable, event ) {
26462
26463
26464
26465		// If you have a highly dynamic page, you might try this option. It renders positions
26466
26467		// every time you move the mouse.
26468
26469		if ( draggable.options.refreshPositions ) {
26470
26471			$.ui.ddmanager.prepareOffsets( draggable, event );
26472
26473		}
26474
26475
26476
26477		// Run through all droppables and check their positions based on specific tolerance options
26478
26479		$.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
26480
26481
26482
26483			if ( this.options.disabled || this.greedyChild || !this.visible ) {
26484
26485				return;
26486
26487			}
26488
26489
26490
26491			var parentInstance, scope, parent,
26492
26493				intersects = intersect( draggable, this, this.options.tolerance, event ),
26494
26495				c = !intersects && this.isover ?
26496
26497					"isout" :
26498
26499					( intersects && !this.isover ? "isover" : null );
26500
26501			if ( !c ) {
26502
26503				return;
26504
26505			}
26506
26507
26508
26509			if ( this.options.greedy ) {
26510
26511
26512
26513				// find droppable parents with same scope
26514
26515				scope = this.options.scope;
26516
26517				parent = this.element.parents( ":data(ui-droppable)" ).filter( function() {
26518
26519					return $( this ).droppable( "instance" ).options.scope === scope;
26520
26521				} );
26522
26523
26524
26525				if ( parent.length ) {
26526
26527					parentInstance = $( parent[ 0 ] ).droppable( "instance" );
26528
26529					parentInstance.greedyChild = ( c === "isover" );
26530
26531				}
26532
26533			}
26534
26535
26536
26537			// We just moved into a greedy child
26538
26539			if ( parentInstance && c === "isover" ) {
26540
26541				parentInstance.isover = false;
26542
26543				parentInstance.isout = true;
26544
26545				parentInstance._out.call( parentInstance, event );
26546
26547			}
26548
26549
26550
26551			this[ c ] = true;
26552
26553			this[ c === "isout" ? "isover" : "isout" ] = false;
26554
26555			this[ c === "isover" ? "_over" : "_out" ].call( this, event );
26556
26557
26558
26559			// We just moved out of a greedy child
26560
26561			if ( parentInstance && c === "isout" ) {
26562
26563				parentInstance.isout = false;
26564
26565				parentInstance.isover = true;
26566
26567				parentInstance._over.call( parentInstance, event );
26568
26569			}
26570
26571		} );
26572
26573
26574
26575	},
26576
26577	dragStop: function( draggable, event ) {
26578
26579		draggable.element.parentsUntil( "body" ).off( "scroll.droppable" );
26580
26581
26582
26583		// Call prepareOffsets one final time since IE does not fire return scroll events when
26584
26585		// overflow was caused by drag (see #5003)
26586
26587		if ( !draggable.options.refreshPositions ) {
26588
26589			$.ui.ddmanager.prepareOffsets( draggable, event );
26590
26591		}
26592
26593	}
26594
26595};
26596
26597
26598
26599// DEPRECATED
26600
26601// TODO: switch return back to widget declaration at top of file when this is removed
26602
26603if ( $.uiBackCompat !== false ) {
26604
26605
26606
26607	// Backcompat for activeClass and hoverClass options
26608
26609	$.widget( "ui.droppable", $.ui.droppable, {
26610
26611		options: {
26612
26613			hoverClass: false,
26614
26615			activeClass: false
26616
26617		},
26618
26619		_addActiveClass: function() {
26620
26621			this._super();
26622
26623			if ( this.options.activeClass ) {
26624
26625				this.element.addClass( this.options.activeClass );
26626
26627			}
26628
26629		},
26630
26631		_removeActiveClass: function() {
26632
26633			this._super();
26634
26635			if ( this.options.activeClass ) {
26636
26637				this.element.removeClass( this.options.activeClass );
26638
26639			}
26640
26641		},
26642
26643		_addHoverClass: function() {
26644
26645			this._super();
26646
26647			if ( this.options.hoverClass ) {
26648
26649				this.element.addClass( this.options.hoverClass );
26650
26651			}
26652
26653		},
26654
26655		_removeHoverClass: function() {
26656
26657			this._super();
26658
26659			if ( this.options.hoverClass ) {
26660
26661				this.element.removeClass( this.options.hoverClass );
26662
26663			}
26664
26665		}
26666
26667	} );
26668
26669}
26670
26671
26672
26673var widgetsDroppable = $.ui.droppable;
26674
26675
26676
26677
26678
26679/*!
26680
26681 * jQuery UI Progressbar 1.12.1
26682
26683 * http://jqueryui.com
vendor: 13,149 bytes, lines 26684-27601
26684
26685 *
26686
26687 * Copyright jQuery Foundation and other contributors
26688
26689 * Released under the MIT license.
26690
26691 * http://jquery.org/license
26692
26693 */
26694
26695
26696
26697//>>label: Progressbar
26698
26699//>>group: Widgets
26700
26701// jscs:disable maximumLineLength
26702
26703//>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators.
26704
26705// jscs:enable maximumLineLength
26706
26707//>>docs: http://api.jqueryui.com/progressbar/
26708
26709//>>demos: http://jqueryui.com/progressbar/
26710
26711//>>css.structure: ../../themes/base/core.css
26712
26713//>>css.structure: ../../themes/base/progressbar.css
26714
26715//>>css.theme: ../../themes/base/theme.css
26716
26717
26718
26719
26720
26721
26722
26723var widgetsProgressbar = $.widget( "ui.progressbar", {
26724
26725	version: "1.12.1",
26726
26727	options: {
26728
26729		classes: {
26730
26731			"ui-progressbar": "ui-corner-all",
26732
26733			"ui-progressbar-value": "ui-corner-left",
26734
26735			"ui-progressbar-complete": "ui-corner-right"
26736
26737		},
26738
26739		max: 100,
26740
26741		value: 0,
26742
26743
26744
26745		change: null,
26746
26747		complete: null
26748
26749	},
26750
26751
26752
26753	min: 0,
26754
26755
26756
26757	_create: function() {
26758
26759
26760
26761		// Constrain initial value
26762
26763		this.oldValue = this.options.value = this._constrainedValue();
26764
26765
26766
26767		this.element.attr( {
26768
26769
26770
26771			// Only set static values; aria-valuenow and aria-valuemax are
26772
26773			// set inside _refreshValue()
26774
26775			role: "progressbar",
26776
26777			"aria-valuemin": this.min
26778
26779		} );
26780
26781		this._addClass( "ui-progressbar", "ui-widget ui-widget-content" );
26782
26783
26784
26785		this.valueDiv = $( "<div>" ).appendTo( this.element );
26786
26787		this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" );
26788
26789		this._refreshValue();
26790
26791	},
26792
26793
26794
26795	_destroy: function() {
26796
26797		this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" );
26798
26799
26800
26801		this.valueDiv.remove();
26802
26803	},
26804
26805
26806
26807	value: function( newValue ) {
26808
26809		if ( newValue === undefined ) {
26810
26811			return this.options.value;
26812
26813		}
26814
26815
26816
26817		this.options.value = this._constrainedValue( newValue );
26818
26819		this._refreshValue();
26820
26821	},
26822
26823
26824
26825	_constrainedValue: function( newValue ) {
26826
26827		if ( newValue === undefined ) {
26828
26829			newValue = this.options.value;
26830
26831		}
26832
26833
26834
26835		this.indeterminate = newValue === false;
26836
26837
26838
26839		// Sanitize value
26840
26841		if ( typeof newValue !== "number" ) {
26842
26843			newValue = 0;
26844
26845		}
26846
26847
26848
26849		return this.indeterminate ? false :
26850
26851			Math.min( this.options.max, Math.max( this.min, newValue ) );
26852
26853	},
26854
26855
26856
26857	_setOptions: function( options ) {
26858
26859
26860
26861		// Ensure "value" option is set after other values (like max)
26862
26863		var value = options.value;
26864
26865		delete options.value;
26866
26867
26868
26869		this._super( options );
26870
26871
26872
26873		this.options.value = this._constrainedValue( value );
26874
26875		this._refreshValue();
26876
26877	},
26878
26879
26880
26881	_setOption: function( key, value ) {
26882
26883		if ( key === "max" ) {
26884
26885
26886
26887			// Don't allow a max less than min
26888
26889			value = Math.max( this.min, value );
26890
26891		}
26892
26893		this._super( key, value );
26894
26895	},
26896
26897
26898
26899	_setOptionDisabled: function( value ) {
26900
26901		this._super( value );
26902
26903
26904
26905		this.element.attr( "aria-disabled", value );
26906
26907		this._toggleClass( null, "ui-state-disabled", !!value );
26908
26909	},
26910
26911
26912
26913	_percentage: function() {
26914
26915		return this.indeterminate ?
26916
26917			100 :
26918
26919			100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
26920
26921	},
26922
26923
26924
26925	_refreshValue: function() {
26926
26927		var value = this.options.value,
26928
26929			percentage = this._percentage();
26930
26931
26932
26933		this.valueDiv
26934
26935			.toggle( this.indeterminate || value > this.min )
26936
26937			.width( percentage.toFixed( 0 ) + "%" );
26938
26939
26940
26941		this
26942
26943			._toggleClass( this.valueDiv, "ui-progressbar-complete", null,
26944
26945				value === this.options.max )
26946
26947			._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate );
26948
26949
26950
26951		if ( this.indeterminate ) {
26952
26953			this.element.removeAttr( "aria-valuenow" );
26954
26955			if ( !this.overlayDiv ) {
26956
26957				this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv );
26958
26959				this._addClass( this.overlayDiv, "ui-progressbar-overlay" );
26960
26961			}
26962
26963		} else {
26964
26965			this.element.attr( {
26966
26967				"aria-valuemax": this.options.max,
26968
26969				"aria-valuenow": value
26970
26971			} );
26972
26973			if ( this.overlayDiv ) {
26974
26975				this.overlayDiv.remove();
26976
26977				this.overlayDiv = null;
26978
26979			}
26980
26981		}
26982
26983
26984
26985		if ( this.oldValue !== value ) {
26986
26987			this.oldValue = value;
26988
26989			this._trigger( "change" );
26990
26991		}
26992
26993		if ( value === this.options.max ) {
26994
26995			this._trigger( "complete" );
26996
26997		}
26998
26999	}
27000
27001} );
27002
27003
27004
27005
27006
27007/*!
27008
27009 * jQuery UI Selectable 1.12.1
27010
27011 * http://jqueryui.com
27012
27013 *
27014
27015 * Copyright jQuery Foundation and other contributors
27016
27017 * Released under the MIT license.
27018
27019 * http://jquery.org/license
27020
27021 */
27022
27023
27024
27025//>>label: Selectable
27026
27027//>>group: Interactions
27028
27029//>>description: Allows groups of elements to be selected with the mouse.
27030
27031//>>docs: http://api.jqueryui.com/selectable/
27032
27033//>>demos: http://jqueryui.com/selectable/
27034
27035//>>css.structure: ../../themes/base/selectable.css
27036
27037
27038
27039
27040
27041
27042
27043var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, {
27044
27045	version: "1.12.1",
27046
27047	options: {
27048
27049		appendTo: "body",
27050
27051		autoRefresh: true,
27052
27053		distance: 0,
27054
27055		filter: "*",
27056
27057		tolerance: "touch",
27058
27059
27060
27061		// Callbacks
27062
27063		selected: null,
27064
27065		selecting: null,
27066
27067		start: null,
27068
27069		stop: null,
27070
27071		unselected: null,
27072
27073		unselecting: null
27074
27075	},
27076
27077	_create: function() {
27078
27079		var that = this;
27080
27081
27082
27083		this._addClass( "ui-selectable" );
27084
27085
27086
27087		this.dragged = false;
27088
27089
27090
27091		// Cache selectee children based on filter
27092
27093		this.refresh = function() {
27094
27095			that.elementPos = $( that.element[ 0 ] ).offset();
27096
27097			that.selectees = $( that.options.filter, that.element[ 0 ] );
27098
27099			that._addClass( that.selectees, "ui-selectee" );
27100
27101			that.selectees.each( function() {
27102
27103				var $this = $( this ),
27104
27105					selecteeOffset = $this.offset(),
27106
27107					pos = {
27108
27109						left: selecteeOffset.left - that.elementPos.left,
27110
27111						top: selecteeOffset.top - that.elementPos.top
27112
27113					};
27114
27115				$.data( this, "selectable-item", {
27116
27117					element: this,
27118
27119					$element: $this,
27120
27121					left: pos.left,
27122
27123					top: pos.top,
27124
27125					right: pos.left + $this.outerWidth(),
27126
27127					bottom: pos.top + $this.outerHeight(),
27128
27129					startselected: false,
27130
27131					selected: $this.hasClass( "ui-selected" ),
27132
27133					selecting: $this.hasClass( "ui-selecting" ),
27134
27135					unselecting: $this.hasClass( "ui-unselecting" )
27136
27137				} );
27138
27139			} );
27140
27141		};
27142
27143		this.refresh();
27144
27145
27146
27147		this._mouseInit();
27148
27149
27150
27151		this.helper = $( "<div>" );
27152
27153		this._addClass( this.helper, "ui-selectable-helper" );
27154
27155	},
27156
27157
27158
27159	_destroy: function() {
27160
27161		this.selectees.removeData( "selectable-item" );
27162
27163		this._mouseDestroy();
27164
27165	},
27166
27167
27168
27169	_mouseStart: function( event ) {
27170
27171		var that = this,
27172
27173			options = this.options;
27174
27175
27176
27177		this.opos = [ event.pageX, event.pageY ];
27178
27179		this.elementPos = $( this.element[ 0 ] ).offset();
27180
27181
27182
27183		if ( this.options.disabled ) {
27184
27185			return;
27186
27187		}
27188
27189
27190
27191		this.selectees = $( options.filter, this.element[ 0 ] );
27192
27193
27194
27195		this._trigger( "start", event );
27196
27197
27198
27199		$( options.appendTo ).append( this.helper );
27200
27201
27202
27203		// position helper (lasso)
27204
27205		this.helper.css( {
27206
27207			"left": event.pageX,
27208
27209			"top": event.pageY,
27210
27211			"width": 0,
27212
27213			"height": 0
27214
27215		} );
27216
27217
27218
27219		if ( options.autoRefresh ) {
27220
27221			this.refresh();
27222
27223		}
27224
27225
27226
27227		this.selectees.filter( ".ui-selected" ).each( function() {
27228
27229			var selectee = $.data( this, "selectable-item" );
27230
27231			selectee.startselected = true;
27232
27233			if ( !event.metaKey && !event.ctrlKey ) {
27234
27235				that._removeClass( selectee.$element, "ui-selected" );
27236
27237				selectee.selected = false;
27238
27239				that._addClass( selectee.$element, "ui-unselecting" );
27240
27241				selectee.unselecting = true;
27242
27243
27244
27245				// selectable UNSELECTING callback
27246
27247				that._trigger( "unselecting", event, {
27248
27249					unselecting: selectee.element
27250
27251				} );
27252
27253			}
27254
27255		} );
27256
27257
27258
27259		$( event.target ).parents().addBack().each( function() {
27260
27261			var doSelect,
27262
27263				selectee = $.data( this, "selectable-item" );
27264
27265			if ( selectee ) {
27266
27267				doSelect = ( !event.metaKey && !event.ctrlKey ) ||
27268
27269					!selectee.$element.hasClass( "ui-selected" );
27270
27271				that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
27272
27273					._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
27274
27275				selectee.unselecting = !doSelect;
27276
27277				selectee.selecting = doSelect;
27278
27279				selectee.selected = doSelect;
27280
27281
27282
27283				// selectable (UN)SELECTING callback
27284
27285				if ( doSelect ) {
27286
27287					that._trigger( "selecting", event, {
27288
27289						selecting: selectee.element
27290
27291					} );
27292
27293				} else {
27294
27295					that._trigger( "unselecting", event, {
27296
27297						unselecting: selectee.element
27298
27299					} );
27300
27301				}
27302
27303				return false;
27304
27305			}
27306
27307		} );
27308
27309
27310
27311	},
27312
27313
27314
27315	_mouseDrag: function( event ) {
27316
27317
27318
27319		this.dragged = true;
27320
27321
27322
27323		if ( this.options.disabled ) {
27324
27325			return;
27326
27327		}
27328
27329
27330
27331		var tmp,
27332
27333			that = this,
27334
27335			options = this.options,
27336
27337			x1 = this.opos[ 0 ],
27338
27339			y1 = this.opos[ 1 ],
27340
27341			x2 = event.pageX,
27342
27343			y2 = event.pageY;
27344
27345
27346
27347		if ( x1 > x2 ) { tmp = x2; x2 = x1; x1 = tmp; }
27348
27349		if ( y1 > y2 ) { tmp = y2; y2 = y1; y1 = tmp; }
27350
27351		this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
27352
27353
27354
27355		this.selectees.each( function() {
27356
27357			var selectee = $.data( this, "selectable-item" ),
27358
27359				hit = false,
27360
27361				offset = {};
27362
27363
27364
27365			//prevent helper from being selected if appendTo: selectable
27366
27367			if ( !selectee || selectee.element === that.element[ 0 ] ) {
27368
27369				return;
27370
27371			}
27372
27373
27374
27375			offset.left   = selectee.left   + that.elementPos.left;
27376
27377			offset.right  = selectee.right  + that.elementPos.left;
27378
27379			offset.top    = selectee.top    + that.elementPos.top;
27380
27381			offset.bottom = selectee.bottom + that.elementPos.top;
27382
27383
27384
27385			if ( options.tolerance === "touch" ) {
27386
27387				hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
27388
27389                    offset.bottom < y1 ) );
27390
27391			} else if ( options.tolerance === "fit" ) {
27392
27393				hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
27394
27395                    offset.bottom < y2 );
27396
27397			}
27398
27399
27400
27401			if ( hit ) {
27402
27403
27404
27405				// SELECT
27406
27407				if ( selectee.selected ) {
27408
27409					that._removeClass( selectee.$element, "ui-selected" );
27410
27411					selectee.selected = false;
27412
27413				}
27414
27415				if ( selectee.unselecting ) {
27416
27417					that._removeClass( selectee.$element, "ui-unselecting" );
27418
27419					selectee.unselecting = false;
27420
27421				}
27422
27423				if ( !selectee.selecting ) {
27424
27425					that._addClass( selectee.$element, "ui-selecting" );
27426
27427					selectee.selecting = true;
27428
27429
27430
27431					// selectable SELECTING callback
27432
27433					that._trigger( "selecting", event, {
27434
27435						selecting: selectee.element
27436
27437					} );
27438
27439				}
27440
27441			} else {
27442
27443
27444
27445				// UNSELECT
27446
27447				if ( selectee.selecting ) {
27448
27449					if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
27450
27451						that._removeClass( selectee.$element, "ui-selecting" );
27452
27453						selectee.selecting = false;
27454
27455						that._addClass( selectee.$element, "ui-selected" );
27456
27457						selectee.selected = true;
27458
27459					} else {
27460
27461						that._removeClass( selectee.$element, "ui-selecting" );
27462
27463						selectee.selecting = false;
27464
27465						if ( selectee.startselected ) {
27466
27467							that._addClass( selectee.$element, "ui-unselecting" );
27468
27469							selectee.unselecting = true;
27470
27471						}
27472
27473
27474
27475						// selectable UNSELECTING callback
27476
27477						that._trigger( "unselecting", event, {
27478
27479							unselecting: selectee.element
27480
27481						} );
27482
27483					}
27484
27485				}
27486
27487				if ( selectee.selected ) {
27488
27489					if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
27490
27491						that._removeClass( selectee.$element, "ui-selected" );
27492
27493						selectee.selected = false;
27494
27495
27496
27497						that._addClass( selectee.$element, "ui-unselecting" );
27498
27499						selectee.unselecting = true;
27500
27501
27502
27503						// selectable UNSELECTING callback
27504
27505						that._trigger( "unselecting", event, {
27506
27507							unselecting: selectee.element
27508
27509						} );
27510
27511					}
27512
27513				}
27514
27515			}
27516
27517		} );
27518
27519
27520
27521		return false;
27522
27523	},
27524
27525
27526
27527	_mouseStop: function( event ) {
27528
27529		var that = this;
27530
27531
27532
27533		this.dragged = false;
27534
27535
27536
27537		$( ".ui-unselecting", this.element[ 0 ] ).each( function() {
27538
27539			var selectee = $.data( this, "selectable-item" );
27540
27541			that._removeClass( selectee.$element, "ui-unselecting" );
27542
27543			selectee.unselecting = false;
27544
27545			selectee.startselected = false;
27546
27547			that._trigger( "unselected", event, {
27548
27549				unselected: selectee.element
27550
27551			} );
27552
27553		} );
27554
27555		$( ".ui-selecting", this.element[ 0 ] ).each( function() {
27556
27557			var selectee = $.data( this, "selectable-item" );
27558
27559			that._removeClass( selectee.$element, "ui-selecting" )
27560
27561				._addClass( selectee.$element, "ui-selected" );
27562
27563			selectee.selecting = false;
27564
27565			selectee.selected = true;
27566
27567			selectee.startselected = true;
27568
27569			that._trigger( "selected", event, {
27570
27571				selected: selectee.element
27572
27573			} );
27574
27575		} );
27576
27577		this._trigger( "stop", event );
27578
27579
27580
27581		this.helper.remove();
27582
27583
27584
27585		return false;
27586
27587	}
27588
27589
27590
27591} );
27592
27593
27594
27595
27596
27597/*!
27598
27599 * jQuery UI Selectmenu 1.12.1
27600
27601 * http://jqueryui.com
vendor: 5,957 bytes, lines 27602-28015
27602
27603 *
27604
27605 * Copyright jQuery Foundation and other contributors
27606
27607 * Released under the MIT license.
27608
27609 * http://jquery.org/license
27610
27611 */
27612
27613
27614
27615//>>label: Selectmenu
27616
27617//>>group: Widgets
27618
27619// jscs:disable maximumLineLength
27620
27621//>>description: Duplicates and extends the functionality of a native HTML select element, allowing it to be customizable in behavior and appearance far beyond the limitations of a native select.
27622
27623// jscs:enable maximumLineLength
27624
27625//>>docs: http://api.jqueryui.com/selectmenu/
27626
27627//>>demos: http://jqueryui.com/selectmenu/
27628
27629//>>css.structure: ../../themes/base/core.css
27630
27631//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css
27632
27633//>>css.theme: ../../themes/base/theme.css
27634
27635
27636
27637
27638
27639
27640
27641var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
27642
27643	version: "1.12.1",
27644
27645	defaultElement: "<select>",
27646
27647	options: {
27648
27649		appendTo: null,
27650
27651		classes: {
27652
27653			"ui-selectmenu-button-open": "ui-corner-top",
27654
27655			"ui-selectmenu-button-closed": "ui-corner-all"
27656
27657		},
27658
27659		disabled: null,
27660
27661		icons: {
27662
27663			button: "ui-icon-triangle-1-s"
27664
27665		},
27666
27667		position: {
27668
27669			my: "left top",
27670
27671			at: "left bottom",
27672
27673			collision: "none"
27674
27675		},
27676
27677		width: false,
27678
27679
27680
27681		// Callbacks
27682
27683		change: null,
27684
27685		close: null,
27686
27687		focus: null,
27688
27689		open: null,
27690
27691		select: null
27692
27693	},
27694
27695
27696
27697	_create: function() {
27698
27699		var selectmenuId = this.element.uniqueId().attr( "id" );
27700
27701		this.ids = {
27702
27703			element: selectmenuId,
27704
27705			button: selectmenuId + "-button",
27706
27707			menu: selectmenuId + "-menu"
27708
27709		};
27710
27711
27712
27713		this._drawButton();
27714
27715		this._drawMenu();
27716
27717		this._bindFormResetHandler();
27718
27719
27720
27721		this._rendered = false;
27722
27723		this.menuItems = $();
27724
27725	},
27726
27727
27728
27729	_drawButton: function() {
27730
27731		var icon,
27732
27733			that = this,
27734
27735			item = this._parseOption(
27736
27737				this.element.find( "option:selected" ),
27738
27739				this.element[ 0 ].selectedIndex
27740
27741			);
27742
27743
27744
27745		// Associate existing label with the new button
27746
27747		this.labels = this.element.labels().attr( "for", this.ids.button );
27748
27749		this._on( this.labels, {
27750
27751			click: function( event ) {
27752
27753				this.button.focus();
27754
27755				event.preventDefault();
27756
27757			}
27758
27759		} );
27760
27761
27762
27763		// Hide original select element
27764
27765		this.element.hide();
27766
27767
27768
27769		// Create button
27770
27771		this.button = $( "<span>", {
27772
27773			tabindex: this.options.disabled ? -1 : 0,
27774
27775			id: this.ids.button,
27776
27777			role: "combobox",
27778
27779			"aria-expanded": "false",
27780
27781			"aria-autocomplete": "list",
27782
27783			"aria-owns": this.ids.menu,
27784
27785			"aria-haspopup": "true",
27786
27787			title: this.element.attr( "title" )
27788
27789		} )
27790
27791			.insertAfter( this.element );
27792
27793
27794
27795		this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed",
27796
27797			"ui-button ui-widget" );
27798
27799
27800
27801		icon = $( "<span>" ).appendTo( this.button );
27802
27803		this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button );
27804
27805		this.buttonItem = this._renderButtonItem( item )
27806
27807			.appendTo( this.button );
27808
27809
27810
27811		if ( this.options.width !== false ) {
27812
27813			this._resizeButton();
27814
27815		}
27816
27817
27818
27819		this._on( this.button, this._buttonEvents );
27820
27821		this.button.one( "focusin", function() {
27822
27823
27824
27825			// Delay rendering the menu items until the button receives focus.
27826
27827			// The menu may have already been rendered via a programmatic open.
27828
27829			if ( !that._rendered ) {
27830
27831				that._refreshMenu();
27832
27833			}
27834
27835		} );
27836
27837	},
27838
27839
27840
27841	_drawMenu: function() {
27842
27843		var that = this;
27844
27845
27846
27847		// Create menu
27848
27849		this.menu = $( "<ul>", {
27850
27851			"aria-hidden": "true",
27852
27853			"aria-labelledby": this.ids.button,
27854
27855			id: this.ids.menu
27856
27857		} );
27858
27859
27860
27861		// Wrap menu
27862
27863		this.menuWrap = $( "<div>" ).append( this.menu );
27864
27865		this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" );
27866
27867		this.menuWrap.appendTo( this._appendTo() );
27868
27869
27870
27871		// Initialize menu widget
27872
27873		this.menuInstance = this.menu
27874
27875			.menu( {
27876
27877				classes: {
27878
27879					"ui-menu": "ui-corner-bottom"
27880
27881				},
27882
27883				role: "listbox",
27884
27885				select: function( event, ui ) {
27886
27887					event.preventDefault();
27888
27889
27890
27891					// Support: IE8
27892
27893					// If the item was selected via a click, the text selection
27894
27895					// will be destroyed in IE
27896
27897					that._setSelection();
27898
27899
27900
27901					that._select( ui.item.data( "ui-selectmenu-item" ), event );
27902
27903				},
27904
27905				focus: function( event, ui ) {
27906
27907					var item = ui.item.data( "ui-selectmenu-item" );
27908
27909
27910
27911					// Prevent inital focus from firing and check if its a newly focused item
27912
27913					if ( that.focusIndex != null && item.index !== that.focusIndex ) {
27914
27915						that._trigger( "focus", event, { item: item } );
27916
27917						if ( !that.isOpen ) {
27918
27919							that._select( item, event );
27920
27921						}
27922
27923					}
27924
27925					that.focusIndex = item.index;
27926
27927
27928
27929					that.button.attr( "aria-activedescendant",
27930
27931						that.menuItems.eq( item.index ).attr( "id" ) );
27932
27933				}
27934
27935			} )
27936
27937			.menu( "instance" );
27938
27939
27940
27941		// Don't close the menu on mouseleave
27942
27943		this.menuInstance._off( this.menu, "mouseleave" );
27944
27945
27946
27947		// Cancel the menu's collapseAll on document click
27948
27949		this.menuInstance._closeOnDocumentClick = function() {
27950
27951			return false;
27952
27953		};
27954
27955
27956
27957		// Selects often contain empty items, but never contain dividers
27958
27959		this.menuInstance._isDivider = function() {
27960
27961			return false;
27962
27963		};
27964
27965	},
27966
27967
27968
27969	refresh: function() {
27970
27971		this._refreshMenu();
27972
27973		this.buttonItem.replaceWith(
27974
27975			this.buttonItem = this._renderButtonItem(
27976
27977
27978
27979				// Fall back to an empty object in case there are no options
27980
27981				this._getSelectedItem().data( "ui-selectmenu-item" ) || {}
27982
27983			)
27984
27985		);
27986
27987		if ( this.options.width === null ) {
27988
27989			this._resizeButton();
27990
27991		}
27992
27993	},
27994
27995
27996
27997	_refreshMenu: function() {
27998
27999		var item,
28000
28001			options = this.element.find( "option" );
28002
28003
28004
28005		this.menu.empty();
28006
28007
28008
28009		this._parseOptions( options );
28010
28011		this._renderMenu( this.menu, this.items );
28012
28013
28014
28015		this.menuInstance.refresh();
vendor: 10,587 bytes, lines 28016-28832
28016
28017		this.menuItems = this.menu.find( "li" )
28018
28019			.not( ".ui-selectmenu-optgroup" )
28020
28021				.find( ".ui-menu-item-wrapper" );
28022
28023
28024
28025		this._rendered = true;
28026
28027
28028
28029		if ( !options.length ) {
28030
28031			return;
28032
28033		}
28034
28035
28036
28037		item = this._getSelectedItem();
28038
28039
28040
28041		// Update the menu to have the correct item focused
28042
28043		this.menuInstance.focus( null, item );
28044
28045		this._setAria( item.data( "ui-selectmenu-item" ) );
28046
28047
28048
28049		// Set disabled state
28050
28051		this._setOption( "disabled", this.element.prop( "disabled" ) );
28052
28053	},
28054
28055
28056
28057	open: function( event ) {
28058
28059		if ( this.options.disabled ) {
28060
28061			return;
28062
28063		}
28064
28065
28066
28067		// If this is the first time the menu is being opened, render the items
28068
28069		if ( !this._rendered ) {
28070
28071			this._refreshMenu();
28072
28073		} else {
28074
28075
28076
28077			// Menu clears focus on close, reset focus to selected item
28078
28079			this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" );
28080
28081			this.menuInstance.focus( null, this._getSelectedItem() );
28082
28083		}
28084
28085
28086
28087		// If there are no options, don't open the menu
28088
28089		if ( !this.menuItems.length ) {
28090
28091			return;
28092
28093		}
28094
28095
28096
28097		this.isOpen = true;
28098
28099		this._toggleAttr();
28100
28101		this._resizeMenu();
28102
28103		this._position();
28104
28105
28106
28107		this._on( this.document, this._documentClick );
28108
28109
28110
28111		this._trigger( "open", event );
28112
28113	},
28114
28115
28116
28117	_position: function() {
28118
28119		this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
28120
28121	},
28122
28123
28124
28125	close: function( event ) {
28126
28127		if ( !this.isOpen ) {
28128
28129			return;
28130
28131		}
28132
28133
28134
28135		this.isOpen = false;
28136
28137		this._toggleAttr();
28138
28139
28140
28141		this.range = null;
28142
28143		this._off( this.document );
28144
28145
28146
28147		this._trigger( "close", event );
28148
28149	},
28150
28151
28152
28153	widget: function() {
28154
28155		return this.button;
28156
28157	},
28158
28159
28160
28161	menuWidget: function() {
28162
28163		return this.menu;
28164
28165	},
28166
28167
28168
28169	_renderButtonItem: function( item ) {
28170
28171		var buttonItem = $( "<span>" );
28172
28173
28174
28175		this._setText( buttonItem, item.label );
28176
28177		this._addClass( buttonItem, "ui-selectmenu-text" );
28178
28179
28180
28181		return buttonItem;
28182
28183	},
28184
28185
28186
28187	_renderMenu: function( ul, items ) {
28188
28189		var that = this,
28190
28191			currentOptgroup = "";
28192
28193
28194
28195		$.each( items, function( index, item ) {
28196
28197			var li;
28198
28199
28200
28201			if ( item.optgroup !== currentOptgroup ) {
28202
28203				li = $( "<li>", {
28204
28205					text: item.optgroup
28206
28207				} );
28208
28209				that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" +
28210
28211					( item.element.parent( "optgroup" ).prop( "disabled" ) ?
28212
28213						" ui-state-disabled" :
28214
28215						"" ) );
28216
28217
28218
28219				li.appendTo( ul );
28220
28221
28222
28223				currentOptgroup = item.optgroup;
28224
28225			}
28226
28227
28228
28229			that._renderItemData( ul, item );
28230
28231		} );
28232
28233	},
28234
28235
28236
28237	_renderItemData: function( ul, item ) {
28238
28239		return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
28240
28241	},
28242
28243
28244
28245	_renderItem: function( ul, item ) {
28246
28247		var li = $( "<li>" ),
28248
28249			wrapper = $( "<div>", {
28250
28251				title: item.element.attr( "title" )
28252
28253			} );
28254
28255
28256
28257		if ( item.disabled ) {
28258
28259			this._addClass( li, null, "ui-state-disabled" );
28260
28261		}
28262
28263		this._setText( wrapper, item.label );
28264
28265
28266
28267		return li.append( wrapper ).appendTo( ul );
28268
28269	},
28270
28271
28272
28273	_setText: function( element, value ) {
28274
28275		if ( value ) {
28276
28277			element.text( value );
28278
28279		} else {
28280
28281			element.html( "&#160;" );
28282
28283		}
28284
28285	},
28286
28287
28288
28289	_move: function( direction, event ) {
28290
28291		var item, next,
28292
28293			filter = ".ui-menu-item";
28294
28295
28296
28297		if ( this.isOpen ) {
28298
28299			item = this.menuItems.eq( this.focusIndex ).parent( "li" );
28300
28301		} else {
28302
28303			item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
28304
28305			filter += ":not(.ui-state-disabled)";
28306
28307		}
28308
28309
28310
28311		if ( direction === "first" || direction === "last" ) {
28312
28313			next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
28314
28315		} else {
28316
28317			next = item[ direction + "All" ]( filter ).eq( 0 );
28318
28319		}
28320
28321
28322
28323		if ( next.length ) {
28324
28325			this.menuInstance.focus( event, next );
28326
28327		}
28328
28329	},
28330
28331
28332
28333	_getSelectedItem: function() {
28334
28335		return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
28336
28337	},
28338
28339
28340
28341	_toggle: function( event ) {
28342
28343		this[ this.isOpen ? "close" : "open" ]( event );
28344
28345	},
28346
28347
28348
28349	_setSelection: function() {
28350
28351		var selection;
28352
28353
28354
28355		if ( !this.range ) {
28356
28357			return;
28358
28359		}
28360
28361
28362
28363		if ( window.getSelection ) {
28364
28365			selection = window.getSelection();
28366
28367			selection.removeAllRanges();
28368
28369			selection.addRange( this.range );
28370
28371
28372
28373		// Support: IE8
28374
28375		} else {
28376
28377			this.range.select();
28378
28379		}
28380
28381
28382
28383		// Support: IE
28384
28385		// Setting the text selection kills the button focus in IE, but
28386
28387		// restoring the focus doesn't kill the selection.
28388
28389		this.button.focus();
28390
28391	},
28392
28393
28394
28395	_documentClick: {
28396
28397		mousedown: function( event ) {
28398
28399			if ( !this.isOpen ) {
28400
28401				return;
28402
28403			}
28404
28405
28406
28407			if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" +
28408
28409					$.ui.escapeSelector( this.ids.button ) ).length ) {
28410
28411				this.close( event );
28412
28413			}
28414
28415		}
28416
28417	},
28418
28419
28420
28421	_buttonEvents: {
28422
28423
28424
28425		// Prevent text selection from being reset when interacting with the selectmenu (#10144)
28426
28427		mousedown: function() {
28428
28429			var selection;
28430
28431
28432
28433			if ( window.getSelection ) {
28434
28435				selection = window.getSelection();
28436
28437				if ( selection.rangeCount ) {
28438
28439					this.range = selection.getRangeAt( 0 );
28440
28441				}
28442
28443
28444
28445			// Support: IE8
28446
28447			} else {
28448
28449				this.range = document.selection.createRange();
28450
28451			}
28452
28453		},
28454
28455
28456
28457		click: function( event ) {
28458
28459			this._setSelection();
28460
28461			this._toggle( event );
28462
28463		},
28464
28465
28466
28467		keydown: function( event ) {
28468
28469			var preventDefault = true;
28470
28471			switch ( event.keyCode ) {
28472
28473			case $.ui.keyCode.TAB:
28474
28475			case $.ui.keyCode.ESCAPE:
28476
28477				this.close( event );
28478
28479				preventDefault = false;
28480
28481				break;
28482
28483			case $.ui.keyCode.ENTER:
28484
28485				if ( this.isOpen ) {
28486
28487					this._selectFocusedItem( event );
28488
28489				}
28490
28491				break;
28492
28493			case $.ui.keyCode.UP:
28494
28495				if ( event.altKey ) {
28496
28497					this._toggle( event );
28498
28499				} else {
28500
28501					this._move( "prev", event );
28502
28503				}
28504
28505				break;
28506
28507			case $.ui.keyCode.DOWN:
28508
28509				if ( event.altKey ) {
28510
28511					this._toggle( event );
28512
28513				} else {
28514
28515					this._move( "next", event );
28516
28517				}
28518
28519				break;
28520
28521			case $.ui.keyCode.SPACE:
28522
28523				if ( this.isOpen ) {
28524
28525					this._selectFocusedItem( event );
28526
28527				} else {
28528
28529					this._toggle( event );
28530
28531				}
28532
28533				break;
28534
28535			case $.ui.keyCode.LEFT:
28536
28537				this._move( "prev", event );
28538
28539				break;
28540
28541			case $.ui.keyCode.RIGHT:
28542
28543				this._move( "next", event );
28544
28545				break;
28546
28547			case $.ui.keyCode.HOME:
28548
28549			case $.ui.keyCode.PAGE_UP:
28550
28551				this._move( "first", event );
28552
28553				break;
28554
28555			case $.ui.keyCode.END:
28556
28557			case $.ui.keyCode.PAGE_DOWN:
28558
28559				this._move( "last", event );
28560
28561				break;
28562
28563			default:
28564
28565				this.menu.trigger( event );
28566
28567				preventDefault = false;
28568
28569			}
28570
28571
28572
28573			if ( preventDefault ) {
28574
28575				event.preventDefault();
28576
28577			}
28578
28579		}
28580
28581	},
28582
28583
28584
28585	_selectFocusedItem: function( event ) {
28586
28587		var item = this.menuItems.eq( this.focusIndex ).parent( "li" );
28588
28589		if ( !item.hasClass( "ui-state-disabled" ) ) {
28590
28591			this._select( item.data( "ui-selectmenu-item" ), event );
28592
28593		}
28594
28595	},
28596
28597
28598
28599	_select: function( item, event ) {
28600
28601		var oldIndex = this.element[ 0 ].selectedIndex;
28602
28603
28604
28605		// Change native select element
28606
28607		this.element[ 0 ].selectedIndex = item.index;
28608
28609		this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) );
28610
28611		this._setAria( item );
28612
28613		this._trigger( "select", event, { item: item } );
28614
28615
28616
28617		if ( item.index !== oldIndex ) {
28618
28619			this._trigger( "change", event, { item: item } );
28620
28621		}
28622
28623
28624
28625		this.close( event );
28626
28627	},
28628
28629
28630
28631	_setAria: function( item ) {
28632
28633		var id = this.menuItems.eq( item.index ).attr( "id" );
28634
28635
28636
28637		this.button.attr( {
28638
28639			"aria-labelledby": id,
28640
28641			"aria-activedescendant": id
28642
28643		} );
28644
28645		this.menu.attr( "aria-activedescendant", id );
28646
28647	},
28648
28649
28650
28651	_setOption: function( key, value ) {
28652
28653		if ( key === "icons" ) {
28654
28655			var icon = this.button.find( "span.ui-icon" );
28656
28657			this._removeClass( icon, null, this.options.icons.button )
28658
28659				._addClass( icon, null, value.button );
28660
28661		}
28662
28663
28664
28665		this._super( key, value );
28666
28667
28668
28669		if ( key === "appendTo" ) {
28670
28671			this.menuWrap.appendTo( this._appendTo() );
28672
28673		}
28674
28675
28676
28677		if ( key === "width" ) {
28678
28679			this._resizeButton();
28680
28681		}
28682
28683	},
28684
28685
28686
28687	_setOptionDisabled: function( value ) {
28688
28689		this._super( value );
28690
28691
28692
28693		this.menuInstance.option( "disabled", value );
28694
28695		this.button.attr( "aria-disabled", value );
28696
28697		this._toggleClass( this.button, null, "ui-state-disabled", value );
28698
28699
28700
28701		this.element.prop( "disabled", value );
28702
28703		if ( value ) {
28704
28705			this.button.attr( "tabindex", -1 );
28706
28707			this.close();
28708
28709		} else {
28710
28711			this.button.attr( "tabindex", 0 );
28712
28713		}
28714
28715	},
28716
28717
28718
28719	_appendTo: function() {
28720
28721		var element = this.options.appendTo;
28722
28723
28724
28725		if ( element ) {
28726
28727			element = element.jquery || element.nodeType ?
28728
28729				$( element ) :
28730
28731				this.document.find( element ).eq( 0 );
28732
28733		}
28734
28735
28736
28737		if ( !element || !element[ 0 ] ) {
28738
28739			element = this.element.closest( ".ui-front, dialog" );
28740
28741		}
28742
28743
28744
28745		if ( !element.length ) {
28746
28747			element = this.document[ 0 ].body;
28748
28749		}
28750
28751
28752
28753		return element;
28754
28755	},
28756
28757
28758
28759	_toggleAttr: function() {
28760
28761		this.button.attr( "aria-expanded", this.isOpen );
28762
28763
28764
28765		// We can't use two _toggleClass() calls here, because we need to make sure
28766
28767		// we always remove classes first and add them second, otherwise if both classes have the
28768
28769		// same theme class, it will be removed after we add it.
28770
28771		this._removeClass( this.button, "ui-selectmenu-button-" +
28772
28773			( this.isOpen ? "closed" : "open" ) )
28774
28775			._addClass( this.button, "ui-selectmenu-button-" +
28776
28777				( this.isOpen ? "open" : "closed" ) )
28778
28779			._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen );
28780
28781
28782
28783		this.menu.attr( "aria-hidden", !this.isOpen );
28784
28785	},
28786
28787
28788
28789	_resizeButton: function() {
28790
28791		var width = this.options.width;
28792
28793
28794
28795		// For `width: false`, just remove inline style and stop
28796
28797		if ( width === false ) {
28798
28799			this.button.css( "width", "" );
28800
28801			return;
28802
28803		}
28804
28805
28806
28807		// For `width: null`, match the width of the original element
28808
28809		if ( width === null ) {
28810
28811			width = this.element.show().outerWidth();
28812
28813			this.element.hide();
28814
28815		}
28816
28817
28818
28819		this.button.outerWidth( width );
28820
28821	},
28822
28823
28824
28825	_resizeMenu: function() {
28826
28827		this.menu.outerWidth( Math.max(
28828
28829			this.button.outerWidth(),
28830
28831
28832
vendor: 5,816 bytes, lines 28833-29259
28833			// Support: IE10
28834
28835			// IE10 wraps long text (possibly a rounding bug)
28836
28837			// so we add 1px to avoid the wrapping
28838
28839			this.menu.width( "" ).outerWidth() + 1
28840
28841		) );
28842
28843	},
28844
28845
28846
28847	_getCreateOptions: function() {
28848
28849		var options = this._super();
28850
28851
28852
28853		options.disabled = this.element.prop( "disabled" );
28854
28855
28856
28857		return options;
28858
28859	},
28860
28861
28862
28863	_parseOptions: function( options ) {
28864
28865		var that = this,
28866
28867			data = [];
28868
28869		options.each( function( index, item ) {
28870
28871			data.push( that._parseOption( $( item ), index ) );
28872
28873		} );
28874
28875		this.items = data;
28876
28877	},
28878
28879
28880
28881	_parseOption: function( option, index ) {
28882
28883		var optgroup = option.parent( "optgroup" );
28884
28885
28886
28887		return {
28888
28889			element: option,
28890
28891			index: index,
28892
28893			value: option.val(),
28894
28895			label: option.text(),
28896
28897			optgroup: optgroup.attr( "label" ) || "",
28898
28899			disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
28900
28901		};
28902
28903	},
28904
28905
28906
28907	_destroy: function() {
28908
28909		this._unbindFormResetHandler();
28910
28911		this.menuWrap.remove();
28912
28913		this.button.remove();
28914
28915		this.element.show();
28916
28917		this.element.removeUniqueId();
28918
28919		this.labels.attr( "for", this.ids.element );
28920
28921	}
28922
28923} ] );
28924
28925
28926
28927
28928
28929/*!
28930
28931 * jQuery UI Slider 1.12.1
28932
28933 * http://jqueryui.com
28934
28935 *
28936
28937 * Copyright jQuery Foundation and other contributors
28938
28939 * Released under the MIT license.
28940
28941 * http://jquery.org/license
28942
28943 */
28944
28945
28946
28947//>>label: Slider
28948
28949//>>group: Widgets
28950
28951//>>description: Displays a flexible slider with ranges and accessibility via keyboard.
28952
28953//>>docs: http://api.jqueryui.com/slider/
28954
28955//>>demos: http://jqueryui.com/slider/
28956
28957//>>css.structure: ../../themes/base/core.css
28958
28959//>>css.structure: ../../themes/base/slider.css
28960
28961//>>css.theme: ../../themes/base/theme.css
28962
28963
28964
28965
28966
28967
28968
28969var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, {
28970
28971	version: "1.12.1",
28972
28973	widgetEventPrefix: "slide",
28974
28975
28976
28977	options: {
28978
28979		animate: false,
28980
28981		classes: {
28982
28983			"ui-slider": "ui-corner-all",
28984
28985			"ui-slider-handle": "ui-corner-all",
28986
28987
28988
28989			// Note: ui-widget-header isn't the most fittingly semantic framework class for this
28990
28991			// element, but worked best visually with a variety of themes
28992
28993			"ui-slider-range": "ui-corner-all ui-widget-header"
28994
28995		},
28996
28997		distance: 0,
28998
28999		max: 100,
29000
29001		min: 0,
29002
29003		orientation: "horizontal",
29004
29005		range: false,
29006
29007		step: 1,
29008
29009		value: 0,
29010
29011		values: null,
29012
29013
29014
29015		// Callbacks
29016
29017		change: null,
29018
29019		slide: null,
29020
29021		start: null,
29022
29023		stop: null
29024
29025	},
29026
29027
29028
29029	// Number of pages in a slider
29030
29031	// (how many times can you page up/down to go through the whole range)
29032
29033	numPages: 5,
29034
29035
29036
29037	_create: function() {
29038
29039		this._keySliding = false;
29040
29041		this._mouseSliding = false;
29042
29043		this._animateOff = true;
29044
29045		this._handleIndex = null;
29046
29047		this._detectOrientation();
29048
29049		this._mouseInit();
29050
29051		this._calculateNewMax();
29052
29053
29054
29055		this._addClass( "ui-slider ui-slider-" + this.orientation,
29056
29057			"ui-widget ui-widget-content" );
29058
29059
29060
29061		this._refresh();
29062
29063
29064
29065		this._animateOff = false;
29066
29067	},
29068
29069
29070
29071	_refresh: function() {
29072
29073		this._createRange();
29074
29075		this._createHandles();
29076
29077		this._setupEvents();
29078
29079		this._refreshValue();
29080
29081	},
29082
29083
29084
29085	_createHandles: function() {
29086
29087		var i, handleCount,
29088
29089			options = this.options,
29090
29091			existingHandles = this.element.find( ".ui-slider-handle" ),
29092
29093			handle = "<span tabindex='0'></span>",
29094
29095			handles = [];
29096
29097
29098
29099		handleCount = ( options.values && options.values.length ) || 1;
29100
29101
29102
29103		if ( existingHandles.length > handleCount ) {
29104
29105			existingHandles.slice( handleCount ).remove();
29106
29107			existingHandles = existingHandles.slice( 0, handleCount );
29108
29109		}
29110
29111
29112
29113		for ( i = existingHandles.length; i < handleCount; i++ ) {
29114
29115			handles.push( handle );
29116
29117		}
29118
29119
29120
29121		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
29122
29123
29124
29125		this._addClass( this.handles, "ui-slider-handle", "ui-state-default" );
29126
29127
29128
29129		this.handle = this.handles.eq( 0 );
29130
29131
29132
29133		this.handles.each( function( i ) {
29134
29135			$( this )
29136
29137				.data( "ui-slider-handle-index", i )
29138
29139				.attr( "tabIndex", 0 );
29140
29141		} );
29142
29143	},
29144
29145
29146
29147	_createRange: function() {
29148
29149		var options = this.options;
29150
29151
29152
29153		if ( options.range ) {
29154
29155			if ( options.range === true ) {
29156
29157				if ( !options.values ) {
29158
29159					options.values = [ this._valueMin(), this._valueMin() ];
29160
29161				} else if ( options.values.length && options.values.length !== 2 ) {
29162
29163					options.values = [ options.values[ 0 ], options.values[ 0 ] ];
29164
29165				} else if ( $.isArray( options.values ) ) {
29166
29167					options.values = options.values.slice( 0 );
29168
29169				}
29170
29171			}
29172
29173
29174
29175			if ( !this.range || !this.range.length ) {
29176
29177				this.range = $( "<div>" )
29178
29179					.appendTo( this.element );
29180
29181
29182
29183				this._addClass( this.range, "ui-slider-range" );
29184
29185			} else {
29186
29187				this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" );
29188
29189
29190
29191				// Handle range switching from true to min/max
29192
29193				this.range.css( {
29194
29195					"left": "",
29196
29197					"bottom": ""
29198
29199				} );
29200
29201			}
29202
29203			if ( options.range === "min" || options.range === "max" ) {
29204
29205				this._addClass( this.range, "ui-slider-range-" + options.range );
29206
29207			}
29208
29209		} else {
29210
29211			if ( this.range ) {
29212
29213				this.range.remove();
29214
29215			}
29216
29217			this.range = null;
29218
29219		}
29220
29221	},
29222
29223
29224
29225	_setupEvents: function() {
29226
29227		this._off( this.handles );
29228
29229		this._on( this.handles, this._handleEvents );
29230
29231		this._hoverable( this.handles );
29232
29233		this._focusable( this.handles );
29234
29235	},
29236
29237
29238
29239	_destroy: function() {
29240
29241		this.handles.remove();
29242
29243		if ( this.range ) {
29244
29245			this.range.remove();
29246
29247		}
29248
29249
29250
29251		this._mouseDestroy();
29252
29253	},
29254
29255
29256
29257	_mouseCapture: function( event ) {
29258
29259		var position, normValue, distance, closestHandle, index, allowed, offset, mou
vendor: 18,689 bytes, lines 29259-30551
29259seOverHandle,
29260
29261			that = this,
29262
29263			o = this.options;
29264
29265
29266
29267		if ( o.disabled ) {
29268
29269			return false;
29270
29271		}
29272
29273
29274
29275		this.elementSize = {
29276
29277			width: this.element.outerWidth(),
29278
29279			height: this.element.outerHeight()
29280
29281		};
29282
29283		this.elementOffset = this.element.offset();
29284
29285
29286
29287		position = { x: event.pageX, y: event.pageY };
29288
29289		normValue = this._normValueFromMouse( position );
29290
29291		distance = this._valueMax() - this._valueMin() + 1;
29292
29293		this.handles.each( function( i ) {
29294
29295			var thisDistance = Math.abs( normValue - that.values( i ) );
29296
29297			if ( ( distance > thisDistance ) ||
29298
29299				( distance === thisDistance &&
29300
29301					( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) {
29302
29303				distance = thisDistance;
29304
29305				closestHandle = $( this );
29306
29307				index = i;
29308
29309			}
29310
29311		} );
29312
29313
29314
29315		allowed = this._start( event, index );
29316
29317		if ( allowed === false ) {
29318
29319			return false;
29320
29321		}
29322
29323		this._mouseSliding = true;
29324
29325
29326
29327		this._handleIndex = index;
29328
29329
29330
29331		this._addClass( closestHandle, null, "ui-state-active" );
29332
29333		closestHandle.trigger( "focus" );
29334
29335
29336
29337		offset = closestHandle.offset();
29338
29339		mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
29340
29341		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
29342
29343			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
29344
29345			top: event.pageY - offset.top -
29346
29347				( closestHandle.height() / 2 ) -
29348
29349				( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) -
29350
29351				( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) +
29352
29353				( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 )
29354
29355		};
29356
29357
29358
29359		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
29360
29361			this._slide( event, index, normValue );
29362
29363		}
29364
29365		this._animateOff = true;
29366
29367		return true;
29368
29369	},
29370
29371
29372
29373	_mouseStart: function() {
29374
29375		return true;
29376
29377	},
29378
29379
29380
29381	_mouseDrag: function( event ) {
29382
29383		var position = { x: event.pageX, y: event.pageY },
29384
29385			normValue = this._normValueFromMouse( position );
29386
29387
29388
29389		this._slide( event, this._handleIndex, normValue );
29390
29391
29392
29393		return false;
29394
29395	},
29396
29397
29398
29399	_mouseStop: function( event ) {
29400
29401		this._removeClass( this.handles, null, "ui-state-active" );
29402
29403		this._mouseSliding = false;
29404
29405
29406
29407		this._stop( event, this._handleIndex );
29408
29409		this._change( event, this._handleIndex );
29410
29411
29412
29413		this._handleIndex = null;
29414
29415		this._clickOffset = null;
29416
29417		this._animateOff = false;
29418
29419
29420
29421		return false;
29422
29423	},
29424
29425
29426
29427	_detectOrientation: function() {
29428
29429		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
29430
29431	},
29432
29433
29434
29435	_normValueFromMouse: function( position ) {
29436
29437		var pixelTotal,
29438
29439			pixelMouse,
29440
29441			percentMouse,
29442
29443			valueTotal,
29444
29445			valueMouse;
29446
29447
29448
29449		if ( this.orientation === "horizontal" ) {
29450
29451			pixelTotal = this.elementSize.width;
29452
29453			pixelMouse = position.x - this.elementOffset.left -
29454
29455				( this._clickOffset ? this._clickOffset.left : 0 );
29456
29457		} else {
29458
29459			pixelTotal = this.elementSize.height;
29460
29461			pixelMouse = position.y - this.elementOffset.top -
29462
29463				( this._clickOffset ? this._clickOffset.top : 0 );
29464
29465		}
29466
29467
29468
29469		percentMouse = ( pixelMouse / pixelTotal );
29470
29471		if ( percentMouse > 1 ) {
29472
29473			percentMouse = 1;
29474
29475		}
29476
29477		if ( percentMouse < 0 ) {
29478
29479			percentMouse = 0;
29480
29481		}
29482
29483		if ( this.orientation === "vertical" ) {
29484
29485			percentMouse = 1 - percentMouse;
29486
29487		}
29488
29489
29490
29491		valueTotal = this._valueMax() - this._valueMin();
29492
29493		valueMouse = this._valueMin() + percentMouse * valueTotal;
29494
29495
29496
29497		return this._trimAlignValue( valueMouse );
29498
29499	},
29500
29501
29502
29503	_uiHash: function( index, value, values ) {
29504
29505		var uiHash = {
29506
29507			handle: this.handles[ index ],
29508
29509			handleIndex: index,
29510
29511			value: value !== undefined ? value : this.value()
29512
29513		};
29514
29515
29516
29517		if ( this._hasMultipleValues() ) {
29518
29519			uiHash.value = value !== undefined ? value : this.values( index );
29520
29521			uiHash.values = values || this.values();
29522
29523		}
29524
29525
29526
29527		return uiHash;
29528
29529	},
29530
29531
29532
29533	_hasMultipleValues: function() {
29534
29535		return this.options.values && this.options.values.length;
29536
29537	},
29538
29539
29540
29541	_start: function( event, index ) {
29542
29543		return this._trigger( "start", event, this._uiHash( index ) );
29544
29545	},
29546
29547
29548
29549	_slide: function( event, index, newVal ) {
29550
29551		var allowed, otherVal,
29552
29553			currentValue = this.value(),
29554
29555			newValues = this.values();
29556
29557
29558
29559		if ( this._hasMultipleValues() ) {
29560
29561			otherVal = this.values( index ? 0 : 1 );
29562
29563			currentValue = this.values( index );
29564
29565
29566
29567			if ( this.options.values.length === 2 && this.options.range === true ) {
29568
29569				newVal =  index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal );
29570
29571			}
29572
29573
29574
29575			newValues[ index ] = newVal;
29576
29577		}
29578
29579
29580
29581		if ( newVal === currentValue ) {
29582
29583			return;
29584
29585		}
29586
29587
29588
29589		allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) );
29590
29591
29592
29593		// A slide can be canceled by returning false from the slide callback
29594
29595		if ( allowed === false ) {
29596
29597			return;
29598
29599		}
29600
29601
29602
29603		if ( this._hasMultipleValues() ) {
29604
29605			this.values( index, newVal );
29606
29607		} else {
29608
29609			this.value( newVal );
29610
29611		}
29612
29613	},
29614
29615
29616
29617	_stop: function( event, index ) {
29618
29619		this._trigger( "stop", event, this._uiHash( index ) );
29620
29621	},
29622
29623
29624
29625	_change: function( event, index ) {
29626
29627		if ( !this._keySliding && !this._mouseSliding ) {
29628
29629
29630
29631			//store the last changed value index for reference when handles overlap
29632
29633			this._lastChangedValue = index;
29634
29635			this._trigger( "change", event, this._uiHash( index ) );
29636
29637		}
29638
29639	},
29640
29641
29642
29643	value: function( newValue ) {
29644
29645		if ( arguments.length ) {
29646
29647			this.options.value = this._trimAlignValue( newValue );
29648
29649			this._refreshValue();
29650
29651			this._change( null, 0 );
29652
29653			return;
29654
29655		}
29656
29657
29658
29659		return this._value();
29660
29661	},
29662
29663
29664
29665	values: function( index, newValue ) {
29666
29667		var vals,
29668
29669			newValues,
29670
29671			i;
29672
29673
29674
29675		if ( arguments.length > 1 ) {
29676
29677			this.options.values[ index ] = this._trimAlignValue( newValue );
29678
29679			this._refreshValue();
29680
29681			this._change( null, index );
29682
29683			return;
29684
29685		}
29686
29687
29688
29689		if ( arguments.length ) {
29690
29691			if ( $.isArray( arguments[ 0 ] ) ) {
29692
29693				vals = this.options.values;
29694
29695				newValues = arguments[ 0 ];
29696
29697				for ( i = 0; i < vals.length; i += 1 ) {
29698
29699					vals[ i ] = this._trimAlignValue( newValues[ i ] );
29700
29701					this._change( null, i );
29702
29703				}
29704
29705				this._refreshValue();
29706
29707			} else {
29708
29709				if ( this._hasMultipleValues() ) {
29710
29711					return this._values( index );
29712
29713				} else {
29714
29715					return this.value();
29716
29717				}
29718
29719			}
29720
29721		} else {
29722
29723			return this._values();
29724
29725		}
29726
29727	},
29728
29729
29730
29731	_setOption: function( key, value ) {
29732
29733		var i,
29734
29735			valsLength = 0;
29736
29737
29738
29739		if ( key === "range" && this.options.range === true ) {
29740
29741			if ( value === "min" ) {
29742
29743				this.options.value = this._values( 0 );
29744
29745				this.options.values = null;
29746
29747			} else if ( value === "max" ) {
29748
29749				this.options.value = this._values( this.options.values.length - 1 );
29750
29751				this.options.values = null;
29752
29753			}
29754
29755		}
29756
29757
29758
29759		if ( $.isArray( this.options.values ) ) {
29760
29761			valsLength = this.options.values.length;
29762
29763		}
29764
29765
29766
29767		this._super( key, value );
29768
29769
29770
29771		switch ( key ) {
29772
29773			case "orientation":
29774
29775				this._detectOrientation();
29776
29777				this._removeClass( "ui-slider-horizontal ui-slider-vertical" )
29778
29779					._addClass( "ui-slider-" + this.orientation );
29780
29781				this._refreshValue();
29782
29783				if ( this.options.range ) {
29784
29785					this._refreshRange( value );
29786
29787				}
29788
29789
29790
29791				// Reset positioning from previous orientation
29792
29793				this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
29794
29795				break;
29796
29797			case "value":
29798
29799				this._animateOff = true;
29800
29801				this._refreshValue();
29802
29803				this._change( null, 0 );
29804
29805				this._animateOff = false;
29806
29807				break;
29808
29809			case "values":
29810
29811				this._animateOff = true;
29812
29813				this._refreshValue();
29814
29815
29816
29817				// Start from the last handle to prevent unreachable handles (#9046)
29818
29819				for ( i = valsLength - 1; i >= 0; i-- ) {
29820
29821					this._change( null, i );
29822
29823				}
29824
29825				this._animateOff = false;
29826
29827				break;
29828
29829			case "step":
29830
29831			case "min":
29832
29833			case "max":
29834
29835				this._animateOff = true;
29836
29837				this._calculateNewMax();
29838
29839				this._refreshValue();
29840
29841				this._animateOff = false;
29842
29843				break;
29844
29845			case "range":
29846
29847				this._animateOff = true;
29848
29849				this._refresh();
29850
29851				this._animateOff = false;
29852
29853				break;
29854
29855		}
29856
29857	},
29858
29859
29860
29861	_setOptionDisabled: function( value ) {
29862
29863		this._super( value );
29864
29865
29866
29867		this._toggleClass( null, "ui-state-disabled", !!value );
29868
29869	},
29870
29871
29872
29873	//internal value getter
29874
29875	// _value() returns value trimmed by min and max, aligned by step
29876
29877	_value: function() {
29878
29879		var val = this.options.value;
29880
29881		val = this._trimAlignValue( val );
29882
29883
29884
29885		return val;
29886
29887	},
29888
29889
29890
29891	//internal values getter
29892
29893	// _values() returns array of values trimmed by min and max, aligned by step
29894
29895	// _values( index ) returns single value trimmed by min and max, aligned by step
29896
29897	_values: function( index ) {
29898
29899		var val,
29900
29901			vals,
29902
29903			i;
29904
29905
29906
29907		if ( arguments.length ) {
29908
29909			val = this.options.values[ index ];
29910
29911			val = this._trimAlignValue( val );
29912
29913
29914
29915			return val;
29916
29917		} else if ( this._hasMultipleValues() ) {
29918
29919
29920
29921			// .slice() creates a copy of the array
29922
29923			// this copy gets trimmed by min and max and then returned
29924
29925			vals = this.options.values.slice();
29926
29927			for ( i = 0; i < vals.length; i += 1 ) {
29928
29929				vals[ i ] = this._trimAlignValue( vals[ i ] );
29930
29931			}
29932
29933
29934
29935			return vals;
29936
29937		} else {
29938
29939			return [];
29940
29941		}
29942
29943	},
29944
29945
29946
29947	// Returns the step-aligned value that val is closest to, between (inclusive) min and max
29948
29949	_trimAlignValue: function( val ) {
29950
29951		if ( val <= this._valueMin() ) {
29952
29953			return this._valueMin();
29954
29955		}
29956
29957		if ( val >= this._valueMax() ) {
29958
29959			return this._valueMax();
29960
29961		}
29962
29963		var step = ( this.options.step > 0 ) ? this.options.step : 1,
29964
29965			valModStep = ( val - this._valueMin() ) % step,
29966
29967			alignValue = val - valModStep;
29968
29969
29970
29971		if ( Math.abs( valModStep ) * 2 >= step ) {
29972
29973			alignValue += ( valModStep > 0 ) ? step : ( -step );
29974
29975		}
29976
29977
29978
29979		// Since JavaScript has problems with large floats, round
29980
29981		// the final value to 5 digits after the decimal point (see #4124)
29982
29983		return parseFloat( alignValue.toFixed( 5 ) );
29984
29985	},
29986
29987
29988
29989	_calculateNewMax: function() {
29990
29991		var max = this.options.max,
29992
29993			min = this._valueMin(),
29994
29995			step = this.options.step,
29996
29997			aboveMin = Math.round( ( max - min ) / step ) * step;
29998
29999		max = aboveMin + min;
30000
30001		if ( max > this.options.max ) {
30002
30003
30004
30005			//If max is not divisible by step, rounding off may increase its value
30006
30007			max -= step;
30008
30009		}
30010
30011		this.max = parseFloat( max.toFixed( this._precision() ) );
30012
30013	},
30014
30015
30016
30017	_precision: function() {
30018
30019		var precision = this._precisionOf( this.options.step );
30020
30021		if ( this.options.min !== null ) {
30022
30023			precision = Math.max( precision, this._precisionOf( this.options.min ) );
30024
30025		}
30026
30027		return precision;
30028
30029	},
30030
30031
30032
30033	_precisionOf: function( num ) {
30034
30035		var str = num.toString(),
30036
30037			decimal = str.indexOf( "." );
30038
30039		return decimal === -1 ? 0 : str.length - decimal - 1;
30040
30041	},
30042
30043
30044
30045	_valueMin: function() {
30046
30047		return this.options.min;
30048
30049	},
30050
30051
30052
30053	_valueMax: function() {
30054
30055		return this.max;
30056
30057	},
30058
30059
30060
30061	_refreshRange: function( orientation ) {
30062
30063		if ( orientation === "vertical" ) {
30064
30065			this.range.css( { "width": "", "left": "" } );
30066
30067		}
30068
30069		if ( orientation === "horizontal" ) {
30070
30071			this.range.css( { "height": "", "bottom": "" } );
30072
30073		}
30074
30075	},
30076
30077
30078
30079	_refreshValue: function() {
30080
30081		var lastValPercent, valPercent, value, valueMin, valueMax,
30082
30083			oRange = this.options.range,
30084
30085			o = this.options,
30086
30087			that = this,
30088
30089			animate = ( !this._animateOff ) ? o.animate : false,
30090
30091			_set = {};
30092
30093
30094
30095		if ( this._hasMultipleValues() ) {
30096
30097			this.handles.each( function( i ) {
30098
30099				valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() -
30100
30101					that._valueMin() ) * 100;
30102
30103				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
30104
30105				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
30106
30107				if ( that.options.range === true ) {
30108
30109					if ( that.orientation === "horizontal" ) {
30110
30111						if ( i === 0 ) {
30112
30113							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
30114
30115								left: valPercent + "%"
30116
30117							}, o.animate );
30118
30119						}
30120
30121						if ( i === 1 ) {
30122
30123							that.range[ animate ? "animate" : "css" ]( {
30124
30125								width: ( valPercent - lastValPercent ) + "%"
30126
30127							}, {
30128
30129								queue: false,
30130
30131								duration: o.animate
30132
30133							} );
30134
30135						}
30136
30137					} else {
30138
30139						if ( i === 0 ) {
30140
30141							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
30142
30143								bottom: ( valPercent ) + "%"
30144
30145							}, o.animate );
30146
30147						}
30148
30149						if ( i === 1 ) {
30150
30151							that.range[ animate ? "animate" : "css" ]( {
30152
30153								height: ( valPercent - lastValPercent ) + "%"
30154
30155							}, {
30156
30157								queue: false,
30158
30159								duration: o.animate
30160
30161							} );
30162
30163						}
30164
30165					}
30166
30167				}
30168
30169				lastValPercent = valPercent;
30170
30171			} );
30172
30173		} else {
30174
30175			value = this.value();
30176
30177			valueMin = this._valueMin();
30178
30179			valueMax = this._valueMax();
30180
30181			valPercent = ( valueMax !== valueMin ) ?
30182
30183					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
30184
30185					0;
30186
30187			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
30188
30189			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
30190
30191
30192
30193			if ( oRange === "min" && this.orientation === "horizontal" ) {
30194
30195				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
30196
30197					width: valPercent + "%"
30198
30199				}, o.animate );
30200
30201			}
30202
30203			if ( oRange === "max" && this.orientation === "horizontal" ) {
30204
30205				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
30206
30207					width: ( 100 - valPercent ) + "%"
30208
30209				}, o.animate );
30210
30211			}
30212
30213			if ( oRange === "min" && this.orientation === "vertical" ) {
30214
30215				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
30216
30217					height: valPercent + "%"
30218
30219				}, o.animate );
30220
30221			}
30222
30223			if ( oRange === "max" && this.orientation === "vertical" ) {
30224
30225				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
30226
30227					height: ( 100 - valPercent ) + "%"
30228
30229				}, o.animate );
30230
30231			}
30232
30233		}
30234
30235	},
30236
30237
30238
30239	_handleEvents: {
30240
30241		keydown: function( event ) {
30242
30243			var allowed, curVal, newVal, step,
30244
30245				index = $( event.target ).data( "ui-slider-handle-index" );
30246
30247
30248
30249			switch ( event.keyCode ) {
30250
30251				case $.ui.keyCode.HOME:
30252
30253				case $.ui.keyCode.END:
30254
30255				case $.ui.keyCode.PAGE_UP:
30256
30257				case $.ui.keyCode.PAGE_DOWN:
30258
30259				case $.ui.keyCode.UP:
30260
30261				case $.ui.keyCode.RIGHT:
30262
30263				case $.ui.keyCode.DOWN:
30264
30265				case $.ui.keyCode.LEFT:
30266
30267					event.preventDefault();
30268
30269					if ( !this._keySliding ) {
30270
30271						this._keySliding = true;
30272
30273						this._addClass( $( event.target ), null, "ui-state-active" );
30274
30275						allowed = this._start( event, index );
30276
30277						if ( allowed === false ) {
30278
30279							return;
30280
30281						}
30282
30283					}
30284
30285					break;
30286
30287			}
30288
30289
30290
30291			step = this.options.step;
30292
30293			if ( this._hasMultipleValues() ) {
30294
30295				curVal = newVal = this.values( index );
30296
30297			} else {
30298
30299				curVal = newVal = this.value();
30300
30301			}
30302
30303
30304
30305			switch ( event.keyCode ) {
30306
30307				case $.ui.keyCode.HOME:
30308
30309					newVal = this._valueMin();
30310
30311					break;
30312
30313				case $.ui.keyCode.END:
30314
30315					newVal = this._valueMax();
30316
30317					break;
30318
30319				case $.ui.keyCode.PAGE_UP:
30320
30321					newVal = this._trimAlignValue(
30322
30323						curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
30324
30325					);
30326
30327					break;
30328
30329				case $.ui.keyCode.PAGE_DOWN:
30330
30331					newVal = this._trimAlignValue(
30332
30333						curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) );
30334
30335					break;
30336
30337				case $.ui.keyCode.UP:
30338
30339				case $.ui.keyCode.RIGHT:
30340
30341					if ( curVal === this._valueMax() ) {
30342
30343						return;
30344
30345					}
30346
30347					newVal = this._trimAlignValue( curVal + step );
30348
30349					break;
30350
30351				case $.ui.keyCode.DOWN:
30352
30353				case $.ui.keyCode.LEFT:
30354
30355					if ( curVal === this._valueMin() ) {
30356
30357						return;
30358
30359					}
30360
30361					newVal = this._trimAlignValue( curVal - step );
30362
30363					break;
30364
30365			}
30366
30367
30368
30369			this._slide( event, index, newVal );
30370
30371		},
30372
30373		keyup: function( event ) {
30374
30375			var index = $( event.target ).data( "ui-slider-handle-index" );
30376
30377
30378
30379			if ( this._keySliding ) {
30380
30381				this._keySliding = false;
30382
30383				this._stop( event, index );
30384
30385				this._change( event, index );
30386
30387				this._removeClass( $( event.target ), null, "ui-state-active" );
30388
30389			}
30390
30391		}
30392
30393	}
30394
30395} );
30396
30397
30398
30399
30400
30401/*!
30402
30403 * jQuery UI Sortable 1.12.1
30404
30405 * http://jqueryui.com
30406
30407 *
30408
30409 * Copyright jQuery Foundation and other contributors
30410
30411 * Released under the MIT license.
30412
30413 * http://jquery.org/license
30414
30415 */
30416
30417
30418
30419//>>label: Sortable
30420
30421//>>group: Interactions
30422
30423//>>description: Enables items in a list to be sorted using the mouse.
30424
30425//>>docs: http://api.jqueryui.com/sortable/
30426
30427//>>demos: http://jqueryui.com/sortable/
30428
30429//>>css.structure: ../../themes/base/sortable.css
30430
30431
30432
30433
30434
30435
30436
30437var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, {
30438
30439	version: "1.12.1",
30440
30441	widgetEventPrefix: "sort",
30442
30443	ready: false,
30444
30445	options: {
30446
30447		appendTo: "parent",
30448
30449		axis: false,
30450
30451		connectWith: false,
30452
30453		containment: false,
30454
30455		cursor: "auto",
30456
30457		cursorAt: false,
30458
30459		dropOnEmpty: true,
30460
30461		forcePlaceholderSize: false,
30462
30463		forceHelperSize: false,
30464
30465		grid: false,
30466
30467		handle: false,
30468
30469		helper: "original",
30470
30471		items: "> *",
30472
30473		opacity: false,
30474
30475		placeholder: false,
30476
30477		revert: false,
30478
30479		scroll: true,
30480
30481		scrollSensitivity: 20,
30482
30483		scrollSpeed: 20,
30484
30485		scope: "default",
30486
30487		tolerance: "intersect",
30488
30489		zIndex: 1000,
30490
30491
30492
30493		// Callbacks
30494
30495		activate: null,
30496
30497		beforeStop: null,
30498
30499		change: null,
30500
30501		deactivate: null,
30502
30503		out: null,
30504
30505		over: null,
30506
30507		receive: null,
30508
30509		remove: null,
30510
30511		sort: null,
30512
30513		start: null,
30514
30515		stop: null,
30516
30517		update: null
30518
30519	},
30520
30521
30522
30523	_isOverAxis: function( x, reference, size ) {
30524
30525		return ( x >= reference ) && ( x < ( reference + size ) );
30526
30527	},
30528
30529
30530
30531	_isFloating: function( item ) {
30532
30533		return ( /left|right/ ).test( item.css( "float" ) ) ||
30534
30535			( /inline|table-cell/ ).test( item.css( "display" ) );
30536
30537	},
30538
30539
30540
30541	_create: function() {
30542
30543		this.containerCache = {};
30544
30545		this._addClass( "ui-sortable" );
30546
30547
30548
30549		//Get the items
30550
30551		this.refresh();
vendor: 36,925 bytes, lines 30552-32799
30552
30553
30554
30555		//Let's determine the parent's offset
30556
30557		this.offset = this.element.offset();
30558
30559
30560
30561		//Initialize mouse events for interaction
30562
30563		this._mouseInit();
30564
30565
30566
30567		this._setHandleClassName();
30568
30569
30570
30571		//We're ready to go
30572
30573		this.ready = true;
30574
30575
30576
30577	},
30578
30579
30580
30581	_setOption: function( key, value ) {
30582
30583		this._super( key, value );
30584
30585
30586
30587		if ( key === "handle" ) {
30588
30589			this._setHandleClassName();
30590
30591		}
30592
30593	},
30594
30595
30596
30597	_setHandleClassName: function() {
30598
30599		var that = this;
30600
30601		this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" );
30602
30603		$.each( this.items, function() {
30604
30605			that._addClass(
30606
30607				this.instance.options.handle ?
30608
30609					this.item.find( this.instance.options.handle ) :
30610
30611					this.item,
30612
30613				"ui-sortable-handle"
30614
30615			);
30616
30617		} );
30618
30619	},
30620
30621
30622
30623	_destroy: function() {
30624
30625		this._mouseDestroy();
30626
30627
30628
30629		for ( var i = this.items.length - 1; i >= 0; i-- ) {
30630
30631			this.items[ i ].item.removeData( this.widgetName + "-item" );
30632
30633		}
30634
30635
30636
30637		return this;
30638
30639	},
30640
30641
30642
30643	_mouseCapture: function( event, overrideHandle ) {
30644
30645		var currentItem = null,
30646
30647			validHandle = false,
30648
30649			that = this;
30650
30651
30652
30653		if ( this.reverting ) {
30654
30655			return false;
30656
30657		}
30658
30659
30660
30661		if ( this.options.disabled || this.options.type === "static" ) {
30662
30663			return false;
30664
30665		}
30666
30667
30668
30669		//We have to refresh the items data once first
30670
30671		this._refreshItems( event );
30672
30673
30674
30675		//Find out if the clicked node (or one of its parents) is a actual item in this.items
30676
30677		$( event.target ).parents().each( function() {
30678
30679			if ( $.data( this, that.widgetName + "-item" ) === that ) {
30680
30681				currentItem = $( this );
30682
30683				return false;
30684
30685			}
30686
30687		} );
30688
30689		if ( $.data( event.target, that.widgetName + "-item" ) === that ) {
30690
30691			currentItem = $( event.target );
30692
30693		}
30694
30695
30696
30697		if ( !currentItem ) {
30698
30699			return false;
30700
30701		}
30702
30703		if ( this.options.handle && !overrideHandle ) {
30704
30705			$( this.options.handle, currentItem ).find( "*" ).addBack().each( function() {
30706
30707				if ( this === event.target ) {
30708
30709					validHandle = true;
30710
30711				}
30712
30713			} );
30714
30715			if ( !validHandle ) {
30716
30717				return false;
30718
30719			}
30720
30721		}
30722
30723
30724
30725		this.currentItem = currentItem;
30726
30727		this._removeCurrentsFromItems();
30728
30729		return true;
30730
30731
30732
30733	},
30734
30735
30736
30737	_mouseStart: function( event, overrideHandle, noActivation ) {
30738
30739
30740
30741		var i, body,
30742
30743			o = this.options;
30744
30745
30746
30747		this.currentContainer = this;
30748
30749
30750
30751		//We only need to call refreshPositions, because the refreshItems call has been moved to
30752
30753		// mouseCapture
30754
30755		this.refreshPositions();
30756
30757
30758
30759		//Create and append the visible helper
30760
30761		this.helper = this._createHelper( event );
30762
30763
30764
30765		//Cache the helper size
30766
30767		this._cacheHelperProportions();
30768
30769
30770
30771		/*
30772
30773		 * - Position generation -
30774
30775		 * This block generates everything position related - it's the core of draggables.
30776
30777		 */
30778
30779
30780
30781		//Cache the margins of the original element
30782
30783		this._cacheMargins();
30784
30785
30786
30787		//Get the next scrolling parent
30788
30789		this.scrollParent = this.helper.scrollParent();
30790
30791
30792
30793		//The element's absolute position on the page minus margins
30794
30795		this.offset = this.currentItem.offset();
30796
30797		this.offset = {
30798
30799			top: this.offset.top - this.margins.top,
30800
30801			left: this.offset.left - this.margins.left
30802
30803		};
30804
30805
30806
30807		$.extend( this.offset, {
30808
30809			click: { //Where the click happened, relative to the element
30810
30811				left: event.pageX - this.offset.left,
30812
30813				top: event.pageY - this.offset.top
30814
30815			},
30816
30817			parent: this._getParentOffset(),
30818
30819
30820
30821			// This is a relative to absolute position minus the actual position calculation -
30822
30823			// only used for relative positioned helper
30824
30825			relative: this._getRelativeOffset()
30826
30827		} );
30828
30829
30830
30831		// Only after we got the offset, we can change the helper's position to absolute
30832
30833		// TODO: Still need to figure out a way to make relative sorting possible
30834
30835		this.helper.css( "position", "absolute" );
30836
30837		this.cssPosition = this.helper.css( "position" );
30838
30839
30840
30841		//Generate the original position
30842
30843		this.originalPosition = this._generatePosition( event );
30844
30845		this.originalPageX = event.pageX;
30846
30847		this.originalPageY = event.pageY;
30848
30849
30850
30851		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
30852
30853		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
30854
30855
30856
30857		//Cache the former DOM position
30858
30859		this.domPosition = {
30860
30861			prev: this.currentItem.prev()[ 0 ],
30862
30863			parent: this.currentItem.parent()[ 0 ]
30864
30865		};
30866
30867
30868
30869		// If the helper is not the original, hide the original so it's not playing any role during
30870
30871		// the drag, won't cause anything bad this way
30872
30873		if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
30874
30875			this.currentItem.hide();
30876
30877		}
30878
30879
30880
30881		//Create the placeholder
30882
30883		this._createPlaceholder();
30884
30885
30886
30887		//Set a containment if given in the options
30888
30889		if ( o.containment ) {
30890
30891			this._setContainment();
30892
30893		}
30894
30895
30896
30897		if ( o.cursor && o.cursor !== "auto" ) { // cursor option
30898
30899			body = this.document.find( "body" );
30900
30901
30902
30903			// Support: IE
30904
30905			this.storedCursor = body.css( "cursor" );
30906
30907			body.css( "cursor", o.cursor );
30908
30909
30910
30911			this.storedStylesheet =
30912
30913				$( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body );
30914
30915		}
30916
30917
30918
30919		if ( o.opacity ) { // opacity option
30920
30921			if ( this.helper.css( "opacity" ) ) {
30922
30923				this._storedOpacity = this.helper.css( "opacity" );
30924
30925			}
30926
30927			this.helper.css( "opacity", o.opacity );
30928
30929		}
30930
30931
30932
30933		if ( o.zIndex ) { // zIndex option
30934
30935			if ( this.helper.css( "zIndex" ) ) {
30936
30937				this._storedZIndex = this.helper.css( "zIndex" );
30938
30939			}
30940
30941			this.helper.css( "zIndex", o.zIndex );
30942
30943		}
30944
30945
30946
30947		//Prepare scrolling
30948
30949		if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
30950
30951				this.scrollParent[ 0 ].tagName !== "HTML" ) {
30952
30953			this.overflowOffset = this.scrollParent.offset();
30954
30955		}
30956
30957
30958
30959		//Call callbacks
30960
30961		this._trigger( "start", event, this._uiHash() );
30962
30963
30964
30965		//Recache the helper size
30966
30967		if ( !this._preserveHelperProportions ) {
30968
30969			this._cacheHelperProportions();
30970
30971		}
30972
30973
30974
30975		//Post "activate" events to possible containers
30976
30977		if ( !noActivation ) {
30978
30979			for ( i = this.containers.length - 1; i >= 0; i-- ) {
30980
30981				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
30982
30983			}
30984
30985		}
30986
30987
30988
30989		//Prepare possible droppables
30990
30991		if ( $.ui.ddmanager ) {
30992
30993			$.ui.ddmanager.current = this;
30994
30995		}
30996
30997
30998
30999		if ( $.ui.ddmanager && !o.dropBehaviour ) {
31000
31001			$.ui.ddmanager.prepareOffsets( this, event );
31002
31003		}
31004
31005
31006
31007		this.dragging = true;
31008
31009
31010
31011		this._addClass( this.helper, "ui-sortable-helper" );
31012
31013
31014
31015		// Execute the drag once - this causes the helper not to be visiblebefore getting its
31016
31017		// correct position
31018
31019		this._mouseDrag( event );
31020
31021		return true;
31022
31023
31024
31025	},
31026
31027
31028
31029	_mouseDrag: function( event ) {
31030
31031		var i, item, itemElement, intersection,
31032
31033			o = this.options,
31034
31035			scrolled = false;
31036
31037
31038
31039		//Compute the helpers position
31040
31041		this.position = this._generatePosition( event );
31042
31043		this.positionAbs = this._convertPositionTo( "absolute" );
31044
31045
31046
31047		if ( !this.lastPositionAbs ) {
31048
31049			this.lastPositionAbs = this.positionAbs;
31050
31051		}
31052
31053
31054
31055		//Do scrolling
31056
31057		if ( this.options.scroll ) {
31058
31059			if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
31060
31061					this.scrollParent[ 0 ].tagName !== "HTML" ) {
31062
31063
31064
31065				if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -
31066
31067						event.pageY < o.scrollSensitivity ) {
31068
31069					this.scrollParent[ 0 ].scrollTop =
31070
31071						scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;
31072
31073				} else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {
31074
31075					this.scrollParent[ 0 ].scrollTop =
31076
31077						scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;
31078
31079				}
31080
31081
31082
31083				if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -
31084
31085						event.pageX < o.scrollSensitivity ) {
31086
31087					this.scrollParent[ 0 ].scrollLeft = scrolled =
31088
31089						this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;
31090
31091				} else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {
31092
31093					this.scrollParent[ 0 ].scrollLeft = scrolled =
31094
31095						this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;
31096
31097				}
31098
31099
31100
31101			} else {
31102
31103
31104
31105				if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {
31106
31107					scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );
31108
31109				} else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <
31110
31111						o.scrollSensitivity ) {
31112
31113					scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );
31114
31115				}
31116
31117
31118
31119				if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {
31120
31121					scrolled = this.document.scrollLeft(
31122
31123						this.document.scrollLeft() - o.scrollSpeed
31124
31125					);
31126
31127				} else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <
31128
31129						o.scrollSensitivity ) {
31130
31131					scrolled = this.document.scrollLeft(
31132
31133						this.document.scrollLeft() + o.scrollSpeed
31134
31135					);
31136
31137				}
31138
31139
31140
31141			}
31142
31143
31144
31145			if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
31146
31147				$.ui.ddmanager.prepareOffsets( this, event );
31148
31149			}
31150
31151		}
31152
31153
31154
31155		//Regenerate the absolute position used for position checks
31156
31157		this.positionAbs = this._convertPositionTo( "absolute" );
31158
31159
31160
31161		//Set the helper position
31162
31163		if ( !this.options.axis || this.options.axis !== "y" ) {
31164
31165			this.helper[ 0 ].style.left = this.position.left + "px";
31166
31167		}
31168
31169		if ( !this.options.axis || this.options.axis !== "x" ) {
31170
31171			this.helper[ 0 ].style.top = this.position.top + "px";
31172
31173		}
31174
31175
31176
31177		//Rearrange
31178
31179		for ( i = this.items.length - 1; i >= 0; i-- ) {
31180
31181
31182
31183			//Cache variables and intersection, continue if no intersection
31184
31185			item = this.items[ i ];
31186
31187			itemElement = item.item[ 0 ];
31188
31189			intersection = this._intersectsWithPointer( item );
31190
31191			if ( !intersection ) {
31192
31193				continue;
31194
31195			}
31196
31197
31198
31199			// Only put the placeholder inside the current Container, skip all
31200
31201			// items from other containers. This works because when moving
31202
31203			// an item from one container to another the
31204
31205			// currentContainer is switched before the placeholder is moved.
31206
31207			//
31208
31209			// Without this, moving items in "sub-sortables" can cause
31210
31211			// the placeholder to jitter between the outer and inner container.
31212
31213			if ( item.instance !== this.currentContainer ) {
31214
31215				continue;
31216
31217			}
31218
31219
31220
31221			// Cannot intersect with itself
31222
31223			// no useless actions that have been done before
31224
31225			// no action if the item moved is the parent of the item checked
31226
31227			if ( itemElement !== this.currentItem[ 0 ] &&
31228
31229				this.placeholder[ intersection === 1 ? "next" : "prev" ]()[ 0 ] !== itemElement &&
31230
31231				!$.contains( this.placeholder[ 0 ], itemElement ) &&
31232
31233				( this.options.type === "semi-dynamic" ?
31234
31235					!$.contains( this.element[ 0 ], itemElement ) :
31236
31237					true
31238
31239				)
31240
31241			) {
31242
31243
31244
31245				this.direction = intersection === 1 ? "down" : "up";
31246
31247
31248
31249				if ( this.options.tolerance === "pointer" || this._intersectsWithSides( item ) ) {
31250
31251					this._rearrange( event, item );
31252
31253				} else {
31254
31255					break;
31256
31257				}
31258
31259
31260
31261				this._trigger( "change", event, this._uiHash() );
31262
31263				break;
31264
31265			}
31266
31267		}
31268
31269
31270
31271		//Post events to containers
31272
31273		this._contactContainers( event );
31274
31275
31276
31277		//Interconnect with droppables
31278
31279		if ( $.ui.ddmanager ) {
31280
31281			$.ui.ddmanager.drag( this, event );
31282
31283		}
31284
31285
31286
31287		//Call callbacks
31288
31289		this._trigger( "sort", event, this._uiHash() );
31290
31291
31292
31293		this.lastPositionAbs = this.positionAbs;
31294
31295		return false;
31296
31297
31298
31299	},
31300
31301
31302
31303	_mouseStop: function( event, noPropagation ) {
31304
31305
31306
31307		if ( !event ) {
31308
31309			return;
31310
31311		}
31312
31313
31314
31315		//If we are using droppables, inform the manager about the drop
31316
31317		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
31318
31319			$.ui.ddmanager.drop( this, event );
31320
31321		}
31322
31323
31324
31325		if ( this.options.revert ) {
31326
31327			var that = this,
31328
31329				cur = this.placeholder.offset(),
31330
31331				axis = this.options.axis,
31332
31333				animation = {};
31334
31335
31336
31337			if ( !axis || axis === "x" ) {
31338
31339				animation.left = cur.left - this.offset.parent.left - this.margins.left +
31340
31341					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
31342
31343						0 :
31344
31345						this.offsetParent[ 0 ].scrollLeft
31346
31347					);
31348
31349			}
31350
31351			if ( !axis || axis === "y" ) {
31352
31353				animation.top = cur.top - this.offset.parent.top - this.margins.top +
31354
31355					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
31356
31357						0 :
31358
31359						this.offsetParent[ 0 ].scrollTop
31360
31361					);
31362
31363			}
31364
31365			this.reverting = true;
31366
31367			$( this.helper ).animate(
31368
31369				animation,
31370
31371				parseInt( this.options.revert, 10 ) || 500,
31372
31373				function() {
31374
31375					that._clear( event );
31376
31377				}
31378
31379			);
31380
31381		} else {
31382
31383			this._clear( event, noPropagation );
31384
31385		}
31386
31387
31388
31389		return false;
31390
31391
31392
31393	},
31394
31395
31396
31397	cancel: function() {
31398
31399
31400
31401		if ( this.dragging ) {
31402
31403
31404
31405			this._mouseUp( new $.Event( "mouseup", { target: null } ) );
31406
31407
31408
31409			if ( this.options.helper === "original" ) {
31410
31411				this.currentItem.css( this._storedCSS );
31412
31413				this._removeClass( this.currentItem, "ui-sortable-helper" );
31414
31415			} else {
31416
31417				this.currentItem.show();
31418
31419			}
31420
31421
31422
31423			//Post deactivating events to containers
31424
31425			for ( var i = this.containers.length - 1; i >= 0; i-- ) {
31426
31427				this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) );
31428
31429				if ( this.containers[ i ].containerCache.over ) {
31430
31431					this.containers[ i ]._trigger( "out", null, this._uiHash( this ) );
31432
31433					this.containers[ i ].containerCache.over = 0;
31434
31435				}
31436
31437			}
31438
31439
31440
31441		}
31442
31443
31444
31445		if ( this.placeholder ) {
31446
31447
31448
31449			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
31450
31451			// it unbinds ALL events from the original node!
31452
31453			if ( this.placeholder[ 0 ].parentNode ) {
31454
31455				this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
31456
31457			}
31458
31459			if ( this.options.helper !== "original" && this.helper &&
31460
31461					this.helper[ 0 ].parentNode ) {
31462
31463				this.helper.remove();
31464
31465			}
31466
31467
31468
31469			$.extend( this, {
31470
31471				helper: null,
31472
31473				dragging: false,
31474
31475				reverting: false,
31476
31477				_noFinalSort: null
31478
31479			} );
31480
31481
31482
31483			if ( this.domPosition.prev ) {
31484
31485				$( this.domPosition.prev ).after( this.currentItem );
31486
31487			} else {
31488
31489				$( this.domPosition.parent ).prepend( this.currentItem );
31490
31491			}
31492
31493		}
31494
31495
31496
31497		return this;
31498
31499
31500
31501	},
31502
31503
31504
31505	serialize: function( o ) {
31506
31507
31508
31509		var items = this._getItemsAsjQuery( o && o.connected ),
31510
31511			str = [];
31512
31513		o = o || {};
31514
31515
31516
31517		$( items ).each( function() {
31518
31519			var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" )
31520
31521				.match( o.expression || ( /(.+)[\-=_](.+)/ ) );
31522
31523			if ( res ) {
31524
31525				str.push(
31526
31527					( o.key || res[ 1 ] + "[]" ) +
31528
31529					"=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );
31530
31531			}
31532
31533		} );
31534
31535
31536
31537		if ( !str.length && o.key ) {
31538
31539			str.push( o.key + "=" );
31540
31541		}
31542
31543
31544
31545		return str.join( "&" );
31546
31547
31548
31549	},
31550
31551
31552
31553	toArray: function( o ) {
31554
31555
31556
31557		var items = this._getItemsAsjQuery( o && o.connected ),
31558
31559			ret = [];
31560
31561
31562
31563		o = o || {};
31564
31565
31566
31567		items.each( function() {
31568
31569			ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" );
31570
31571		} );
31572
31573		return ret;
31574
31575
31576
31577	},
31578
31579
31580
31581	/* Be careful with the following core functions */
31582
31583	_intersectsWith: function( item ) {
31584
31585
31586
31587		var x1 = this.positionAbs.left,
31588
31589			x2 = x1 + this.helperProportions.width,
31590
31591			y1 = this.positionAbs.top,
31592
31593			y2 = y1 + this.helperProportions.height,
31594
31595			l = item.left,
31596
31597			r = l + item.width,
31598
31599			t = item.top,
31600
31601			b = t + item.height,
31602
31603			dyClick = this.offset.click.top,
31604
31605			dxClick = this.offset.click.left,
31606
31607			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t &&
31608
31609				( y1 + dyClick ) < b ),
31610
31611			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l &&
31612
31613				( x1 + dxClick ) < r ),
31614
31615			isOverElement = isOverElementHeight && isOverElementWidth;
31616
31617
31618
31619		if ( this.options.tolerance === "pointer" ||
31620
31621			this.options.forcePointerForContainers ||
31622
31623			( this.options.tolerance !== "pointer" &&
31624
31625				this.helperProportions[ this.floating ? "width" : "height" ] >
31626
31627				item[ this.floating ? "width" : "height" ] )
31628
31629		) {
31630
31631			return isOverElement;
31632
31633		} else {
31634
31635
31636
31637			return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half
31638
31639				x2 - ( this.helperProportions.width / 2 ) < r && // Left Half
31640
31641				t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half
31642
31643				y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half
31644
31645
31646
31647		}
31648
31649	},
31650
31651
31652
31653	_intersectsWithPointer: function( item ) {
31654
31655		var verticalDirection, horizontalDirection,
31656
31657			isOverElementHeight = ( this.options.axis === "x" ) ||
31658
31659				this._isOverAxis(
31660
31661					this.positionAbs.top + this.offset.click.top, item.top, item.height ),
31662
31663			isOverElementWidth = ( this.options.axis === "y" ) ||
31664
31665				this._isOverAxis(
31666
31667					this.positionAbs.left + this.offset.click.left, item.left, item.width ),
31668
31669			isOverElement = isOverElementHeight && isOverElementWidth;
31670
31671
31672
31673		if ( !isOverElement ) {
31674
31675			return false;
31676
31677		}
31678
31679
31680
31681		verticalDirection = this._getDragVerticalDirection();
31682
31683		horizontalDirection = this._getDragHorizontalDirection();
31684
31685
31686
31687		return this.floating ?
31688
31689			( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 )
31690
31691			: ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) );
31692
31693
31694
31695	},
31696
31697
31698
31699	_intersectsWithSides: function( item ) {
31700
31701
31702
31703		var isOverBottomHalf = this._isOverAxis( this.positionAbs.top +
31704
31705				this.offset.click.top, item.top + ( item.height / 2 ), item.height ),
31706
31707			isOverRightHalf = this._isOverAxis( this.positionAbs.left +
31708
31709				this.offset.click.left, item.left + ( item.width / 2 ), item.width ),
31710
31711			verticalDirection = this._getDragVerticalDirection(),
31712
31713			horizontalDirection = this._getDragHorizontalDirection();
31714
31715
31716
31717		if ( this.floating && horizontalDirection ) {
31718
31719			return ( ( horizontalDirection === "right" && isOverRightHalf ) ||
31720
31721				( horizontalDirection === "left" && !isOverRightHalf ) );
31722
31723		} else {
31724
31725			return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) ||
31726
31727				( verticalDirection === "up" && !isOverBottomHalf ) );
31728
31729		}
31730
31731
31732
31733	},
31734
31735
31736
31737	_getDragVerticalDirection: function() {
31738
31739		var delta = this.positionAbs.top - this.lastPositionAbs.top;
31740
31741		return delta !== 0 && ( delta > 0 ? "down" : "up" );
31742
31743	},
31744
31745
31746
31747	_getDragHorizontalDirection: function() {
31748
31749		var delta = this.positionAbs.left - this.lastPositionAbs.left;
31750
31751		return delta !== 0 && ( delta > 0 ? "right" : "left" );
31752
31753	},
31754
31755
31756
31757	refresh: function( event ) {
31758
31759		this._refreshItems( event );
31760
31761		this._setHandleClassName();
31762
31763		this.refreshPositions();
31764
31765		return this;
31766
31767	},
31768
31769
31770
31771	_connectWith: function() {
31772
31773		var options = this.options;
31774
31775		return options.connectWith.constructor === String ?
31776
31777			[ options.connectWith ] :
31778
31779			options.connectWith;
31780
31781	},
31782
31783
31784
31785	_getItemsAsjQuery: function( connected ) {
31786
31787
31788
31789		var i, j, cur, inst,
31790
31791			items = [],
31792
31793			queries = [],
31794
31795			connectWith = this._connectWith();
31796
31797
31798
31799		if ( connectWith && connected ) {
31800
31801			for ( i = connectWith.length - 1; i >= 0; i-- ) {
31802
31803				cur = $( connectWith[ i ], this.document[ 0 ] );
31804
31805				for ( j = cur.length - 1; j >= 0; j-- ) {
31806
31807					inst = $.data( cur[ j ], this.widgetFullName );
31808
31809					if ( inst && inst !== this && !inst.options.disabled ) {
31810
31811						queries.push( [ $.isFunction( inst.options.items ) ?
31812
31813							inst.options.items.call( inst.element ) :
31814
31815							$( inst.options.items, inst.element )
31816
31817								.not( ".ui-sortable-helper" )
31818
31819								.not( ".ui-sortable-placeholder" ), inst ] );
31820
31821					}
31822
31823				}
31824
31825			}
31826
31827		}
31828
31829
31830
31831		queries.push( [ $.isFunction( this.options.items ) ?
31832
31833			this.options.items
31834
31835				.call( this.element, null, { options: this.options, item: this.currentItem } ) :
31836
31837			$( this.options.items, this.element )
31838
31839				.not( ".ui-sortable-helper" )
31840
31841				.not( ".ui-sortable-placeholder" ), this ] );
31842
31843
31844
31845		function addItems() {
31846
31847			items.push( this );
31848
31849		}
31850
31851		for ( i = queries.length - 1; i >= 0; i-- ) {
31852
31853			queries[ i ][ 0 ].each( addItems );
31854
31855		}
31856
31857
31858
31859		return $( items );
31860
31861
31862
31863	},
31864
31865
31866
31867	_removeCurrentsFromItems: function() {
31868
31869
31870
31871		var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" );
31872
31873
31874
31875		this.items = $.grep( this.items, function( item ) {
31876
31877			for ( var j = 0; j < list.length; j++ ) {
31878
31879				if ( list[ j ] === item.item[ 0 ] ) {
31880
31881					return false;
31882
31883				}
31884
31885			}
31886
31887			return true;
31888
31889		} );
31890
31891
31892
31893	},
31894
31895
31896
31897	_refreshItems: function( event ) {
31898
31899
31900
31901		this.items = [];
31902
31903		this.containers = [ this ];
31904
31905
31906
31907		var i, j, cur, inst, targetData, _queries, item, queriesLength,
31908
31909			items = this.items,
31910
31911			queries = [ [ $.isFunction( this.options.items ) ?
31912
31913				this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :
31914
31915				$( this.options.items, this.element ), this ] ],
31916
31917			connectWith = this._connectWith();
31918
31919
31920
31921		//Shouldn't be run the first time through due to massive slow-down
31922
31923		if ( connectWith && this.ready ) {
31924
31925			for ( i = connectWith.length - 1; i >= 0; i-- ) {
31926
31927				cur = $( connectWith[ i ], this.document[ 0 ] );
31928
31929				for ( j = cur.length - 1; j >= 0; j-- ) {
31930
31931					inst = $.data( cur[ j ], this.widgetFullName );
31932
31933					if ( inst && inst !== this && !inst.options.disabled ) {
31934
31935						queries.push( [ $.isFunction( inst.options.items ) ?
31936
31937							inst.options.items
31938
31939								.call( inst.element[ 0 ], event, { item: this.currentItem } ) :
31940
31941							$( inst.options.items, inst.element ), inst ] );
31942
31943						this.containers.push( inst );
31944
31945					}
31946
31947				}
31948
31949			}
31950
31951		}
31952
31953
31954
31955		for ( i = queries.length - 1; i >= 0; i-- ) {
31956
31957			targetData = queries[ i ][ 1 ];
31958
31959			_queries = queries[ i ][ 0 ];
31960
31961
31962
31963			for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {
31964
31965				item = $( _queries[ j ] );
31966
31967
31968
31969				// Data for target checking (mouse manager)
31970
31971				item.data( this.widgetName + "-item", targetData );
31972
31973
31974
31975				items.push( {
31976
31977					item: item,
31978
31979					instance: targetData,
31980
31981					width: 0, height: 0,
31982
31983					left: 0, top: 0
31984
31985				} );
31986
31987			}
31988
31989		}
31990
31991
31992
31993	},
31994
31995
31996
31997	refreshPositions: function( fast ) {
31998
31999
32000
32001		// Determine whether items are being displayed horizontally
32002
32003		this.floating = this.items.length ?
32004
32005			this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
32006
32007			false;
32008
32009
32010
32011		//This has to be redone because due to the item being moved out/into the offsetParent,
32012
32013		// the offsetParent's position will change
32014
32015		if ( this.offsetParent && this.helper ) {
32016
32017			this.offset.parent = this._getParentOffset();
32018
32019		}
32020
32021
32022
32023		var i, item, t, p;
32024
32025
32026
32027		for ( i = this.items.length - 1; i >= 0; i-- ) {
32028
32029			item = this.items[ i ];
32030
32031
32032
32033			//We ignore calculating positions of all connected containers when we're not over them
32034
32035			if ( item.instance !== this.currentContainer && this.currentContainer &&
32036
32037					item.item[ 0 ] !== this.currentItem[ 0 ] ) {
32038
32039				continue;
32040
32041			}
32042
32043
32044
32045			t = this.options.toleranceElement ?
32046
32047				$( this.options.toleranceElement, item.item ) :
32048
32049				item.item;
32050
32051
32052
32053			if ( !fast ) {
32054
32055				item.width = t.outerWidth();
32056
32057				item.height = t.outerHeight();
32058
32059			}
32060
32061
32062
32063			p = t.offset();
32064
32065			item.left = p.left;
32066
32067			item.top = p.top;
32068
32069		}
32070
32071
32072
32073		if ( this.options.custom && this.options.custom.refreshContainers ) {
32074
32075			this.options.custom.refreshContainers.call( this );
32076
32077		} else {
32078
32079			for ( i = this.containers.length - 1; i >= 0; i-- ) {
32080
32081				p = this.containers[ i ].element.offset();
32082
32083				this.containers[ i ].containerCache.left = p.left;
32084
32085				this.containers[ i ].containerCache.top = p.top;
32086
32087				this.containers[ i ].containerCache.width =
32088
32089					this.containers[ i ].element.outerWidth();
32090
32091				this.containers[ i ].containerCache.height =
32092
32093					this.containers[ i ].element.outerHeight();
32094
32095			}
32096
32097		}
32098
32099
32100
32101		return this;
32102
32103	},
32104
32105
32106
32107	_createPlaceholder: function( that ) {
32108
32109		that = that || this;
32110
32111		var className,
32112
32113			o = that.options;
32114
32115
32116
32117		if ( !o.placeholder || o.placeholder.constructor === String ) {
32118
32119			className = o.placeholder;
32120
32121			o.placeholder = {
32122
32123				element: function() {
32124
32125
32126
32127					var nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(),
32128
32129						element = $( "<" + nodeName + ">", that.document[ 0 ] );
32130
32131
32132
32133						that._addClass( element, "ui-sortable-placeholder",
32134
32135								className || that.currentItem[ 0 ].className )
32136
32137							._removeClass( element, "ui-sortable-helper" );
32138
32139
32140
32141					if ( nodeName === "tbody" ) {
32142
32143						that._createTrPlaceholder(
32144
32145							that.currentItem.find( "tr" ).eq( 0 ),
32146
32147							$( "<tr>", that.document[ 0 ] ).appendTo( element )
32148
32149						);
32150
32151					} else if ( nodeName === "tr" ) {
32152
32153						that._createTrPlaceholder( that.currentItem, element );
32154
32155					} else if ( nodeName === "img" ) {
32156
32157						element.attr( "src", that.currentItem.attr( "src" ) );
32158
32159					}
32160
32161
32162
32163					if ( !className ) {
32164
32165						element.css( "visibility", "hidden" );
32166
32167					}
32168
32169
32170
32171					return element;
32172
32173				},
32174
32175				update: function( container, p ) {
32176
32177
32178
32179					// 1. If a className is set as 'placeholder option, we don't force sizes -
32180
32181					// the class is responsible for that
32182
32183					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a
32184
32185					// class name is specified
32186
32187					if ( className && !o.forcePlaceholderSize ) {
32188
32189						return;
32190
32191					}
32192
32193
32194
32195					//If the element doesn't have a actual height by itself (without styles coming
32196
32197					// from a stylesheet), it receives the inline height from the dragged item
32198
32199					if ( !p.height() ) {
32200
32201						p.height(
32202
32203							that.currentItem.innerHeight() -
32204
32205							parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) -
32206
32207							parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) );
32208
32209					}
32210
32211					if ( !p.width() ) {
32212
32213						p.width(
32214
32215							that.currentItem.innerWidth() -
32216
32217							parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) -
32218
32219							parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) );
32220
32221					}
32222
32223				}
32224
32225			};
32226
32227		}
32228
32229
32230
32231		//Create the placeholder
32232
32233		that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );
32234
32235
32236
32237		//Append it after the actual current item
32238
32239		that.currentItem.after( that.placeholder );
32240
32241
32242
32243		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
32244
32245		o.placeholder.update( that, that.placeholder );
32246
32247
32248
32249	},
32250
32251
32252
32253	_createTrPlaceholder: function( sourceTr, targetTr ) {
32254
32255		var that = this;
32256
32257
32258
32259		sourceTr.children().each( function() {
32260
32261			$( "<td>&#160;</td>", that.document[ 0 ] )
32262
32263				.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
32264
32265				.appendTo( targetTr );
32266
32267		} );
32268
32269	},
32270
32271
32272
32273	_contactContainers: function( event ) {
32274
32275		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
32276
32277			floating, axis,
32278
32279			innermostContainer = null,
32280
32281			innermostIndex = null;
32282
32283
32284
32285		// Get innermost container that intersects with item
32286
32287		for ( i = this.containers.length - 1; i >= 0; i-- ) {
32288
32289
32290
32291			// Never consider a container that's located within the item itself
32292
32293			if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {
32294
32295				continue;
32296
32297			}
32298
32299
32300
32301			if ( this._intersectsWith( this.containers[ i ].containerCache ) ) {
32302
32303
32304
32305				// If we've already found a container and it's more "inner" than this, then continue
32306
32307				if ( innermostContainer &&
32308
32309						$.contains(
32310
32311							this.containers[ i ].element[ 0 ],
32312
32313							innermostContainer.element[ 0 ] ) ) {
32314
32315					continue;
32316
32317				}
32318
32319
32320
32321				innermostContainer = this.containers[ i ];
32322
32323				innermostIndex = i;
32324
32325
32326
32327			} else {
32328
32329
32330
32331				// container doesn't intersect. trigger "out" event if necessary
32332
32333				if ( this.containers[ i ].containerCache.over ) {
32334
32335					this.containers[ i ]._trigger( "out", event, this._uiHash( this ) );
32336
32337					this.containers[ i ].containerCache.over = 0;
32338
32339				}
32340
32341			}
32342
32343
32344
32345		}
32346
32347
32348
32349		// If no intersecting containers found, return
32350
32351		if ( !innermostContainer ) {
32352
32353			return;
32354
32355		}
32356
32357
32358
32359		// Move the item into the container if it's not there already
32360
32361		if ( this.containers.length === 1 ) {
32362
32363			if ( !this.containers[ innermostIndex ].containerCache.over ) {
32364
32365				this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
32366
32367				this.containers[ innermostIndex ].containerCache.over = 1;
32368
32369			}
32370
32371		} else {
32372
32373
32374
32375			// When entering a new container, we will find the item with the least distance and
32376
32377			// append our item near it
32378
32379			dist = 10000;
32380
32381			itemWithLeastDistance = null;
32382
32383			floating = innermostContainer.floating || this._isFloating( this.currentItem );
32384
32385			posProperty = floating ? "left" : "top";
32386
32387			sizeProperty = floating ? "width" : "height";
32388
32389			axis = floating ? "pageX" : "pageY";
32390
32391
32392
32393			for ( j = this.items.length - 1; j >= 0; j-- ) {
32394
32395				if ( !$.contains(
32396
32397						this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )
32398
32399				) {
32400
32401					continue;
32402
32403				}
32404
32405				if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {
32406
32407					continue;
32408
32409				}
32410
32411
32412
32413				cur = this.items[ j ].item.offset()[ posProperty ];
32414
32415				nearBottom = false;
32416
32417				if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
32418
32419					nearBottom = true;
32420
32421				}
32422
32423
32424
32425				if ( Math.abs( event[ axis ] - cur ) < dist ) {
32426
32427					dist = Math.abs( event[ axis ] - cur );
32428
32429					itemWithLeastDistance = this.items[ j ];
32430
32431					this.direction = nearBottom ? "up" : "down";
32432
32433				}
32434
32435			}
32436
32437
32438
32439			//Check if dropOnEmpty is enabled
32440
32441			if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {
32442
32443				return;
32444
32445			}
32446
32447
32448
32449			if ( this.currentContainer === this.containers[ innermostIndex ] ) {
32450
32451				if ( !this.currentContainer.containerCache.over ) {
32452
32453					this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
32454
32455					this.currentContainer.containerCache.over = 1;
32456
32457				}
32458
32459				return;
32460
32461			}
32462
32463
32464
32465			itemWithLeastDistance ?
32466
32467				this._rearrange( event, itemWithLeastDistance, null, true ) :
32468
32469				this._rearrange( event, null, this.containers[ innermostIndex ].element, true );
32470
32471			this._trigger( "change", event, this._uiHash() );
32472
32473			this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) );
32474
32475			this.currentContainer = this.containers[ innermostIndex ];
32476
32477
32478
32479			//Update the placeholder
32480
32481			this.options.placeholder.update( this.currentContainer, this.placeholder );
32482
32483
32484
32485			this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
32486
32487			this.containers[ innermostIndex ].containerCache.over = 1;
32488
32489		}
32490
32491
32492
32493	},
32494
32495
32496
32497	_createHelper: function( event ) {
32498
32499
32500
32501		var o = this.options,
32502
32503			helper = $.isFunction( o.helper ) ?
32504
32505				$( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :
32506
32507				( o.helper === "clone" ? this.currentItem.clone() : this.currentItem );
32508
32509
32510
32511		//Add the helper to the DOM if that didn't happen already
32512
32513		if ( !helper.parents( "body" ).length ) {
32514
32515			$( o.appendTo !== "parent" ?
32516
32517				o.appendTo :
32518
32519				this.currentItem[ 0 ].parentNode )[ 0 ].appendChild( helper[ 0 ] );
32520
32521		}
32522
32523
32524
32525		if ( helper[ 0 ] === this.currentItem[ 0 ] ) {
32526
32527			this._storedCSS = {
32528
32529				width: this.currentItem[ 0 ].style.width,
32530
32531				height: this.currentItem[ 0 ].style.height,
32532
32533				position: this.currentItem.css( "position" ),
32534
32535				top: this.currentItem.css( "top" ),
32536
32537				left: this.currentItem.css( "left" )
32538
32539			};
32540
32541		}
32542
32543
32544
32545		if ( !helper[ 0 ].style.width || o.forceHelperSize ) {
32546
32547			helper.width( this.currentItem.width() );
32548
32549		}
32550
32551		if ( !helper[ 0 ].style.height || o.forceHelperSize ) {
32552
32553			helper.height( this.currentItem.height() );
32554
32555		}
32556
32557
32558
32559		return helper;
32560
32561
32562
32563	},
32564
32565
32566
32567	_adjustOffsetFromHelper: function( obj ) {
32568
32569		if ( typeof obj === "string" ) {
32570
32571			obj = obj.split( " " );
32572
32573		}
32574
32575		if ( $.isArray( obj ) ) {
32576
32577			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
32578
32579		}
32580
32581		if ( "left" in obj ) {
32582
32583			this.offset.click.left = obj.left + this.margins.left;
32584
32585		}
32586
32587		if ( "right" in obj ) {
32588
32589			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
32590
32591		}
32592
32593		if ( "top" in obj ) {
32594
32595			this.offset.click.top = obj.top + this.margins.top;
32596
32597		}
32598
32599		if ( "bottom" in obj ) {
32600
32601			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
32602
32603		}
32604
32605	},
32606
32607
32608
32609	_getParentOffset: function() {
32610
32611
32612
32613		//Get the offsetParent and cache its position
32614
32615		this.offsetParent = this.helper.offsetParent();
32616
32617		var po = this.offsetParent.offset();
32618
32619
32620
32621		// This is a special case where we need to modify a offset calculated on start, since the
32622
32623		// following happened:
32624
32625		// 1. The position of the helper is absolute, so it's position is calculated based on the
32626
32627		// next positioned parent
32628
32629		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
32630
32631		// the document, which means that the scroll is included in the initial calculation of the
32632
32633		// offset of the parent, and never recalculated upon drag
32634
32635		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&
32636
32637				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
32638
32639			po.left += this.scrollParent.scrollLeft();
32640
32641			po.top += this.scrollParent.scrollTop();
32642
32643		}
32644
32645
32646
32647		// This needs to be actually done for all browsers, since pageX/pageY includes this
32648
32649		// information with an ugly IE fix
32650
32651		if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ||
32652
32653				( this.offsetParent[ 0 ].tagName &&
32654
32655				this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) {
32656
32657			po = { top: 0, left: 0 };
32658
32659		}
32660
32661
32662
32663		return {
32664
32665			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
32666
32667			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
32668
32669		};
32670
32671
32672
32673	},
32674
32675
32676
32677	_getRelativeOffset: function() {
32678
32679
32680
32681		if ( this.cssPosition === "relative" ) {
32682
32683			var p = this.currentItem.position();
32684
32685			return {
32686
32687				top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
32688
32689					this.scrollParent.scrollTop(),
32690
32691				left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
32692
32693					this.scrollParent.scrollLeft()
32694
32695			};
32696
32697		} else {
32698
32699			return { top: 0, left: 0 };
32700
32701		}
32702
32703
32704
32705	},
32706
32707
32708
32709	_cacheMargins: function() {
32710
32711		this.margins = {
32712
32713			left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ),
32714
32715			top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 )
32716
32717		};
32718
32719	},
32720
32721
32722
32723	_cacheHelperProportions: function() {
32724
32725		this.helperProportions = {
32726
32727			width: this.helper.outerWidth(),
32728
32729			height: this.helper.outerHeight()
32730
32731		};
32732
32733	},
32734
32735
32736
32737	_setContainment: function() {
32738
32739
32740
32741		var ce, co, over,
32742
32743			o = this.options;
32744
32745		if ( o.containment === "parent" ) {
32746
32747			o.containment = this.helper[ 0 ].parentNode;
32748
32749		}
32750
32751		if ( o.containment === "document" || o.containment === "window" ) {
32752
32753			this.containment = [
32754
32755				0 - this.offset.relative.left - this.offset.parent.left,
32756
32757				0 - this.offset.relative.top - this.offset.parent.top,
32758
32759				o.containment === "document" ?
32760
32761					this.document.width() :
32762
32763					this.window.width() - this.helperProportions.width - this.margins.left,
32764
32765				( o.containment === "document" ?
32766
32767					( this.document.height() || document.body.parentNode.scrollHeight ) :
32768
32769					this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight
32770
32771				) - this.helperProportions.height - this.margins.top
32772
32773			];
32774
32775		}
32776
32777
32778
32779		if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {
32780
32781			ce = $( o.containment )[ 0 ];
32782
32783			co = $( o.containment ).offset();
32784
32785			over = ( $( ce ).css( "overflow" ) !== "hidden" );
32786
32787
32788
32789			this.containment = [
32790
32791				co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) +
32792
32793					( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left,
32794
32795				co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) +
32796
32797					( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top,
32798
32799				co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) 
vendor: 1,906 bytes, lines 32799-32904
32799: ce.offsetWidth ) -
32800
32801					( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) -
32802
32803					( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) -
32804
32805					this.helperProportions.width - this.margins.left,
32806
32807				co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
32808
32809					( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) -
32810
32811					( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) -
32812
32813					this.helperProportions.height - this.margins.top
32814
32815			];
32816
32817		}
32818
32819
32820
32821	},
32822
32823
32824
32825	_convertPositionTo: function( d, pos ) {
32826
32827
32828
32829		if ( !pos ) {
32830
32831			pos = this.position;
32832
32833		}
32834
32835		var mod = d === "absolute" ? 1 : -1,
32836
32837			scroll = this.cssPosition === "absolute" &&
32838
32839				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
32840
32841				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
32842
32843					this.offsetParent :
32844
32845					this.scrollParent,
32846
32847			scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
32848
32849
32850
32851		return {
32852
32853			top: (
32854
32855
32856
32857				// The absolute mouse position
32858
32859				pos.top	+
32860
32861
32862
32863				// Only for relative positioned nodes: Relative offset from element to offset parent
32864
32865				this.offset.relative.top * mod +
32866
32867
32868
32869				// The offsetParent's offset without borders (offset + border)
32870
32871				this.offset.parent.top * mod -
32872
32873				( ( this.cssPosition === "fixed" ?
32874
32875					-this.scrollParent.scrollTop() :
32876
32877					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )
32878
32879			),
32880
32881			left: (
32882
32883
32884
32885				// The absolute mouse position
32886
32887				pos.left +
32888
32889
32890
32891				// Only for relative positioned nodes: Relative offset from element to offset parent
32892
32893				this.offset.relative.left * mod +
32894
32895
32896
32897				// The offsetParent's offset without borders (offset + border)
32898
32899				this.offset.parent.left * mod	-
32900
32901				( ( this.cssPosition === "fixed" ?
32902
32903					-this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
32904
vendor: 9,720 bytes, lines 32905-33474
32905					scroll.scrollLeft() ) * mod )
32906
32907			)
32908
32909		};
32910
32911
32912
32913	},
32914
32915
32916
32917	_generatePosition: function( event ) {
32918
32919
32920
32921		var top, left,
32922
32923			o = this.options,
32924
32925			pageX = event.pageX,
32926
32927			pageY = event.pageY,
32928
32929			scroll = this.cssPosition === "absolute" &&
32930
32931				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
32932
32933				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
32934
32935					this.offsetParent :
32936
32937					this.scrollParent,
32938
32939				scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
32940
32941
32942
32943		// This is another very weird special case that only happens for relative elements:
32944
32945		// 1. If the css position is relative
32946
32947		// 2. and the scroll parent is the document or similar to the offset parent
32948
32949		// we have to refresh the relative offset during the scroll so there are no jumps
32950
32951		if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
32952
32953				this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {
32954
32955			this.offset.relative = this._getRelativeOffset();
32956
32957		}
32958
32959
32960
32961		/*
32962
32963		 * - Position constraining -
32964
32965		 * Constrain the position to a mix of grid, containment.
32966
32967		 */
32968
32969
32970
32971		if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options
32972
32973
32974
32975			if ( this.containment ) {
32976
32977				if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {
32978
32979					pageX = this.containment[ 0 ] + this.offset.click.left;
32980
32981				}
32982
32983				if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {
32984
32985					pageY = this.containment[ 1 ] + this.offset.click.top;
32986
32987				}
32988
32989				if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {
32990
32991					pageX = this.containment[ 2 ] + this.offset.click.left;
32992
32993				}
32994
32995				if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {
32996
32997					pageY = this.containment[ 3 ] + this.offset.click.top;
32998
32999				}
33000
33001			}
33002
33003
33004
33005			if ( o.grid ) {
33006
33007				top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /
33008
33009					o.grid[ 1 ] ) * o.grid[ 1 ];
33010
33011				pageY = this.containment ?
33012
33013					( ( top - this.offset.click.top >= this.containment[ 1 ] &&
33014
33015						top - this.offset.click.top <= this.containment[ 3 ] ) ?
33016
33017							top :
33018
33019							( ( top - this.offset.click.top >= this.containment[ 1 ] ) ?
33020
33021								top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) :
33022
33023								top;
33024
33025
33026
33027				left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /
33028
33029					o.grid[ 0 ] ) * o.grid[ 0 ];
33030
33031				pageX = this.containment ?
33032
33033					( ( left - this.offset.click.left >= this.containment[ 0 ] &&
33034
33035						left - this.offset.click.left <= this.containment[ 2 ] ) ?
33036
33037							left :
33038
33039							( ( left - this.offset.click.left >= this.containment[ 0 ] ) ?
33040
33041								left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) :
33042
33043								left;
33044
33045			}
33046
33047
33048
33049		}
33050
33051
33052
33053		return {
33054
33055			top: (
33056
33057
33058
33059				// The absolute mouse position
33060
33061				pageY -
33062
33063
33064
33065				// Click offset (relative to the element)
33066
33067				this.offset.click.top -
33068
33069
33070
33071				// Only for relative positioned nodes: Relative offset from element to offset parent
33072
33073				this.offset.relative.top -
33074
33075
33076
33077				// The offsetParent's offset without borders (offset + border)
33078
33079				this.offset.parent.top +
33080
33081				( ( this.cssPosition === "fixed" ?
33082
33083					-this.scrollParent.scrollTop() :
33084
33085					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )
33086
33087			),
33088
33089			left: (
33090
33091
33092
33093				// The absolute mouse position
33094
33095				pageX -
33096
33097
33098
33099				// Click offset (relative to the element)
33100
33101				this.offset.click.left -
33102
33103
33104
33105				// Only for relative positioned nodes: Relative offset from element to offset parent
33106
33107				this.offset.relative.left -
33108
33109
33110
33111				// The offsetParent's offset without borders (offset + border)
33112
33113				this.offset.parent.left +
33114
33115				( ( this.cssPosition === "fixed" ?
33116
33117					-this.scrollParent.scrollLeft() :
33118
33119					scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
33120
33121			)
33122
33123		};
33124
33125
33126
33127	},
33128
33129
33130
33131	_rearrange: function( event, i, a, hardRefresh ) {
33132
33133
33134
33135		a ? a[ 0 ].appendChild( this.placeholder[ 0 ] ) :
33136
33137			i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ],
33138
33139				( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) );
33140
33141
33142
33143		//Various things done here to improve the performance:
33144
33145		// 1. we create a setTimeout, that calls refreshPositions
33146
33147		// 2. on the instance, we have a counter variable, that get's higher after every append
33148
33149		// 3. on the local scope, we copy the counter variable, and check in the timeout,
33150
33151		// if it's still the same
33152
33153		// 4. this lets only the last addition to the timeout stack through
33154
33155		this.counter = this.counter ? ++this.counter : 1;
33156
33157		var counter = this.counter;
33158
33159
33160
33161		this._delay( function() {
33162
33163			if ( counter === this.counter ) {
33164
33165
33166
33167				//Precompute after each DOM insertion, NOT on mousemove
33168
33169				this.refreshPositions( !hardRefresh );
33170
33171			}
33172
33173		} );
33174
33175
33176
33177	},
33178
33179
33180
33181	_clear: function( event, noPropagation ) {
33182
33183
33184
33185		this.reverting = false;
33186
33187
33188
33189		// We delay all events that have to be triggered to after the point where the placeholder
33190
33191		// has been removed and everything else normalized again
33192
33193		var i,
33194
33195			delayedTriggers = [];
33196
33197
33198
33199		// We first have to update the dom position of the actual currentItem
33200
33201		// Note: don't do it if the current item is already removed (by a user), or it gets
33202
33203		// reappended (see #4088)
33204
33205		if ( !this._noFinalSort && this.currentItem.parent().length ) {
33206
33207			this.placeholder.before( this.currentItem );
33208
33209		}
33210
33211		this._noFinalSort = null;
33212
33213
33214
33215		if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {
33216
33217			for ( i in this._storedCSS ) {
33218
33219				if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) {
33220
33221					this._storedCSS[ i ] = "";
33222
33223				}
33224
33225			}
33226
33227			this.currentItem.css( this._storedCSS );
33228
33229			this._removeClass( this.currentItem, "ui-sortable-helper" );
33230
33231		} else {
33232
33233			this.currentItem.show();
33234
33235		}
33236
33237
33238
33239		if ( this.fromOutside && !noPropagation ) {
33240
33241			delayedTriggers.push( function( event ) {
33242
33243				this._trigger( "receive", event, this._uiHash( this.fromOutside ) );
33244
33245			} );
33246
33247		}
33248
33249		if ( ( this.fromOutside ||
33250
33251				this.domPosition.prev !==
33252
33253				this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] ||
33254
33255				this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {
33256
33257
33258
33259			// Trigger update callback if the DOM position has changed
33260
33261			delayedTriggers.push( function( event ) {
33262
33263				this._trigger( "update", event, this._uiHash() );
33264
33265			} );
33266
33267		}
33268
33269
33270
33271		// Check if the items Container has Changed and trigger appropriate
33272
33273		// events.
33274
33275		if ( this !== this.currentContainer ) {
33276
33277			if ( !noPropagation ) {
33278
33279				delayedTriggers.push( function( event ) {
33280
33281					this._trigger( "remove", event, this._uiHash() );
33282
33283				} );
33284
33285				delayedTriggers.push( ( function( c ) {
33286
33287					return function( event ) {
33288
33289						c._trigger( "receive", event, this._uiHash( this ) );
33290
33291					};
33292
33293				} ).call( this, this.currentContainer ) );
33294
33295				delayedTriggers.push( ( function( c ) {
33296
33297					return function( event ) {
33298
33299						c._trigger( "update", event, this._uiHash( this ) );
33300
33301					};
33302
33303				} ).call( this, this.currentContainer ) );
33304
33305			}
33306
33307		}
33308
33309
33310
33311		//Post events to containers
33312
33313		function delayEvent( type, instance, container ) {
33314
33315			return function( event ) {
33316
33317				container._trigger( type, event, instance._uiHash( instance ) );
33318
33319			};
33320
33321		}
33322
33323		for ( i = this.containers.length - 1; i >= 0; i-- ) {
33324
33325			if ( !noPropagation ) {
33326
33327				delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
33328
33329			}
33330
33331			if ( this.containers[ i ].containerCache.over ) {
33332
33333				delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
33334
33335				this.containers[ i ].containerCache.over = 0;
33336
33337			}
33338
33339		}
33340
33341
33342
33343		//Do what was originally in plugins
33344
33345		if ( this.storedCursor ) {
33346
33347			this.document.find( "body" ).css( "cursor", this.storedCursor );
33348
33349			this.storedStylesheet.remove();
33350
33351		}
33352
33353		if ( this._storedOpacity ) {
33354
33355			this.helper.css( "opacity", this._storedOpacity );
33356
33357		}
33358
33359		if ( this._storedZIndex ) {
33360
33361			this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex );
33362
33363		}
33364
33365
33366
33367		this.dragging = false;
33368
33369
33370
33371		if ( !noPropagation ) {
33372
33373			this._trigger( "beforeStop", event, this._uiHash() );
33374
33375		}
33376
33377
33378
33379		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
33380
33381		// it unbinds ALL events from the original node!
33382
33383		this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
33384
33385
33386
33387		if ( !this.cancelHelperRemoval ) {
33388
33389			if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
33390
33391				this.helper.remove();
33392
33393			}
33394
33395			this.helper = null;
33396
33397		}
33398
33399
33400
33401		if ( !noPropagation ) {
33402
33403			for ( i = 0; i < delayedTriggers.length; i++ ) {
33404
33405
33406
33407				// Trigger all delayed events
33408
33409				delayedTriggers[ i ].call( this, event );
33410
33411			}
33412
33413			this._trigger( "stop", event, this._uiHash() );
33414
33415		}
33416
33417
33418
33419		this.fromOutside = false;
33420
33421		return !this.cancelHelperRemoval;
33422
33423
33424
33425	},
33426
33427
33428
33429	_trigger: function() {
33430
33431		if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {
33432
33433			this.cancel();
33434
33435		}
33436
33437	},
33438
33439
33440
33441	_uiHash: function( _inst ) {
33442
33443		var inst = _inst || this;
33444
33445		return {
33446
33447			helper: inst.helper,
33448
33449			placeholder: inst.placeholder || $( [] ),
33450
33451			position: inst.position,
33452
33453			originalPosition: inst.originalPosition,
33454
33455			offset: inst.positionAbs,
33456
33457			item: inst.currentItem,
33458
33459			sender: _inst ? _inst.element : null
33460
33461		};
33462
33463	}
33464
33465
33466
33467} );
33468
33469
33470
33471
33472
33473/*!
33474
vendor: 4,853 bytes, lines 33475-33808
33475 * jQuery UI Spinner 1.12.1
33476
33477 * http://jqueryui.com
33478
33479 *
33480
33481 * Copyright jQuery Foundation and other contributors
33482
33483 * Released under the MIT license.
33484
33485 * http://jquery.org/license
33486
33487 */
33488
33489
33490
33491//>>label: Spinner
33492
33493//>>group: Widgets
33494
33495//>>description: Displays buttons to easily input numbers via the keyboard or mouse.
33496
33497//>>docs: http://api.jqueryui.com/spinner/
33498
33499//>>demos: http://jqueryui.com/spinner/
33500
33501//>>css.structure: ../../themes/base/core.css
33502
33503//>>css.structure: ../../themes/base/spinner.css
33504
33505//>>css.theme: ../../themes/base/theme.css
33506
33507
33508
33509
33510
33511
33512
33513function spinnerModifer( fn ) {
33514
33515	return function() {
33516
33517		var previous = this.element.val();
33518
33519		fn.apply( this, arguments );
33520
33521		this._refresh();
33522
33523		if ( previous !== this.element.val() ) {
33524
33525			this._trigger( "change" );
33526
33527		}
33528
33529	};
33530
33531}
33532
33533
33534
33535$.widget( "ui.spinner", {
33536
33537	version: "1.12.1",
33538
33539	defaultElement: "<input>",
33540
33541	widgetEventPrefix: "spin",
33542
33543	options: {
33544
33545		classes: {
33546
33547			"ui-spinner": "ui-corner-all",
33548
33549			"ui-spinner-down": "ui-corner-br",
33550
33551			"ui-spinner-up": "ui-corner-tr"
33552
33553		},
33554
33555		culture: null,
33556
33557		icons: {
33558
33559			down: "ui-icon-triangle-1-s",
33560
33561			up: "ui-icon-triangle-1-n"
33562
33563		},
33564
33565		incremental: true,
33566
33567		max: null,
33568
33569		min: null,
33570
33571		numberFormat: null,
33572
33573		page: 10,
33574
33575		step: 1,
33576
33577
33578
33579		change: null,
33580
33581		spin: null,
33582
33583		start: null,
33584
33585		stop: null
33586
33587	},
33588
33589
33590
33591	_create: function() {
33592
33593
33594
33595		// handle string values that need to be parsed
33596
33597		this._setOption( "max", this.options.max );
33598
33599		this._setOption( "min", this.options.min );
33600
33601		this._setOption( "step", this.options.step );
33602
33603
33604
33605		// Only format if there is a value, prevents the field from being marked
33606
33607		// as invalid in Firefox, see #9573.
33608
33609		if ( this.value() !== "" ) {
33610
33611
33612
33613			// Format the value, but don't constrain.
33614
33615			this._value( this.element.val(), true );
33616
33617		}
33618
33619
33620
33621		this._draw();
33622
33623		this._on( this._events );
33624
33625		this._refresh();
33626
33627
33628
33629		// Turning off autocomplete prevents the browser from remembering the
33630
33631		// value when navigating through history, so we re-enable autocomplete
33632
33633		// if the page is unloaded before the widget is destroyed. #7790
33634
33635		this._on( this.window, {
33636
33637			beforeunload: function() {
33638
33639				this.element.removeAttr( "autocomplete" );
33640
33641			}
33642
33643		} );
33644
33645	},
33646
33647
33648
33649	_getCreateOptions: function() {
33650
33651		var options = this._super();
33652
33653		var element = this.element;
33654
33655
33656
33657		$.each( [ "min", "max", "step" ], function( i, option ) {
33658
33659			var value = element.attr( option );
33660
33661			if ( value != null && value.length ) {
33662
33663				options[ option ] = value;
33664
33665			}
33666
33667		} );
33668
33669
33670
33671		return options;
33672
33673	},
33674
33675
33676
33677	_events: {
33678
33679		keydown: function( event ) {
33680
33681			if ( this._start( event ) && this._keydown( event ) ) {
33682
33683				event.preventDefault();
33684
33685			}
33686
33687		},
33688
33689		keyup: "_stop",
33690
33691		focus: function() {
33692
33693			this.previous = this.element.val();
33694
33695		},
33696
33697		blur: function( event ) {
33698
33699			if ( this.cancelBlur ) {
33700
33701				delete this.cancelBlur;
33702
33703				return;
33704
33705			}
33706
33707
33708
33709			this._stop();
33710
33711			this._refresh();
33712
33713			if ( this.previous !== this.element.val() ) {
33714
33715				this._trigger( "change", event );
33716
33717			}
33718
33719		},
33720
33721		mousewheel: function( event, delta ) {
33722
33723			if ( !delta ) {
33724
33725				return;
33726
33727			}
33728
33729			if ( !this.spinning && !this._start( event ) ) {
33730
33731				return false;
33732
33733			}
33734
33735
33736
33737			this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event );
33738
33739			clearTimeout( this.mousewheelTimer );
33740
33741			this.mousewheelTimer = this._delay( function() {
33742
33743				if ( this.spinning ) {
33744
33745					this._stop( event );
33746
33747				}
33748
33749			}, 100 );
33750
33751			event.preventDefault();
33752
33753		},
33754
33755		"mousedown .ui-spinner-button": function( event ) {
33756
33757			var previous;
33758
33759
33760
33761			// We never want the buttons to have focus; whenever the user is
33762
33763			// interacting with the spinner, the focus should be on the input.
33764
33765			// If the input is focused then this.previous is properly set from
33766
33767			// when the input first received focus. If the input is not focused
33768
33769			// then we need to set this.previous based on the value before spinning.
33770
33771			previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ?
33772
33773				this.previous : this.element.val();
33774
33775			function checkFocus() {
33776
33777				var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] );
33778
33779				if ( !isActive ) {
33780
33781					this.element.trigger( "focus" );
33782
33783					this.previous = previous;
33784
33785
33786
33787					// support: IE
33788
33789					// IE sets focus asynchronously, so we need to check if focus
33790
33791					// moved off of the input because the user clicked on the button.
33792
33793					this._delay( function() {
33794
33795						this.previous = previous;
33796
33797					} );
33798
33799				}
33800
33801			}
33802
33803
33804
33805			// Ensure focus is on (or stays on) the text field
33806
33807			event.preventDefault();
33808
vendor: 6,446 bytes, lines 33809-34268
33809			checkFocus.call( this );
33810
33811
33812
33813			// Support: IE
33814
33815			// IE doesn't prevent moving focus even with event.preventDefault()
33816
33817			// so we set a flag to know when we should ignore the blur event
33818
33819			// and check (again) if focus moved off of the input.
33820
33821			this.cancelBlur = true;
33822
33823			this._delay( function() {
33824
33825				delete this.cancelBlur;
33826
33827				checkFocus.call( this );
33828
33829			} );
33830
33831
33832
33833			if ( this._start( event ) === false ) {
33834
33835				return;
33836
33837			}
33838
33839
33840
33841			this._repeat( null, $( event.currentTarget )
33842
33843				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
33844
33845		},
33846
33847		"mouseup .ui-spinner-button": "_stop",
33848
33849		"mouseenter .ui-spinner-button": function( event ) {
33850
33851
33852
33853			// button will add ui-state-active if mouse was down while mouseleave and kept down
33854
33855			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
33856
33857				return;
33858
33859			}
33860
33861
33862
33863			if ( this._start( event ) === false ) {
33864
33865				return false;
33866
33867			}
33868
33869			this._repeat( null, $( event.currentTarget )
33870
33871				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
33872
33873		},
33874
33875
33876
33877		// TODO: do we really want to consider this a stop?
33878
33879		// shouldn't we just stop the repeater and wait until mouseup before
33880
33881		// we trigger the stop event?
33882
33883		"mouseleave .ui-spinner-button": "_stop"
33884
33885	},
33886
33887
33888
33889	// Support mobile enhanced option and make backcompat more sane
33890
33891	_enhance: function() {
33892
33893		this.uiSpinner = this.element
33894
33895			.attr( "autocomplete", "off" )
33896
33897			.wrap( "<span>" )
33898
33899			.parent()
33900
33901
33902
33903				// Add buttons
33904
33905				.append(
33906
33907					"<a></a><a></a>"
33908
33909				);
33910
33911	},
33912
33913
33914
33915	_draw: function() {
33916
33917		this._enhance();
33918
33919
33920
33921		this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" );
33922
33923		this._addClass( "ui-spinner-input" );
33924
33925
33926
33927		this.element.attr( "role", "spinbutton" );
33928
33929
33930
33931		// Button bindings
33932
33933		this.buttons = this.uiSpinner.children( "a" )
33934
33935			.attr( "tabIndex", -1 )
33936
33937			.attr( "aria-hidden", true )
33938
33939			.button( {
33940
33941				classes: {
33942
33943					"ui-button": ""
33944
33945				}
33946
33947			} );
33948
33949
33950
33951		// TODO: Right now button does not support classes this is already updated in button PR
33952
33953		this._removeClass( this.buttons, "ui-corner-all" );
33954
33955
33956
33957		this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" );
33958
33959		this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" );
33960
33961		this.buttons.first().button( {
33962
33963			"icon": this.options.icons.up,
33964
33965			"showLabel": false
33966
33967		} );
33968
33969		this.buttons.last().button( {
33970
33971			"icon": this.options.icons.down,
33972
33973			"showLabel": false
33974
33975		} );
33976
33977
33978
33979		// IE 6 doesn't understand height: 50% for the buttons
33980
33981		// unless the wrapper has an explicit height
33982
33983		if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) &&
33984
33985				this.uiSpinner.height() > 0 ) {
33986
33987			this.uiSpinner.height( this.uiSpinner.height() );
33988
33989		}
33990
33991	},
33992
33993
33994
33995	_keydown: function( event ) {
33996
33997		var options = this.options,
33998
33999			keyCode = $.ui.keyCode;
34000
34001
34002
34003		switch ( event.keyCode ) {
34004
34005		case keyCode.UP:
34006
34007			this._repeat( null, 1, event );
34008
34009			return true;
34010
34011		case keyCode.DOWN:
34012
34013			this._repeat( null, -1, event );
34014
34015			return true;
34016
34017		case keyCode.PAGE_UP:
34018
34019			this._repeat( null, options.page, event );
34020
34021			return true;
34022
34023		case keyCode.PAGE_DOWN:
34024
34025			this._repeat( null, -options.page, event );
34026
34027			return true;
34028
34029		}
34030
34031
34032
34033		return false;
34034
34035	},
34036
34037
34038
34039	_start: function( event ) {
34040
34041		if ( !this.spinning && this._trigger( "start", event ) === false ) {
34042
34043			return false;
34044
34045		}
34046
34047
34048
34049		if ( !this.counter ) {
34050
34051			this.counter = 1;
34052
34053		}
34054
34055		this.spinning = true;
34056
34057		return true;
34058
34059	},
34060
34061
34062
34063	_repeat: function( i, steps, event ) {
34064
34065		i = i || 500;
34066
34067
34068
34069		clearTimeout( this.timer );
34070
34071		this.timer = this._delay( function() {
34072
34073			this._repeat( 40, steps, event );
34074
34075		}, i );
34076
34077
34078
34079		this._spin( steps * this.options.step, event );
34080
34081	},
34082
34083
34084
34085	_spin: function( step, event ) {
34086
34087		var value = this.value() || 0;
34088
34089
34090
34091		if ( !this.counter ) {
34092
34093			this.counter = 1;
34094
34095		}
34096
34097
34098
34099		value = this._adjustValue( value + step * this._increment( this.counter ) );
34100
34101
34102
34103		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) {
34104
34105			this._value( value );
34106
34107			this.counter++;
34108
34109		}
34110
34111	},
34112
34113
34114
34115	_increment: function( i ) {
34116
34117		var incremental = this.options.incremental;
34118
34119
34120
34121		if ( incremental ) {
34122
34123			return $.isFunction( incremental ) ?
34124
34125				incremental( i ) :
34126
34127				Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
34128
34129		}
34130
34131
34132
34133		return 1;
34134
34135	},
34136
34137
34138
34139	_precision: function() {
34140
34141		var precision = this._precisionOf( this.options.step );
34142
34143		if ( this.options.min !== null ) {
34144
34145			precision = Math.max( precision, this._precisionOf( this.options.min ) );
34146
34147		}
34148
34149		return precision;
34150
34151	},
34152
34153
34154
34155	_precisionOf: function( num ) {
34156
34157		var str = num.toString(),
34158
34159			decimal = str.indexOf( "." );
34160
34161		return decimal === -1 ? 0 : str.length - decimal - 1;
34162
34163	},
34164
34165
34166
34167	_adjustValue: function( value ) {
34168
34169		var base, aboveMin,
34170
34171			options = this.options;
34172
34173
34174
34175		// Make sure we're at a valid step
34176
34177		// - find out where we are relative to the base (min or 0)
34178
34179		base = options.min !== null ? options.min : 0;
34180
34181		aboveMin = value - base;
34182
34183
34184
34185		// - round to the nearest step
34186
34187		aboveMin = Math.round( aboveMin / options.step ) * options.step;
34188
34189
34190
34191		// - rounding is based on 0, so adjust back to our base
34192
34193		value = base + aboveMin;
34194
34195
34196
34197		// Fix precision from bad JS floating point math
34198
34199		value = parseFloat( value.toFixed( this._precision() ) );
34200
34201
34202
34203		// Clamp the value
34204
34205		if ( options.max !== null && value > options.max ) {
34206
34207			return options.max;
34208
34209		}
34210
34211		if ( options.min !== null && value < options.min ) {
34212
34213			return options.min;
34214
34215		}
34216
34217
34218
34219		return value;
34220
34221	},
34222
34223
34224
34225	_stop: function( event ) {
34226
34227		if ( !this.spinning ) {
34228
34229			return;
34230
34231		}
34232
34233
34234
34235		clearTimeout( this.timer );
34236
34237		clearTimeout( this.mousewheelTimer );
34238
34239		this.counter = 0;
34240
34241		this.spinning = false;
34242
34243		this._trigger( "stop", event );
34244
34245	},
34246
34247
34248
34249	_setOption: function( key, value ) {
34250
34251		var prevValue, first, last;
34252
34253
34254
34255		if ( key === "culture" || key === "numberFormat" ) {
34256
34257			prevValue = this._parse( this.element.val() );
34258
34259			this.options[ key ] = value;
34260
34261			this.element.val( this._format( prevValue ) );
34262
34263			return;
34264
34265		}
34266
34267
34268
vendor: 13,912 bytes, lines 34269-35261
34269		if ( key === "max" || key === "min" || key === "step" ) {
34270
34271			if ( typeof value === "string" ) {
34272
34273				value = this._parse( value );
34274
34275			}
34276
34277		}
34278
34279		if ( key === "icons" ) {
34280
34281			first = this.buttons.first().find( ".ui-icon" );
34282
34283			this._removeClass( first, null, this.options.icons.up );
34284
34285			this._addClass( first, null, value.up );
34286
34287			last = this.buttons.last().find( ".ui-icon" );
34288
34289			this._removeClass( last, null, this.options.icons.down );
34290
34291			this._addClass( last, null, value.down );
34292
34293		}
34294
34295
34296
34297		this._super( key, value );
34298
34299	},
34300
34301
34302
34303	_setOptionDisabled: function( value ) {
34304
34305		this._super( value );
34306
34307
34308
34309		this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value );
34310
34311		this.element.prop( "disabled", !!value );
34312
34313		this.buttons.button( value ? "disable" : "enable" );
34314
34315	},
34316
34317
34318
34319	_setOptions: spinnerModifer( function( options ) {
34320
34321		this._super( options );
34322
34323	} ),
34324
34325
34326
34327	_parse: function( val ) {
34328
34329		if ( typeof val === "string" && val !== "" ) {
34330
34331			val = window.Globalize && this.options.numberFormat ?
34332
34333				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
34334
34335		}
34336
34337		return val === "" || isNaN( val ) ? null : val;
34338
34339	},
34340
34341
34342
34343	_format: function( value ) {
34344
34345		if ( value === "" ) {
34346
34347			return "";
34348
34349		}
34350
34351		return window.Globalize && this.options.numberFormat ?
34352
34353			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
34354
34355			value;
34356
34357	},
34358
34359
34360
34361	_refresh: function() {
34362
34363		this.element.attr( {
34364
34365			"aria-valuemin": this.options.min,
34366
34367			"aria-valuemax": this.options.max,
34368
34369
34370
34371			// TODO: what should we do with values that can't be parsed?
34372
34373			"aria-valuenow": this._parse( this.element.val() )
34374
34375		} );
34376
34377	},
34378
34379
34380
34381	isValid: function() {
34382
34383		var value = this.value();
34384
34385
34386
34387		// Null is invalid
34388
34389		if ( value === null ) {
34390
34391			return false;
34392
34393		}
34394
34395
34396
34397		// If value gets adjusted, it's invalid
34398
34399		return value === this._adjustValue( value );
34400
34401	},
34402
34403
34404
34405	// Update the value without triggering change
34406
34407	_value: function( value, allowAny ) {
34408
34409		var parsed;
34410
34411		if ( value !== "" ) {
34412
34413			parsed = this._parse( value );
34414
34415			if ( parsed !== null ) {
34416
34417				if ( !allowAny ) {
34418
34419					parsed = this._adjustValue( parsed );
34420
34421				}
34422
34423				value = this._format( parsed );
34424
34425			}
34426
34427		}
34428
34429		this.element.val( value );
34430
34431		this._refresh();
34432
34433	},
34434
34435
34436
34437	_destroy: function() {
34438
34439		this.element
34440
34441			.prop( "disabled", false )
34442
34443			.removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" );
34444
34445
34446
34447		this.uiSpinner.replaceWith( this.element );
34448
34449	},
34450
34451
34452
34453	stepUp: spinnerModifer( function( steps ) {
34454
34455		this._stepUp( steps );
34456
34457	} ),
34458
34459	_stepUp: function( steps ) {
34460
34461		if ( this._start() ) {
34462
34463			this._spin( ( steps || 1 ) * this.options.step );
34464
34465			this._stop();
34466
34467		}
34468
34469	},
34470
34471
34472
34473	stepDown: spinnerModifer( function( steps ) {
34474
34475		this._stepDown( steps );
34476
34477	} ),
34478
34479	_stepDown: function( steps ) {
34480
34481		if ( this._start() ) {
34482
34483			this._spin( ( steps || 1 ) * -this.options.step );
34484
34485			this._stop();
34486
34487		}
34488
34489	},
34490
34491
34492
34493	pageUp: spinnerModifer( function( pages ) {
34494
34495		this._stepUp( ( pages || 1 ) * this.options.page );
34496
34497	} ),
34498
34499
34500
34501	pageDown: spinnerModifer( function( pages ) {
34502
34503		this._stepDown( ( pages || 1 ) * this.options.page );
34504
34505	} ),
34506
34507
34508
34509	value: function( newVal ) {
34510
34511		if ( !arguments.length ) {
34512
34513			return this._parse( this.element.val() );
34514
34515		}
34516
34517		spinnerModifer( this._value ).call( this, newVal );
34518
34519	},
34520
34521
34522
34523	widget: function() {
34524
34525		return this.uiSpinner;
34526
34527	}
34528
34529} );
34530
34531
34532
34533// DEPRECATED
34534
34535// TODO: switch return back to widget declaration at top of file when this is removed
34536
34537if ( $.uiBackCompat !== false ) {
34538
34539
34540
34541	// Backcompat for spinner html extension points
34542
34543	$.widget( "ui.spinner", $.ui.spinner, {
34544
34545		_enhance: function() {
34546
34547			this.uiSpinner = this.element
34548
34549				.attr( "autocomplete", "off" )
34550
34551				.wrap( this._uiSpinnerHtml() )
34552
34553				.parent()
34554
34555
34556
34557					// Add buttons
34558
34559					.append( this._buttonHtml() );
34560
34561		},
34562
34563		_uiSpinnerHtml: function() {
34564
34565			return "<span>";
34566
34567		},
34568
34569
34570
34571		_buttonHtml: function() {
34572
34573			return "<a></a><a></a>";
34574
34575		}
34576
34577	} );
34578
34579}
34580
34581
34582
34583var widgetsSpinner = $.ui.spinner;
34584
34585
34586
34587
34588
34589/*!
34590
34591 * jQuery UI Tabs 1.12.1
34592
34593 * http://jqueryui.com
34594
34595 *
34596
34597 * Copyright jQuery Foundation and other contributors
34598
34599 * Released under the MIT license.
34600
34601 * http://jquery.org/license
34602
34603 */
34604
34605
34606
34607//>>label: Tabs
34608
34609//>>group: Widgets
34610
34611//>>description: Transforms a set of container elements into a tab structure.
34612
34613//>>docs: http://api.jqueryui.com/tabs/
34614
34615//>>demos: http://jqueryui.com/tabs/
34616
34617//>>css.structure: ../../themes/base/core.css
34618
34619//>>css.structure: ../../themes/base/tabs.css
34620
34621//>>css.theme: ../../themes/base/theme.css
34622
34623
34624
34625
34626
34627
34628
34629$.widget( "ui.tabs", {
34630
34631	version: "1.12.1",
34632
34633	delay: 300,
34634
34635	options: {
34636
34637		active: null,
34638
34639		classes: {
34640
34641			"ui-tabs": "ui-corner-all",
34642
34643			"ui-tabs-nav": "ui-corner-all",
34644
34645			"ui-tabs-panel": "ui-corner-bottom",
34646
34647			"ui-tabs-tab": "ui-corner-top"
34648
34649		},
34650
34651		collapsible: false,
34652
34653		event: "click",
34654
34655		heightStyle: "content",
34656
34657		hide: null,
34658
34659		show: null,
34660
34661
34662
34663		// Callbacks
34664
34665		activate: null,
34666
34667		beforeActivate: null,
34668
34669		beforeLoad: null,
34670
34671		load: null
34672
34673	},
34674
34675
34676
34677	_isLocal: ( function() {
34678
34679		var rhash = /#.*$/;
34680
34681
34682
34683		return function( anchor ) {
34684
34685			var anchorUrl, locationUrl;
34686
34687
34688
34689			anchorUrl = anchor.href.replace( rhash, "" );
34690
34691			locationUrl = location.href.replace( rhash, "" );
34692
34693
34694
34695			// Decoding may throw an error if the URL isn't UTF-8 (#9518)
34696
34697			try {
34698
34699				anchorUrl = decodeURIComponent( anchorUrl );
34700
34701			} catch ( error ) {}
34702
34703			try {
34704
34705				locationUrl = decodeURIComponent( locationUrl );
34706
34707			} catch ( error ) {}
34708
34709
34710
34711			return anchor.hash.length > 1 && anchorUrl === locationUrl;
34712
34713		};
34714
34715	} )(),
34716
34717
34718
34719	_create: function() {
34720
34721		var that = this,
34722
34723			options = this.options;
34724
34725
34726
34727		this.running = false;
34728
34729
34730
34731		this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
34732
34733		this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
34734
34735
34736
34737		this._processTabs();
34738
34739		options.active = this._initialActive();
34740
34741
34742
34743		// Take disabling tabs via class attribute from HTML
34744
34745		// into account and update option properly.
34746
34747		if ( $.isArray( options.disabled ) ) {
34748
34749			options.disabled = $.unique( options.disabled.concat(
34750
34751				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
34752
34753					return that.tabs.index( li );
34754
34755				} )
34756
34757			) ).sort();
34758
34759		}
34760
34761
34762
34763		// Check for length avoids error when initializing empty list
34764
34765		if ( this.options.active !== false && this.anchors.length ) {
34766
34767			this.active = this._findActive( options.active );
34768
34769		} else {
34770
34771			this.active = $();
34772
34773		}
34774
34775
34776
34777		this._refresh();
34778
34779
34780
34781		if ( this.active.length ) {
34782
34783			this.load( options.active );
34784
34785		}
34786
34787	},
34788
34789
34790
34791	_initialActive: function() {
34792
34793		var active = this.options.active,
34794
34795			collapsible = this.options.collapsible,
34796
34797			locationHash = location.hash.substring( 1 );
34798
34799
34800
34801		if ( active === null ) {
34802
34803
34804
34805			// check the fragment identifier in the URL
34806
34807			if ( locationHash ) {
34808
34809				this.tabs.each( function( i, tab ) {
34810
34811					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
34812
34813						active = i;
34814
34815						return false;
34816
34817					}
34818
34819				} );
34820
34821			}
34822
34823
34824
34825			// Check for a tab marked active via a class
34826
34827			if ( active === null ) {
34828
34829				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
34830
34831			}
34832
34833
34834
34835			// No active tab, set to false
34836
34837			if ( active === null || active === -1 ) {
34838
34839				active = this.tabs.length ? 0 : false;
34840
34841			}
34842
34843		}
34844
34845
34846
34847		// Handle numbers: negative, out of range
34848
34849		if ( active !== false ) {
34850
34851			active = this.tabs.index( this.tabs.eq( active ) );
34852
34853			if ( active === -1 ) {
34854
34855				active = collapsible ? false : 0;
34856
34857			}
34858
34859		}
34860
34861
34862
34863		// Don't allow collapsible: false and active: false
34864
34865		if ( !collapsible && active === false && this.anchors.length ) {
34866
34867			active = 0;
34868
34869		}
34870
34871
34872
34873		return active;
34874
34875	},
34876
34877
34878
34879	_getCreateEventData: function() {
34880
34881		return {
34882
34883			tab: this.active,
34884
34885			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
34886
34887		};
34888
34889	},
34890
34891
34892
34893	_tabKeydown: function( event ) {
34894
34895		var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ),
34896
34897			selectedIndex = this.tabs.index( focusedTab ),
34898
34899			goingForward = true;
34900
34901
34902
34903		if ( this._handlePageNav( event ) ) {
34904
34905			return;
34906
34907		}
34908
34909
34910
34911		switch ( event.keyCode ) {
34912
34913		case $.ui.keyCode.RIGHT:
34914
34915		case $.ui.keyCode.DOWN:
34916
34917			selectedIndex++;
34918
34919			break;
34920
34921		case $.ui.keyCode.UP:
34922
34923		case $.ui.keyCode.LEFT:
34924
34925			goingForward = false;
34926
34927			selectedIndex--;
34928
34929			break;
34930
34931		case $.ui.keyCode.END:
34932
34933			selectedIndex = this.anchors.length - 1;
34934
34935			break;
34936
34937		case $.ui.keyCode.HOME:
34938
34939			selectedIndex = 0;
34940
34941			break;
34942
34943		case $.ui.keyCode.SPACE:
34944
34945
34946
34947			// Activate only, no collapsing
34948
34949			event.preventDefault();
34950
34951			clearTimeout( this.activating );
34952
34953			this._activate( selectedIndex );
34954
34955			return;
34956
34957		case $.ui.keyCode.ENTER:
34958
34959
34960
34961			// Toggle (cancel delayed activation, allow collapsing)
34962
34963			event.preventDefault();
34964
34965			clearTimeout( this.activating );
34966
34967
34968
34969			// Determine if we should collapse or activate
34970
34971			this._activate( selectedIndex === this.options.active ? false : selectedIndex );
34972
34973			return;
34974
34975		default:
34976
34977			return;
34978
34979		}
34980
34981
34982
34983		// Focus the appropriate tab, based on which key was pressed
34984
34985		event.preventDefault();
34986
34987		clearTimeout( this.activating );
34988
34989		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
34990
34991
34992
34993		// Navigating with control/command key will prevent automatic activation
34994
34995		if ( !event.ctrlKey && !event.metaKey ) {
34996
34997
34998
34999			// Update aria-selected immediately so that AT think the tab is already selected.
35000
35001			// Otherwise AT may confuse the user by stating that they need to activate the tab,
35002
35003			// but the tab will already be activated by the time the announcement finishes.
35004
35005			focusedTab.attr( "aria-selected", "false" );
35006
35007			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
35008
35009
35010
35011			this.activating = this._delay( function() {
35012
35013				this.option( "active", selectedIndex );
35014
35015			}, this.delay );
35016
35017		}
35018
35019	},
35020
35021
35022
35023	_panelKeydown: function( event ) {
35024
35025		if ( this._handlePageNav( event ) ) {
35026
35027			return;
35028
35029		}
35030
35031
35032
35033		// Ctrl+up moves focus to the current tab
35034
35035		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
35036
35037			event.preventDefault();
35038
35039			this.active.trigger( "focus" );
35040
35041		}
35042
35043	},
35044
35045
35046
35047	// Alt+page up/down moves focus to the previous/next tab (and activates)
35048
35049	_handlePageNav: function( event ) {
35050
35051		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
35052
35053			this._activate( this._focusNextTab( this.options.active - 1, false ) );
35054
35055			return true;
35056
35057		}
35058
35059		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
35060
35061			this._activate( this._focusNextTab( this.options.active + 1, true ) );
35062
35063			return true;
35064
35065		}
35066
35067	},
35068
35069
35070
35071	_findNextTab: function( index, goingForward ) {
35072
35073		var lastTabIndex = this.tabs.length - 1;
35074
35075
35076
35077		function constrain() {
35078
35079			if ( index > lastTabIndex ) {
35080
35081				index = 0;
35082
35083			}
35084
35085			if ( index < 0 ) {
35086
35087				index = lastTabIndex;
35088
35089			}
35090
35091			return index;
35092
35093		}
35094
35095
35096
35097		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
35098
35099			index = goingForward ? index + 1 : index - 1;
35100
35101		}
35102
35103
35104
35105		return index;
35106
35107	},
35108
35109
35110
35111	_focusNextTab: function( index, goingForward ) {
35112
35113		index = this._findNextTab( index, goingForward );
35114
35115		this.tabs.eq( index ).trigger( "focus" );
35116
35117		return index;
35118
35119	},
35120
35121
35122
35123	_setOption: function( key, value ) {
35124
35125		if ( key === "active" ) {
35126
35127
35128
35129			// _activate() will handle invalid values and update this.options
35130
35131			this._activate( value );
35132
35133			return;
35134
35135		}
35136
35137
35138
35139		this._super( key, value );
35140
35141
35142
35143		if ( key === "collapsible" ) {
35144
35145			this._toggleClass( "ui-tabs-collapsible", null, value );
35146
35147
35148
35149			// Setting collapsible: false while collapsed; open first panel
35150
35151			if ( !value && this.options.active === false ) {
35152
35153				this._activate( 0 );
35154
35155			}
35156
35157		}
35158
35159
35160
35161		if ( key === "event" ) {
35162
35163			this._setupEvents( value );
35164
35165		}
35166
35167
35168
35169		if ( key === "heightStyle" ) {
35170
35171			this._setupHeightStyle( value );
35172
35173		}
35174
35175	},
35176
35177
35178
35179	_sanitizeSelector: function( hash ) {
35180
35181		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
35182
35183	},
35184
35185
35186
35187	refresh: function() {
35188
35189		var options = this.options,
35190
35191			lis = this.tablist.children( ":has(a[href])" );
35192
35193
35194
35195		// Get disabled tabs from class attribute from HTML
35196
35197		// this will get converted to a boolean if needed in _refresh()
35198
35199		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
35200
35201			return lis.index( tab );
35202
35203		} );
35204
35205
35206
35207		this._processTabs();
35208
35209
35210
35211		// Was collapsed or no tabs
35212
35213		if ( options.active === false || !this.anchors.length ) {
35214
35215			options.active = false;
35216
35217			this.active = $();
35218
35219
35220
35221		// was active, but active tab is gone
35222
35223		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
35224
35225
35226
35227			// all remaining tabs are disabled
35228
35229			if ( this.tabs.length === options.disabled.length ) {
35230
35231				options.active = false;
35232
35233				this.active = $();
35234
35235
35236
35237			// activate previous tab
35238
35239			} else {
35240
35241				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
35242
35243			}
35244
35245
35246
35247		// was active, active tab still exists
35248
35249		} else {
35250
35251
35252
35253			// make sure active index is correct
35254
35255			options.active = this.tabs.index( this.active );
35256
35257		}
35258
35259
35260
35261		this._refresh();
vendor: 20,320 bytes, lines 35262-36674
35262
35263	},
35264
35265
35266
35267	_refresh: function() {
35268
35269		this._setOptionDisabled( this.options.disabled );
35270
35271		this._setupEvents( this.options.event );
35272
35273		this._setupHeightStyle( this.options.heightStyle );
35274
35275
35276
35277		this.tabs.not( this.active ).attr( {
35278
35279			"aria-selected": "false",
35280
35281			"aria-expanded": "false",
35282
35283			tabIndex: -1
35284
35285		} );
35286
35287		this.panels.not( this._getPanelForTab( this.active ) )
35288
35289			.hide()
35290
35291			.attr( {
35292
35293				"aria-hidden": "true"
35294
35295			} );
35296
35297
35298
35299		// Make sure one tab is in the tab order
35300
35301		if ( !this.active.length ) {
35302
35303			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
35304
35305		} else {
35306
35307			this.active
35308
35309				.attr( {
35310
35311					"aria-selected": "true",
35312
35313					"aria-expanded": "true",
35314
35315					tabIndex: 0
35316
35317				} );
35318
35319			this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
35320
35321			this._getPanelForTab( this.active )
35322
35323				.show()
35324
35325				.attr( {
35326
35327					"aria-hidden": "false"
35328
35329				} );
35330
35331		}
35332
35333	},
35334
35335
35336
35337	_processTabs: function() {
35338
35339		var that = this,
35340
35341			prevTabs = this.tabs,
35342
35343			prevAnchors = this.anchors,
35344
35345			prevPanels = this.panels;
35346
35347
35348
35349		this.tablist = this._getList().attr( "role", "tablist" );
35350
35351		this._addClass( this.tablist, "ui-tabs-nav",
35352
35353			"ui-helper-reset ui-helper-clearfix ui-widget-header" );
35354
35355
35356
35357		// Prevent users from focusing disabled tabs via click
35358
35359		this.tablist
35360
35361			.on( "mousedown" + this.eventNamespace, "> li", function( event ) {
35362
35363				if ( $( this ).is( ".ui-state-disabled" ) ) {
35364
35365					event.preventDefault();
35366
35367				}
35368
35369			} )
35370
35371
35372
35373			// Support: IE <9
35374
35375			// Preventing the default action in mousedown doesn't prevent IE
35376
35377			// from focusing the element, so if the anchor gets focused, blur.
35378
35379			// We don't have to worry about focusing the previously focused
35380
35381			// element since clicking on a non-focusable element should focus
35382
35383			// the body anyway.
35384
35385			.on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() {
35386
35387				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
35388
35389					this.blur();
35390
35391				}
35392
35393			} );
35394
35395
35396
35397		this.tabs = this.tablist.find( "> li:has(a[href])" )
35398
35399			.attr( {
35400
35401				role: "tab",
35402
35403				tabIndex: -1
35404
35405			} );
35406
35407		this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" );
35408
35409
35410
35411		this.anchors = this.tabs.map( function() {
35412
35413			return $( "a", this )[ 0 ];
35414
35415		} )
35416
35417			.attr( {
35418
35419				role: "presentation",
35420
35421				tabIndex: -1
35422
35423			} );
35424
35425		this._addClass( this.anchors, "ui-tabs-anchor" );
35426
35427
35428
35429		this.panels = $();
35430
35431
35432
35433		this.anchors.each( function( i, anchor ) {
35434
35435			var selector, panel, panelId,
35436
35437				anchorId = $( anchor ).uniqueId().attr( "id" ),
35438
35439				tab = $( anchor ).closest( "li" ),
35440
35441				originalAriaControls = tab.attr( "aria-controls" );
35442
35443
35444
35445			// Inline tab
35446
35447			if ( that._isLocal( anchor ) ) {
35448
35449				selector = anchor.hash;
35450
35451				panelId = selector.substring( 1 );
35452
35453				panel = that.element.find( that._sanitizeSelector( selector ) );
35454
35455
35456
35457			// remote tab
35458
35459			} else {
35460
35461
35462
35463				// If the tab doesn't already have aria-controls,
35464
35465				// generate an id by using a throw-away element
35466
35467				panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
35468
35469				selector = "#" + panelId;
35470
35471				panel = that.element.find( selector );
35472
35473				if ( !panel.length ) {
35474
35475					panel = that._createPanel( panelId );
35476
35477					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
35478
35479				}
35480
35481				panel.attr( "aria-live", "polite" );
35482
35483			}
35484
35485
35486
35487			if ( panel.length ) {
35488
35489				that.panels = that.panels.add( panel );
35490
35491			}
35492
35493			if ( originalAriaControls ) {
35494
35495				tab.data( "ui-tabs-aria-controls", originalAriaControls );
35496
35497			}
35498
35499			tab.attr( {
35500
35501				"aria-controls": panelId,
35502
35503				"aria-labelledby": anchorId
35504
35505			} );
35506
35507			panel.attr( "aria-labelledby", anchorId );
35508
35509		} );
35510
35511
35512
35513		this.panels.attr( "role", "tabpanel" );
35514
35515		this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
35516
35517
35518
35519		// Avoid memory leaks (#10056)
35520
35521		if ( prevTabs ) {
35522
35523			this._off( prevTabs.not( this.tabs ) );
35524
35525			this._off( prevAnchors.not( this.anchors ) );
35526
35527			this._off( prevPanels.not( this.panels ) );
35528
35529		}
35530
35531	},
35532
35533
35534
35535	// Allow overriding how to find the list for rare usage scenarios (#7715)
35536
35537	_getList: function() {
35538
35539		return this.tablist || this.element.find( "ol, ul" ).eq( 0 );
35540
35541	},
35542
35543
35544
35545	_createPanel: function( id ) {
35546
35547		return $( "<div>" )
35548
35549			.attr( "id", id )
35550
35551			.data( "ui-tabs-destroy", true );
35552
35553	},
35554
35555
35556
35557	_setOptionDisabled: function( disabled ) {
35558
35559		var currentItem, li, i;
35560
35561
35562
35563		if ( $.isArray( disabled ) ) {
35564
35565			if ( !disabled.length ) {
35566
35567				disabled = false;
35568
35569			} else if ( disabled.length === this.anchors.length ) {
35570
35571				disabled = true;
35572
35573			}
35574
35575		}
35576
35577
35578
35579		// Disable tabs
35580
35581		for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
35582
35583			currentItem = $( li );
35584
35585			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
35586
35587				currentItem.attr( "aria-disabled", "true" );
35588
35589				this._addClass( currentItem, null, "ui-state-disabled" );
35590
35591			} else {
35592
35593				currentItem.removeAttr( "aria-disabled" );
35594
35595				this._removeClass( currentItem, null, "ui-state-disabled" );
35596
35597			}
35598
35599		}
35600
35601
35602
35603		this.options.disabled = disabled;
35604
35605
35606
35607		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null,
35608
35609			disabled === true );
35610
35611	},
35612
35613
35614
35615	_setupEvents: function( event ) {
35616
35617		var events = {};
35618
35619		if ( event ) {
35620
35621			$.each( event.split( " " ), function( index, eventName ) {
35622
35623				events[ eventName ] = "_eventHandler";
35624
35625			} );
35626
35627		}
35628
35629
35630
35631		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
35632
35633
35634
35635		// Always prevent the default action, even when disabled
35636
35637		this._on( true, this.anchors, {
35638
35639			click: function( event ) {
35640
35641				event.preventDefault();
35642
35643			}
35644
35645		} );
35646
35647		this._on( this.anchors, events );
35648
35649		this._on( this.tabs, { keydown: "_tabKeydown" } );
35650
35651		this._on( this.panels, { keydown: "_panelKeydown" } );
35652
35653
35654
35655		this._focusable( this.tabs );
35656
35657		this._hoverable( this.tabs );
35658
35659	},
35660
35661
35662
35663	_setupHeightStyle: function( heightStyle ) {
35664
35665		var maxHeight,
35666
35667			parent = this.element.parent();
35668
35669
35670
35671		if ( heightStyle === "fill" ) {
35672
35673			maxHeight = parent.height();
35674
35675			maxHeight -= this.element.outerHeight() - this.element.height();
35676
35677
35678
35679			this.element.siblings( ":visible" ).each( function() {
35680
35681				var elem = $( this ),
35682
35683					position = elem.css( "position" );
35684
35685
35686
35687				if ( position === "absolute" || position === "fixed" ) {
35688
35689					return;
35690
35691				}
35692
35693				maxHeight -= elem.outerHeight( true );
35694
35695			} );
35696
35697
35698
35699			this.element.children().not( this.panels ).each( function() {
35700
35701				maxHeight -= $( this ).outerHeight( true );
35702
35703			} );
35704
35705
35706
35707			this.panels.each( function() {
35708
35709				$( this ).height( Math.max( 0, maxHeight -
35710
35711					$( this ).innerHeight() + $( this ).height() ) );
35712
35713			} )
35714
35715				.css( "overflow", "auto" );
35716
35717		} else if ( heightStyle === "auto" ) {
35718
35719			maxHeight = 0;
35720
35721			this.panels.each( function() {
35722
35723				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
35724
35725			} ).height( maxHeight );
35726
35727		}
35728
35729	},
35730
35731
35732
35733	_eventHandler: function( event ) {
35734
35735		var options = this.options,
35736
35737			active = this.active,
35738
35739			anchor = $( event.currentTarget ),
35740
35741			tab = anchor.closest( "li" ),
35742
35743			clickedIsActive = tab[ 0 ] === active[ 0 ],
35744
35745			collapsing = clickedIsActive && options.collapsible,
35746
35747			toShow = collapsing ? $() : this._getPanelForTab( tab ),
35748
35749			toHide = !active.length ? $() : this._getPanelForTab( active ),
35750
35751			eventData = {
35752
35753				oldTab: active,
35754
35755				oldPanel: toHide,
35756
35757				newTab: collapsing ? $() : tab,
35758
35759				newPanel: toShow
35760
35761			};
35762
35763
35764
35765		event.preventDefault();
35766
35767
35768
35769		if ( tab.hasClass( "ui-state-disabled" ) ||
35770
35771
35772
35773				// tab is already loading
35774
35775				tab.hasClass( "ui-tabs-loading" ) ||
35776
35777
35778
35779				// can't switch durning an animation
35780
35781				this.running ||
35782
35783
35784
35785				// click on active header, but not collapsible
35786
35787				( clickedIsActive && !options.collapsible ) ||
35788
35789
35790
35791				// allow canceling activation
35792
35793				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
35794
35795			return;
35796
35797		}
35798
35799
35800
35801		options.active = collapsing ? false : this.tabs.index( tab );
35802
35803
35804
35805		this.active = clickedIsActive ? $() : tab;
35806
35807		if ( this.xhr ) {
35808
35809			this.xhr.abort();
35810
35811		}
35812
35813
35814
35815		if ( !toHide.length && !toShow.length ) {
35816
35817			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
35818
35819		}
35820
35821
35822
35823		if ( toShow.length ) {
35824
35825			this.load( this.tabs.index( tab ), event );
35826
35827		}
35828
35829		this._toggle( event, eventData );
35830
35831	},
35832
35833
35834
35835	// Handles show/hide for selecting tabs
35836
35837	_toggle: function( event, eventData ) {
35838
35839		var that = this,
35840
35841			toShow = eventData.newPanel,
35842
35843			toHide = eventData.oldPanel;
35844
35845
35846
35847		this.running = true;
35848
35849
35850
35851		function complete() {
35852
35853			that.running = false;
35854
35855			that._trigger( "activate", event, eventData );
35856
35857		}
35858
35859
35860
35861		function show() {
35862
35863			that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
35864
35865
35866
35867			if ( toShow.length && that.options.show ) {
35868
35869				that._show( toShow, that.options.show, complete );
35870
35871			} else {
35872
35873				toShow.show();
35874
35875				complete();
35876
35877			}
35878
35879		}
35880
35881
35882
35883		// Start out by hiding, then showing, then completing
35884
35885		if ( toHide.length && this.options.hide ) {
35886
35887			this._hide( toHide, this.options.hide, function() {
35888
35889				that._removeClass( eventData.oldTab.closest( "li" ),
35890
35891					"ui-tabs-active", "ui-state-active" );
35892
35893				show();
35894
35895			} );
35896
35897		} else {
35898
35899			this._removeClass( eventData.oldTab.closest( "li" ),
35900
35901				"ui-tabs-active", "ui-state-active" );
35902
35903			toHide.hide();
35904
35905			show();
35906
35907		}
35908
35909
35910
35911		toHide.attr( "aria-hidden", "true" );
35912
35913		eventData.oldTab.attr( {
35914
35915			"aria-selected": "false",
35916
35917			"aria-expanded": "false"
35918
35919		} );
35920
35921
35922
35923		// If we're switching tabs, remove the old tab from the tab order.
35924
35925		// If we're opening from collapsed state, remove the previous tab from the tab order.
35926
35927		// If we're collapsing, then keep the collapsing tab in the tab order.
35928
35929		if ( toShow.length && toHide.length ) {
35930
35931			eventData.oldTab.attr( "tabIndex", -1 );
35932
35933		} else if ( toShow.length ) {
35934
35935			this.tabs.filter( function() {
35936
35937				return $( this ).attr( "tabIndex" ) === 0;
35938
35939			} )
35940
35941				.attr( "tabIndex", -1 );
35942
35943		}
35944
35945
35946
35947		toShow.attr( "aria-hidden", "false" );
35948
35949		eventData.newTab.attr( {
35950
35951			"aria-selected": "true",
35952
35953			"aria-expanded": "true",
35954
35955			tabIndex: 0
35956
35957		} );
35958
35959	},
35960
35961
35962
35963	_activate: function( index ) {
35964
35965		var anchor,
35966
35967			active = this._findActive( index );
35968
35969
35970
35971		// Trying to activate the already active panel
35972
35973		if ( active[ 0 ] === this.active[ 0 ] ) {
35974
35975			return;
35976
35977		}
35978
35979
35980
35981		// Trying to collapse, simulate a click on the current active header
35982
35983		if ( !active.length ) {
35984
35985			active = this.active;
35986
35987		}
35988
35989
35990
35991		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
35992
35993		this._eventHandler( {
35994
35995			target: anchor,
35996
35997			currentTarget: anchor,
35998
35999			preventDefault: $.noop
36000
36001		} );
36002
36003	},
36004
36005
36006
36007	_findActive: function( index ) {
36008
36009		return index === false ? $() : this.tabs.eq( index );
36010
36011	},
36012
36013
36014
36015	_getIndex: function( index ) {
36016
36017
36018
36019		// meta-function to give users option to provide a href string instead of a numerical index.
36020
36021		if ( typeof index === "string" ) {
36022
36023			index = this.anchors.index( this.anchors.filter( "[href$='" +
36024
36025				$.ui.escapeSelector( index ) + "']" ) );
36026
36027		}
36028
36029
36030
36031		return index;
36032
36033	},
36034
36035
36036
36037	_destroy: function() {
36038
36039		if ( this.xhr ) {
36040
36041			this.xhr.abort();
36042
36043		}
36044
36045
36046
36047		this.tablist
36048
36049			.removeAttr( "role" )
36050
36051			.off( this.eventNamespace );
36052
36053
36054
36055		this.anchors
36056
36057			.removeAttr( "role tabIndex" )
36058
36059			.removeUniqueId();
36060
36061
36062
36063		this.tabs.add( this.panels ).each( function() {
36064
36065			if ( $.data( this, "ui-tabs-destroy" ) ) {
36066
36067				$( this ).remove();
36068
36069			} else {
36070
36071				$( this ).removeAttr( "role tabIndex " +
36072
36073					"aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" );
36074
36075			}
36076
36077		} );
36078
36079
36080
36081		this.tabs.each( function() {
36082
36083			var li = $( this ),
36084
36085				prev = li.data( "ui-tabs-aria-controls" );
36086
36087			if ( prev ) {
36088
36089				li
36090
36091					.attr( "aria-controls", prev )
36092
36093					.removeData( "ui-tabs-aria-controls" );
36094
36095			} else {
36096
36097				li.removeAttr( "aria-controls" );
36098
36099			}
36100
36101		} );
36102
36103
36104
36105		this.panels.show();
36106
36107
36108
36109		if ( this.options.heightStyle !== "content" ) {
36110
36111			this.panels.css( "height", "" );
36112
36113		}
36114
36115	},
36116
36117
36118
36119	enable: function( index ) {
36120
36121		var disabled = this.options.disabled;
36122
36123		if ( disabled === false ) {
36124
36125			return;
36126
36127		}
36128
36129
36130
36131		if ( index === undefined ) {
36132
36133			disabled = false;
36134
36135		} else {
36136
36137			index = this._getIndex( index );
36138
36139			if ( $.isArray( disabled ) ) {
36140
36141				disabled = $.map( disabled, function( num ) {
36142
36143					return num !== index ? num : null;
36144
36145				} );
36146
36147			} else {
36148
36149				disabled = $.map( this.tabs, function( li, num ) {
36150
36151					return num !== index ? num : null;
36152
36153				} );
36154
36155			}
36156
36157		}
36158
36159		this._setOptionDisabled( disabled );
36160
36161	},
36162
36163
36164
36165	disable: function( index ) {
36166
36167		var disabled = this.options.disabled;
36168
36169		if ( disabled === true ) {
36170
36171			return;
36172
36173		}
36174
36175
36176
36177		if ( index === undefined ) {
36178
36179			disabled = true;
36180
36181		} else {
36182
36183			index = this._getIndex( index );
36184
36185			if ( $.inArray( index, disabled ) !== -1 ) {
36186
36187				return;
36188
36189			}
36190
36191			if ( $.isArray( disabled ) ) {
36192
36193				disabled = $.merge( [ index ], disabled ).sort();
36194
36195			} else {
36196
36197				disabled = [ index ];
36198
36199			}
36200
36201		}
36202
36203		this._setOptionDisabled( disabled );
36204
36205	},
36206
36207
36208
36209	load: function( index, event ) {
36210
36211		index = this._getIndex( index );
36212
36213		var that = this,
36214
36215			tab = this.tabs.eq( index ),
36216
36217			anchor = tab.find( ".ui-tabs-anchor" ),
36218
36219			panel = this._getPanelForTab( tab ),
36220
36221			eventData = {
36222
36223				tab: tab,
36224
36225				panel: panel
36226
36227			},
36228
36229			complete = function( jqXHR, status ) {
36230
36231				if ( status === "abort" ) {
36232
36233					that.panels.stop( false, true );
36234
36235				}
36236
36237
36238
36239				that._removeClass( tab, "ui-tabs-loading" );
36240
36241				panel.removeAttr( "aria-busy" );
36242
36243
36244
36245				if ( jqXHR === that.xhr ) {
36246
36247					delete that.xhr;
36248
36249				}
36250
36251			};
36252
36253
36254
36255		// Not remote
36256
36257		if ( this._isLocal( anchor[ 0 ] ) ) {
36258
36259			return;
36260
36261		}
36262
36263
36264
36265		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
36266
36267
36268
36269		// Support: jQuery <1.8
36270
36271		// jQuery <1.8 returns false if the request is canceled in beforeSend,
36272
36273		// but as of 1.8, $.ajax() always returns a jqXHR object.
36274
36275		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
36276
36277			this._addClass( tab, "ui-tabs-loading" );
36278
36279			panel.attr( "aria-busy", "true" );
36280
36281
36282
36283			this.xhr
36284
36285				.done( function( response, status, jqXHR ) {
36286
36287
36288
36289					// support: jQuery <1.8
36290
36291					// http://bugs.jquery.com/ticket/11778
36292
36293					setTimeout( function() {
36294
36295						panel.html( response );
36296
36297						that._trigger( "load", event, eventData );
36298
36299
36300
36301						complete( jqXHR, status );
36302
36303					}, 1 );
36304
36305				} )
36306
36307				.fail( function( jqXHR, status ) {
36308
36309
36310
36311					// support: jQuery <1.8
36312
36313					// http://bugs.jquery.com/ticket/11778
36314
36315					setTimeout( function() {
36316
36317						complete( jqXHR, status );
36318
36319					}, 1 );
36320
36321				} );
36322
36323		}
36324
36325	},
36326
36327
36328
36329	_ajaxSettings: function( anchor, event, eventData ) {
36330
36331		var that = this;
36332
36333		return {
36334
36335
36336
36337			// Support: IE <11 only
36338
36339			// Strip any hash that exists to prevent errors with the Ajax request
36340
36341			url: anchor.attr( "href" ).replace( /#.*$/, "" ),
36342
36343			beforeSend: function( jqXHR, settings ) {
36344
36345				return that._trigger( "beforeLoad", event,
36346
36347					$.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
36348
36349			}
36350
36351		};
36352
36353	},
36354
36355
36356
36357	_getPanelForTab: function( tab ) {
36358
36359		var id = $( tab ).attr( "aria-controls" );
36360
36361		return this.element.find( this._sanitizeSelector( "#" + id ) );
36362
36363	}
36364
36365} );
36366
36367
36368
36369// DEPRECATED
36370
36371// TODO: Switch return back to widget declaration at top of file when this is removed
36372
36373if ( $.uiBackCompat !== false ) {
36374
36375
36376
36377	// Backcompat for ui-tab class (now ui-tabs-tab)
36378
36379	$.widget( "ui.tabs", $.ui.tabs, {
36380
36381		_processTabs: function() {
36382
36383			this._superApply( arguments );
36384
36385			this._addClass( this.tabs, "ui-tab" );
36386
36387		}
36388
36389	} );
36390
36391}
36392
36393
36394
36395var widgetsTabs = $.ui.tabs;
36396
36397
36398
36399
36400
36401/*!
36402
36403 * jQuery UI Tooltip 1.12.1
36404
36405 * http://jqueryui.com
36406
36407 *
36408
36409 * Copyright jQuery Foundation and other contributors
36410
36411 * Released under the MIT license.
36412
36413 * http://jquery.org/license
36414
36415 */
36416
36417
36418
36419//>>label: Tooltip
36420
36421//>>group: Widgets
36422
36423//>>description: Shows additional information for any element on hover or focus.
36424
36425//>>docs: http://api.jqueryui.com/tooltip/
36426
36427//>>demos: http://jqueryui.com/tooltip/
36428
36429//>>css.structure: ../../themes/base/core.css
36430
36431//>>css.structure: ../../themes/base/tooltip.css
36432
36433//>>css.theme: ../../themes/base/theme.css
36434
36435
36436
36437
36438
36439
36440
36441$.widget( "ui.tooltip", {
36442
36443	version: "1.12.1",
36444
36445	options: {
36446
36447		classes: {
36448
36449			"ui-tooltip": "ui-corner-all ui-widget-shadow"
36450
36451		},
36452
36453		content: function() {
36454
36455
36456
36457			// support: IE<9, Opera in jQuery <1.7
36458
36459			// .text() can't accept undefined, so coerce to a string
36460
36461			var title = $( this ).attr( "title" ) || "";
36462
36463
36464
36465			// Escape title, since we're going from an attribute to raw HTML
36466
36467			return $( "<a>" ).text( title ).html();
36468
36469		},
36470
36471		hide: true,
36472
36473
36474
36475		// Disabled elements have inconsistent behavior across browsers (#8661)
36476
36477		items: "[title]:not([disabled])",
36478
36479		position: {
36480
36481			my: "left top+15",
36482
36483			at: "left bottom",
36484
36485			collision: "flipfit flip"
36486
36487		},
36488
36489		show: true,
36490
36491		track: false,
36492
36493
36494
36495		// Callbacks
36496
36497		close: null,
36498
36499		open: null
36500
36501	},
36502
36503
36504
36505	_addDescribedBy: function( elem, id ) {
36506
36507		var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ );
36508
36509		describedby.push( id );
36510
36511		elem
36512
36513			.data( "ui-tooltip-id", id )
36514
36515			.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
36516
36517	},
36518
36519
36520
36521	_removeDescribedBy: function( elem ) {
36522
36523		var id = elem.data( "ui-tooltip-id" ),
36524
36525			describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ),
36526
36527			index = $.inArray( id, describedby );
36528
36529
36530
36531		if ( index !== -1 ) {
36532
36533			describedby.splice( index, 1 );
36534
36535		}
36536
36537
36538
36539		elem.removeData( "ui-tooltip-id" );
36540
36541		describedby = $.trim( describedby.join( " " ) );
36542
36543		if ( describedby ) {
36544
36545			elem.attr( "aria-describedby", describedby );
36546
36547		} else {
36548
36549			elem.removeAttr( "aria-describedby" );
36550
36551		}
36552
36553	},
36554
36555
36556
36557	_create: function() {
36558
36559		this._on( {
36560
36561			mouseover: "open",
36562
36563			focusin: "open"
36564
36565		} );
36566
36567
36568
36569		// IDs of generated tooltips, needed for destroy
36570
36571		this.tooltips = {};
36572
36573
36574
36575		// IDs of parent tooltips where we removed the title attribute
36576
36577		this.parents = {};
36578
36579
36580
36581		// Append the aria-live region so tooltips announce correctly
36582
36583		this.liveRegion = $( "<div>" )
36584
36585			.attr( {
36586
36587				role: "log",
36588
36589				"aria-live": "assertive",
36590
36591				"aria-relevant": "additions"
36592
36593			} )
36594
36595			.appendTo( this.document[ 0 ].body );
36596
36597		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
36598
36599
36600
36601		this.disabledTitles = $( [] );
36602
36603	},
36604
36605
36606
36607	_setOption: function( key, value ) {
36608
36609		var that = this;
36610
36611
36612
36613		this._super( key, value );
36614
36615
36616
36617		if ( key === "content" ) {
36618
36619			$.each( this.tooltips, function( id, tooltipData ) {
36620
36621				that._updateContent( tooltipData.element );
36622
36623			} );
36624
36625		}
36626
36627	},
36628
36629
36630
36631	_setOptionDisabled: function( value ) {
36632
36633		this[ value ? "_disable" : "_enable" ]();
36634
36635	},
36636
36637
36638
36639	_disable: function() {
36640
36641		var that = this;
36642
36643
36644
36645		// Close open tooltips
36646
36647		$.each( this.tooltips, function( id, tooltipData ) {
36648
36649			var event = $.Event( "blur" );
36650
36651			event.target = event.currentTarget = tooltipData.element[ 0 ];
36652
36653			that.close( event, true );
36654
36655		} );
36656
36657
36658
36659		// Remove title attributes to prevent native tooltips
36660
36661		this.disabledTitles = this.disabledTitles.add(
36662
36663			this.element.find( this.options.items ).addBack()
36664
36665				.filter( function() {
36666
36667					var element = $( this );
36668
36669					if ( element.is( "[title]" ) ) {
36670
36671						return element
36672
36673							.data( "ui-tooltip-title", element.attr( "title" ) )
36674
vendor: 4,132 bytes, lines 36675-36928
36675							.removeAttr( "title" );
36676
36677					}
36678
36679				} )
36680
36681		);
36682
36683	},
36684
36685
36686
36687	_enable: function() {
36688
36689
36690
36691		// restore title attributes
36692
36693		this.disabledTitles.each( function() {
36694
36695			var element = $( this );
36696
36697			if ( element.data( "ui-tooltip-title" ) ) {
36698
36699				element.attr( "title", element.data( "ui-tooltip-title" ) );
36700
36701			}
36702
36703		} );
36704
36705		this.disabledTitles = $( [] );
36706
36707	},
36708
36709
36710
36711	open: function( event ) {
36712
36713		var that = this,
36714
36715			target = $( event ? event.target : this.element )
36716
36717
36718
36719				// we need closest here due to mouseover bubbling,
36720
36721				// but always pointing at the same event target
36722
36723				.closest( this.options.items );
36724
36725
36726
36727		// No element to show a tooltip for or the tooltip is already open
36728
36729		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
36730
36731			return;
36732
36733		}
36734
36735
36736
36737		if ( target.attr( "title" ) ) {
36738
36739			target.data( "ui-tooltip-title", target.attr( "title" ) );
36740
36741		}
36742
36743
36744
36745		target.data( "ui-tooltip-open", true );
36746
36747
36748
36749		// Kill parent tooltips, custom or native, for hover
36750
36751		if ( event && event.type === "mouseover" ) {
36752
36753			target.parents().each( function() {
36754
36755				var parent = $( this ),
36756
36757					blurEvent;
36758
36759				if ( parent.data( "ui-tooltip-open" ) ) {
36760
36761					blurEvent = $.Event( "blur" );
36762
36763					blurEvent.target = blurEvent.currentTarget = this;
36764
36765					that.close( blurEvent, true );
36766
36767				}
36768
36769				if ( parent.attr( "title" ) ) {
36770
36771					parent.uniqueId();
36772
36773					that.parents[ this.id ] = {
36774
36775						element: this,
36776
36777						title: parent.attr( "title" )
36778
36779					};
36780
36781					parent.attr( "title", "" );
36782
36783				}
36784
36785			} );
36786
36787		}
36788
36789
36790
36791		this._registerCloseHandlers( event, target );
36792
36793		this._updateContent( target, event );
36794
36795	},
36796
36797
36798
36799	_updateContent: function( target, event ) {
36800
36801		var content,
36802
36803			contentOption = this.options.content,
36804
36805			that = this,
36806
36807			eventType = event ? event.type : null;
36808
36809
36810
36811		if ( typeof contentOption === "string" || contentOption.nodeType ||
36812
36813				contentOption.jquery ) {
36814
36815			return this._open( event, target, contentOption );
36816
36817		}
36818
36819
36820
36821		content = contentOption.call( target[ 0 ], function( response ) {
36822
36823
36824
36825			// IE may instantly serve a cached response for ajax requests
36826
36827			// delay this call to _open so the other call to _open runs first
36828
36829			that._delay( function() {
36830
36831
36832
36833				// Ignore async response if tooltip was closed already
36834
36835				if ( !target.data( "ui-tooltip-open" ) ) {
36836
36837					return;
36838
36839				}
36840
36841
36842
36843				// JQuery creates a special event for focusin when it doesn't
36844
36845				// exist natively. To improve performance, the native event
36846
36847				// object is reused and the type is changed. Therefore, we can't
36848
36849				// rely on the type being correct after the event finished
36850
36851				// bubbling, so we set it back to the previous value. (#8740)
36852
36853				if ( event ) {
36854
36855					event.type = eventType;
36856
36857				}
36858
36859				this._open( event, target, response );
36860
36861			} );
36862
36863		} );
36864
36865		if ( content ) {
36866
36867			this._open( event, target, content );
36868
36869		}
36870
36871	},
36872
36873
36874
36875	_open: function( event, target, content ) {
36876
36877		var tooltipData, tooltip, delayedShow, a11yContent,
36878
36879			positionOption = $.extend( {}, this.options.position );
36880
36881
36882
36883		if ( !content ) {
36884
36885			return;
36886
36887		}
36888
36889
36890
36891		// Content can be updated multiple times. If the tooltip already
36892
36893		// exists, then just update the content and bail.
36894
36895		tooltipData = this._find( target );
36896
36897		if ( tooltipData ) {
36898
36899			tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
36900
36901			return;
36902
36903		}
36904
36905
36906
36907		// If we have a title, clear it to prevent the native tooltip
36908
36909		// we have to check first to avoid defining a title if none exists
36910
36911		// (we don't want to cause an element to start matching [title])
36912
36913		//
36914
36915		// We use removeAttr only for key events, to allow IE to export the correct
36916
36917		// accessible attributes. For mouse events, set to empty string to avoid
36918
36919		// native tooltip showing up (happens only when removing inside mouseover).
36920
36921		if ( target.is( "[title]" ) ) {
36922
36923			if ( event && event.type === "mouseover" ) {
36924
36925				target.attr( "title", "" );
36926
36927			} else {
36928
vendor: 7,521 bytes, lines 36929-37411
36929				target.removeAttr( "title" );
36930
36931			}
36932
36933		}
36934
36935
36936
36937		tooltipData = this._tooltip( target );
36938
36939		tooltip = tooltipData.tooltip;
36940
36941		this._addDescribedBy( target, tooltip.attr( "id" ) );
36942
36943		tooltip.find( ".ui-tooltip-content" ).html( content );
36944
36945
36946
36947		// Support: Voiceover on OS X, JAWS on IE <= 9
36948
36949		// JAWS announces deletions even when aria-relevant="additions"
36950
36951		// Voiceover will sometimes re-read the entire log region's contents from the beginning
36952
36953		this.liveRegion.children().hide();
36954
36955		a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() );
36956
36957		a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" );
36958
36959		a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
36960
36961		a11yContent.appendTo( this.liveRegion );
36962
36963
36964
36965		function position( event ) {
36966
36967			positionOption.of = event;
36968
36969			if ( tooltip.is( ":hidden" ) ) {
36970
36971				return;
36972
36973			}
36974
36975			tooltip.position( positionOption );
36976
36977		}
36978
36979		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
36980
36981			this._on( this.document, {
36982
36983				mousemove: position
36984
36985			} );
36986
36987
36988
36989			// trigger once to override element-relative positioning
36990
36991			position( event );
36992
36993		} else {
36994
36995			tooltip.position( $.extend( {
36996
36997				of: target
36998
36999			}, this.options.position ) );
37000
37001		}
37002
37003
37004
37005		tooltip.hide();
37006
37007
37008
37009		this._show( tooltip, this.options.show );
37010
37011
37012
37013		// Handle tracking tooltips that are shown with a delay (#8644). As soon
37014
37015		// as the tooltip is visible, position the tooltip using the most recent
37016
37017		// event.
37018
37019		// Adds the check to add the timers only when both delay and track options are set (#14682)
37020
37021		if ( this.options.track && this.options.show && this.options.show.delay ) {
37022
37023			delayedShow = this.delayedShow = setInterval( function() {
37024
37025				if ( tooltip.is( ":visible" ) ) {
37026
37027					position( positionOption.of );
37028
37029					clearInterval( delayedShow );
37030
37031				}
37032
37033			}, $.fx.interval );
37034
37035		}
37036
37037
37038
37039		this._trigger( "open", event, { tooltip: tooltip } );
37040
37041	},
37042
37043
37044
37045	_registerCloseHandlers: function( event, target ) {
37046
37047		var events = {
37048
37049			keyup: function( event ) {
37050
37051				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
37052
37053					var fakeEvent = $.Event( event );
37054
37055					fakeEvent.currentTarget = target[ 0 ];
37056
37057					this.close( fakeEvent, true );
37058
37059				}
37060
37061			}
37062
37063		};
37064
37065
37066
37067		// Only bind remove handler for delegated targets. Non-delegated
37068
37069		// tooltips will handle this in destroy.
37070
37071		if ( target[ 0 ] !== this.element[ 0 ] ) {
37072
37073			events.remove = function() {
37074
37075				this._removeTooltip( this._find( target ).tooltip );
37076
37077			};
37078
37079		}
37080
37081
37082
37083		if ( !event || event.type === "mouseover" ) {
37084
37085			events.mouseleave = "close";
37086
37087		}
37088
37089		if ( !event || event.type === "focusin" ) {
37090
37091			events.focusout = "close";
37092
37093		}
37094
37095		this._on( true, target, events );
37096
37097	},
37098
37099
37100
37101	close: function( event ) {
37102
37103		var tooltip,
37104
37105			that = this,
37106
37107			target = $( event ? event.currentTarget : this.element ),
37108
37109			tooltipData = this._find( target );
37110
37111
37112
37113		// The tooltip may already be closed
37114
37115		if ( !tooltipData ) {
37116
37117
37118
37119			// We set ui-tooltip-open immediately upon open (in open()), but only set the
37120
37121			// additional data once there's actually content to show (in _open()). So even if the
37122
37123			// tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
37124
37125			// the period between open() and _open().
37126
37127			target.removeData( "ui-tooltip-open" );
37128
37129			return;
37130
37131		}
37132
37133
37134
37135		tooltip = tooltipData.tooltip;
37136
37137
37138
37139		// Disabling closes the tooltip, so we need to track when we're closing
37140
37141		// to avoid an infinite loop in case the tooltip becomes disabled on close
37142
37143		if ( tooltipData.closing ) {
37144
37145			return;
37146
37147		}
37148
37149
37150
37151		// Clear the interval for delayed tracking tooltips
37152
37153		clearInterval( this.delayedShow );
37154
37155
37156
37157		// Only set title if we had one before (see comment in _open())
37158
37159		// If the title attribute has changed since open(), don't restore
37160
37161		if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
37162
37163			target.attr( "title", target.data( "ui-tooltip-title" ) );
37164
37165		}
37166
37167
37168
37169		this._removeDescribedBy( target );
37170
37171
37172
37173		tooltipData.hiding = true;
37174
37175		tooltip.stop( true );
37176
37177		this._hide( tooltip, this.options.hide, function() {
37178
37179			that._removeTooltip( $( this ) );
37180
37181		} );
37182
37183
37184
37185		target.removeData( "ui-tooltip-open" );
37186
37187		this._off( target, "mouseleave focusout keyup" );
37188
37189
37190
37191		// Remove 'remove' binding only on delegated targets
37192
37193		if ( target[ 0 ] !== this.element[ 0 ] ) {
37194
37195			this._off( target, "remove" );
37196
37197		}
37198
37199		this._off( this.document, "mousemove" );
37200
37201
37202
37203		if ( event && event.type === "mouseleave" ) {
37204
37205			$.each( this.parents, function( id, parent ) {
37206
37207				$( parent.element ).attr( "title", parent.title );
37208
37209				delete that.parents[ id ];
37210
37211			} );
37212
37213		}
37214
37215
37216
37217		tooltipData.closing = true;
37218
37219		this._trigger( "close", event, { tooltip: tooltip } );
37220
37221		if ( !tooltipData.hiding ) {
37222
37223			tooltipData.closing = false;
37224
37225		}
37226
37227	},
37228
37229
37230
37231	_tooltip: function( element ) {
37232
37233		var tooltip = $( "<div>" ).attr( "role", "tooltip" ),
37234
37235			content = $( "<div>" ).appendTo( tooltip ),
37236
37237			id = tooltip.uniqueId().attr( "id" );
37238
37239
37240
37241		this._addClass( content, "ui-tooltip-content" );
37242
37243		this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" );
37244
37245
37246
37247		tooltip.appendTo( this._appendTo( element ) );
37248
37249
37250
37251		return this.tooltips[ id ] = {
37252
37253			element: element,
37254
37255			tooltip: tooltip
37256
37257		};
37258
37259	},
37260
37261
37262
37263	_find: function( target ) {
37264
37265		var id = target.data( "ui-tooltip-id" );
37266
37267		return id ? this.tooltips[ id ] : null;
37268
37269	},
37270
37271
37272
37273	_removeTooltip: function( tooltip ) {
37274
37275		tooltip.remove();
37276
37277		delete this.tooltips[ tooltip.attr( "id" ) ];
37278
37279	},
37280
37281
37282
37283	_appendTo: function( target ) {
37284
37285		var element = target.closest( ".ui-front, dialog" );
37286
37287
37288
37289		if ( !element.length ) {
37290
37291			element = this.document[ 0 ].body;
37292
37293		}
37294
37295
37296
37297		return element;
37298
37299	},
37300
37301
37302
37303	_destroy: function() {
37304
37305		var that = this;
37306
37307
37308
37309		// Close open tooltips
37310
37311		$.each( this.tooltips, function( id, tooltipData ) {
37312
37313
37314
37315			// Delegate to close method to handle common cleanup
37316
37317			var event = $.Event( "blur" ),
37318
37319				element = tooltipData.element;
37320
37321			event.target = event.currentTarget = element[ 0 ];
37322
37323			that.close( event, true );
37324
37325
37326
37327			// Remove immediately; destroying an open tooltip doesn't use the
37328
37329			// hide animation
37330
37331			$( "#" + id ).remove();
37332
37333
37334
37335			// Restore the title
37336
37337			if ( element.data( "ui-tooltip-title" ) ) {
37338
37339
37340
37341				// If the title attribute has changed since open(), don't restore
37342
37343				if ( !element.attr( "title" ) ) {
37344
37345					element.attr( "title", element.data( "ui-tooltip-title" ) );
37346
37347				}
37348
37349				element.removeData( "ui-tooltip-title" );
37350
37351			}
37352
37353		} );
37354
37355		this.liveRegion.remove();
37356
37357	}
37358
37359} );
37360
37361
37362
37363// DEPRECATED
37364
37365// TODO: Switch return back to widget declaration at top of file when this is removed
37366
37367if ( $.uiBackCompat !== false ) {
37368
37369
37370
37371	// Backcompat for tooltipClass option
37372
37373	$.widget( "ui.tooltip", $.ui.tooltip, {
37374
37375		options: {
37376
37377			tooltipClass: null
37378
37379		},
37380
37381		_tooltip: function() {
37382
37383			var tooltipData = this._superApply( arguments );
37384
37385			if ( this.options.tooltipClass ) {
37386
37387				tooltipData.tooltip.addClass( this.options.tooltipClass );
37388
37389			}
37390
37391			return tooltipData;
37392
37393		}
37394
37395	} );
37396
37397}
37398
37399
37400
37401var widgetsTooltip = $.ui.tooltip;
37402
37403
37404
37405
37406
37407
37408
37409
37410
37411}));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.