src/eric7/WebBrowser/data/javascript/jquery-ui.js

branch
eric7
changeset 9678
32ddecc54baf
parent 9209
b99e7fd55fd3
equal deleted inserted replaced
9677:916fe5dddbb0 9678:32ddecc54baf
1 /*! jQuery UI - v1.13.2 - 2022-07-14
2 * http://jqueryui.com
3 * Includes: widget.js, position.js, data.js, disable-selection.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js, focusable.js, form-reset-mixin.js, jquery-patch.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/draggable.js, widgets/droppable.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/resizable.js, widgets/selectable.js, widgets/selectmenu.js, widgets/slider.js, widgets/sortable.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js
4 * Copyright jQuery Foundation and other contributors; Licensed MIT */
5
6 ( function( factory ) {
7 "use strict";
8
9 if ( typeof define === "function" && define.amd ) {
10
11 // AMD. Register as an anonymous module.
12 define( [ "jquery" ], factory );
13 } else {
14
15 // Browser globals
16 factory( jQuery );
17 }
18 } )( function( $ ) {
19 "use strict";
20
21 $.ui = $.ui || {};
22
23 var version = $.ui.version = "1.13.2";
24
25
1 /*! 26 /*!
2 * jQuery UI 1.8.16 27 * jQuery UI Widget 1.13.2
28 * http://jqueryui.com
3 * 29 *
4 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 30 * Copyright jQuery Foundation and other contributors
5 * Dual licensed under the MIT or GPL Version 2 licenses. 31 * Released under the MIT license.
32 * http://jquery.org/license
33 */
34
35 //>>label: Widget
36 //>>group: Core
37 //>>description: Provides a factory for creating stateful widgets with a common API.
38 //>>docs: http://api.jqueryui.com/jQuery.widget/
39 //>>demos: http://jqueryui.com/widget/
40
41
42 var widgetUuid = 0;
43 var widgetHasOwnProperty = Array.prototype.hasOwnProperty;
44 var widgetSlice = Array.prototype.slice;
45
46 $.cleanData = ( function( orig ) {
47 return function( elems ) {
48 var events, elem, i;
49 for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
50
51 // Only trigger remove when necessary to save time
52 events = $._data( elem, "events" );
53 if ( events && events.remove ) {
54 $( elem ).triggerHandler( "remove" );
55 }
56 }
57 orig( elems );
58 };
59 } )( $.cleanData );
60
61 $.widget = function( name, base, prototype ) {
62 var existingConstructor, constructor, basePrototype;
63
64 // ProxiedPrototype allows the provided prototype to remain unmodified
65 // so that it can be used as a mixin for multiple widgets (#8876)
66 var proxiedPrototype = {};
67
68 var namespace = name.split( "." )[ 0 ];
69 name = name.split( "." )[ 1 ];
70 var fullName = namespace + "-" + name;
71
72 if ( !prototype ) {
73 prototype = base;
74 base = $.Widget;
75 }
76
77 if ( Array.isArray( prototype ) ) {
78 prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
79 }
80
81 // Create selector for plugin
82 $.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) {
83 return !!$.data( elem, fullName );
84 };
85
86 $[ namespace ] = $[ namespace ] || {};
87 existingConstructor = $[ namespace ][ name ];
88 constructor = $[ namespace ][ name ] = function( options, element ) {
89
90 // Allow instantiation without "new" keyword
91 if ( !this || !this._createWidget ) {
92 return new constructor( options, element );
93 }
94
95 // Allow instantiation without initializing for simple inheritance
96 // must use "new" keyword (the code above always passes args)
97 if ( arguments.length ) {
98 this._createWidget( options, element );
99 }
100 };
101
102 // Extend with the existing constructor to carry over any static properties
103 $.extend( constructor, existingConstructor, {
104 version: prototype.version,
105
106 // Copy the object used to create the prototype in case we need to
107 // redefine the widget later
108 _proto: $.extend( {}, prototype ),
109
110 // Track widgets that inherit from this widget in case this widget is
111 // redefined after a widget inherits from it
112 _childConstructors: []
113 } );
114
115 basePrototype = new base();
116
117 // We need to make the options hash a property directly on the new instance
118 // otherwise we'll modify the options hash on the prototype that we're
119 // inheriting from
120 basePrototype.options = $.widget.extend( {}, basePrototype.options );
121 $.each( prototype, function( prop, value ) {
122 if ( typeof value !== "function" ) {
123 proxiedPrototype[ prop ] = value;
124 return;
125 }
126 proxiedPrototype[ prop ] = ( function() {
127 function _super() {
128 return base.prototype[ prop ].apply( this, arguments );
129 }
130
131 function _superApply( args ) {
132 return base.prototype[ prop ].apply( this, args );
133 }
134
135 return function() {
136 var __super = this._super;
137 var __superApply = this._superApply;
138 var returnValue;
139
140 this._super = _super;
141 this._superApply = _superApply;
142
143 returnValue = value.apply( this, arguments );
144
145 this._super = __super;
146 this._superApply = __superApply;
147
148 return returnValue;
149 };
150 } )();
151 } );
152 constructor.prototype = $.widget.extend( basePrototype, {
153
154 // TODO: remove support for widgetEventPrefix
155 // always use the name + a colon as the prefix, e.g., draggable:start
156 // don't prefix for widgets that aren't DOM-based
157 widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
158 }, proxiedPrototype, {
159 constructor: constructor,
160 namespace: namespace,
161 widgetName: name,
162 widgetFullName: fullName
163 } );
164
165 // If this widget is being redefined then we need to find all widgets that
166 // are inheriting from it and redefine all of them so that they inherit from
167 // the new version of this widget. We're essentially trying to replace one
168 // level in the prototype chain.
169 if ( existingConstructor ) {
170 $.each( existingConstructor._childConstructors, function( i, child ) {
171 var childPrototype = child.prototype;
172
173 // Redefine the child widget using the same prototype that was
174 // originally used, but inherit from the new version of the base
175 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
176 child._proto );
177 } );
178
179 // Remove the list of existing child constructors from the old constructor
180 // so the old child constructors can be garbage collected
181 delete existingConstructor._childConstructors;
182 } else {
183 base._childConstructors.push( constructor );
184 }
185
186 $.widget.bridge( name, constructor );
187
188 return constructor;
189 };
190
191 $.widget.extend = function( target ) {
192 var input = widgetSlice.call( arguments, 1 );
193 var inputIndex = 0;
194 var inputLength = input.length;
195 var key;
196 var value;
197
198 for ( ; inputIndex < inputLength; inputIndex++ ) {
199 for ( key in input[ inputIndex ] ) {
200 value = input[ inputIndex ][ key ];
201 if ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) {
202
203 // Clone objects
204 if ( $.isPlainObject( value ) ) {
205 target[ key ] = $.isPlainObject( target[ key ] ) ?
206 $.widget.extend( {}, target[ key ], value ) :
207
208 // Don't extend strings, arrays, etc. with objects
209 $.widget.extend( {}, value );
210
211 // Copy everything else by reference
212 } else {
213 target[ key ] = value;
214 }
215 }
216 }
217 }
218 return target;
219 };
220
221 $.widget.bridge = function( name, object ) {
222 var fullName = object.prototype.widgetFullName || name;
223 $.fn[ name ] = function( options ) {
224 var isMethodCall = typeof options === "string";
225 var args = widgetSlice.call( arguments, 1 );
226 var returnValue = this;
227
228 if ( isMethodCall ) {
229
230 // If this is an empty collection, we need to have the instance method
231 // return undefined instead of the jQuery instance
232 if ( !this.length && options === "instance" ) {
233 returnValue = undefined;
234 } else {
235 this.each( function() {
236 var methodValue;
237 var instance = $.data( this, fullName );
238
239 if ( options === "instance" ) {
240 returnValue = instance;
241 return false;
242 }
243
244 if ( !instance ) {
245 return $.error( "cannot call methods on " + name +
246 " prior to initialization; " +
247 "attempted to call method '" + options + "'" );
248 }
249
250 if ( typeof instance[ options ] !== "function" ||
251 options.charAt( 0 ) === "_" ) {
252 return $.error( "no such method '" + options + "' for " + name +
253 " widget instance" );
254 }
255
256 methodValue = instance[ options ].apply( instance, args );
257
258 if ( methodValue !== instance && methodValue !== undefined ) {
259 returnValue = methodValue && methodValue.jquery ?
260 returnValue.pushStack( methodValue.get() ) :
261 methodValue;
262 return false;
263 }
264 } );
265 }
266 } else {
267
268 // Allow multiple hashes to be passed on init
269 if ( args.length ) {
270 options = $.widget.extend.apply( null, [ options ].concat( args ) );
271 }
272
273 this.each( function() {
274 var instance = $.data( this, fullName );
275 if ( instance ) {
276 instance.option( options || {} );
277 if ( instance._init ) {
278 instance._init();
279 }
280 } else {
281 $.data( this, fullName, new object( options, this ) );
282 }
283 } );
284 }
285
286 return returnValue;
287 };
288 };
289
290 $.Widget = function( /* options, element */ ) {};
291 $.Widget._childConstructors = [];
292
293 $.Widget.prototype = {
294 widgetName: "widget",
295 widgetEventPrefix: "",
296 defaultElement: "<div>",
297
298 options: {
299 classes: {},
300 disabled: false,
301
302 // Callbacks
303 create: null
304 },
305
306 _createWidget: function( options, element ) {
307 element = $( element || this.defaultElement || this )[ 0 ];
308 this.element = $( element );
309 this.uuid = widgetUuid++;
310 this.eventNamespace = "." + this.widgetName + this.uuid;
311
312 this.bindings = $();
313 this.hoverable = $();
314 this.focusable = $();
315 this.classesElementLookup = {};
316
317 if ( element !== this ) {
318 $.data( element, this.widgetFullName, this );
319 this._on( true, this.element, {
320 remove: function( event ) {
321 if ( event.target === element ) {
322 this.destroy();
323 }
324 }
325 } );
326 this.document = $( element.style ?
327
328 // Element within the document
329 element.ownerDocument :
330
331 // Element is window or document
332 element.document || element );
333 this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
334 }
335
336 this.options = $.widget.extend( {},
337 this.options,
338 this._getCreateOptions(),
339 options );
340
341 this._create();
342
343 if ( this.options.disabled ) {
344 this._setOptionDisabled( this.options.disabled );
345 }
346
347 this._trigger( "create", null, this._getCreateEventData() );
348 this._init();
349 },
350
351 _getCreateOptions: function() {
352 return {};
353 },
354
355 _getCreateEventData: $.noop,
356
357 _create: $.noop,
358
359 _init: $.noop,
360
361 destroy: function() {
362 var that = this;
363
364 this._destroy();
365 $.each( this.classesElementLookup, function( key, value ) {
366 that._removeClass( value, key );
367 } );
368
369 // We can probably remove the unbind calls in 2.0
370 // all event bindings should go through this._on()
371 this.element
372 .off( this.eventNamespace )
373 .removeData( this.widgetFullName );
374 this.widget()
375 .off( this.eventNamespace )
376 .removeAttr( "aria-disabled" );
377
378 // Clean up events and states
379 this.bindings.off( this.eventNamespace );
380 },
381
382 _destroy: $.noop,
383
384 widget: function() {
385 return this.element;
386 },
387
388 option: function( key, value ) {
389 var options = key;
390 var parts;
391 var curOption;
392 var i;
393
394 if ( arguments.length === 0 ) {
395
396 // Don't return a reference to the internal hash
397 return $.widget.extend( {}, this.options );
398 }
399
400 if ( typeof key === "string" ) {
401
402 // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
403 options = {};
404 parts = key.split( "." );
405 key = parts.shift();
406 if ( parts.length ) {
407 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
408 for ( i = 0; i < parts.length - 1; i++ ) {
409 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
410 curOption = curOption[ parts[ i ] ];
411 }
412 key = parts.pop();
413 if ( arguments.length === 1 ) {
414 return curOption[ key ] === undefined ? null : curOption[ key ];
415 }
416 curOption[ key ] = value;
417 } else {
418 if ( arguments.length === 1 ) {
419 return this.options[ key ] === undefined ? null : this.options[ key ];
420 }
421 options[ key ] = value;
422 }
423 }
424
425 this._setOptions( options );
426
427 return this;
428 },
429
430 _setOptions: function( options ) {
431 var key;
432
433 for ( key in options ) {
434 this._setOption( key, options[ key ] );
435 }
436
437 return this;
438 },
439
440 _setOption: function( key, value ) {
441 if ( key === "classes" ) {
442 this._setOptionClasses( value );
443 }
444
445 this.options[ key ] = value;
446
447 if ( key === "disabled" ) {
448 this._setOptionDisabled( value );
449 }
450
451 return this;
452 },
453
454 _setOptionClasses: function( value ) {
455 var classKey, elements, currentElements;
456
457 for ( classKey in value ) {
458 currentElements = this.classesElementLookup[ classKey ];
459 if ( value[ classKey ] === this.options.classes[ classKey ] ||
460 !currentElements ||
461 !currentElements.length ) {
462 continue;
463 }
464
465 // We are doing this to create a new jQuery object because the _removeClass() call
466 // on the next line is going to destroy the reference to the current elements being
467 // tracked. We need to save a copy of this collection so that we can add the new classes
468 // below.
469 elements = $( currentElements.get() );
470 this._removeClass( currentElements, classKey );
471
472 // We don't use _addClass() here, because that uses this.options.classes
473 // for generating the string of classes. We want to use the value passed in from
474 // _setOption(), this is the new value of the classes option which was passed to
475 // _setOption(). We pass this value directly to _classes().
476 elements.addClass( this._classes( {
477 element: elements,
478 keys: classKey,
479 classes: value,
480 add: true
481 } ) );
482 }
483 },
484
485 _setOptionDisabled: function( value ) {
486 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
487
488 // If the widget is becoming disabled, then nothing is interactive
489 if ( value ) {
490 this._removeClass( this.hoverable, null, "ui-state-hover" );
491 this._removeClass( this.focusable, null, "ui-state-focus" );
492 }
493 },
494
495 enable: function() {
496 return this._setOptions( { disabled: false } );
497 },
498
499 disable: function() {
500 return this._setOptions( { disabled: true } );
501 },
502
503 _classes: function( options ) {
504 var full = [];
505 var that = this;
506
507 options = $.extend( {
508 element: this.element,
509 classes: this.options.classes || {}
510 }, options );
511
512 function bindRemoveEvent() {
513 var nodesToBind = [];
514
515 options.element.each( function( _, element ) {
516 var isTracked = $.map( that.classesElementLookup, function( elements ) {
517 return elements;
518 } )
519 .some( function( elements ) {
520 return elements.is( element );
521 } );
522
523 if ( !isTracked ) {
524 nodesToBind.push( element );
525 }
526 } );
527
528 that._on( $( nodesToBind ), {
529 remove: "_untrackClassesElement"
530 } );
531 }
532
533 function processClassString( classes, checkOption ) {
534 var current, i;
535 for ( i = 0; i < classes.length; i++ ) {
536 current = that.classesElementLookup[ classes[ i ] ] || $();
537 if ( options.add ) {
538 bindRemoveEvent();
539 current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) );
540 } else {
541 current = $( current.not( options.element ).get() );
542 }
543 that.classesElementLookup[ classes[ i ] ] = current;
544 full.push( classes[ i ] );
545 if ( checkOption && options.classes[ classes[ i ] ] ) {
546 full.push( options.classes[ classes[ i ] ] );
547 }
548 }
549 }
550
551 if ( options.keys ) {
552 processClassString( options.keys.match( /\S+/g ) || [], true );
553 }
554 if ( options.extra ) {
555 processClassString( options.extra.match( /\S+/g ) || [] );
556 }
557
558 return full.join( " " );
559 },
560
561 _untrackClassesElement: function( event ) {
562 var that = this;
563 $.each( that.classesElementLookup, function( key, value ) {
564 if ( $.inArray( event.target, value ) !== -1 ) {
565 that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
566 }
567 } );
568
569 this._off( $( event.target ) );
570 },
571
572 _removeClass: function( element, keys, extra ) {
573 return this._toggleClass( element, keys, extra, false );
574 },
575
576 _addClass: function( element, keys, extra ) {
577 return this._toggleClass( element, keys, extra, true );
578 },
579
580 _toggleClass: function( element, keys, extra, add ) {
581 add = ( typeof add === "boolean" ) ? add : extra;
582 var shift = ( typeof element === "string" || element === null ),
583 options = {
584 extra: shift ? keys : extra,
585 keys: shift ? element : keys,
586 element: shift ? this.element : element,
587 add: add
588 };
589 options.element.toggleClass( this._classes( options ), add );
590 return this;
591 },
592
593 _on: function( suppressDisabledCheck, element, handlers ) {
594 var delegateElement;
595 var instance = this;
596
597 // No suppressDisabledCheck flag, shuffle arguments
598 if ( typeof suppressDisabledCheck !== "boolean" ) {
599 handlers = element;
600 element = suppressDisabledCheck;
601 suppressDisabledCheck = false;
602 }
603
604 // No element argument, shuffle and use this.element
605 if ( !handlers ) {
606 handlers = element;
607 element = this.element;
608 delegateElement = this.widget();
609 } else {
610 element = delegateElement = $( element );
611 this.bindings = this.bindings.add( element );
612 }
613
614 $.each( handlers, function( event, handler ) {
615 function handlerProxy() {
616
617 // Allow widgets to customize the disabled handling
618 // - disabled as an array instead of boolean
619 // - disabled class as method for disabling individual parts
620 if ( !suppressDisabledCheck &&
621 ( instance.options.disabled === true ||
622 $( this ).hasClass( "ui-state-disabled" ) ) ) {
623 return;
624 }
625 return ( typeof handler === "string" ? instance[ handler ] : handler )
626 .apply( instance, arguments );
627 }
628
629 // Copy the guid so direct unbinding works
630 if ( typeof handler !== "string" ) {
631 handlerProxy.guid = handler.guid =
632 handler.guid || handlerProxy.guid || $.guid++;
633 }
634
635 var match = event.match( /^([\w:-]*)\s*(.*)$/ );
636 var eventName = match[ 1 ] + instance.eventNamespace;
637 var selector = match[ 2 ];
638
639 if ( selector ) {
640 delegateElement.on( eventName, selector, handlerProxy );
641 } else {
642 element.on( eventName, handlerProxy );
643 }
644 } );
645 },
646
647 _off: function( element, eventName ) {
648 eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
649 this.eventNamespace;
650 element.off( eventName );
651
652 // Clear the stack to avoid memory leaks (#10056)
653 this.bindings = $( this.bindings.not( element ).get() );
654 this.focusable = $( this.focusable.not( element ).get() );
655 this.hoverable = $( this.hoverable.not( element ).get() );
656 },
657
658 _delay: function( handler, delay ) {
659 function handlerProxy() {
660 return ( typeof handler === "string" ? instance[ handler ] : handler )
661 .apply( instance, arguments );
662 }
663 var instance = this;
664 return setTimeout( handlerProxy, delay || 0 );
665 },
666
667 _hoverable: function( element ) {
668 this.hoverable = this.hoverable.add( element );
669 this._on( element, {
670 mouseenter: function( event ) {
671 this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
672 },
673 mouseleave: function( event ) {
674 this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
675 }
676 } );
677 },
678
679 _focusable: function( element ) {
680 this.focusable = this.focusable.add( element );
681 this._on( element, {
682 focusin: function( event ) {
683 this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
684 },
685 focusout: function( event ) {
686 this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
687 }
688 } );
689 },
690
691 _trigger: function( type, event, data ) {
692 var prop, orig;
693 var callback = this.options[ type ];
694
695 data = data || {};
696 event = $.Event( event );
697 event.type = ( type === this.widgetEventPrefix ?
698 type :
699 this.widgetEventPrefix + type ).toLowerCase();
700
701 // The original event may come from any element
702 // so we need to reset the target on the new event
703 event.target = this.element[ 0 ];
704
705 // Copy original event properties over to the new event
706 orig = event.originalEvent;
707 if ( orig ) {
708 for ( prop in orig ) {
709 if ( !( prop in event ) ) {
710 event[ prop ] = orig[ prop ];
711 }
712 }
713 }
714
715 this.element.trigger( event, data );
716 return !( typeof callback === "function" &&
717 callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
718 event.isDefaultPrevented() );
719 }
720 };
721
722 $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
723 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
724 if ( typeof options === "string" ) {
725 options = { effect: options };
726 }
727
728 var hasOptions;
729 var effectName = !options ?
730 method :
731 options === true || typeof options === "number" ?
732 defaultEffect :
733 options.effect || defaultEffect;
734
735 options = options || {};
736 if ( typeof options === "number" ) {
737 options = { duration: options };
738 } else if ( options === true ) {
739 options = {};
740 }
741
742 hasOptions = !$.isEmptyObject( options );
743 options.complete = callback;
744
745 if ( options.delay ) {
746 element.delay( options.delay );
747 }
748
749 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
750 element[ method ]( options );
751 } else if ( effectName !== method && element[ effectName ] ) {
752 element[ effectName ]( options.duration, options.easing, callback );
753 } else {
754 element.queue( function( next ) {
755 $( this )[ method ]();
756 if ( callback ) {
757 callback.call( element[ 0 ] );
758 }
759 next();
760 } );
761 }
762 };
763 } );
764
765 var widget = $.widget;
766
767
768 /*!
769 * jQuery UI Position 1.13.2
770 * http://jqueryui.com
771 *
772 * Copyright jQuery Foundation and other contributors
773 * Released under the MIT license.
6 * http://jquery.org/license 774 * http://jquery.org/license
7 * 775 *
8 * http://docs.jquery.com/UI 776 * http://api.jqueryui.com/position/
9 */ 777 */
10 (function(c,j){function k(a,b){var d=a.nodeName.toLowerCase();if("area"===d){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&l(a)}return(/input|select|textarea|button|object/.test(d)?!a.disabled:"a"==d?a.href||b:b)&&l(a)}function l(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.16", 778
11 keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({propAttr:c.fn.prop||c.fn.attr,_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d= 779 //>>label: Position
12 this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this, 780 //>>group: Core
13 "overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"),10);if(!isNaN(b)&&b!==0)return b}a=a.parent()}}return 0},disableSelection:function(){return this.bind((c.support.selectstart?"selectstart": 781 //>>description: Positions elements relative to other elements.
14 "mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});c.each(["Width","Height"],function(a,b){function d(f,g,m,n){c.each(e,function(){g-=parseFloat(c.curCSS(f,"padding"+this,true))||0;if(m)g-=parseFloat(c.curCSS(f,"border"+this+"Width",true))||0;if(n)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight, 782 //>>docs: http://api.jqueryui.com/position/
15 outerWidth:c.fn.outerWidth,outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c(this).css(h,d(this,f)+"px")})};c.fn["outer"+b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c(this).css(h,d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){return k(a,!isNaN(c.attr(a,"tabindex")))},tabbable:function(a){var b=c.attr(a, 783 //>>demos: http://jqueryui.com/position/
16 "tabindex"),d=isNaN(b);return(d||b>=0)&&k(a,!d)}});c(function(){var a=document.body,b=a.appendChild(b=document.createElement("div"));c.extend(b.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});c.support.minHeight=b.offsetHeight===100;c.support.selectstart="onselectstart"in b;a.removeChild(b).style.display="none"});c.extend(c.ui,{plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&& 784
17 a.element[0].parentNode)for(var e=0;e<b.length;e++)a.options[b[e][0]]&&b[e][1].apply(a.element,d)}},contains:function(a,b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(a,b){if(c(a).css("overflow")==="hidden")return false;b=b&&b==="left"?"scrollLeft":"scrollTop";var d=false;if(a[b]>0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a<b+d},isOver:function(a,b,d,e,h,i){return c.ui.isOverAxis(a,d,h)&& 785
18 c.ui.isOverAxis(b,e,i)}})}})(jQuery); 786 ( function() {
19 ;/*! 787 var cachedScrollbarWidth,
20 * jQuery UI Widget 1.8.16 788 max = Math.max,
789 abs = Math.abs,
790 rhorizontal = /left|center|right/,
791 rvertical = /top|center|bottom/,
792 roffset = /[\+\-]\d+(\.[\d]+)?%?/,
793 rposition = /^\w+/,
794 rpercent = /%$/,
795 _position = $.fn.position;
796
797 function getOffsets( offsets, width, height ) {
798 return [
799 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
800 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
801 ];
802 }
803
804 function parseCss( element, property ) {
805 return parseInt( $.css( element, property ), 10 ) || 0;
806 }
807
808 function isWindow( obj ) {
809 return obj != null && obj === obj.window;
810 }
811
812 function getDimensions( elem ) {
813 var raw = elem[ 0 ];
814 if ( raw.nodeType === 9 ) {
815 return {
816 width: elem.width(),
817 height: elem.height(),
818 offset: { top: 0, left: 0 }
819 };
820 }
821 if ( isWindow( raw ) ) {
822 return {
823 width: elem.width(),
824 height: elem.height(),
825 offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
826 };
827 }
828 if ( raw.preventDefault ) {
829 return {
830 width: 0,
831 height: 0,
832 offset: { top: raw.pageY, left: raw.pageX }
833 };
834 }
835 return {
836 width: elem.outerWidth(),
837 height: elem.outerHeight(),
838 offset: elem.offset()
839 };
840 }
841
842 $.position = {
843 scrollbarWidth: function() {
844 if ( cachedScrollbarWidth !== undefined ) {
845 return cachedScrollbarWidth;
846 }
847 var w1, w2,
848 div = $( "<div style=" +
849 "'display:block;position:absolute;width:200px;height:200px;overflow:hidden;'>" +
850 "<div style='height:300px;width:auto;'></div></div>" ),
851 innerDiv = div.children()[ 0 ];
852
853 $( "body" ).append( div );
854 w1 = innerDiv.offsetWidth;
855 div.css( "overflow", "scroll" );
856
857 w2 = innerDiv.offsetWidth;
858
859 if ( w1 === w2 ) {
860 w2 = div[ 0 ].clientWidth;
861 }
862
863 div.remove();
864
865 return ( cachedScrollbarWidth = w1 - w2 );
866 },
867 getScrollInfo: function( within ) {
868 var overflowX = within.isWindow || within.isDocument ? "" :
869 within.element.css( "overflow-x" ),
870 overflowY = within.isWindow || within.isDocument ? "" :
871 within.element.css( "overflow-y" ),
872 hasOverflowX = overflowX === "scroll" ||
873 ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ),
874 hasOverflowY = overflowY === "scroll" ||
875 ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight );
876 return {
877 width: hasOverflowY ? $.position.scrollbarWidth() : 0,
878 height: hasOverflowX ? $.position.scrollbarWidth() : 0
879 };
880 },
881 getWithinInfo: function( element ) {
882 var withinElement = $( element || window ),
883 isElemWindow = isWindow( withinElement[ 0 ] ),
884 isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,
885 hasOffset = !isElemWindow && !isDocument;
886 return {
887 element: withinElement,
888 isWindow: isElemWindow,
889 isDocument: isDocument,
890 offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },
891 scrollLeft: withinElement.scrollLeft(),
892 scrollTop: withinElement.scrollTop(),
893 width: withinElement.outerWidth(),
894 height: withinElement.outerHeight()
895 };
896 }
897 };
898
899 $.fn.position = function( options ) {
900 if ( !options || !options.of ) {
901 return _position.apply( this, arguments );
902 }
903
904 // Make a copy, we don't want to modify arguments
905 options = $.extend( {}, options );
906
907 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
908
909 // Make sure string options are treated as CSS selectors
910 target = typeof options.of === "string" ?
911 $( document ).find( options.of ) :
912 $( options.of ),
913
914 within = $.position.getWithinInfo( options.within ),
915 scrollInfo = $.position.getScrollInfo( within ),
916 collision = ( options.collision || "flip" ).split( " " ),
917 offsets = {};
918
919 dimensions = getDimensions( target );
920 if ( target[ 0 ].preventDefault ) {
921
922 // Force left top to allow flipping
923 options.at = "left top";
924 }
925 targetWidth = dimensions.width;
926 targetHeight = dimensions.height;
927 targetOffset = dimensions.offset;
928
929 // Clone to reuse original targetOffset later
930 basePosition = $.extend( {}, targetOffset );
931
932 // Force my and at to have valid horizontal and vertical positions
933 // if a value is missing or invalid, it will be converted to center
934 $.each( [ "my", "at" ], function() {
935 var pos = ( options[ this ] || "" ).split( " " ),
936 horizontalOffset,
937 verticalOffset;
938
939 if ( pos.length === 1 ) {
940 pos = rhorizontal.test( pos[ 0 ] ) ?
941 pos.concat( [ "center" ] ) :
942 rvertical.test( pos[ 0 ] ) ?
943 [ "center" ].concat( pos ) :
944 [ "center", "center" ];
945 }
946 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
947 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
948
949 // Calculate offsets
950 horizontalOffset = roffset.exec( pos[ 0 ] );
951 verticalOffset = roffset.exec( pos[ 1 ] );
952 offsets[ this ] = [
953 horizontalOffset ? horizontalOffset[ 0 ] : 0,
954 verticalOffset ? verticalOffset[ 0 ] : 0
955 ];
956
957 // Reduce to just the positions without the offsets
958 options[ this ] = [
959 rposition.exec( pos[ 0 ] )[ 0 ],
960 rposition.exec( pos[ 1 ] )[ 0 ]
961 ];
962 } );
963
964 // Normalize collision option
965 if ( collision.length === 1 ) {
966 collision[ 1 ] = collision[ 0 ];
967 }
968
969 if ( options.at[ 0 ] === "right" ) {
970 basePosition.left += targetWidth;
971 } else if ( options.at[ 0 ] === "center" ) {
972 basePosition.left += targetWidth / 2;
973 }
974
975 if ( options.at[ 1 ] === "bottom" ) {
976 basePosition.top += targetHeight;
977 } else if ( options.at[ 1 ] === "center" ) {
978 basePosition.top += targetHeight / 2;
979 }
980
981 atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
982 basePosition.left += atOffset[ 0 ];
983 basePosition.top += atOffset[ 1 ];
984
985 return this.each( function() {
986 var collisionPosition, using,
987 elem = $( this ),
988 elemWidth = elem.outerWidth(),
989 elemHeight = elem.outerHeight(),
990 marginLeft = parseCss( this, "marginLeft" ),
991 marginTop = parseCss( this, "marginTop" ),
992 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) +
993 scrollInfo.width,
994 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) +
995 scrollInfo.height,
996 position = $.extend( {}, basePosition ),
997 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
998
999 if ( options.my[ 0 ] === "right" ) {
1000 position.left -= elemWidth;
1001 } else if ( options.my[ 0 ] === "center" ) {
1002 position.left -= elemWidth / 2;
1003 }
1004
1005 if ( options.my[ 1 ] === "bottom" ) {
1006 position.top -= elemHeight;
1007 } else if ( options.my[ 1 ] === "center" ) {
1008 position.top -= elemHeight / 2;
1009 }
1010
1011 position.left += myOffset[ 0 ];
1012 position.top += myOffset[ 1 ];
1013
1014 collisionPosition = {
1015 marginLeft: marginLeft,
1016 marginTop: marginTop
1017 };
1018
1019 $.each( [ "left", "top" ], function( i, dir ) {
1020 if ( $.ui.position[ collision[ i ] ] ) {
1021 $.ui.position[ collision[ i ] ][ dir ]( position, {
1022 targetWidth: targetWidth,
1023 targetHeight: targetHeight,
1024 elemWidth: elemWidth,
1025 elemHeight: elemHeight,
1026 collisionPosition: collisionPosition,
1027 collisionWidth: collisionWidth,
1028 collisionHeight: collisionHeight,
1029 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1030 my: options.my,
1031 at: options.at,
1032 within: within,
1033 elem: elem
1034 } );
1035 }
1036 } );
1037
1038 if ( options.using ) {
1039
1040 // Adds feedback as second argument to using callback, if present
1041 using = function( props ) {
1042 var left = targetOffset.left - position.left,
1043 right = left + targetWidth - elemWidth,
1044 top = targetOffset.top - position.top,
1045 bottom = top + targetHeight - elemHeight,
1046 feedback = {
1047 target: {
1048 element: target,
1049 left: targetOffset.left,
1050 top: targetOffset.top,
1051 width: targetWidth,
1052 height: targetHeight
1053 },
1054 element: {
1055 element: elem,
1056 left: position.left,
1057 top: position.top,
1058 width: elemWidth,
1059 height: elemHeight
1060 },
1061 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1062 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1063 };
1064 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1065 feedback.horizontal = "center";
1066 }
1067 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1068 feedback.vertical = "middle";
1069 }
1070 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1071 feedback.important = "horizontal";
1072 } else {
1073 feedback.important = "vertical";
1074 }
1075 options.using.call( this, props, feedback );
1076 };
1077 }
1078
1079 elem.offset( $.extend( position, { using: using } ) );
1080 } );
1081 };
1082
1083 $.ui.position = {
1084 fit: {
1085 left: function( position, data ) {
1086 var within = data.within,
1087 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1088 outerWidth = within.width,
1089 collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1090 overLeft = withinOffset - collisionPosLeft,
1091 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1092 newOverRight;
1093
1094 // Element is wider than within
1095 if ( data.collisionWidth > outerWidth ) {
1096
1097 // Element is initially over the left side of within
1098 if ( overLeft > 0 && overRight <= 0 ) {
1099 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth -
1100 withinOffset;
1101 position.left += overLeft - newOverRight;
1102
1103 // Element is initially over right side of within
1104 } else if ( overRight > 0 && overLeft <= 0 ) {
1105 position.left = withinOffset;
1106
1107 // Element is initially over both left and right sides of within
1108 } else {
1109 if ( overLeft > overRight ) {
1110 position.left = withinOffset + outerWidth - data.collisionWidth;
1111 } else {
1112 position.left = withinOffset;
1113 }
1114 }
1115
1116 // Too far left -> align with left edge
1117 } else if ( overLeft > 0 ) {
1118 position.left += overLeft;
1119
1120 // Too far right -> align with right edge
1121 } else if ( overRight > 0 ) {
1122 position.left -= overRight;
1123
1124 // Adjust based on position and margin
1125 } else {
1126 position.left = max( position.left - collisionPosLeft, position.left );
1127 }
1128 },
1129 top: function( position, data ) {
1130 var within = data.within,
1131 withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1132 outerHeight = data.within.height,
1133 collisionPosTop = position.top - data.collisionPosition.marginTop,
1134 overTop = withinOffset - collisionPosTop,
1135 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1136 newOverBottom;
1137
1138 // Element is taller than within
1139 if ( data.collisionHeight > outerHeight ) {
1140
1141 // Element is initially over the top of within
1142 if ( overTop > 0 && overBottom <= 0 ) {
1143 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight -
1144 withinOffset;
1145 position.top += overTop - newOverBottom;
1146
1147 // Element is initially over bottom of within
1148 } else if ( overBottom > 0 && overTop <= 0 ) {
1149 position.top = withinOffset;
1150
1151 // Element is initially over both top and bottom of within
1152 } else {
1153 if ( overTop > overBottom ) {
1154 position.top = withinOffset + outerHeight - data.collisionHeight;
1155 } else {
1156 position.top = withinOffset;
1157 }
1158 }
1159
1160 // Too far up -> align with top
1161 } else if ( overTop > 0 ) {
1162 position.top += overTop;
1163
1164 // Too far down -> align with bottom edge
1165 } else if ( overBottom > 0 ) {
1166 position.top -= overBottom;
1167
1168 // Adjust based on position and margin
1169 } else {
1170 position.top = max( position.top - collisionPosTop, position.top );
1171 }
1172 }
1173 },
1174 flip: {
1175 left: function( position, data ) {
1176 var within = data.within,
1177 withinOffset = within.offset.left + within.scrollLeft,
1178 outerWidth = within.width,
1179 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1180 collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1181 overLeft = collisionPosLeft - offsetLeft,
1182 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1183 myOffset = data.my[ 0 ] === "left" ?
1184 -data.elemWidth :
1185 data.my[ 0 ] === "right" ?
1186 data.elemWidth :
1187 0,
1188 atOffset = data.at[ 0 ] === "left" ?
1189 data.targetWidth :
1190 data.at[ 0 ] === "right" ?
1191 -data.targetWidth :
1192 0,
1193 offset = -2 * data.offset[ 0 ],
1194 newOverRight,
1195 newOverLeft;
1196
1197 if ( overLeft < 0 ) {
1198 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -
1199 outerWidth - withinOffset;
1200 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1201 position.left += myOffset + atOffset + offset;
1202 }
1203 } else if ( overRight > 0 ) {
1204 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +
1205 atOffset + offset - offsetLeft;
1206 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1207 position.left += myOffset + atOffset + offset;
1208 }
1209 }
1210 },
1211 top: function( position, data ) {
1212 var within = data.within,
1213 withinOffset = within.offset.top + within.scrollTop,
1214 outerHeight = within.height,
1215 offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1216 collisionPosTop = position.top - data.collisionPosition.marginTop,
1217 overTop = collisionPosTop - offsetTop,
1218 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1219 top = data.my[ 1 ] === "top",
1220 myOffset = top ?
1221 -data.elemHeight :
1222 data.my[ 1 ] === "bottom" ?
1223 data.elemHeight :
1224 0,
1225 atOffset = data.at[ 1 ] === "top" ?
1226 data.targetHeight :
1227 data.at[ 1 ] === "bottom" ?
1228 -data.targetHeight :
1229 0,
1230 offset = -2 * data.offset[ 1 ],
1231 newOverTop,
1232 newOverBottom;
1233 if ( overTop < 0 ) {
1234 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -
1235 outerHeight - withinOffset;
1236 if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
1237 position.top += myOffset + atOffset + offset;
1238 }
1239 } else if ( overBottom > 0 ) {
1240 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +
1241 offset - offsetTop;
1242 if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
1243 position.top += myOffset + atOffset + offset;
1244 }
1245 }
1246 }
1247 },
1248 flipfit: {
1249 left: function() {
1250 $.ui.position.flip.left.apply( this, arguments );
1251 $.ui.position.fit.left.apply( this, arguments );
1252 },
1253 top: function() {
1254 $.ui.position.flip.top.apply( this, arguments );
1255 $.ui.position.fit.top.apply( this, arguments );
1256 }
1257 }
1258 };
1259
1260 } )();
1261
1262 var position = $.ui.position;
1263
1264
1265 /*!
1266 * jQuery UI :data 1.13.2
1267 * http://jqueryui.com
21 * 1268 *
22 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 1269 * Copyright jQuery Foundation and other contributors
23 * Dual licensed under the MIT or GPL Version 2 licenses. 1270 * Released under the MIT license.
1271 * http://jquery.org/license
1272 */
1273
1274 //>>label: :data Selector
1275 //>>group: Core
1276 //>>description: Selects elements which have data stored under the specified key.
1277 //>>docs: http://api.jqueryui.com/data-selector/
1278
1279
1280 var data = $.extend( $.expr.pseudos, {
1281 data: $.expr.createPseudo ?
1282 $.expr.createPseudo( function( dataName ) {
1283 return function( elem ) {
1284 return !!$.data( elem, dataName );
1285 };
1286 } ) :
1287
1288 // Support: jQuery <1.8
1289 function( elem, i, match ) {
1290 return !!$.data( elem, match[ 3 ] );
1291 }
1292 } );
1293
1294 /*!
1295 * jQuery UI Disable Selection 1.13.2
1296 * http://jqueryui.com
1297 *
1298 * Copyright jQuery Foundation and other contributors
1299 * Released under the MIT license.
1300 * http://jquery.org/license
1301 */
1302
1303 //>>label: disableSelection
1304 //>>group: Core
1305 //>>description: Disable selection of text content within the set of matched elements.
1306 //>>docs: http://api.jqueryui.com/disableSelection/
1307
1308 // This file is deprecated
1309
1310 var disableSelection = $.fn.extend( {
1311 disableSelection: ( function() {
1312 var eventType = "onselectstart" in document.createElement( "div" ) ?
1313 "selectstart" :
1314 "mousedown";
1315
1316 return function() {
1317 return this.on( eventType + ".ui-disableSelection", function( event ) {
1318 event.preventDefault();
1319 } );
1320 };
1321 } )(),
1322
1323 enableSelection: function() {
1324 return this.off( ".ui-disableSelection" );
1325 }
1326 } );
1327
1328
1329
1330 // Create a local jQuery because jQuery Color relies on it and the
1331 // global may not exist with AMD and a custom build (#10199).
1332 // This module is a noop if used as a regular AMD module.
1333 // eslint-disable-next-line no-unused-vars
1334 var jQuery = $;
1335
1336
1337 /*!
1338 * jQuery Color Animations v2.2.0
1339 * https://github.com/jquery/jquery-color
1340 *
1341 * Copyright OpenJS Foundation and other contributors
1342 * Released under the MIT license.
24 * http://jquery.org/license 1343 * http://jquery.org/license
25 * 1344 *
26 * http://docs.jquery.com/UI/Widget 1345 * Date: Sun May 10 09:02:36 2020 +0200
27 */ 1346 */
28 (function(b,j){if(b.cleanData){var k=b.cleanData;b.cleanData=function(a){for(var c=0,d;(d=a[c])!=null;c++)try{b(d).triggerHandler("remove")}catch(e){}k(a)}}else{var l=b.fn.remove;b.fn.remove=function(a,c){return this.each(function(){if(!c)if(!a||b.filter(a,[this]).length)b("*",this).add([this]).each(function(){try{b(this).triggerHandler("remove")}catch(d){}});return l.call(b(this),a,c)})}}b.widget=function(a,c,d){var e=a.split(".")[0],f;a=a.split(".")[1];f=e+"-"+a;if(!d){d=c;c=b.Widget}b.expr[":"][f]= 1347
29 function(h){return!!b.data(h,a)};b[e]=b[e]||{};b[e][a]=function(h,g){arguments.length&&this._createWidget(h,g)};c=new c;c.options=b.extend(true,{},c.options);b[e][a].prototype=b.extend(true,c,{namespace:e,widgetName:a,widgetEventPrefix:b[e][a].prototype.widgetEventPrefix||a,widgetBaseClass:f},d);b.widget.bridge(a,b[e][a])};b.widget.bridge=function(a,c){b.fn[a]=function(d){var e=typeof d==="string",f=Array.prototype.slice.call(arguments,1),h=this;d=!e&&f.length?b.extend.apply(null,[true,d].concat(f)): 1348
30 d;if(e&&d.charAt(0)==="_")return h;e?this.each(function(){var g=b.data(this,a),i=g&&b.isFunction(g[d])?g[d].apply(g,f):g;if(i!==g&&i!==j){h=i;return false}}):this.each(function(){var g=b.data(this,a);g?g.option(d||{})._init():b.data(this,a,new c(d,this))});return h}};b.Widget=function(a,c){arguments.length&&this._createWidget(a,c)};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(a,c){b.data(c,this.widgetName,this);this.element=b(c);this.options= 1349
31 b.extend(true,{},this.options,this._getCreateOptions(),a);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return b.metadata&&b.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+ 1350 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " +
32 "-disabled ui-state-disabled")},widget:function(){return this.element},option:function(a,c){var d=a;if(arguments.length===0)return b.extend({},this.options);if(typeof a==="string"){if(c===j)return this.options[a];d={};d[a]=c}this._setOptions(d);return this},_setOptions:function(a){var c=this;b.each(a,function(d,e){c._setOption(d,e)});return this},_setOption:function(a,c){this.options[a]=c;if(a==="disabled")this.widget()[c?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled", 1351 "borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
33 c);return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(a,c,d){var e=this.options[a];c=b.Event(c);c.type=(a===this.widgetEventPrefix?a:this.widgetEventPrefix+a).toLowerCase();d=d||{};if(c.originalEvent){a=b.event.props.length;for(var f;a;){f=b.event.props[--a];c[f]=c.originalEvent[f]}}this.element.trigger(c,d);return!(b.isFunction(e)&&e.call(this.element[0],c,d)===false||c.isDefaultPrevented())}}})(jQuery); 1352
34 ;/*! 1353 class2type = {},
35 * jQuery UI Mouse 1.8.16 1354 toString = class2type.toString,
1355
1356 // plusequals test for += 100 -= 100
1357 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
1358
1359 // a set of RE's that can match strings and generate color tuples.
1360 stringParsers = [ {
1361 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1362 parse: function( execResult ) {
1363 return [
1364 execResult[ 1 ],
1365 execResult[ 2 ],
1366 execResult[ 3 ],
1367 execResult[ 4 ]
1368 ];
1369 }
1370 }, {
1371 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1372 parse: function( execResult ) {
1373 return [
1374 execResult[ 1 ] * 2.55,
1375 execResult[ 2 ] * 2.55,
1376 execResult[ 3 ] * 2.55,
1377 execResult[ 4 ]
1378 ];
1379 }
1380 }, {
1381
1382 // this regex ignores A-F because it's compared against an already lowercased string
1383 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?/,
1384 parse: function( execResult ) {
1385 return [
1386 parseInt( execResult[ 1 ], 16 ),
1387 parseInt( execResult[ 2 ], 16 ),
1388 parseInt( execResult[ 3 ], 16 ),
1389 execResult[ 4 ] ?
1390 ( parseInt( execResult[ 4 ], 16 ) / 255 ).toFixed( 2 ) :
1391 1
1392 ];
1393 }
1394 }, {
1395
1396 // this regex ignores A-F because it's compared against an already lowercased string
1397 re: /#([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])?/,
1398 parse: function( execResult ) {
1399 return [
1400 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
1401 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
1402 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ),
1403 execResult[ 4 ] ?
1404 ( parseInt( execResult[ 4 ] + execResult[ 4 ], 16 ) / 255 )
1405 .toFixed( 2 ) :
1406 1
1407 ];
1408 }
1409 }, {
1410 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1411 space: "hsla",
1412 parse: function( execResult ) {
1413 return [
1414 execResult[ 1 ],
1415 execResult[ 2 ] / 100,
1416 execResult[ 3 ] / 100,
1417 execResult[ 4 ]
1418 ];
1419 }
1420 } ],
1421
1422 // jQuery.Color( )
1423 color = jQuery.Color = function( color, green, blue, alpha ) {
1424 return new jQuery.Color.fn.parse( color, green, blue, alpha );
1425 },
1426 spaces = {
1427 rgba: {
1428 props: {
1429 red: {
1430 idx: 0,
1431 type: "byte"
1432 },
1433 green: {
1434 idx: 1,
1435 type: "byte"
1436 },
1437 blue: {
1438 idx: 2,
1439 type: "byte"
1440 }
1441 }
1442 },
1443
1444 hsla: {
1445 props: {
1446 hue: {
1447 idx: 0,
1448 type: "degrees"
1449 },
1450 saturation: {
1451 idx: 1,
1452 type: "percent"
1453 },
1454 lightness: {
1455 idx: 2,
1456 type: "percent"
1457 }
1458 }
1459 }
1460 },
1461 propTypes = {
1462 "byte": {
1463 floor: true,
1464 max: 255
1465 },
1466 "percent": {
1467 max: 1
1468 },
1469 "degrees": {
1470 mod: 360,
1471 floor: true
1472 }
1473 },
1474 support = color.support = {},
1475
1476 // element for support tests
1477 supportElem = jQuery( "<p>" )[ 0 ],
1478
1479 // colors = jQuery.Color.names
1480 colors,
1481
1482 // local aliases of functions called often
1483 each = jQuery.each;
1484
1485 // determine rgba support immediately
1486 supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
1487 support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
1488
1489 // define cache name and alpha properties
1490 // for rgba and hsla spaces
1491 each( spaces, function( spaceName, space ) {
1492 space.cache = "_" + spaceName;
1493 space.props.alpha = {
1494 idx: 3,
1495 type: "percent",
1496 def: 1
1497 };
1498 } );
1499
1500 // Populate the class2type map
1501 jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
1502 function( _i, name ) {
1503 class2type[ "[object " + name + "]" ] = name.toLowerCase();
1504 } );
1505
1506 function getType( obj ) {
1507 if ( obj == null ) {
1508 return obj + "";
1509 }
1510
1511 return typeof obj === "object" ?
1512 class2type[ toString.call( obj ) ] || "object" :
1513 typeof obj;
1514 }
1515
1516 function clamp( value, prop, allowEmpty ) {
1517 var type = propTypes[ prop.type ] || {};
1518
1519 if ( value == null ) {
1520 return ( allowEmpty || !prop.def ) ? null : prop.def;
1521 }
1522
1523 // ~~ is an short way of doing floor for positive numbers
1524 value = type.floor ? ~~value : parseFloat( value );
1525
1526 // IE will pass in empty strings as value for alpha,
1527 // which will hit this case
1528 if ( isNaN( value ) ) {
1529 return prop.def;
1530 }
1531
1532 if ( type.mod ) {
1533
1534 // we add mod before modding to make sure that negatives values
1535 // get converted properly: -10 -> 350
1536 return ( value + type.mod ) % type.mod;
1537 }
1538
1539 // for now all property types without mod have min and max
1540 return Math.min( type.max, Math.max( 0, value ) );
1541 }
1542
1543 function stringParse( string ) {
1544 var inst = color(),
1545 rgba = inst._rgba = [];
1546
1547 string = string.toLowerCase();
1548
1549 each( stringParsers, function( _i, parser ) {
1550 var parsed,
1551 match = parser.re.exec( string ),
1552 values = match && parser.parse( match ),
1553 spaceName = parser.space || "rgba";
1554
1555 if ( values ) {
1556 parsed = inst[ spaceName ]( values );
1557
1558 // if this was an rgba parse the assignment might happen twice
1559 // oh well....
1560 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
1561 rgba = inst._rgba = parsed._rgba;
1562
1563 // exit each( stringParsers ) here because we matched
1564 return false;
1565 }
1566 } );
1567
1568 // Found a stringParser that handled it
1569 if ( rgba.length ) {
1570
1571 // if this came from a parsed string, force "transparent" when alpha is 0
1572 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
1573 if ( rgba.join() === "0,0,0,0" ) {
1574 jQuery.extend( rgba, colors.transparent );
1575 }
1576 return inst;
1577 }
1578
1579 // named colors
1580 return colors[ string ];
1581 }
1582
1583 color.fn = jQuery.extend( color.prototype, {
1584 parse: function( red, green, blue, alpha ) {
1585 if ( red === undefined ) {
1586 this._rgba = [ null, null, null, null ];
1587 return this;
1588 }
1589 if ( red.jquery || red.nodeType ) {
1590 red = jQuery( red ).css( green );
1591 green = undefined;
1592 }
1593
1594 var inst = this,
1595 type = getType( red ),
1596 rgba = this._rgba = [];
1597
1598 // more than 1 argument specified - assume ( red, green, blue, alpha )
1599 if ( green !== undefined ) {
1600 red = [ red, green, blue, alpha ];
1601 type = "array";
1602 }
1603
1604 if ( type === "string" ) {
1605 return this.parse( stringParse( red ) || colors._default );
1606 }
1607
1608 if ( type === "array" ) {
1609 each( spaces.rgba.props, function( _key, prop ) {
1610 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
1611 } );
1612 return this;
1613 }
1614
1615 if ( type === "object" ) {
1616 if ( red instanceof color ) {
1617 each( spaces, function( _spaceName, space ) {
1618 if ( red[ space.cache ] ) {
1619 inst[ space.cache ] = red[ space.cache ].slice();
1620 }
1621 } );
1622 } else {
1623 each( spaces, function( _spaceName, space ) {
1624 var cache = space.cache;
1625 each( space.props, function( key, prop ) {
1626
1627 // if the cache doesn't exist, and we know how to convert
1628 if ( !inst[ cache ] && space.to ) {
1629
1630 // if the value was null, we don't need to copy it
1631 // if the key was alpha, we don't need to copy it either
1632 if ( key === "alpha" || red[ key ] == null ) {
1633 return;
1634 }
1635 inst[ cache ] = space.to( inst._rgba );
1636 }
1637
1638 // this is the only case where we allow nulls for ALL properties.
1639 // call clamp with alwaysAllowEmpty
1640 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
1641 } );
1642
1643 // everything defined but alpha?
1644 if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
1645
1646 // use the default of 1
1647 if ( inst[ cache ][ 3 ] == null ) {
1648 inst[ cache ][ 3 ] = 1;
1649 }
1650
1651 if ( space.from ) {
1652 inst._rgba = space.from( inst[ cache ] );
1653 }
1654 }
1655 } );
1656 }
1657 return this;
1658 }
1659 },
1660 is: function( compare ) {
1661 var is = color( compare ),
1662 same = true,
1663 inst = this;
1664
1665 each( spaces, function( _, space ) {
1666 var localCache,
1667 isCache = is[ space.cache ];
1668 if ( isCache ) {
1669 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
1670 each( space.props, function( _, prop ) {
1671 if ( isCache[ prop.idx ] != null ) {
1672 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
1673 return same;
1674 }
1675 } );
1676 }
1677 return same;
1678 } );
1679 return same;
1680 },
1681 _space: function() {
1682 var used = [],
1683 inst = this;
1684 each( spaces, function( spaceName, space ) {
1685 if ( inst[ space.cache ] ) {
1686 used.push( spaceName );
1687 }
1688 } );
1689 return used.pop();
1690 },
1691 transition: function( other, distance ) {
1692 var end = color( other ),
1693 spaceName = end._space(),
1694 space = spaces[ spaceName ],
1695 startColor = this.alpha() === 0 ? color( "transparent" ) : this,
1696 start = startColor[ space.cache ] || space.to( startColor._rgba ),
1697 result = start.slice();
1698
1699 end = end[ space.cache ];
1700 each( space.props, function( _key, prop ) {
1701 var index = prop.idx,
1702 startValue = start[ index ],
1703 endValue = end[ index ],
1704 type = propTypes[ prop.type ] || {};
1705
1706 // if null, don't override start value
1707 if ( endValue === null ) {
1708 return;
1709 }
1710
1711 // if null - use end
1712 if ( startValue === null ) {
1713 result[ index ] = endValue;
1714 } else {
1715 if ( type.mod ) {
1716 if ( endValue - startValue > type.mod / 2 ) {
1717 startValue += type.mod;
1718 } else if ( startValue - endValue > type.mod / 2 ) {
1719 startValue -= type.mod;
1720 }
1721 }
1722 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
1723 }
1724 } );
1725 return this[ spaceName ]( result );
1726 },
1727 blend: function( opaque ) {
1728
1729 // if we are already opaque - return ourself
1730 if ( this._rgba[ 3 ] === 1 ) {
1731 return this;
1732 }
1733
1734 var rgb = this._rgba.slice(),
1735 a = rgb.pop(),
1736 blend = color( opaque )._rgba;
1737
1738 return color( jQuery.map( rgb, function( v, i ) {
1739 return ( 1 - a ) * blend[ i ] + a * v;
1740 } ) );
1741 },
1742 toRgbaString: function() {
1743 var prefix = "rgba(",
1744 rgba = jQuery.map( this._rgba, function( v, i ) {
1745 if ( v != null ) {
1746 return v;
1747 }
1748 return i > 2 ? 1 : 0;
1749 } );
1750
1751 if ( rgba[ 3 ] === 1 ) {
1752 rgba.pop();
1753 prefix = "rgb(";
1754 }
1755
1756 return prefix + rgba.join() + ")";
1757 },
1758 toHslaString: function() {
1759 var prefix = "hsla(",
1760 hsla = jQuery.map( this.hsla(), function( v, i ) {
1761 if ( v == null ) {
1762 v = i > 2 ? 1 : 0;
1763 }
1764
1765 // catch 1 and 2
1766 if ( i && i < 3 ) {
1767 v = Math.round( v * 100 ) + "%";
1768 }
1769 return v;
1770 } );
1771
1772 if ( hsla[ 3 ] === 1 ) {
1773 hsla.pop();
1774 prefix = "hsl(";
1775 }
1776 return prefix + hsla.join() + ")";
1777 },
1778 toHexString: function( includeAlpha ) {
1779 var rgba = this._rgba.slice(),
1780 alpha = rgba.pop();
1781
1782 if ( includeAlpha ) {
1783 rgba.push( ~~( alpha * 255 ) );
1784 }
1785
1786 return "#" + jQuery.map( rgba, function( v ) {
1787
1788 // default to 0 when nulls exist
1789 v = ( v || 0 ).toString( 16 );
1790 return v.length === 1 ? "0" + v : v;
1791 } ).join( "" );
1792 },
1793 toString: function() {
1794 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
1795 }
1796 } );
1797 color.fn.parse.prototype = color.fn;
1798
1799 // hsla conversions adapted from:
1800 // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
1801
1802 function hue2rgb( p, q, h ) {
1803 h = ( h + 1 ) % 1;
1804 if ( h * 6 < 1 ) {
1805 return p + ( q - p ) * h * 6;
1806 }
1807 if ( h * 2 < 1 ) {
1808 return q;
1809 }
1810 if ( h * 3 < 2 ) {
1811 return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
1812 }
1813 return p;
1814 }
1815
1816 spaces.hsla.to = function( rgba ) {
1817 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
1818 return [ null, null, null, rgba[ 3 ] ];
1819 }
1820 var r = rgba[ 0 ] / 255,
1821 g = rgba[ 1 ] / 255,
1822 b = rgba[ 2 ] / 255,
1823 a = rgba[ 3 ],
1824 max = Math.max( r, g, b ),
1825 min = Math.min( r, g, b ),
1826 diff = max - min,
1827 add = max + min,
1828 l = add * 0.5,
1829 h, s;
1830
1831 if ( min === max ) {
1832 h = 0;
1833 } else if ( r === max ) {
1834 h = ( 60 * ( g - b ) / diff ) + 360;
1835 } else if ( g === max ) {
1836 h = ( 60 * ( b - r ) / diff ) + 120;
1837 } else {
1838 h = ( 60 * ( r - g ) / diff ) + 240;
1839 }
1840
1841 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
1842 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
1843 if ( diff === 0 ) {
1844 s = 0;
1845 } else if ( l <= 0.5 ) {
1846 s = diff / add;
1847 } else {
1848 s = diff / ( 2 - add );
1849 }
1850 return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ];
1851 };
1852
1853 spaces.hsla.from = function( hsla ) {
1854 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
1855 return [ null, null, null, hsla[ 3 ] ];
1856 }
1857 var h = hsla[ 0 ] / 360,
1858 s = hsla[ 1 ],
1859 l = hsla[ 2 ],
1860 a = hsla[ 3 ],
1861 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
1862 p = 2 * l - q;
1863
1864 return [
1865 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
1866 Math.round( hue2rgb( p, q, h ) * 255 ),
1867 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
1868 a
1869 ];
1870 };
1871
1872
1873 each( spaces, function( spaceName, space ) {
1874 var props = space.props,
1875 cache = space.cache,
1876 to = space.to,
1877 from = space.from;
1878
1879 // makes rgba() and hsla()
1880 color.fn[ spaceName ] = function( value ) {
1881
1882 // generate a cache for this space if it doesn't exist
1883 if ( to && !this[ cache ] ) {
1884 this[ cache ] = to( this._rgba );
1885 }
1886 if ( value === undefined ) {
1887 return this[ cache ].slice();
1888 }
1889
1890 var ret,
1891 type = getType( value ),
1892 arr = ( type === "array" || type === "object" ) ? value : arguments,
1893 local = this[ cache ].slice();
1894
1895 each( props, function( key, prop ) {
1896 var val = arr[ type === "object" ? key : prop.idx ];
1897 if ( val == null ) {
1898 val = local[ prop.idx ];
1899 }
1900 local[ prop.idx ] = clamp( val, prop );
1901 } );
1902
1903 if ( from ) {
1904 ret = color( from( local ) );
1905 ret[ cache ] = local;
1906 return ret;
1907 } else {
1908 return color( local );
1909 }
1910 };
1911
1912 // makes red() green() blue() alpha() hue() saturation() lightness()
1913 each( props, function( key, prop ) {
1914
1915 // alpha is included in more than one space
1916 if ( color.fn[ key ] ) {
1917 return;
1918 }
1919 color.fn[ key ] = function( value ) {
1920 var local, cur, match, fn,
1921 vtype = getType( value );
1922
1923 if ( key === "alpha" ) {
1924 fn = this._hsla ? "hsla" : "rgba";
1925 } else {
1926 fn = spaceName;
1927 }
1928 local = this[ fn ]();
1929 cur = local[ prop.idx ];
1930
1931 if ( vtype === "undefined" ) {
1932 return cur;
1933 }
1934
1935 if ( vtype === "function" ) {
1936 value = value.call( this, cur );
1937 vtype = getType( value );
1938 }
1939 if ( value == null && prop.empty ) {
1940 return this;
1941 }
1942 if ( vtype === "string" ) {
1943 match = rplusequals.exec( value );
1944 if ( match ) {
1945 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
1946 }
1947 }
1948 local[ prop.idx ] = value;
1949 return this[ fn ]( local );
1950 };
1951 } );
1952 } );
1953
1954 // add cssHook and .fx.step function for each named hook.
1955 // accept a space separated string of properties
1956 color.hook = function( hook ) {
1957 var hooks = hook.split( " " );
1958 each( hooks, function( _i, hook ) {
1959 jQuery.cssHooks[ hook ] = {
1960 set: function( elem, value ) {
1961 var parsed, curElem,
1962 backgroundColor = "";
1963
1964 if ( value !== "transparent" && ( getType( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
1965 value = color( parsed || value );
1966 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
1967 curElem = hook === "backgroundColor" ? elem.parentNode : elem;
1968 while (
1969 ( backgroundColor === "" || backgroundColor === "transparent" ) &&
1970 curElem && curElem.style
1971 ) {
1972 try {
1973 backgroundColor = jQuery.css( curElem, "backgroundColor" );
1974 curElem = curElem.parentNode;
1975 } catch ( e ) {
1976 }
1977 }
1978
1979 value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
1980 backgroundColor :
1981 "_default" );
1982 }
1983
1984 value = value.toRgbaString();
1985 }
1986 try {
1987 elem.style[ hook ] = value;
1988 } catch ( e ) {
1989
1990 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
1991 }
1992 }
1993 };
1994 jQuery.fx.step[ hook ] = function( fx ) {
1995 if ( !fx.colorInit ) {
1996 fx.start = color( fx.elem, hook );
1997 fx.end = color( fx.end );
1998 fx.colorInit = true;
1999 }
2000 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
2001 };
2002 } );
2003
2004 };
2005
2006 color.hook( stepHooks );
2007
2008 jQuery.cssHooks.borderColor = {
2009 expand: function( value ) {
2010 var expanded = {};
2011
2012 each( [ "Top", "Right", "Bottom", "Left" ], function( _i, part ) {
2013 expanded[ "border" + part + "Color" ] = value;
2014 } );
2015 return expanded;
2016 }
2017 };
2018
2019 // Basic color names only.
2020 // Usage of any of the other color names requires adding yourself or including
2021 // jquery.color.svg-names.js.
2022 colors = jQuery.Color.names = {
2023
2024 // 4.1. Basic color keywords
2025 aqua: "#00ffff",
2026 black: "#000000",
2027 blue: "#0000ff",
2028 fuchsia: "#ff00ff",
2029 gray: "#808080",
2030 green: "#008000",
2031 lime: "#00ff00",
2032 maroon: "#800000",
2033 navy: "#000080",
2034 olive: "#808000",
2035 purple: "#800080",
2036 red: "#ff0000",
2037 silver: "#c0c0c0",
2038 teal: "#008080",
2039 white: "#ffffff",
2040 yellow: "#ffff00",
2041
2042 // 4.2.3. "transparent" color keyword
2043 transparent: [ null, null, null, 0 ],
2044
2045 _default: "#ffffff"
2046 };
2047
2048
2049 /*!
2050 * jQuery UI Effects 1.13.2
2051 * http://jqueryui.com
36 * 2052 *
37 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 2053 * Copyright jQuery Foundation and other contributors
38 * Dual licensed under the MIT or GPL Version 2 licenses. 2054 * Released under the MIT license.
2055 * http://jquery.org/license
2056 */
2057
2058 //>>label: Effects Core
2059 //>>group: Effects
2060 /* eslint-disable max-len */
2061 //>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects.
2062 /* eslint-enable max-len */
2063 //>>docs: http://api.jqueryui.com/category/effects-core/
2064 //>>demos: http://jqueryui.com/effect/
2065
2066
2067 var dataSpace = "ui-effects-",
2068 dataSpaceStyle = "ui-effects-style",
2069 dataSpaceAnimated = "ui-effects-animated";
2070
2071 $.effects = {
2072 effect: {}
2073 };
2074
2075 /******************************************************************************/
2076 /****************************** CLASS ANIMATIONS ******************************/
2077 /******************************************************************************/
2078 ( function() {
2079
2080 var classAnimationActions = [ "add", "remove", "toggle" ],
2081 shorthandStyles = {
2082 border: 1,
2083 borderBottom: 1,
2084 borderColor: 1,
2085 borderLeft: 1,
2086 borderRight: 1,
2087 borderTop: 1,
2088 borderWidth: 1,
2089 margin: 1,
2090 padding: 1
2091 };
2092
2093 $.each(
2094 [ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ],
2095 function( _, prop ) {
2096 $.fx.step[ prop ] = function( fx ) {
2097 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
2098 jQuery.style( fx.elem, prop, fx.end );
2099 fx.setAttr = true;
2100 }
2101 };
2102 }
2103 );
2104
2105 function camelCase( string ) {
2106 return string.replace( /-([\da-z])/gi, function( all, letter ) {
2107 return letter.toUpperCase();
2108 } );
2109 }
2110
2111 function getElementStyles( elem ) {
2112 var key, len,
2113 style = elem.ownerDocument.defaultView ?
2114 elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
2115 elem.currentStyle,
2116 styles = {};
2117
2118 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
2119 len = style.length;
2120 while ( len-- ) {
2121 key = style[ len ];
2122 if ( typeof style[ key ] === "string" ) {
2123 styles[ camelCase( key ) ] = style[ key ];
2124 }
2125 }
2126
2127 // Support: Opera, IE <9
2128 } else {
2129 for ( key in style ) {
2130 if ( typeof style[ key ] === "string" ) {
2131 styles[ key ] = style[ key ];
2132 }
2133 }
2134 }
2135
2136 return styles;
2137 }
2138
2139 function styleDifference( oldStyle, newStyle ) {
2140 var diff = {},
2141 name, value;
2142
2143 for ( name in newStyle ) {
2144 value = newStyle[ name ];
2145 if ( oldStyle[ name ] !== value ) {
2146 if ( !shorthandStyles[ name ] ) {
2147 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
2148 diff[ name ] = value;
2149 }
2150 }
2151 }
2152 }
2153
2154 return diff;
2155 }
2156
2157 // Support: jQuery <1.8
2158 if ( !$.fn.addBack ) {
2159 $.fn.addBack = function( selector ) {
2160 return this.add( selector == null ?
2161 this.prevObject : this.prevObject.filter( selector )
2162 );
2163 };
2164 }
2165
2166 $.effects.animateClass = function( value, duration, easing, callback ) {
2167 var o = $.speed( duration, easing, callback );
2168
2169 return this.queue( function() {
2170 var animated = $( this ),
2171 baseClass = animated.attr( "class" ) || "",
2172 applyClassChange,
2173 allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
2174
2175 // Map the animated objects to store the original styles.
2176 allAnimations = allAnimations.map( function() {
2177 var el = $( this );
2178 return {
2179 el: el,
2180 start: getElementStyles( this )
2181 };
2182 } );
2183
2184 // Apply class change
2185 applyClassChange = function() {
2186 $.each( classAnimationActions, function( i, action ) {
2187 if ( value[ action ] ) {
2188 animated[ action + "Class" ]( value[ action ] );
2189 }
2190 } );
2191 };
2192 applyClassChange();
2193
2194 // Map all animated objects again - calculate new styles and diff
2195 allAnimations = allAnimations.map( function() {
2196 this.end = getElementStyles( this.el[ 0 ] );
2197 this.diff = styleDifference( this.start, this.end );
2198 return this;
2199 } );
2200
2201 // Apply original class
2202 animated.attr( "class", baseClass );
2203
2204 // Map all animated objects again - this time collecting a promise
2205 allAnimations = allAnimations.map( function() {
2206 var styleInfo = this,
2207 dfd = $.Deferred(),
2208 opts = $.extend( {}, o, {
2209 queue: false,
2210 complete: function() {
2211 dfd.resolve( styleInfo );
2212 }
2213 } );
2214
2215 this.el.animate( this.diff, opts );
2216 return dfd.promise();
2217 } );
2218
2219 // Once all animations have completed:
2220 $.when.apply( $, allAnimations.get() ).done( function() {
2221
2222 // Set the final class
2223 applyClassChange();
2224
2225 // For each animated element,
2226 // clear all css properties that were animated
2227 $.each( arguments, function() {
2228 var el = this.el;
2229 $.each( this.diff, function( key ) {
2230 el.css( key, "" );
2231 } );
2232 } );
2233
2234 // This is guarnteed to be there if you use jQuery.speed()
2235 // it also handles dequeuing the next anim...
2236 o.complete.call( animated[ 0 ] );
2237 } );
2238 } );
2239 };
2240
2241 $.fn.extend( {
2242 addClass: ( function( orig ) {
2243 return function( classNames, speed, easing, callback ) {
2244 return speed ?
2245 $.effects.animateClass.call( this,
2246 { add: classNames }, speed, easing, callback ) :
2247 orig.apply( this, arguments );
2248 };
2249 } )( $.fn.addClass ),
2250
2251 removeClass: ( function( orig ) {
2252 return function( classNames, speed, easing, callback ) {
2253 return arguments.length > 1 ?
2254 $.effects.animateClass.call( this,
2255 { remove: classNames }, speed, easing, callback ) :
2256 orig.apply( this, arguments );
2257 };
2258 } )( $.fn.removeClass ),
2259
2260 toggleClass: ( function( orig ) {
2261 return function( classNames, force, speed, easing, callback ) {
2262 if ( typeof force === "boolean" || force === undefined ) {
2263 if ( !speed ) {
2264
2265 // Without speed parameter
2266 return orig.apply( this, arguments );
2267 } else {
2268 return $.effects.animateClass.call( this,
2269 ( force ? { add: classNames } : { remove: classNames } ),
2270 speed, easing, callback );
2271 }
2272 } else {
2273
2274 // Without force parameter
2275 return $.effects.animateClass.call( this,
2276 { toggle: classNames }, force, speed, easing );
2277 }
2278 };
2279 } )( $.fn.toggleClass ),
2280
2281 switchClass: function( remove, add, speed, easing, callback ) {
2282 return $.effects.animateClass.call( this, {
2283 add: add,
2284 remove: remove
2285 }, speed, easing, callback );
2286 }
2287 } );
2288
2289 } )();
2290
2291 /******************************************************************************/
2292 /*********************************** EFFECTS **********************************/
2293 /******************************************************************************/
2294
2295 ( function() {
2296
2297 if ( $.expr && $.expr.pseudos && $.expr.pseudos.animated ) {
2298 $.expr.pseudos.animated = ( function( orig ) {
2299 return function( elem ) {
2300 return !!$( elem ).data( dataSpaceAnimated ) || orig( elem );
2301 };
2302 } )( $.expr.pseudos.animated );
2303 }
2304
2305 if ( $.uiBackCompat !== false ) {
2306 $.extend( $.effects, {
2307
2308 // Saves a set of properties in a data storage
2309 save: function( element, set ) {
2310 var i = 0, length = set.length;
2311 for ( ; i < length; i++ ) {
2312 if ( set[ i ] !== null ) {
2313 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
2314 }
2315 }
2316 },
2317
2318 // Restores a set of previously saved properties from a data storage
2319 restore: function( element, set ) {
2320 var val, i = 0, length = set.length;
2321 for ( ; i < length; i++ ) {
2322 if ( set[ i ] !== null ) {
2323 val = element.data( dataSpace + set[ i ] );
2324 element.css( set[ i ], val );
2325 }
2326 }
2327 },
2328
2329 setMode: function( el, mode ) {
2330 if ( mode === "toggle" ) {
2331 mode = el.is( ":hidden" ) ? "show" : "hide";
2332 }
2333 return mode;
2334 },
2335
2336 // Wraps the element around a wrapper that copies position properties
2337 createWrapper: function( element ) {
2338
2339 // If the element is already wrapped, return it
2340 if ( element.parent().is( ".ui-effects-wrapper" ) ) {
2341 return element.parent();
2342 }
2343
2344 // Wrap the element
2345 var props = {
2346 width: element.outerWidth( true ),
2347 height: element.outerHeight( true ),
2348 "float": element.css( "float" )
2349 },
2350 wrapper = $( "<div></div>" )
2351 .addClass( "ui-effects-wrapper" )
2352 .css( {
2353 fontSize: "100%",
2354 background: "transparent",
2355 border: "none",
2356 margin: 0,
2357 padding: 0
2358 } ),
2359
2360 // Store the size in case width/height are defined in % - Fixes #5245
2361 size = {
2362 width: element.width(),
2363 height: element.height()
2364 },
2365 active = document.activeElement;
2366
2367 // Support: Firefox
2368 // Firefox incorrectly exposes anonymous content
2369 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
2370 try {
2371 // eslint-disable-next-line no-unused-expressions
2372 active.id;
2373 } catch ( e ) {
2374 active = document.body;
2375 }
2376
2377 element.wrap( wrapper );
2378
2379 // Fixes #7595 - Elements lose focus when wrapped.
2380 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
2381 $( active ).trigger( "focus" );
2382 }
2383
2384 // Hotfix for jQuery 1.4 since some change in wrap() seems to actually
2385 // lose the reference to the wrapped element
2386 wrapper = element.parent();
2387
2388 // Transfer positioning properties to the wrapper
2389 if ( element.css( "position" ) === "static" ) {
2390 wrapper.css( { position: "relative" } );
2391 element.css( { position: "relative" } );
2392 } else {
2393 $.extend( props, {
2394 position: element.css( "position" ),
2395 zIndex: element.css( "z-index" )
2396 } );
2397 $.each( [ "top", "left", "bottom", "right" ], function( i, pos ) {
2398 props[ pos ] = element.css( pos );
2399 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
2400 props[ pos ] = "auto";
2401 }
2402 } );
2403 element.css( {
2404 position: "relative",
2405 top: 0,
2406 left: 0,
2407 right: "auto",
2408 bottom: "auto"
2409 } );
2410 }
2411 element.css( size );
2412
2413 return wrapper.css( props ).show();
2414 },
2415
2416 removeWrapper: function( element ) {
2417 var active = document.activeElement;
2418
2419 if ( element.parent().is( ".ui-effects-wrapper" ) ) {
2420 element.parent().replaceWith( element );
2421
2422 // Fixes #7595 - Elements lose focus when wrapped.
2423 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
2424 $( active ).trigger( "focus" );
2425 }
2426 }
2427
2428 return element;
2429 }
2430 } );
2431 }
2432
2433 $.extend( $.effects, {
2434 version: "1.13.2",
2435
2436 define: function( name, mode, effect ) {
2437 if ( !effect ) {
2438 effect = mode;
2439 mode = "effect";
2440 }
2441
2442 $.effects.effect[ name ] = effect;
2443 $.effects.effect[ name ].mode = mode;
2444
2445 return effect;
2446 },
2447
2448 scaledDimensions: function( element, percent, direction ) {
2449 if ( percent === 0 ) {
2450 return {
2451 height: 0,
2452 width: 0,
2453 outerHeight: 0,
2454 outerWidth: 0
2455 };
2456 }
2457
2458 var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1,
2459 y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1;
2460
2461 return {
2462 height: element.height() * y,
2463 width: element.width() * x,
2464 outerHeight: element.outerHeight() * y,
2465 outerWidth: element.outerWidth() * x
2466 };
2467
2468 },
2469
2470 clipToBox: function( animation ) {
2471 return {
2472 width: animation.clip.right - animation.clip.left,
2473 height: animation.clip.bottom - animation.clip.top,
2474 left: animation.clip.left,
2475 top: animation.clip.top
2476 };
2477 },
2478
2479 // Injects recently queued functions to be first in line (after "inprogress")
2480 unshift: function( element, queueLength, count ) {
2481 var queue = element.queue();
2482
2483 if ( queueLength > 1 ) {
2484 queue.splice.apply( queue,
2485 [ 1, 0 ].concat( queue.splice( queueLength, count ) ) );
2486 }
2487 element.dequeue();
2488 },
2489
2490 saveStyle: function( element ) {
2491 element.data( dataSpaceStyle, element[ 0 ].style.cssText );
2492 },
2493
2494 restoreStyle: function( element ) {
2495 element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || "";
2496 element.removeData( dataSpaceStyle );
2497 },
2498
2499 mode: function( element, mode ) {
2500 var hidden = element.is( ":hidden" );
2501
2502 if ( mode === "toggle" ) {
2503 mode = hidden ? "show" : "hide";
2504 }
2505 if ( hidden ? mode === "hide" : mode === "show" ) {
2506 mode = "none";
2507 }
2508 return mode;
2509 },
2510
2511 // Translates a [top,left] array into a baseline value
2512 getBaseline: function( origin, original ) {
2513 var y, x;
2514
2515 switch ( origin[ 0 ] ) {
2516 case "top":
2517 y = 0;
2518 break;
2519 case "middle":
2520 y = 0.5;
2521 break;
2522 case "bottom":
2523 y = 1;
2524 break;
2525 default:
2526 y = origin[ 0 ] / original.height;
2527 }
2528
2529 switch ( origin[ 1 ] ) {
2530 case "left":
2531 x = 0;
2532 break;
2533 case "center":
2534 x = 0.5;
2535 break;
2536 case "right":
2537 x = 1;
2538 break;
2539 default:
2540 x = origin[ 1 ] / original.width;
2541 }
2542
2543 return {
2544 x: x,
2545 y: y
2546 };
2547 },
2548
2549 // Creates a placeholder element so that the original element can be made absolute
2550 createPlaceholder: function( element ) {
2551 var placeholder,
2552 cssPosition = element.css( "position" ),
2553 position = element.position();
2554
2555 // Lock in margins first to account for form elements, which
2556 // will change margin if you explicitly set height
2557 // see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380
2558 // Support: Safari
2559 element.css( {
2560 marginTop: element.css( "marginTop" ),
2561 marginBottom: element.css( "marginBottom" ),
2562 marginLeft: element.css( "marginLeft" ),
2563 marginRight: element.css( "marginRight" )
2564 } )
2565 .outerWidth( element.outerWidth() )
2566 .outerHeight( element.outerHeight() );
2567
2568 if ( /^(static|relative)/.test( cssPosition ) ) {
2569 cssPosition = "absolute";
2570
2571 placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( {
2572
2573 // Convert inline to inline block to account for inline elements
2574 // that turn to inline block based on content (like img)
2575 display: /^(inline|ruby)/.test( element.css( "display" ) ) ?
2576 "inline-block" :
2577 "block",
2578 visibility: "hidden",
2579
2580 // Margins need to be set to account for margin collapse
2581 marginTop: element.css( "marginTop" ),
2582 marginBottom: element.css( "marginBottom" ),
2583 marginLeft: element.css( "marginLeft" ),
2584 marginRight: element.css( "marginRight" ),
2585 "float": element.css( "float" )
2586 } )
2587 .outerWidth( element.outerWidth() )
2588 .outerHeight( element.outerHeight() )
2589 .addClass( "ui-effects-placeholder" );
2590
2591 element.data( dataSpace + "placeholder", placeholder );
2592 }
2593
2594 element.css( {
2595 position: cssPosition,
2596 left: position.left,
2597 top: position.top
2598 } );
2599
2600 return placeholder;
2601 },
2602
2603 removePlaceholder: function( element ) {
2604 var dataKey = dataSpace + "placeholder",
2605 placeholder = element.data( dataKey );
2606
2607 if ( placeholder ) {
2608 placeholder.remove();
2609 element.removeData( dataKey );
2610 }
2611 },
2612
2613 // Removes a placeholder if it exists and restores
2614 // properties that were modified during placeholder creation
2615 cleanUp: function( element ) {
2616 $.effects.restoreStyle( element );
2617 $.effects.removePlaceholder( element );
2618 },
2619
2620 setTransition: function( element, list, factor, value ) {
2621 value = value || {};
2622 $.each( list, function( i, x ) {
2623 var unit = element.cssUnit( x );
2624 if ( unit[ 0 ] > 0 ) {
2625 value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
2626 }
2627 } );
2628 return value;
2629 }
2630 } );
2631
2632 // Return an effect options object for the given parameters:
2633 function _normalizeArguments( effect, options, speed, callback ) {
2634
2635 // Allow passing all options as the first parameter
2636 if ( $.isPlainObject( effect ) ) {
2637 options = effect;
2638 effect = effect.effect;
2639 }
2640
2641 // Convert to an object
2642 effect = { effect: effect };
2643
2644 // Catch (effect, null, ...)
2645 if ( options == null ) {
2646 options = {};
2647 }
2648
2649 // Catch (effect, callback)
2650 if ( typeof options === "function" ) {
2651 callback = options;
2652 speed = null;
2653 options = {};
2654 }
2655
2656 // Catch (effect, speed, ?)
2657 if ( typeof options === "number" || $.fx.speeds[ options ] ) {
2658 callback = speed;
2659 speed = options;
2660 options = {};
2661 }
2662
2663 // Catch (effect, options, callback)
2664 if ( typeof speed === "function" ) {
2665 callback = speed;
2666 speed = null;
2667 }
2668
2669 // Add options to effect
2670 if ( options ) {
2671 $.extend( effect, options );
2672 }
2673
2674 speed = speed || options.duration;
2675 effect.duration = $.fx.off ? 0 :
2676 typeof speed === "number" ? speed :
2677 speed in $.fx.speeds ? $.fx.speeds[ speed ] :
2678 $.fx.speeds._default;
2679
2680 effect.complete = callback || options.complete;
2681
2682 return effect;
2683 }
2684
2685 function standardAnimationOption( option ) {
2686
2687 // Valid standard speeds (nothing, number, named speed)
2688 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
2689 return true;
2690 }
2691
2692 // Invalid strings - treat as "normal" speed
2693 if ( typeof option === "string" && !$.effects.effect[ option ] ) {
2694 return true;
2695 }
2696
2697 // Complete callback
2698 if ( typeof option === "function" ) {
2699 return true;
2700 }
2701
2702 // Options hash (but not naming an effect)
2703 if ( typeof option === "object" && !option.effect ) {
2704 return true;
2705 }
2706
2707 // Didn't match any standard API
2708 return false;
2709 }
2710
2711 $.fn.extend( {
2712 effect: function( /* effect, options, speed, callback */ ) {
2713 var args = _normalizeArguments.apply( this, arguments ),
2714 effectMethod = $.effects.effect[ args.effect ],
2715 defaultMode = effectMethod.mode,
2716 queue = args.queue,
2717 queueName = queue || "fx",
2718 complete = args.complete,
2719 mode = args.mode,
2720 modes = [],
2721 prefilter = function( next ) {
2722 var el = $( this ),
2723 normalizedMode = $.effects.mode( el, mode ) || defaultMode;
2724
2725 // Sentinel for duck-punching the :animated pseudo-selector
2726 el.data( dataSpaceAnimated, true );
2727
2728 // Save effect mode for later use,
2729 // we can't just call $.effects.mode again later,
2730 // as the .show() below destroys the initial state
2731 modes.push( normalizedMode );
2732
2733 // See $.uiBackCompat inside of run() for removal of defaultMode in 1.14
2734 if ( defaultMode && ( normalizedMode === "show" ||
2735 ( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) {
2736 el.show();
2737 }
2738
2739 if ( !defaultMode || normalizedMode !== "none" ) {
2740 $.effects.saveStyle( el );
2741 }
2742
2743 if ( typeof next === "function" ) {
2744 next();
2745 }
2746 };
2747
2748 if ( $.fx.off || !effectMethod ) {
2749
2750 // Delegate to the original method (e.g., .show()) if possible
2751 if ( mode ) {
2752 return this[ mode ]( args.duration, complete );
2753 } else {
2754 return this.each( function() {
2755 if ( complete ) {
2756 complete.call( this );
2757 }
2758 } );
2759 }
2760 }
2761
2762 function run( next ) {
2763 var elem = $( this );
2764
2765 function cleanup() {
2766 elem.removeData( dataSpaceAnimated );
2767
2768 $.effects.cleanUp( elem );
2769
2770 if ( args.mode === "hide" ) {
2771 elem.hide();
2772 }
2773
2774 done();
2775 }
2776
2777 function done() {
2778 if ( typeof complete === "function" ) {
2779 complete.call( elem[ 0 ] );
2780 }
2781
2782 if ( typeof next === "function" ) {
2783 next();
2784 }
2785 }
2786
2787 // Override mode option on a per element basis,
2788 // as toggle can be either show or hide depending on element state
2789 args.mode = modes.shift();
2790
2791 if ( $.uiBackCompat !== false && !defaultMode ) {
2792 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
2793
2794 // Call the core method to track "olddisplay" properly
2795 elem[ mode ]();
2796 done();
2797 } else {
2798 effectMethod.call( elem[ 0 ], args, done );
2799 }
2800 } else {
2801 if ( args.mode === "none" ) {
2802
2803 // Call the core method to track "olddisplay" properly
2804 elem[ mode ]();
2805 done();
2806 } else {
2807 effectMethod.call( elem[ 0 ], args, cleanup );
2808 }
2809 }
2810 }
2811
2812 // Run prefilter on all elements first to ensure that
2813 // any showing or hiding happens before placeholder creation,
2814 // which ensures that any layout changes are correctly captured.
2815 return queue === false ?
2816 this.each( prefilter ).each( run ) :
2817 this.queue( queueName, prefilter ).queue( queueName, run );
2818 },
2819
2820 show: ( function( orig ) {
2821 return function( option ) {
2822 if ( standardAnimationOption( option ) ) {
2823 return orig.apply( this, arguments );
2824 } else {
2825 var args = _normalizeArguments.apply( this, arguments );
2826 args.mode = "show";
2827 return this.effect.call( this, args );
2828 }
2829 };
2830 } )( $.fn.show ),
2831
2832 hide: ( function( orig ) {
2833 return function( option ) {
2834 if ( standardAnimationOption( option ) ) {
2835 return orig.apply( this, arguments );
2836 } else {
2837 var args = _normalizeArguments.apply( this, arguments );
2838 args.mode = "hide";
2839 return this.effect.call( this, args );
2840 }
2841 };
2842 } )( $.fn.hide ),
2843
2844 toggle: ( function( orig ) {
2845 return function( option ) {
2846 if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
2847 return orig.apply( this, arguments );
2848 } else {
2849 var args = _normalizeArguments.apply( this, arguments );
2850 args.mode = "toggle";
2851 return this.effect.call( this, args );
2852 }
2853 };
2854 } )( $.fn.toggle ),
2855
2856 cssUnit: function( key ) {
2857 var style = this.css( key ),
2858 val = [];
2859
2860 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
2861 if ( style.indexOf( unit ) > 0 ) {
2862 val = [ parseFloat( style ), unit ];
2863 }
2864 } );
2865 return val;
2866 },
2867
2868 cssClip: function( clipObj ) {
2869 if ( clipObj ) {
2870 return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " +
2871 clipObj.bottom + "px " + clipObj.left + "px)" );
2872 }
2873 return parseClip( this.css( "clip" ), this );
2874 },
2875
2876 transfer: function( options, done ) {
2877 var element = $( this ),
2878 target = $( options.to ),
2879 targetFixed = target.css( "position" ) === "fixed",
2880 body = $( "body" ),
2881 fixTop = targetFixed ? body.scrollTop() : 0,
2882 fixLeft = targetFixed ? body.scrollLeft() : 0,
2883 endPosition = target.offset(),
2884 animation = {
2885 top: endPosition.top - fixTop,
2886 left: endPosition.left - fixLeft,
2887 height: target.innerHeight(),
2888 width: target.innerWidth()
2889 },
2890 startPosition = element.offset(),
2891 transfer = $( "<div class='ui-effects-transfer'></div>" );
2892
2893 transfer
2894 .appendTo( "body" )
2895 .addClass( options.className )
2896 .css( {
2897 top: startPosition.top - fixTop,
2898 left: startPosition.left - fixLeft,
2899 height: element.innerHeight(),
2900 width: element.innerWidth(),
2901 position: targetFixed ? "fixed" : "absolute"
2902 } )
2903 .animate( animation, options.duration, options.easing, function() {
2904 transfer.remove();
2905 if ( typeof done === "function" ) {
2906 done();
2907 }
2908 } );
2909 }
2910 } );
2911
2912 function parseClip( str, element ) {
2913 var outerWidth = element.outerWidth(),
2914 outerHeight = element.outerHeight(),
2915 clipRegex = /^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/,
2916 values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ];
2917
2918 return {
2919 top: parseFloat( values[ 1 ] ) || 0,
2920 right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ),
2921 bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ),
2922 left: parseFloat( values[ 4 ] ) || 0
2923 };
2924 }
2925
2926 $.fx.step.clip = function( fx ) {
2927 if ( !fx.clipInit ) {
2928 fx.start = $( fx.elem ).cssClip();
2929 if ( typeof fx.end === "string" ) {
2930 fx.end = parseClip( fx.end, fx.elem );
2931 }
2932 fx.clipInit = true;
2933 }
2934
2935 $( fx.elem ).cssClip( {
2936 top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top,
2937 right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right,
2938 bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom,
2939 left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left
2940 } );
2941 };
2942
2943 } )();
2944
2945 /******************************************************************************/
2946 /*********************************** EASING ***********************************/
2947 /******************************************************************************/
2948
2949 ( function() {
2950
2951 // Based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
2952
2953 var baseEasings = {};
2954
2955 $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
2956 baseEasings[ name ] = function( p ) {
2957 return Math.pow( p, i + 2 );
2958 };
2959 } );
2960
2961 $.extend( baseEasings, {
2962 Sine: function( p ) {
2963 return 1 - Math.cos( p * Math.PI / 2 );
2964 },
2965 Circ: function( p ) {
2966 return 1 - Math.sqrt( 1 - p * p );
2967 },
2968 Elastic: function( p ) {
2969 return p === 0 || p === 1 ? p :
2970 -Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );
2971 },
2972 Back: function( p ) {
2973 return p * p * ( 3 * p - 2 );
2974 },
2975 Bounce: function( p ) {
2976 var pow2,
2977 bounce = 4;
2978
2979 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
2980 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
2981 }
2982 } );
2983
2984 $.each( baseEasings, function( name, easeIn ) {
2985 $.easing[ "easeIn" + name ] = easeIn;
2986 $.easing[ "easeOut" + name ] = function( p ) {
2987 return 1 - easeIn( 1 - p );
2988 };
2989 $.easing[ "easeInOut" + name ] = function( p ) {
2990 return p < 0.5 ?
2991 easeIn( p * 2 ) / 2 :
2992 1 - easeIn( p * -2 + 2 ) / 2;
2993 };
2994 } );
2995
2996 } )();
2997
2998 var effect = $.effects;
2999
3000
3001 /*!
3002 * jQuery UI Effects Blind 1.13.2
3003 * http://jqueryui.com
3004 *
3005 * Copyright jQuery Foundation and other contributors
3006 * Released under the MIT license.
3007 * http://jquery.org/license
3008 */
3009
3010 //>>label: Blind Effect
3011 //>>group: Effects
3012 //>>description: Blinds the element.
3013 //>>docs: http://api.jqueryui.com/blind-effect/
3014 //>>demos: http://jqueryui.com/effect/
3015
3016
3017 var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) {
3018 var map = {
3019 up: [ "bottom", "top" ],
3020 vertical: [ "bottom", "top" ],
3021 down: [ "top", "bottom" ],
3022 left: [ "right", "left" ],
3023 horizontal: [ "right", "left" ],
3024 right: [ "left", "right" ]
3025 },
3026 element = $( this ),
3027 direction = options.direction || "up",
3028 start = element.cssClip(),
3029 animate = { clip: $.extend( {}, start ) },
3030 placeholder = $.effects.createPlaceholder( element );
3031
3032 animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ];
3033
3034 if ( options.mode === "show" ) {
3035 element.cssClip( animate.clip );
3036 if ( placeholder ) {
3037 placeholder.css( $.effects.clipToBox( animate ) );
3038 }
3039
3040 animate.clip = start;
3041 }
3042
3043 if ( placeholder ) {
3044 placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing );
3045 }
3046
3047 element.animate( animate, {
3048 queue: false,
3049 duration: options.duration,
3050 easing: options.easing,
3051 complete: done
3052 } );
3053 } );
3054
3055
3056 /*!
3057 * jQuery UI Effects Bounce 1.13.2
3058 * http://jqueryui.com
3059 *
3060 * Copyright jQuery Foundation and other contributors
3061 * Released under the MIT license.
3062 * http://jquery.org/license
3063 */
3064
3065 //>>label: Bounce Effect
3066 //>>group: Effects
3067 //>>description: Bounces an element horizontally or vertically n times.
3068 //>>docs: http://api.jqueryui.com/bounce-effect/
3069 //>>demos: http://jqueryui.com/effect/
3070
3071
3072 var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) {
3073 var upAnim, downAnim, refValue,
3074 element = $( this ),
3075
3076 // Defaults:
3077 mode = options.mode,
3078 hide = mode === "hide",
3079 show = mode === "show",
3080 direction = options.direction || "up",
3081 distance = options.distance,
3082 times = options.times || 5,
3083
3084 // Number of internal animations
3085 anims = times * 2 + ( show || hide ? 1 : 0 ),
3086 speed = options.duration / anims,
3087 easing = options.easing,
3088
3089 // Utility:
3090 ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3091 motion = ( direction === "up" || direction === "left" ),
3092 i = 0,
3093
3094 queuelen = element.queue().length;
3095
3096 $.effects.createPlaceholder( element );
3097
3098 refValue = element.css( ref );
3099
3100 // Default distance for the BIGGEST bounce is the outer Distance / 3
3101 if ( !distance ) {
3102 distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
3103 }
3104
3105 if ( show ) {
3106 downAnim = { opacity: 1 };
3107 downAnim[ ref ] = refValue;
3108
3109 // If we are showing, force opacity 0 and set the initial position
3110 // then do the "first" animation
3111 element
3112 .css( "opacity", 0 )
3113 .css( ref, motion ? -distance * 2 : distance * 2 )
3114 .animate( downAnim, speed, easing );
3115 }
3116
3117 // Start at the smallest distance if we are hiding
3118 if ( hide ) {
3119 distance = distance / Math.pow( 2, times - 1 );
3120 }
3121
3122 downAnim = {};
3123 downAnim[ ref ] = refValue;
3124
3125 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
3126 for ( ; i < times; i++ ) {
3127 upAnim = {};
3128 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
3129
3130 element
3131 .animate( upAnim, speed, easing )
3132 .animate( downAnim, speed, easing );
3133
3134 distance = hide ? distance * 2 : distance / 2;
3135 }
3136
3137 // Last Bounce when Hiding
3138 if ( hide ) {
3139 upAnim = { opacity: 0 };
3140 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
3141
3142 element.animate( upAnim, speed, easing );
3143 }
3144
3145 element.queue( done );
3146
3147 $.effects.unshift( element, queuelen, anims + 1 );
3148 } );
3149
3150
3151 /*!
3152 * jQuery UI Effects Clip 1.13.2
3153 * http://jqueryui.com
3154 *
3155 * Copyright jQuery Foundation and other contributors
3156 * Released under the MIT license.
3157 * http://jquery.org/license
3158 */
3159
3160 //>>label: Clip Effect
3161 //>>group: Effects
3162 //>>description: Clips the element on and off like an old TV.
3163 //>>docs: http://api.jqueryui.com/clip-effect/
3164 //>>demos: http://jqueryui.com/effect/
3165
3166
3167 var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) {
3168 var start,
3169 animate = {},
3170 element = $( this ),
3171 direction = options.direction || "vertical",
3172 both = direction === "both",
3173 horizontal = both || direction === "horizontal",
3174 vertical = both || direction === "vertical";
3175
3176 start = element.cssClip();
3177 animate.clip = {
3178 top: vertical ? ( start.bottom - start.top ) / 2 : start.top,
3179 right: horizontal ? ( start.right - start.left ) / 2 : start.right,
3180 bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom,
3181 left: horizontal ? ( start.right - start.left ) / 2 : start.left
3182 };
3183
3184 $.effects.createPlaceholder( element );
3185
3186 if ( options.mode === "show" ) {
3187 element.cssClip( animate.clip );
3188 animate.clip = start;
3189 }
3190
3191 element.animate( animate, {
3192 queue: false,
3193 duration: options.duration,
3194 easing: options.easing,
3195 complete: done
3196 } );
3197
3198 } );
3199
3200
3201 /*!
3202 * jQuery UI Effects Drop 1.13.2
3203 * http://jqueryui.com
3204 *
3205 * Copyright jQuery Foundation and other contributors
3206 * Released under the MIT license.
3207 * http://jquery.org/license
3208 */
3209
3210 //>>label: Drop Effect
3211 //>>group: Effects
3212 //>>description: Moves an element in one direction and hides it at the same time.
3213 //>>docs: http://api.jqueryui.com/drop-effect/
3214 //>>demos: http://jqueryui.com/effect/
3215
3216
3217 var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) {
3218
3219 var distance,
3220 element = $( this ),
3221 mode = options.mode,
3222 show = mode === "show",
3223 direction = options.direction || "left",
3224 ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3225 motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=",
3226 oppositeMotion = ( motion === "+=" ) ? "-=" : "+=",
3227 animation = {
3228 opacity: 0
3229 };
3230
3231 $.effects.createPlaceholder( element );
3232
3233 distance = options.distance ||
3234 element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
3235
3236 animation[ ref ] = motion + distance;
3237
3238 if ( show ) {
3239 element.css( animation );
3240
3241 animation[ ref ] = oppositeMotion + distance;
3242 animation.opacity = 1;
3243 }
3244
3245 // Animate
3246 element.animate( animation, {
3247 queue: false,
3248 duration: options.duration,
3249 easing: options.easing,
3250 complete: done
3251 } );
3252 } );
3253
3254
3255 /*!
3256 * jQuery UI Effects Explode 1.13.2
3257 * http://jqueryui.com
3258 *
3259 * Copyright jQuery Foundation and other contributors
3260 * Released under the MIT license.
3261 * http://jquery.org/license
3262 */
3263
3264 //>>label: Explode Effect
3265 //>>group: Effects
3266 /* eslint-disable max-len */
3267 //>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness.
3268 /* eslint-enable max-len */
3269 //>>docs: http://api.jqueryui.com/explode-effect/
3270 //>>demos: http://jqueryui.com/effect/
3271
3272
3273 var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) {
3274
3275 var i, j, left, top, mx, my,
3276 rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3,
3277 cells = rows,
3278 element = $( this ),
3279 mode = options.mode,
3280 show = mode === "show",
3281
3282 // Show and then visibility:hidden the element before calculating offset
3283 offset = element.show().css( "visibility", "hidden" ).offset(),
3284
3285 // Width and height of a piece
3286 width = Math.ceil( element.outerWidth() / cells ),
3287 height = Math.ceil( element.outerHeight() / rows ),
3288 pieces = [];
3289
3290 // Children animate complete:
3291 function childComplete() {
3292 pieces.push( this );
3293 if ( pieces.length === rows * cells ) {
3294 animComplete();
3295 }
3296 }
3297
3298 // Clone the element for each row and cell.
3299 for ( i = 0; i < rows; i++ ) { // ===>
3300 top = offset.top + i * height;
3301 my = i - ( rows - 1 ) / 2;
3302
3303 for ( j = 0; j < cells; j++ ) { // |||
3304 left = offset.left + j * width;
3305 mx = j - ( cells - 1 ) / 2;
3306
3307 // Create a clone of the now hidden main element that will be absolute positioned
3308 // within a wrapper div off the -left and -top equal to size of our pieces
3309 element
3310 .clone()
3311 .appendTo( "body" )
3312 .wrap( "<div></div>" )
3313 .css( {
3314 position: "absolute",
3315 visibility: "visible",
3316 left: -j * width,
3317 top: -i * height
3318 } )
3319
3320 // Select the wrapper - make it overflow: hidden and absolute positioned based on
3321 // where the original was located +left and +top equal to the size of pieces
3322 .parent()
3323 .addClass( "ui-effects-explode" )
3324 .css( {
3325 position: "absolute",
3326 overflow: "hidden",
3327 width: width,
3328 height: height,
3329 left: left + ( show ? mx * width : 0 ),
3330 top: top + ( show ? my * height : 0 ),
3331 opacity: show ? 0 : 1
3332 } )
3333 .animate( {
3334 left: left + ( show ? 0 : mx * width ),
3335 top: top + ( show ? 0 : my * height ),
3336 opacity: show ? 1 : 0
3337 }, options.duration || 500, options.easing, childComplete );
3338 }
3339 }
3340
3341 function animComplete() {
3342 element.css( {
3343 visibility: "visible"
3344 } );
3345 $( pieces ).remove();
3346 done();
3347 }
3348 } );
3349
3350
3351 /*!
3352 * jQuery UI Effects Fade 1.13.2
3353 * http://jqueryui.com
3354 *
3355 * Copyright jQuery Foundation and other contributors
3356 * Released under the MIT license.
3357 * http://jquery.org/license
3358 */
3359
3360 //>>label: Fade Effect
3361 //>>group: Effects
3362 //>>description: Fades the element.
3363 //>>docs: http://api.jqueryui.com/fade-effect/
3364 //>>demos: http://jqueryui.com/effect/
3365
3366
3367 var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) {
3368 var show = options.mode === "show";
3369
3370 $( this )
3371 .css( "opacity", show ? 0 : 1 )
3372 .animate( {
3373 opacity: show ? 1 : 0
3374 }, {
3375 queue: false,
3376 duration: options.duration,
3377 easing: options.easing,
3378 complete: done
3379 } );
3380 } );
3381
3382
3383 /*!
3384 * jQuery UI Effects Fold 1.13.2
3385 * http://jqueryui.com
3386 *
3387 * Copyright jQuery Foundation and other contributors
3388 * Released under the MIT license.
3389 * http://jquery.org/license
3390 */
3391
3392 //>>label: Fold Effect
3393 //>>group: Effects
3394 //>>description: Folds an element first horizontally and then vertically.
3395 //>>docs: http://api.jqueryui.com/fold-effect/
3396 //>>demos: http://jqueryui.com/effect/
3397
3398
3399 var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) {
3400
3401 // Create element
3402 var element = $( this ),
3403 mode = options.mode,
3404 show = mode === "show",
3405 hide = mode === "hide",
3406 size = options.size || 15,
3407 percent = /([0-9]+)%/.exec( size ),
3408 horizFirst = !!options.horizFirst,
3409 ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ],
3410 duration = options.duration / 2,
3411
3412 placeholder = $.effects.createPlaceholder( element ),
3413
3414 start = element.cssClip(),
3415 animation1 = { clip: $.extend( {}, start ) },
3416 animation2 = { clip: $.extend( {}, start ) },
3417
3418 distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ],
3419
3420 queuelen = element.queue().length;
3421
3422 if ( percent ) {
3423 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
3424 }
3425 animation1.clip[ ref[ 0 ] ] = size;
3426 animation2.clip[ ref[ 0 ] ] = size;
3427 animation2.clip[ ref[ 1 ] ] = 0;
3428
3429 if ( show ) {
3430 element.cssClip( animation2.clip );
3431 if ( placeholder ) {
3432 placeholder.css( $.effects.clipToBox( animation2 ) );
3433 }
3434
3435 animation2.clip = start;
3436 }
3437
3438 // Animate
3439 element
3440 .queue( function( next ) {
3441 if ( placeholder ) {
3442 placeholder
3443 .animate( $.effects.clipToBox( animation1 ), duration, options.easing )
3444 .animate( $.effects.clipToBox( animation2 ), duration, options.easing );
3445 }
3446
3447 next();
3448 } )
3449 .animate( animation1, duration, options.easing )
3450 .animate( animation2, duration, options.easing )
3451 .queue( done );
3452
3453 $.effects.unshift( element, queuelen, 4 );
3454 } );
3455
3456
3457 /*!
3458 * jQuery UI Effects Highlight 1.13.2
3459 * http://jqueryui.com
3460 *
3461 * Copyright jQuery Foundation and other contributors
3462 * Released under the MIT license.
3463 * http://jquery.org/license
3464 */
3465
3466 //>>label: Highlight Effect
3467 //>>group: Effects
3468 //>>description: Highlights the background of an element in a defined color for a custom duration.
3469 //>>docs: http://api.jqueryui.com/highlight-effect/
3470 //>>demos: http://jqueryui.com/effect/
3471
3472
3473 var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) {
3474 var element = $( this ),
3475 animation = {
3476 backgroundColor: element.css( "backgroundColor" )
3477 };
3478
3479 if ( options.mode === "hide" ) {
3480 animation.opacity = 0;
3481 }
3482
3483 $.effects.saveStyle( element );
3484
3485 element
3486 .css( {
3487 backgroundImage: "none",
3488 backgroundColor: options.color || "#ffff99"
3489 } )
3490 .animate( animation, {
3491 queue: false,
3492 duration: options.duration,
3493 easing: options.easing,
3494 complete: done
3495 } );
3496 } );
3497
3498
3499 /*!
3500 * jQuery UI Effects Size 1.13.2
3501 * http://jqueryui.com
3502 *
3503 * Copyright jQuery Foundation and other contributors
3504 * Released under the MIT license.
3505 * http://jquery.org/license
3506 */
3507
3508 //>>label: Size Effect
3509 //>>group: Effects
3510 //>>description: Resize an element to a specified width and height.
3511 //>>docs: http://api.jqueryui.com/size-effect/
3512 //>>demos: http://jqueryui.com/effect/
3513
3514
3515 var effectsEffectSize = $.effects.define( "size", function( options, done ) {
3516
3517 // Create element
3518 var baseline, factor, temp,
3519 element = $( this ),
3520
3521 // Copy for children
3522 cProps = [ "fontSize" ],
3523 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
3524 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
3525
3526 // Set options
3527 mode = options.mode,
3528 restore = mode !== "effect",
3529 scale = options.scale || "both",
3530 origin = options.origin || [ "middle", "center" ],
3531 position = element.css( "position" ),
3532 pos = element.position(),
3533 original = $.effects.scaledDimensions( element ),
3534 from = options.from || original,
3535 to = options.to || $.effects.scaledDimensions( element, 0 );
3536
3537 $.effects.createPlaceholder( element );
3538
3539 if ( mode === "show" ) {
3540 temp = from;
3541 from = to;
3542 to = temp;
3543 }
3544
3545 // Set scaling factor
3546 factor = {
3547 from: {
3548 y: from.height / original.height,
3549 x: from.width / original.width
3550 },
3551 to: {
3552 y: to.height / original.height,
3553 x: to.width / original.width
3554 }
3555 };
3556
3557 // Scale the css box
3558 if ( scale === "box" || scale === "both" ) {
3559
3560 // Vertical props scaling
3561 if ( factor.from.y !== factor.to.y ) {
3562 from = $.effects.setTransition( element, vProps, factor.from.y, from );
3563 to = $.effects.setTransition( element, vProps, factor.to.y, to );
3564 }
3565
3566 // Horizontal props scaling
3567 if ( factor.from.x !== factor.to.x ) {
3568 from = $.effects.setTransition( element, hProps, factor.from.x, from );
3569 to = $.effects.setTransition( element, hProps, factor.to.x, to );
3570 }
3571 }
3572
3573 // Scale the content
3574 if ( scale === "content" || scale === "both" ) {
3575
3576 // Vertical props scaling
3577 if ( factor.from.y !== factor.to.y ) {
3578 from = $.effects.setTransition( element, cProps, factor.from.y, from );
3579 to = $.effects.setTransition( element, cProps, factor.to.y, to );
3580 }
3581 }
3582
3583 // Adjust the position properties based on the provided origin points
3584 if ( origin ) {
3585 baseline = $.effects.getBaseline( origin, original );
3586 from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top;
3587 from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left;
3588 to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top;
3589 to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left;
3590 }
3591 delete from.outerHeight;
3592 delete from.outerWidth;
3593 element.css( from );
3594
3595 // Animate the children if desired
3596 if ( scale === "content" || scale === "both" ) {
3597
3598 vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps );
3599 hProps = hProps.concat( [ "marginLeft", "marginRight" ] );
3600
3601 // Only animate children with width attributes specified
3602 // TODO: is this right? should we include anything with css width specified as well
3603 element.find( "*[width]" ).each( function() {
3604 var child = $( this ),
3605 childOriginal = $.effects.scaledDimensions( child ),
3606 childFrom = {
3607 height: childOriginal.height * factor.from.y,
3608 width: childOriginal.width * factor.from.x,
3609 outerHeight: childOriginal.outerHeight * factor.from.y,
3610 outerWidth: childOriginal.outerWidth * factor.from.x
3611 },
3612 childTo = {
3613 height: childOriginal.height * factor.to.y,
3614 width: childOriginal.width * factor.to.x,
3615 outerHeight: childOriginal.height * factor.to.y,
3616 outerWidth: childOriginal.width * factor.to.x
3617 };
3618
3619 // Vertical props scaling
3620 if ( factor.from.y !== factor.to.y ) {
3621 childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom );
3622 childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo );
3623 }
3624
3625 // Horizontal props scaling
3626 if ( factor.from.x !== factor.to.x ) {
3627 childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom );
3628 childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo );
3629 }
3630
3631 if ( restore ) {
3632 $.effects.saveStyle( child );
3633 }
3634
3635 // Animate children
3636 child.css( childFrom );
3637 child.animate( childTo, options.duration, options.easing, function() {
3638
3639 // Restore children
3640 if ( restore ) {
3641 $.effects.restoreStyle( child );
3642 }
3643 } );
3644 } );
3645 }
3646
3647 // Animate
3648 element.animate( to, {
3649 queue: false,
3650 duration: options.duration,
3651 easing: options.easing,
3652 complete: function() {
3653
3654 var offset = element.offset();
3655
3656 if ( to.opacity === 0 ) {
3657 element.css( "opacity", from.opacity );
3658 }
3659
3660 if ( !restore ) {
3661 element
3662 .css( "position", position === "static" ? "relative" : position )
3663 .offset( offset );
3664
3665 // Need to save style here so that automatic style restoration
3666 // doesn't restore to the original styles from before the animation.
3667 $.effects.saveStyle( element );
3668 }
3669
3670 done();
3671 }
3672 } );
3673
3674 } );
3675
3676
3677 /*!
3678 * jQuery UI Effects Scale 1.13.2
3679 * http://jqueryui.com
3680 *
3681 * Copyright jQuery Foundation and other contributors
3682 * Released under the MIT license.
3683 * http://jquery.org/license
3684 */
3685
3686 //>>label: Scale Effect
3687 //>>group: Effects
3688 //>>description: Grows or shrinks an element and its content.
3689 //>>docs: http://api.jqueryui.com/scale-effect/
3690 //>>demos: http://jqueryui.com/effect/
3691
3692
3693 var effectsEffectScale = $.effects.define( "scale", function( options, done ) {
3694
3695 // Create element
3696 var el = $( this ),
3697 mode = options.mode,
3698 percent = parseInt( options.percent, 10 ) ||
3699 ( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ),
3700
3701 newOptions = $.extend( true, {
3702 from: $.effects.scaledDimensions( el ),
3703 to: $.effects.scaledDimensions( el, percent, options.direction || "both" ),
3704 origin: options.origin || [ "middle", "center" ]
3705 }, options );
3706
3707 // Fade option to support puff
3708 if ( options.fade ) {
3709 newOptions.from.opacity = 1;
3710 newOptions.to.opacity = 0;
3711 }
3712
3713 $.effects.effect.size.call( this, newOptions, done );
3714 } );
3715
3716
3717 /*!
3718 * jQuery UI Effects Puff 1.13.2
3719 * http://jqueryui.com
3720 *
3721 * Copyright jQuery Foundation and other contributors
3722 * Released under the MIT license.
3723 * http://jquery.org/license
3724 */
3725
3726 //>>label: Puff Effect
3727 //>>group: Effects
3728 //>>description: Creates a puff effect by scaling the element up and hiding it at the same time.
3729 //>>docs: http://api.jqueryui.com/puff-effect/
3730 //>>demos: http://jqueryui.com/effect/
3731
3732
3733 var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) {
3734 var newOptions = $.extend( true, {}, options, {
3735 fade: true,
3736 percent: parseInt( options.percent, 10 ) || 150
3737 } );
3738
3739 $.effects.effect.scale.call( this, newOptions, done );
3740 } );
3741
3742
3743 /*!
3744 * jQuery UI Effects Pulsate 1.13.2
3745 * http://jqueryui.com
3746 *
3747 * Copyright jQuery Foundation and other contributors
3748 * Released under the MIT license.
3749 * http://jquery.org/license
3750 */
3751
3752 //>>label: Pulsate Effect
3753 //>>group: Effects
3754 //>>description: Pulsates an element n times by changing the opacity to zero and back.
3755 //>>docs: http://api.jqueryui.com/pulsate-effect/
3756 //>>demos: http://jqueryui.com/effect/
3757
3758
3759 var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) {
3760 var element = $( this ),
3761 mode = options.mode,
3762 show = mode === "show",
3763 hide = mode === "hide",
3764 showhide = show || hide,
3765
3766 // Showing or hiding leaves off the "last" animation
3767 anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
3768 duration = options.duration / anims,
3769 animateTo = 0,
3770 i = 1,
3771 queuelen = element.queue().length;
3772
3773 if ( show || !element.is( ":visible" ) ) {
3774 element.css( "opacity", 0 ).show();
3775 animateTo = 1;
3776 }
3777
3778 // Anims - 1 opacity "toggles"
3779 for ( ; i < anims; i++ ) {
3780 element.animate( { opacity: animateTo }, duration, options.easing );
3781 animateTo = 1 - animateTo;
3782 }
3783
3784 element.animate( { opacity: animateTo }, duration, options.easing );
3785
3786 element.queue( done );
3787
3788 $.effects.unshift( element, queuelen, anims + 1 );
3789 } );
3790
3791
3792 /*!
3793 * jQuery UI Effects Shake 1.13.2
3794 * http://jqueryui.com
3795 *
3796 * Copyright jQuery Foundation and other contributors
3797 * Released under the MIT license.
3798 * http://jquery.org/license
3799 */
3800
3801 //>>label: Shake Effect
3802 //>>group: Effects
3803 //>>description: Shakes an element horizontally or vertically n times.
3804 //>>docs: http://api.jqueryui.com/shake-effect/
3805 //>>demos: http://jqueryui.com/effect/
3806
3807
3808 var effectsEffectShake = $.effects.define( "shake", function( options, done ) {
3809
3810 var i = 1,
3811 element = $( this ),
3812 direction = options.direction || "left",
3813 distance = options.distance || 20,
3814 times = options.times || 3,
3815 anims = times * 2 + 1,
3816 speed = Math.round( options.duration / anims ),
3817 ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3818 positiveMotion = ( direction === "up" || direction === "left" ),
3819 animation = {},
3820 animation1 = {},
3821 animation2 = {},
3822
3823 queuelen = element.queue().length;
3824
3825 $.effects.createPlaceholder( element );
3826
3827 // Animation
3828 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
3829 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
3830 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
3831
3832 // Animate
3833 element.animate( animation, speed, options.easing );
3834
3835 // Shakes
3836 for ( ; i < times; i++ ) {
3837 element
3838 .animate( animation1, speed, options.easing )
3839 .animate( animation2, speed, options.easing );
3840 }
3841
3842 element
3843 .animate( animation1, speed, options.easing )
3844 .animate( animation, speed / 2, options.easing )
3845 .queue( done );
3846
3847 $.effects.unshift( element, queuelen, anims + 1 );
3848 } );
3849
3850
3851 /*!
3852 * jQuery UI Effects Slide 1.13.2
3853 * http://jqueryui.com
3854 *
3855 * Copyright jQuery Foundation and other contributors
3856 * Released under the MIT license.
3857 * http://jquery.org/license
3858 */
3859
3860 //>>label: Slide Effect
3861 //>>group: Effects
3862 //>>description: Slides an element in and out of the viewport.
3863 //>>docs: http://api.jqueryui.com/slide-effect/
3864 //>>demos: http://jqueryui.com/effect/
3865
3866
3867 var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) {
3868 var startClip, startRef,
3869 element = $( this ),
3870 map = {
3871 up: [ "bottom", "top" ],
3872 down: [ "top", "bottom" ],
3873 left: [ "right", "left" ],
3874 right: [ "left", "right" ]
3875 },
3876 mode = options.mode,
3877 direction = options.direction || "left",
3878 ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3879 positiveMotion = ( direction === "up" || direction === "left" ),
3880 distance = options.distance ||
3881 element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ),
3882 animation = {};
3883
3884 $.effects.createPlaceholder( element );
3885
3886 startClip = element.cssClip();
3887 startRef = element.position()[ ref ];
3888
3889 // Define hide animation
3890 animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef;
3891 animation.clip = element.cssClip();
3892 animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ];
3893
3894 // Reverse the animation if we're showing
3895 if ( mode === "show" ) {
3896 element.cssClip( animation.clip );
3897 element.css( ref, animation[ ref ] );
3898 animation.clip = startClip;
3899 animation[ ref ] = startRef;
3900 }
3901
3902 // Actually animate
3903 element.animate( animation, {
3904 queue: false,
3905 duration: options.duration,
3906 easing: options.easing,
3907 complete: done
3908 } );
3909 } );
3910
3911
3912 /*!
3913 * jQuery UI Effects Transfer 1.13.2
3914 * http://jqueryui.com
3915 *
3916 * Copyright jQuery Foundation and other contributors
3917 * Released under the MIT license.
3918 * http://jquery.org/license
3919 */
3920
3921 //>>label: Transfer Effect
3922 //>>group: Effects
3923 //>>description: Displays a transfer effect from one element to another.
3924 //>>docs: http://api.jqueryui.com/transfer-effect/
3925 //>>demos: http://jqueryui.com/effect/
3926
3927
3928 var effect;
3929 if ( $.uiBackCompat !== false ) {
3930 effect = $.effects.define( "transfer", function( options, done ) {
3931 $( this ).transfer( options, done );
3932 } );
3933 }
3934 var effectsEffectTransfer = effect;
3935
3936
3937 /*!
3938 * jQuery UI Focusable 1.13.2
3939 * http://jqueryui.com
3940 *
3941 * Copyright jQuery Foundation and other contributors
3942 * Released under the MIT license.
3943 * http://jquery.org/license
3944 */
3945
3946 //>>label: :focusable Selector
3947 //>>group: Core
3948 //>>description: Selects elements which can be focused.
3949 //>>docs: http://api.jqueryui.com/focusable-selector/
3950
3951
3952 // Selectors
3953 $.ui.focusable = function( element, hasTabindex ) {
3954 var map, mapName, img, focusableIfVisible, fieldset,
3955 nodeName = element.nodeName.toLowerCase();
3956
3957 if ( "area" === nodeName ) {
3958 map = element.parentNode;
3959 mapName = map.name;
3960 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
3961 return false;
3962 }
3963 img = $( "img[usemap='#" + mapName + "']" );
3964 return img.length > 0 && img.is( ":visible" );
3965 }
3966
3967 if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) {
3968 focusableIfVisible = !element.disabled;
3969
3970 if ( focusableIfVisible ) {
3971
3972 // Form controls within a disabled fieldset are disabled.
3973 // However, controls within the fieldset's legend do not get disabled.
3974 // Since controls generally aren't placed inside legends, we skip
3975 // this portion of the check.
3976 fieldset = $( element ).closest( "fieldset" )[ 0 ];
3977 if ( fieldset ) {
3978 focusableIfVisible = !fieldset.disabled;
3979 }
3980 }
3981 } else if ( "a" === nodeName ) {
3982 focusableIfVisible = element.href || hasTabindex;
3983 } else {
3984 focusableIfVisible = hasTabindex;
3985 }
3986
3987 return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) );
3988 };
3989
3990 // Support: IE 8 only
3991 // IE 8 doesn't resolve inherit to visible/hidden for computed values
3992 function visible( element ) {
3993 var visibility = element.css( "visibility" );
3994 while ( visibility === "inherit" ) {
3995 element = element.parent();
3996 visibility = element.css( "visibility" );
3997 }
3998 return visibility === "visible";
3999 }
4000
4001 $.extend( $.expr.pseudos, {
4002 focusable: function( element ) {
4003 return $.ui.focusable( element, $.attr( element, "tabindex" ) != null );
4004 }
4005 } );
4006
4007 var focusable = $.ui.focusable;
4008
4009
4010
4011 // Support: IE8 Only
4012 // IE8 does not support the form attribute and when it is supplied. It overwrites the form prop
4013 // with a string, so we need to find the proper form.
4014 var form = $.fn._form = function() {
4015 return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form );
4016 };
4017
4018
4019 /*!
4020 * jQuery UI Form Reset Mixin 1.13.2
4021 * http://jqueryui.com
4022 *
4023 * Copyright jQuery Foundation and other contributors
4024 * Released under the MIT license.
4025 * http://jquery.org/license
4026 */
4027
4028 //>>label: Form Reset Mixin
4029 //>>group: Core
4030 //>>description: Refresh input widgets when their form is reset
4031 //>>docs: http://api.jqueryui.com/form-reset-mixin/
4032
4033
4034 var formResetMixin = $.ui.formResetMixin = {
4035 _formResetHandler: function() {
4036 var form = $( this );
4037
4038 // Wait for the form reset to actually happen before refreshing
4039 setTimeout( function() {
4040 var instances = form.data( "ui-form-reset-instances" );
4041 $.each( instances, function() {
4042 this.refresh();
4043 } );
4044 } );
4045 },
4046
4047 _bindFormResetHandler: function() {
4048 this.form = this.element._form();
4049 if ( !this.form.length ) {
4050 return;
4051 }
4052
4053 var instances = this.form.data( "ui-form-reset-instances" ) || [];
4054 if ( !instances.length ) {
4055
4056 // We don't use _on() here because we use a single event handler per form
4057 this.form.on( "reset.ui-form-reset", this._formResetHandler );
4058 }
4059 instances.push( this );
4060 this.form.data( "ui-form-reset-instances", instances );
4061 },
4062
4063 _unbindFormResetHandler: function() {
4064 if ( !this.form.length ) {
4065 return;
4066 }
4067
4068 var instances = this.form.data( "ui-form-reset-instances" );
4069 instances.splice( $.inArray( this, instances ), 1 );
4070 if ( instances.length ) {
4071 this.form.data( "ui-form-reset-instances", instances );
4072 } else {
4073 this.form
4074 .removeData( "ui-form-reset-instances" )
4075 .off( "reset.ui-form-reset" );
4076 }
4077 }
4078 };
4079
4080
4081 /*!
4082 * jQuery UI Support for jQuery core 1.8.x and newer 1.13.2
4083 * http://jqueryui.com
4084 *
4085 * Copyright jQuery Foundation and other contributors
4086 * Released under the MIT license.
39 * http://jquery.org/license 4087 * http://jquery.org/license
40 * 4088 *
41 * http://docs.jquery.com/UI/Mouse 4089 */
4090
4091 //>>label: jQuery 1.8+ Support
4092 //>>group: Core
4093 //>>description: Support version 1.8.x and newer of jQuery core
4094
4095
4096 // Support: jQuery 1.9.x or older
4097 // $.expr[ ":" ] is deprecated.
4098 if ( !$.expr.pseudos ) {
4099 $.expr.pseudos = $.expr[ ":" ];
4100 }
4101
4102 // Support: jQuery 1.11.x or older
4103 // $.unique has been renamed to $.uniqueSort
4104 if ( !$.uniqueSort ) {
4105 $.uniqueSort = $.unique;
4106 }
4107
4108 // Support: jQuery 2.2.x or older.
4109 // This method has been defined in jQuery 3.0.0.
4110 // Code from https://github.com/jquery/jquery/blob/e539bac79e666bba95bba86d690b4e609dca2286/src/selector/escapeSelector.js
4111 if ( !$.escapeSelector ) {
4112
4113 // CSS string/identifier serialization
4114 // https://drafts.csswg.org/cssom/#common-serializing-idioms
4115 var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;
4116
4117 var fcssescape = function( ch, asCodePoint ) {
4118 if ( asCodePoint ) {
4119
4120 // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
4121 if ( ch === "\0" ) {
4122 return "\uFFFD";
4123 }
4124
4125 // Control characters and (dependent upon position) numbers get escaped as code points
4126 return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
4127 }
4128
4129 // Other potentially-special ASCII characters get backslash-escaped
4130 return "\\" + ch;
4131 };
4132
4133 $.escapeSelector = function( sel ) {
4134 return ( sel + "" ).replace( rcssescape, fcssescape );
4135 };
4136 }
4137
4138 // Support: jQuery 3.4.x or older
4139 // These methods have been defined in jQuery 3.5.0.
4140 if ( !$.fn.even || !$.fn.odd ) {
4141 $.fn.extend( {
4142 even: function() {
4143 return this.filter( function( i ) {
4144 return i % 2 === 0;
4145 } );
4146 },
4147 odd: function() {
4148 return this.filter( function( i ) {
4149 return i % 2 === 1;
4150 } );
4151 }
4152 } );
4153 }
4154
4155 ;
4156 /*!
4157 * jQuery UI Keycode 1.13.2
4158 * http://jqueryui.com
42 * 4159 *
43 * Depends: 4160 * Copyright jQuery Foundation and other contributors
44 * jquery.ui.widget.js 4161 * Released under the MIT license.
4162 * http://jquery.org/license
45 */ 4163 */
46 (function(b){var d=false;b(document).mouseup(function(){d=false});b.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var a=this;this.element.bind("mousedown."+this.widgetName,function(c){return a._mouseDown(c)}).bind("click."+this.widgetName,function(c){if(true===b.data(c.target,a.widgetName+".preventClickEvent")){b.removeData(c.target,a.widgetName+".preventClickEvent");c.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+ 4164
47 this.widgetName)},_mouseDown:function(a){if(!d){this._mouseStarted&&this._mouseUp(a);this._mouseDownEvent=a;var c=this,f=a.which==1,g=typeof this.options.cancel=="string"&&a.target.nodeName?b(a.target).closest(this.options.cancel).length:false;if(!f||g||!this._mouseCapture(a))return true;this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet)this._mouseDelayTimer=setTimeout(function(){c.mouseDelayMet=true},this.options.delay);if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a)){this._mouseStarted= 4165 //>>label: Keycode
48 this._mouseStart(a)!==false;if(!this._mouseStarted){a.preventDefault();return true}}true===b.data(a.target,this.widgetName+".preventClickEvent")&&b.removeData(a.target,this.widgetName+".preventClickEvent");this._mouseMoveDelegate=function(e){return c._mouseMove(e)};this._mouseUpDelegate=function(e){return c._mouseUp(e)};b(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);a.preventDefault();return d=true}},_mouseMove:function(a){if(b.browser.msie&& 4166 //>>group: Core
49 !(document.documentMode>=9)&&!a.button)return this._mouseUp(a);if(this._mouseStarted){this._mouseDrag(a);return a.preventDefault()}if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,a)!==false)?this._mouseDrag(a):this._mouseUp(a);return!this._mouseStarted},_mouseUp:function(a){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted= 4167 //>>description: Provide keycodes as keynames
50 false;a.target==this._mouseDownEvent.target&&b.data(a.target,this.widgetName+".preventClickEvent",true);this._mouseStop(a)}return false},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery); 4168 //>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/
51 ;/* 4169
52 * jQuery UI Sortable 1.8.16 4170
4171 var keycode = $.ui.keyCode = {
4172 BACKSPACE: 8,
4173 COMMA: 188,
4174 DELETE: 46,
4175 DOWN: 40,
4176 END: 35,
4177 ENTER: 13,
4178 ESCAPE: 27,
4179 HOME: 36,
4180 LEFT: 37,
4181 PAGE_DOWN: 34,
4182 PAGE_UP: 33,
4183 PERIOD: 190,
4184 RIGHT: 39,
4185 SPACE: 32,
4186 TAB: 9,
4187 UP: 38
4188 };
4189
4190
4191 /*!
4192 * jQuery UI Labels 1.13.2
4193 * http://jqueryui.com
53 * 4194 *
54 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 4195 * Copyright jQuery Foundation and other contributors
55 * Dual licensed under the MIT or GPL Version 2 licenses. 4196 * Released under the MIT license.
56 * http://jquery.org/license 4197 * http://jquery.org/license
4198 */
4199
4200 //>>label: labels
4201 //>>group: Core
4202 //>>description: Find all the labels associated with a given input
4203 //>>docs: http://api.jqueryui.com/labels/
4204
4205
4206 var labels = $.fn.labels = function() {
4207 var ancestor, selector, id, labels, ancestors;
4208
4209 if ( !this.length ) {
4210 return this.pushStack( [] );
4211 }
4212
4213 // Check control.labels first
4214 if ( this[ 0 ].labels && this[ 0 ].labels.length ) {
4215 return this.pushStack( this[ 0 ].labels );
4216 }
4217
4218 // Support: IE <= 11, FF <= 37, Android <= 2.3 only
4219 // Above browsers do not support control.labels. Everything below is to support them
4220 // as well as document fragments. control.labels does not work on document fragments
4221 labels = this.eq( 0 ).parents( "label" );
4222
4223 // Look for the label based on the id
4224 id = this.attr( "id" );
4225 if ( id ) {
4226
4227 // We don't search against the document in case the element
4228 // is disconnected from the DOM
4229 ancestor = this.eq( 0 ).parents().last();
4230
4231 // Get a full set of top level ancestors
4232 ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() );
4233
4234 // Create a selector for the label based on the id
4235 selector = "label[for='" + $.escapeSelector( id ) + "']";
4236
4237 labels = labels.add( ancestors.find( selector ).addBack( selector ) );
4238
4239 }
4240
4241 // Return whatever we have found for labels
4242 return this.pushStack( labels );
4243 };
4244
4245
4246 /*!
4247 * jQuery UI Scroll Parent 1.13.2
4248 * http://jqueryui.com
57 * 4249 *
58 * http://docs.jquery.com/UI/Sortables 4250 * Copyright jQuery Foundation and other contributors
4251 * Released under the MIT license.
4252 * http://jquery.org/license
4253 */
4254
4255 //>>label: scrollParent
4256 //>>group: Core
4257 //>>description: Get the closest ancestor element that is scrollable.
4258 //>>docs: http://api.jqueryui.com/scrollParent/
4259
4260
4261 var scrollParent = $.fn.scrollParent = function( includeHidden ) {
4262 var position = this.css( "position" ),
4263 excludeStaticParent = position === "absolute",
4264 overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
4265 scrollParent = this.parents().filter( function() {
4266 var parent = $( this );
4267 if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
4268 return false;
4269 }
4270 return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
4271 parent.css( "overflow-x" ) );
4272 } ).eq( 0 );
4273
4274 return position === "fixed" || !scrollParent.length ?
4275 $( this[ 0 ].ownerDocument || document ) :
4276 scrollParent;
4277 };
4278
4279
4280 /*!
4281 * jQuery UI Tabbable 1.13.2
4282 * http://jqueryui.com
59 * 4283 *
60 * Depends: 4284 * Copyright jQuery Foundation and other contributors
61 * jquery.ui.core.js 4285 * Released under the MIT license.
62 * jquery.ui.mouse.js 4286 * http://jquery.org/license
63 * jquery.ui.widget.js
64 */ 4287 */
65 (function(d){d.widget("ui.sortable",d.ui.mouse,{widgetEventPrefix:"sort",options:{appendTo:"parent",axis:false,connectWith:false,containment:false,cursor:"auto",cursorAt:false,dropOnEmpty:true,forcePlaceholderSize:false,forceHelperSize:false,grid:false,handle:false,helper:"original",items:"> *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1E3},_create:function(){var a=this.options;this.containerCache={};this.element.addClass("ui-sortable"); 4288
66 this.refresh();this.floating=this.items.length?a.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):false;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var a=this.items.length-1;a>=0;a--)this.items[a].item.removeData("sortable-item");return this},_setOption:function(a,b){if(a=== 4289 //>>label: :tabbable Selector
67 "disabled"){this.options[a]=b;this.widget()[b?"addClass":"removeClass"]("ui-sortable-disabled")}else d.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(a,b){if(this.reverting)return false;if(this.options.disabled||this.options.type=="static")return false;this._refreshItems(a);var c=null,e=this;d(a.target).parents().each(function(){if(d.data(this,"sortable-item")==e){c=d(this);return false}});if(d.data(a.target,"sortable-item")==e)c=d(a.target);if(!c)return false;if(this.options.handle&& 4290 //>>group: Core
68 !b){var f=false;d(this.options.handle,c).find("*").andSelf().each(function(){if(this==a.target)f=true});if(!f)return false}this.currentItem=c;this._removeCurrentsFromItems();return true},_mouseStart:function(a,b,c){b=this.options;var e=this;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(a);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top, 4291 //>>description: Selects elements which can be tabbed to.
69 left:this.offset.left-this.margins.left};this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]}; 4292 //>>docs: http://api.jqueryui.com/tabbable-selector/
70 this.helper[0]!=this.currentItem[0]&&this.currentItem.hide();this._createPlaceholder();b.containment&&this._setContainment();if(b.cursor){if(d("body").css("cursor"))this._storedCursor=d("body").css("cursor");d("body").css("cursor",b.cursor)}if(b.opacity){if(this.helper.css("opacity"))this._storedOpacity=this.helper.css("opacity");this.helper.css("opacity",b.opacity)}if(b.zIndex){if(this.helper.css("zIndex"))this._storedZIndex=this.helper.css("zIndex");this.helper.css("zIndex",b.zIndex)}if(this.scrollParent[0]!= 4293
71 document&&this.scrollParent[0].tagName!="HTML")this.overflowOffset=this.scrollParent.offset();this._trigger("start",a,this._uiHash());this._preserveHelperProportions||this._cacheHelperProportions();if(!c)for(c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("activate",a,e._uiHash(this));if(d.ui.ddmanager)d.ui.ddmanager.current=this;d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(a); 4294
72 return true},_mouseDrag:function(a){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!this.lastPositionAbs)this.lastPositionAbs=this.positionAbs;if(this.options.scroll){var b=this.options,c=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if(this.overflowOffset.top+this.scrollParent[0].offsetHeight-a.pageY<b.scrollSensitivity)this.scrollParent[0].scrollTop=c=this.scrollParent[0].scrollTop+b.scrollSpeed;else if(a.pageY-this.overflowOffset.top< 4295 var tabbable = $.extend( $.expr.pseudos, {
73 b.scrollSensitivity)this.scrollParent[0].scrollTop=c=this.scrollParent[0].scrollTop-b.scrollSpeed;if(this.overflowOffset.left+this.scrollParent[0].offsetWidth-a.pageX<b.scrollSensitivity)this.scrollParent[0].scrollLeft=c=this.scrollParent[0].scrollLeft+b.scrollSpeed;else if(a.pageX-this.overflowOffset.left<b.scrollSensitivity)this.scrollParent[0].scrollLeft=c=this.scrollParent[0].scrollLeft-b.scrollSpeed}else{if(a.pageY-d(document).scrollTop()<b.scrollSensitivity)c=d(document).scrollTop(d(document).scrollTop()- 4296 tabbable: function( element ) {
74 b.scrollSpeed);else if(d(window).height()-(a.pageY-d(document).scrollTop())<b.scrollSensitivity)c=d(document).scrollTop(d(document).scrollTop()+b.scrollSpeed);if(a.pageX-d(document).scrollLeft()<b.scrollSensitivity)c=d(document).scrollLeft(d(document).scrollLeft()-b.scrollSpeed);else if(d(window).width()-(a.pageX-d(document).scrollLeft())<b.scrollSensitivity)c=d(document).scrollLeft(d(document).scrollLeft()+b.scrollSpeed)}c!==false&&d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this, 4297 var tabIndex = $.attr( element, "tabindex" ),
75 a)}this.positionAbs=this._convertPositionTo("absolute");if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";for(b=this.items.length-1;b>=0;b--){c=this.items[b];var e=c.item[0],f=this._intersectsWithPointer(c);if(f)if(e!=this.currentItem[0]&&this.placeholder[f==1?"next":"prev"]()[0]!=e&&!d.ui.contains(this.placeholder[0],e)&&(this.options.type=="semi-dynamic"?!d.ui.contains(this.element[0], 4298 hasTabindex = tabIndex != null;
76 e):true)){this.direction=f==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(c))this._rearrange(a,c);else break;this._trigger("change",a,this._uiHash());break}}this._contactContainers(a);d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);this._trigger("sort",a,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(a,b){if(a){d.ui.ddmanager&&!this.options.dropBehaviour&&d.ui.ddmanager.drop(this,a);if(this.options.revert){var c=this;b=c.placeholder.offset(); 4299 return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex );
77 c.reverting=true;d(this.helper).animate({left:b.left-this.offset.parent.left-c.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:b.top-this.offset.parent.top-c.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){c._clear(a)})}else this._clear(a,b);return false}},cancel:function(){var a=this;if(this.dragging){this._mouseUp({target:null});this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"): 4300 }
78 this.currentItem.show();for(var b=this.containers.length-1;b>=0;b--){this.containers[b]._trigger("deactivate",null,a._uiHash(this));if(this.containers[b].containerCache.over){this.containers[b]._trigger("out",null,a._uiHash(this));this.containers[b].containerCache.over=0}}}if(this.placeholder){this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove();d.extend(this,{helper:null, 4301 } );
79 dragging:false,reverting:false,_noFinalSort:null});this.domPosition.prev?d(this.domPosition.prev).after(this.currentItem):d(this.domPosition.parent).prepend(this.currentItem)}return this},serialize:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};d(b).each(function(){var e=(d(a.item||this).attr(a.attribute||"id")||"").match(a.expression||/(.+)[-=_](.+)/);if(e)c.push((a.key||e[1]+"[]")+"="+(a.key&&a.expression?e[1]:e[2]))});!c.length&&a.key&&c.push(a.key+"=");return c.join("&")}, 4302
80 toArray:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};b.each(function(){c.push(d(a.item||this).attr(a.attribute||"id")||"")});return c},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,e=this.positionAbs.top,f=e+this.helperProportions.height,g=a.left,h=g+a.width,i=a.top,k=i+a.height,j=this.offset.click.top,l=this.offset.click.left;j=e+j>i&&e+j<k&&b+l>g&&b+l<h;return this.options.tolerance=="pointer"||this.options.forcePointerForContainers|| 4303
81 this.options.tolerance!="pointer"&&this.helperProportions[this.floating?"width":"height"]>a[this.floating?"width":"height"]?j:g<b+this.helperProportions.width/2&&c-this.helperProportions.width/2<h&&i<e+this.helperProportions.height/2&&f-this.helperProportions.height/2<k},_intersectsWithPointer:function(a){var b=d.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,a.top,a.height);a=d.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,a.left,a.width);b=b&&a;a=this._getDragVerticalDirection(); 4304 /*!
82 var c=this._getDragHorizontalDirection();if(!b)return false;return this.floating?c&&c=="right"||a=="down"?2:1:a&&(a=="down"?2:1)},_intersectsWithSides:function(a){var b=d.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,a.top+a.height/2,a.height);a=d.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,a.left+a.width/2,a.width);var c=this._getDragVerticalDirection(),e=this._getDragHorizontalDirection();return this.floating&&e?e=="right"&&a||e=="left"&&!a:c&&(c=="down"&&b||c=="up"&&!b)}, 4305 * jQuery UI Unique ID 1.13.2
83 _getDragVerticalDirection:function(){var a=this.positionAbs.top-this.lastPositionAbs.top;return a!=0&&(a>0?"down":"up")},_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){this._refreshItems(a);this.refreshPositions();return this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(a){var b=[],c=[],e=this._connectWith(); 4306 * http://jqueryui.com
84 if(e&&a)for(a=e.length-1;a>=0;a--)for(var f=d(e[a]),g=f.length-1;g>=0;g--){var h=d.data(f[g],"sortable");if(h&&h!=this&&!h.options.disabled)c.push([d.isFunction(h.options.items)?h.options.items.call(h.element):d(h.options.items,h.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),h])}c.push([d.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):d(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), 4307 *
85 this]);for(a=c.length-1;a>=0;a--)c[a][0].each(function(){b.push(this)});return d(b)},_removeCurrentsFromItems:function(){for(var a=this.currentItem.find(":data(sortable-item)"),b=0;b<this.items.length;b++)for(var c=0;c<a.length;c++)a[c]==this.items[b].item[0]&&this.items.splice(b,1)},_refreshItems:function(a){this.items=[];this.containers=[this];var b=this.items,c=[[d.isFunction(this.options.items)?this.options.items.call(this.element[0],a,{item:this.currentItem}):d(this.options.items,this.element), 4308 * Copyright jQuery Foundation and other contributors
86 this]],e=this._connectWith();if(e)for(var f=e.length-1;f>=0;f--)for(var g=d(e[f]),h=g.length-1;h>=0;h--){var i=d.data(g[h],"sortable");if(i&&i!=this&&!i.options.disabled){c.push([d.isFunction(i.options.items)?i.options.items.call(i.element[0],a,{item:this.currentItem}):d(i.options.items,i.element),i]);this.containers.push(i)}}for(f=c.length-1;f>=0;f--){a=c[f][1];e=c[f][0];h=0;for(g=e.length;h<g;h++){i=d(e[h]);i.data("sortable-item",a);b.push({item:i,instance:a,width:0,height:0,left:0,top:0})}}},refreshPositions:function(a){if(this.offsetParent&& 4309 * Released under the MIT license.
87 this.helper)this.offset.parent=this._getParentOffset();for(var b=this.items.length-1;b>=0;b--){var c=this.items[b];if(!(c.instance!=this.currentContainer&&this.currentContainer&&c.item[0]!=this.currentItem[0])){var e=this.options.toleranceElement?d(this.options.toleranceElement,c.item):c.item;if(!a){c.width=e.outerWidth();c.height=e.outerHeight()}e=e.offset();c.left=e.left;c.top=e.top}}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(b= 4310 * http://jquery.org/license
88 this.containers.length-1;b>=0;b--){e=this.containers[b].element.offset();this.containers[b].containerCache.left=e.left;this.containers[b].containerCache.top=e.top;this.containers[b].containerCache.width=this.containers[b].element.outerWidth();this.containers[b].containerCache.height=this.containers[b].element.outerHeight()}return this},_createPlaceholder:function(a){var b=a||this,c=b.options;if(!c.placeholder||c.placeholder.constructor==String){var e=c.placeholder;c.placeholder={element:function(){var f= 4311 */
89 d(document.createElement(b.currentItem[0].nodeName)).addClass(e||b.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!e)f.style.visibility="hidden";return f},update:function(f,g){if(!(e&&!c.forcePlaceholderSize)){g.height()||g.height(b.currentItem.innerHeight()-parseInt(b.currentItem.css("paddingTop")||0,10)-parseInt(b.currentItem.css("paddingBottom")||0,10));g.width()||g.width(b.currentItem.innerWidth()-parseInt(b.currentItem.css("paddingLeft")||0,10)-parseInt(b.currentItem.css("paddingRight")|| 4312
90 0,10))}}}}b.placeholder=d(c.placeholder.element.call(b.element,b.currentItem));b.currentItem.after(b.placeholder);c.placeholder.update(b,b.placeholder)},_contactContainers:function(a){for(var b=null,c=null,e=this.containers.length-1;e>=0;e--)if(!d.ui.contains(this.currentItem[0],this.containers[e].element[0]))if(this._intersectsWith(this.containers[e].containerCache)){if(!(b&&d.ui.contains(this.containers[e].element[0],b.element[0]))){b=this.containers[e];c=e}}else if(this.containers[e].containerCache.over){this.containers[e]._trigger("out", 4313 //>>label: uniqueId
91 a,this._uiHash(this));this.containers[e].containerCache.over=0}if(b)if(this.containers.length===1){this.containers[c]._trigger("over",a,this._uiHash(this));this.containers[c].containerCache.over=1}else if(this.currentContainer!=this.containers[c]){b=1E4;e=null;for(var f=this.positionAbs[this.containers[c].floating?"left":"top"],g=this.items.length-1;g>=0;g--)if(d.ui.contains(this.containers[c].element[0],this.items[g].item[0])){var h=this.items[g][this.containers[c].floating?"left":"top"];if(Math.abs(h- 4314 //>>group: Core
92 f)<b){b=Math.abs(h-f);e=this.items[g]}}if(e||this.options.dropOnEmpty){this.currentContainer=this.containers[c];e?this._rearrange(a,e,null,true):this._rearrange(a,null,this.containers[c].element,true);this._trigger("change",a,this._uiHash());this.containers[c]._trigger("change",a,this._uiHash(this));this.options.placeholder.update(this.currentContainer,this.placeholder);this.containers[c]._trigger("over",a,this._uiHash(this));this.containers[c].containerCache.over=1}}},_createHelper:function(a){var b= 4315 //>>description: Functions to generate and remove uniqueId's
93 this.options;a=d.isFunction(b.helper)?d(b.helper.apply(this.element[0],[a,this.currentItem])):b.helper=="clone"?this.currentItem.clone():this.currentItem;a.parents("body").length||d(b.appendTo!="parent"?b.appendTo:this.currentItem[0].parentNode)[0].appendChild(a[0]);if(a[0]==this.currentItem[0])this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")};if(a[0].style.width== 4316 //>>docs: http://api.jqueryui.com/uniqueId/
94 ""||b.forceHelperSize)a.width(this.currentItem.width());if(a[0].style.height==""||b.forceHelperSize)a.height(this.currentItem.height());return a},_adjustOffsetFromHelper:function(a){if(typeof a=="string")a=a.split(" ");if(d.isArray(a))a={left:+a[0],top:+a[1]||0};if("left"in a)this.offset.click.left=a.left+this.margins.left;if("right"in a)this.offset.click.left=this.helperProportions.width-a.right+this.margins.left;if("top"in a)this.offset.click.top=a.top+this.margins.top;if("bottom"in a)this.offset.click.top= 4317
95 this.helperProportions.height-a.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var a=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0])){a.left+=this.scrollParent.scrollLeft();a.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&d.browser.msie)a= 4318
96 {top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.currentItem.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"), 4319 var uniqueId = $.fn.extend( {
97 10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var a=this.options;if(a.containment=="parent")a.containment=this.helper[0].parentNode;if(a.containment=="document"||a.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,d(a.containment=="document"? 4320 uniqueId: ( function() {
98 document:window).width()-this.helperProportions.width-this.margins.left,(d(a.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)){var b=d(a.containment)[0];a=d(a.containment).offset();var c=d(b).css("overflow")!="hidden";this.containment=[a.left+(parseInt(d(b).css("borderLeftWidth"),10)||0)+(parseInt(d(b).css("paddingLeft"),10)||0)-this.margins.left,a.top+(parseInt(d(b).css("borderTopWidth"), 4321 var uuid = 0;
99 10)||0)+(parseInt(d(b).css("paddingTop"),10)||0)-this.margins.top,a.left+(c?Math.max(b.scrollWidth,b.offsetWidth):b.offsetWidth)-(parseInt(d(b).css("borderLeftWidth"),10)||0)-(parseInt(d(b).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,a.top+(c?Math.max(b.scrollHeight,b.offsetHeight):b.offsetHeight)-(parseInt(d(b).css("borderTopWidth"),10)||0)-(parseInt(d(b).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(a,b){if(!b)b= 4322
100 this.position;a=a=="absolute"?1:-1;var c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(c[0].tagName);return{top:b.top+this.offset.relative.top*a+this.offset.parent.top*a-(d.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:c.scrollTop())*a),left:b.left+this.offset.relative.left*a+this.offset.parent.left*a-(d.browser.safari&& 4323 return function() {
101 this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:c.scrollLeft())*a)}},_generatePosition:function(a){var b=this.options,c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(c[0].tagName);if(this.cssPosition=="relative"&&!(this.scrollParent[0]!=document&&this.scrollParent[0]!=this.offsetParent[0]))this.offset.relative=this._getRelativeOffset(); 4324 return this.each( function() {
102 var f=a.pageX,g=a.pageY;if(this.originalPosition){if(this.containment){if(a.pageX-this.offset.click.left<this.containment[0])f=this.containment[0]+this.offset.click.left;if(a.pageY-this.offset.click.top<this.containment[1])g=this.containment[1]+this.offset.click.top;if(a.pageX-this.offset.click.left>this.containment[2])f=this.containment[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>this.containment[3])g=this.containment[3]+this.offset.click.top}if(b.grid){g=this.originalPageY+Math.round((g- 4325 if ( !this.id ) {
103 this.originalPageY)/b.grid[1])*b.grid[1];g=this.containment?!(g-this.offset.click.top<this.containment[1]||g-this.offset.click.top>this.containment[3])?g:!(g-this.offset.click.top<this.containment[1])?g-b.grid[1]:g+b.grid[1]:g;f=this.originalPageX+Math.round((f-this.originalPageX)/b.grid[0])*b.grid[0];f=this.containment?!(f-this.offset.click.left<this.containment[0]||f-this.offset.click.left>this.containment[2])?f:!(f-this.offset.click.left<this.containment[0])?f-b.grid[0]:f+b.grid[0]:f}}return{top:g- 4326 this.id = "ui-id-" + ( ++uuid );
104 this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(d.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:c.scrollTop()),left:f-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(d.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:c.scrollLeft())}},_rearrange:function(a,b,c,e){c?c[0].appendChild(this.placeholder[0]):b.item[0].parentNode.insertBefore(this.placeholder[0], 4327 }
105 this.direction=="down"?b.item[0]:b.item[0].nextSibling);this.counter=this.counter?++this.counter:1;var f=this,g=this.counter;window.setTimeout(function(){g==f.counter&&f.refreshPositions(!e)},0)},_clear:function(a,b){this.reverting=false;var c=[];!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem);this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var e in this._storedCSS)if(this._storedCSS[e]=="auto"||this._storedCSS[e]=="static")this._storedCSS[e]= 4328 } );
106 "";this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();this.fromOutside&&!b&&c.push(function(f){this._trigger("receive",f,this._uiHash(this.fromOutside))});if((this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0])&&!b)c.push(function(f){this._trigger("update",f,this._uiHash())});if(!d.ui.contains(this.element[0],this.currentItem[0])){b||c.push(function(f){this._trigger("remove", 4329 };
107 f,this._uiHash())});for(e=this.containers.length-1;e>=0;e--)if(d.ui.contains(this.containers[e].element[0],this.currentItem[0])&&!b){c.push(function(f){return function(g){f._trigger("receive",g,this._uiHash(this))}}.call(this,this.containers[e]));c.push(function(f){return function(g){f._trigger("update",g,this._uiHash(this))}}.call(this,this.containers[e]))}}for(e=this.containers.length-1;e>=0;e--){b||c.push(function(f){return function(g){f._trigger("deactivate",g,this._uiHash(this))}}.call(this, 4330 } )(),
108 this.containers[e]));if(this.containers[e].containerCache.over){c.push(function(f){return function(g){f._trigger("out",g,this._uiHash(this))}}.call(this,this.containers[e]));this.containers[e].containerCache.over=0}}this._storedCursor&&d("body").css("cursor",this._storedCursor);this._storedOpacity&&this.helper.css("opacity",this._storedOpacity);if(this._storedZIndex)this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex);this.dragging=false;if(this.cancelHelperRemoval){if(!b){this._trigger("beforeStop", 4331
109 a,this._uiHash());for(e=0;e<c.length;e++)c[e].call(this,a);this._trigger("stop",a,this._uiHash())}return false}b||this._trigger("beforeStop",a,this._uiHash());this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.helper[0]!=this.currentItem[0]&&this.helper.remove();this.helper=null;if(!b){for(e=0;e<c.length;e++)c[e].call(this,a);this._trigger("stop",a,this._uiHash())}this.fromOutside=false;return true},_trigger:function(){d.Widget.prototype._trigger.apply(this,arguments)===false&&this.cancel()}, 4332 removeUniqueId: function() {
110 _uiHash:function(a){var b=a||this;return{helper:b.helper,placeholder:b.placeholder||d([]),position:b.position,originalPosition:b.originalPosition,offset:b.positionAbs,item:b.currentItem,sender:a?a.element:null}}});d.extend(d.ui.sortable,{version:"1.8.16"})})(jQuery); 4333 return this.each( function() {
111 ; 4334 if ( /^ui-id-\d+$/.test( this.id ) ) {
4335 $( this ).removeAttr( "id" );
4336 }
4337 } );
4338 }
4339 } );
4340
4341
4342 /*!
4343 * jQuery UI Accordion 1.13.2
4344 * http://jqueryui.com
4345 *
4346 * Copyright jQuery Foundation and other contributors
4347 * Released under the MIT license.
4348 * http://jquery.org/license
4349 */
4350
4351 //>>label: Accordion
4352 //>>group: Widgets
4353 /* eslint-disable max-len */
4354 //>>description: Displays collapsible content panels for presenting information in a limited amount of space.
4355 /* eslint-enable max-len */
4356 //>>docs: http://api.jqueryui.com/accordion/
4357 //>>demos: http://jqueryui.com/accordion/
4358 //>>css.structure: ../../themes/base/core.css
4359 //>>css.structure: ../../themes/base/accordion.css
4360 //>>css.theme: ../../themes/base/theme.css
4361
4362
4363 var widgetsAccordion = $.widget( "ui.accordion", {
4364 version: "1.13.2",
4365 options: {
4366 active: 0,
4367 animate: {},
4368 classes: {
4369 "ui-accordion-header": "ui-corner-top",
4370 "ui-accordion-header-collapsed": "ui-corner-all",
4371 "ui-accordion-content": "ui-corner-bottom"
4372 },
4373 collapsible: false,
4374 event: "click",
4375 header: function( elem ) {
4376 return elem.find( "> li > :first-child" ).add( elem.find( "> :not(li)" ).even() );
4377 },
4378 heightStyle: "auto",
4379 icons: {
4380 activeHeader: "ui-icon-triangle-1-s",
4381 header: "ui-icon-triangle-1-e"
4382 },
4383
4384 // Callbacks
4385 activate: null,
4386 beforeActivate: null
4387 },
4388
4389 hideProps: {
4390 borderTopWidth: "hide",
4391 borderBottomWidth: "hide",
4392 paddingTop: "hide",
4393 paddingBottom: "hide",
4394 height: "hide"
4395 },
4396
4397 showProps: {
4398 borderTopWidth: "show",
4399 borderBottomWidth: "show",
4400 paddingTop: "show",
4401 paddingBottom: "show",
4402 height: "show"
4403 },
4404
4405 _create: function() {
4406 var options = this.options;
4407
4408 this.prevShow = this.prevHide = $();
4409 this._addClass( "ui-accordion", "ui-widget ui-helper-reset" );
4410 this.element.attr( "role", "tablist" );
4411
4412 // Don't allow collapsible: false and active: false / null
4413 if ( !options.collapsible && ( options.active === false || options.active == null ) ) {
4414 options.active = 0;
4415 }
4416
4417 this._processPanels();
4418
4419 // handle negative values
4420 if ( options.active < 0 ) {
4421 options.active += this.headers.length;
4422 }
4423 this._refresh();
4424 },
4425
4426 _getCreateEventData: function() {
4427 return {
4428 header: this.active,
4429 panel: !this.active.length ? $() : this.active.next()
4430 };
4431 },
4432
4433 _createIcons: function() {
4434 var icon, children,
4435 icons = this.options.icons;
4436
4437 if ( icons ) {
4438 icon = $( "<span>" );
4439 this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header );
4440 icon.prependTo( this.headers );
4441 children = this.active.children( ".ui-accordion-header-icon" );
4442 this._removeClass( children, icons.header )
4443 ._addClass( children, null, icons.activeHeader )
4444 ._addClass( this.headers, "ui-accordion-icons" );
4445 }
4446 },
4447
4448 _destroyIcons: function() {
4449 this._removeClass( this.headers, "ui-accordion-icons" );
4450 this.headers.children( ".ui-accordion-header-icon" ).remove();
4451 },
4452
4453 _destroy: function() {
4454 var contents;
4455
4456 // Clean up main element
4457 this.element.removeAttr( "role" );
4458
4459 // Clean up headers
4460 this.headers
4461 .removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" )
4462 .removeUniqueId();
4463
4464 this._destroyIcons();
4465
4466 // Clean up content panels
4467 contents = this.headers.next()
4468 .css( "display", "" )
4469 .removeAttr( "role aria-hidden aria-labelledby" )
4470 .removeUniqueId();
4471
4472 if ( this.options.heightStyle !== "content" ) {
4473 contents.css( "height", "" );
4474 }
4475 },
4476
4477 _setOption: function( key, value ) {
4478 if ( key === "active" ) {
4479
4480 // _activate() will handle invalid values and update this.options
4481 this._activate( value );
4482 return;
4483 }
4484
4485 if ( key === "event" ) {
4486 if ( this.options.event ) {
4487 this._off( this.headers, this.options.event );
4488 }
4489 this._setupEvents( value );
4490 }
4491
4492 this._super( key, value );
4493
4494 // Setting collapsible: false while collapsed; open first panel
4495 if ( key === "collapsible" && !value && this.options.active === false ) {
4496 this._activate( 0 );
4497 }
4498
4499 if ( key === "icons" ) {
4500 this._destroyIcons();
4501 if ( value ) {
4502 this._createIcons();
4503 }
4504 }
4505 },
4506
4507 _setOptionDisabled: function( value ) {
4508 this._super( value );
4509
4510 this.element.attr( "aria-disabled", value );
4511
4512 // Support: IE8 Only
4513 // #5332 / #6059 - opacity doesn't cascade to positioned elements in IE
4514 // so we need to add the disabled class to the headers and panels
4515 this._toggleClass( null, "ui-state-disabled", !!value );
4516 this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled",
4517 !!value );
4518 },
4519
4520 _keydown: function( event ) {
4521 if ( event.altKey || event.ctrlKey ) {
4522 return;
4523 }
4524
4525 var keyCode = $.ui.keyCode,
4526 length = this.headers.length,
4527 currentIndex = this.headers.index( event.target ),
4528 toFocus = false;
4529
4530 switch ( event.keyCode ) {
4531 case keyCode.RIGHT:
4532 case keyCode.DOWN:
4533 toFocus = this.headers[ ( currentIndex + 1 ) % length ];
4534 break;
4535 case keyCode.LEFT:
4536 case keyCode.UP:
4537 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
4538 break;
4539 case keyCode.SPACE:
4540 case keyCode.ENTER:
4541 this._eventHandler( event );
4542 break;
4543 case keyCode.HOME:
4544 toFocus = this.headers[ 0 ];
4545 break;
4546 case keyCode.END:
4547 toFocus = this.headers[ length - 1 ];
4548 break;
4549 }
4550
4551 if ( toFocus ) {
4552 $( event.target ).attr( "tabIndex", -1 );
4553 $( toFocus ).attr( "tabIndex", 0 );
4554 $( toFocus ).trigger( "focus" );
4555 event.preventDefault();
4556 }
4557 },
4558
4559 _panelKeyDown: function( event ) {
4560 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
4561 $( event.currentTarget ).prev().trigger( "focus" );
4562 }
4563 },
4564
4565 refresh: function() {
4566 var options = this.options;
4567 this._processPanels();
4568
4569 // Was collapsed or no panel
4570 if ( ( options.active === false && options.collapsible === true ) ||
4571 !this.headers.length ) {
4572 options.active = false;
4573 this.active = $();
4574
4575 // active false only when collapsible is true
4576 } else if ( options.active === false ) {
4577 this._activate( 0 );
4578
4579 // was active, but active panel is gone
4580 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
4581
4582 // all remaining panel are disabled
4583 if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) {
4584 options.active = false;
4585 this.active = $();
4586
4587 // activate previous panel
4588 } else {
4589 this._activate( Math.max( 0, options.active - 1 ) );
4590 }
4591
4592 // was active, active panel still exists
4593 } else {
4594
4595 // make sure active index is correct
4596 options.active = this.headers.index( this.active );
4597 }
4598
4599 this._destroyIcons();
4600
4601 this._refresh();
4602 },
4603
4604 _processPanels: function() {
4605 var prevHeaders = this.headers,
4606 prevPanels = this.panels;
4607
4608 if ( typeof this.options.header === "function" ) {
4609 this.headers = this.options.header( this.element );
4610 } else {
4611 this.headers = this.element.find( this.options.header );
4612 }
4613 this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed",
4614 "ui-state-default" );
4615
4616 this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide();
4617 this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" );
4618
4619 // Avoid memory leaks (#10056)
4620 if ( prevPanels ) {
4621 this._off( prevHeaders.not( this.headers ) );
4622 this._off( prevPanels.not( this.panels ) );
4623 }
4624 },
4625
4626 _refresh: function() {
4627 var maxHeight,
4628 options = this.options,
4629 heightStyle = options.heightStyle,
4630 parent = this.element.parent();
4631
4632 this.active = this._findActive( options.active );
4633 this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" )
4634 ._removeClass( this.active, "ui-accordion-header-collapsed" );
4635 this._addClass( this.active.next(), "ui-accordion-content-active" );
4636 this.active.next().show();
4637
4638 this.headers
4639 .attr( "role", "tab" )
4640 .each( function() {
4641 var header = $( this ),
4642 headerId = header.uniqueId().attr( "id" ),
4643 panel = header.next(),
4644 panelId = panel.uniqueId().attr( "id" );
4645 header.attr( "aria-controls", panelId );
4646 panel.attr( "aria-labelledby", headerId );
4647 } )
4648 .next()
4649 .attr( "role", "tabpanel" );
4650
4651 this.headers
4652 .not( this.active )
4653 .attr( {
4654 "aria-selected": "false",
4655 "aria-expanded": "false",
4656 tabIndex: -1
4657 } )
4658 .next()
4659 .attr( {
4660 "aria-hidden": "true"
4661 } )
4662 .hide();
4663
4664 // Make sure at least one header is in the tab order
4665 if ( !this.active.length ) {
4666 this.headers.eq( 0 ).attr( "tabIndex", 0 );
4667 } else {
4668 this.active.attr( {
4669 "aria-selected": "true",
4670 "aria-expanded": "true",
4671 tabIndex: 0
4672 } )
4673 .next()
4674 .attr( {
4675 "aria-hidden": "false"
4676 } );
4677 }
4678
4679 this._createIcons();
4680
4681 this._setupEvents( options.event );
4682
4683 if ( heightStyle === "fill" ) {
4684 maxHeight = parent.height();
4685 this.element.siblings( ":visible" ).each( function() {
4686 var elem = $( this ),
4687 position = elem.css( "position" );
4688
4689 if ( position === "absolute" || position === "fixed" ) {
4690 return;
4691 }
4692 maxHeight -= elem.outerHeight( true );
4693 } );
4694
4695 this.headers.each( function() {
4696 maxHeight -= $( this ).outerHeight( true );
4697 } );
4698
4699 this.headers.next()
4700 .each( function() {
4701 $( this ).height( Math.max( 0, maxHeight -
4702 $( this ).innerHeight() + $( this ).height() ) );
4703 } )
4704 .css( "overflow", "auto" );
4705 } else if ( heightStyle === "auto" ) {
4706 maxHeight = 0;
4707 this.headers.next()
4708 .each( function() {
4709 var isVisible = $( this ).is( ":visible" );
4710 if ( !isVisible ) {
4711 $( this ).show();
4712 }
4713 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
4714 if ( !isVisible ) {
4715 $( this ).hide();
4716 }
4717 } )
4718 .height( maxHeight );
4719 }
4720 },
4721
4722 _activate: function( index ) {
4723 var active = this._findActive( index )[ 0 ];
4724
4725 // Trying to activate the already active panel
4726 if ( active === this.active[ 0 ] ) {
4727 return;
4728 }
4729
4730 // Trying to collapse, simulate a click on the currently active header
4731 active = active || this.active[ 0 ];
4732
4733 this._eventHandler( {
4734 target: active,
4735 currentTarget: active,
4736 preventDefault: $.noop
4737 } );
4738 },
4739
4740 _findActive: function( selector ) {
4741 return typeof selector === "number" ? this.headers.eq( selector ) : $();
4742 },
4743
4744 _setupEvents: function( event ) {
4745 var events = {
4746 keydown: "_keydown"
4747 };
4748 if ( event ) {
4749 $.each( event.split( " " ), function( index, eventName ) {
4750 events[ eventName ] = "_eventHandler";
4751 } );
4752 }
4753
4754 this._off( this.headers.add( this.headers.next() ) );
4755 this._on( this.headers, events );
4756 this._on( this.headers.next(), { keydown: "_panelKeyDown" } );
4757 this._hoverable( this.headers );
4758 this._focusable( this.headers );
4759 },
4760
4761 _eventHandler: function( event ) {
4762 var activeChildren, clickedChildren,
4763 options = this.options,
4764 active = this.active,
4765 clicked = $( event.currentTarget ),
4766 clickedIsActive = clicked[ 0 ] === active[ 0 ],
4767 collapsing = clickedIsActive && options.collapsible,
4768 toShow = collapsing ? $() : clicked.next(),
4769 toHide = active.next(),
4770 eventData = {
4771 oldHeader: active,
4772 oldPanel: toHide,
4773 newHeader: collapsing ? $() : clicked,
4774 newPanel: toShow
4775 };
4776
4777 event.preventDefault();
4778
4779 if (
4780
4781 // click on active header, but not collapsible
4782 ( clickedIsActive && !options.collapsible ) ||
4783
4784 // allow canceling activation
4785 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
4786 return;
4787 }
4788
4789 options.active = collapsing ? false : this.headers.index( clicked );
4790
4791 // When the call to ._toggle() comes after the class changes
4792 // it causes a very odd bug in IE 8 (see #6720)
4793 this.active = clickedIsActive ? $() : clicked;
4794 this._toggle( eventData );
4795
4796 // Switch classes
4797 // corner classes on the previously active header stay after the animation
4798 this._removeClass( active, "ui-accordion-header-active", "ui-state-active" );
4799 if ( options.icons ) {
4800 activeChildren = active.children( ".ui-accordion-header-icon" );
4801 this._removeClass( activeChildren, null, options.icons.activeHeader )
4802 ._addClass( activeChildren, null, options.icons.header );
4803 }
4804
4805 if ( !clickedIsActive ) {
4806 this._removeClass( clicked, "ui-accordion-header-collapsed" )
4807 ._addClass( clicked, "ui-accordion-header-active", "ui-state-active" );
4808 if ( options.icons ) {
4809 clickedChildren = clicked.children( ".ui-accordion-header-icon" );
4810 this._removeClass( clickedChildren, null, options.icons.header )
4811 ._addClass( clickedChildren, null, options.icons.activeHeader );
4812 }
4813
4814 this._addClass( clicked.next(), "ui-accordion-content-active" );
4815 }
4816 },
4817
4818 _toggle: function( data ) {
4819 var toShow = data.newPanel,
4820 toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
4821
4822 // Handle activating a panel during the animation for another activation
4823 this.prevShow.add( this.prevHide ).stop( true, true );
4824 this.prevShow = toShow;
4825 this.prevHide = toHide;
4826
4827 if ( this.options.animate ) {
4828 this._animate( toShow, toHide, data );
4829 } else {
4830 toHide.hide();
4831 toShow.show();
4832 this._toggleComplete( data );
4833 }
4834
4835 toHide.attr( {
4836 "aria-hidden": "true"
4837 } );
4838 toHide.prev().attr( {
4839 "aria-selected": "false",
4840 "aria-expanded": "false"
4841 } );
4842
4843 // if we're switching panels, remove the old header from the tab order
4844 // if we're opening from collapsed state, remove the previous header from the tab order
4845 // if we're collapsing, then keep the collapsing header in the tab order
4846 if ( toShow.length && toHide.length ) {
4847 toHide.prev().attr( {
4848 "tabIndex": -1,
4849 "aria-expanded": "false"
4850 } );
4851 } else if ( toShow.length ) {
4852 this.headers.filter( function() {
4853 return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
4854 } )
4855 .attr( "tabIndex", -1 );
4856 }
4857
4858 toShow
4859 .attr( "aria-hidden", "false" )
4860 .prev()
4861 .attr( {
4862 "aria-selected": "true",
4863 "aria-expanded": "true",
4864 tabIndex: 0
4865 } );
4866 },
4867
4868 _animate: function( toShow, toHide, data ) {
4869 var total, easing, duration,
4870 that = this,
4871 adjust = 0,
4872 boxSizing = toShow.css( "box-sizing" ),
4873 down = toShow.length &&
4874 ( !toHide.length || ( toShow.index() < toHide.index() ) ),
4875 animate = this.options.animate || {},
4876 options = down && animate.down || animate,
4877 complete = function() {
4878 that._toggleComplete( data );
4879 };
4880
4881 if ( typeof options === "number" ) {
4882 duration = options;
4883 }
4884 if ( typeof options === "string" ) {
4885 easing = options;
4886 }
4887
4888 // fall back from options to animation in case of partial down settings
4889 easing = easing || options.easing || animate.easing;
4890 duration = duration || options.duration || animate.duration;
4891
4892 if ( !toHide.length ) {
4893 return toShow.animate( this.showProps, duration, easing, complete );
4894 }
4895 if ( !toShow.length ) {
4896 return toHide.animate( this.hideProps, duration, easing, complete );
4897 }
4898
4899 total = toShow.show().outerHeight();
4900 toHide.animate( this.hideProps, {
4901 duration: duration,
4902 easing: easing,
4903 step: function( now, fx ) {
4904 fx.now = Math.round( now );
4905 }
4906 } );
4907 toShow
4908 .hide()
4909 .animate( this.showProps, {
4910 duration: duration,
4911 easing: easing,
4912 complete: complete,
4913 step: function( now, fx ) {
4914 fx.now = Math.round( now );
4915 if ( fx.prop !== "height" ) {
4916 if ( boxSizing === "content-box" ) {
4917 adjust += fx.now;
4918 }
4919 } else if ( that.options.heightStyle !== "content" ) {
4920 fx.now = Math.round( total - toHide.outerHeight() - adjust );
4921 adjust = 0;
4922 }
4923 }
4924 } );
4925 },
4926
4927 _toggleComplete: function( data ) {
4928 var toHide = data.oldPanel,
4929 prev = toHide.prev();
4930
4931 this._removeClass( toHide, "ui-accordion-content-active" );
4932 this._removeClass( prev, "ui-accordion-header-active" )
4933 ._addClass( prev, "ui-accordion-header-collapsed" );
4934
4935 // Work around for rendering bug in IE (#5421)
4936 if ( toHide.length ) {
4937 toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
4938 }
4939 this._trigger( "activate", null, data );
4940 }
4941 } );
4942
4943
4944
4945 var safeActiveElement = $.ui.safeActiveElement = function( document ) {
4946 var activeElement;
4947
4948 // Support: IE 9 only
4949 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
4950 try {
4951 activeElement = document.activeElement;
4952 } catch ( error ) {
4953 activeElement = document.body;
4954 }
4955
4956 // Support: IE 9 - 11 only
4957 // IE may return null instead of an element
4958 // Interestingly, this only seems to occur when NOT in an iframe
4959 if ( !activeElement ) {
4960 activeElement = document.body;
4961 }
4962
4963 // Support: IE 11 only
4964 // IE11 returns a seemingly empty object in some cases when accessing
4965 // document.activeElement from an <iframe>
4966 if ( !activeElement.nodeName ) {
4967 activeElement = document.body;
4968 }
4969
4970 return activeElement;
4971 };
4972
4973
4974 /*!
4975 * jQuery UI Menu 1.13.2
4976 * http://jqueryui.com
4977 *
4978 * Copyright jQuery Foundation and other contributors
4979 * Released under the MIT license.
4980 * http://jquery.org/license
4981 */
4982
4983 //>>label: Menu
4984 //>>group: Widgets
4985 //>>description: Creates nestable menus.
4986 //>>docs: http://api.jqueryui.com/menu/
4987 //>>demos: http://jqueryui.com/menu/
4988 //>>css.structure: ../../themes/base/core.css
4989 //>>css.structure: ../../themes/base/menu.css
4990 //>>css.theme: ../../themes/base/theme.css
4991
4992
4993 var widgetsMenu = $.widget( "ui.menu", {
4994 version: "1.13.2",
4995 defaultElement: "<ul>",
4996 delay: 300,
4997 options: {
4998 icons: {
4999 submenu: "ui-icon-caret-1-e"
5000 },
5001 items: "> *",
5002 menus: "ul",
5003 position: {
5004 my: "left top",
5005 at: "right top"
5006 },
5007 role: "menu",
5008
5009 // Callbacks
5010 blur: null,
5011 focus: null,
5012 select: null
5013 },
5014
5015 _create: function() {
5016 this.activeMenu = this.element;
5017
5018 // Flag used to prevent firing of the click handler
5019 // as the event bubbles up through nested menus
5020 this.mouseHandled = false;
5021 this.lastMousePosition = { x: null, y: null };
5022 this.element
5023 .uniqueId()
5024 .attr( {
5025 role: this.options.role,
5026 tabIndex: 0
5027 } );
5028
5029 this._addClass( "ui-menu", "ui-widget ui-widget-content" );
5030 this._on( {
5031
5032 // Prevent focus from sticking to links inside menu after clicking
5033 // them (focus should always stay on UL during navigation).
5034 "mousedown .ui-menu-item": function( event ) {
5035 event.preventDefault();
5036
5037 this._activateItem( event );
5038 },
5039 "click .ui-menu-item": function( event ) {
5040 var target = $( event.target );
5041 var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
5042 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
5043 this.select( event );
5044
5045 // Only set the mouseHandled flag if the event will bubble, see #9469.
5046 if ( !event.isPropagationStopped() ) {
5047 this.mouseHandled = true;
5048 }
5049
5050 // Open submenu on click
5051 if ( target.has( ".ui-menu" ).length ) {
5052 this.expand( event );
5053 } else if ( !this.element.is( ":focus" ) &&
5054 active.closest( ".ui-menu" ).length ) {
5055
5056 // Redirect focus to the menu
5057 this.element.trigger( "focus", [ true ] );
5058
5059 // If the active item is on the top level, let it stay active.
5060 // Otherwise, blur the active item since it is no longer visible.
5061 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
5062 clearTimeout( this.timer );
5063 }
5064 }
5065 }
5066 },
5067 "mouseenter .ui-menu-item": "_activateItem",
5068 "mousemove .ui-menu-item": "_activateItem",
5069 mouseleave: "collapseAll",
5070 "mouseleave .ui-menu": "collapseAll",
5071 focus: function( event, keepActiveItem ) {
5072
5073 // If there's already an active item, keep it active
5074 // If not, activate the first item
5075 var item = this.active || this._menuItems().first();
5076
5077 if ( !keepActiveItem ) {
5078 this.focus( event, item );
5079 }
5080 },
5081 blur: function( event ) {
5082 this._delay( function() {
5083 var notContained = !$.contains(
5084 this.element[ 0 ],
5085 $.ui.safeActiveElement( this.document[ 0 ] )
5086 );
5087 if ( notContained ) {
5088 this.collapseAll( event );
5089 }
5090 } );
5091 },
5092 keydown: "_keydown"
5093 } );
5094
5095 this.refresh();
5096
5097 // Clicks outside of a menu collapse any open menus
5098 this._on( this.document, {
5099 click: function( event ) {
5100 if ( this._closeOnDocumentClick( event ) ) {
5101 this.collapseAll( event, true );
5102 }
5103
5104 // Reset the mouseHandled flag
5105 this.mouseHandled = false;
5106 }
5107 } );
5108 },
5109
5110 _activateItem: function( event ) {
5111
5112 // Ignore mouse events while typeahead is active, see #10458.
5113 // Prevents focusing the wrong item when typeahead causes a scroll while the mouse
5114 // is over an item in the menu
5115 if ( this.previousFilter ) {
5116 return;
5117 }
5118
5119 // If the mouse didn't actually move, but the page was scrolled, ignore the event (#9356)
5120 if ( event.clientX === this.lastMousePosition.x &&
5121 event.clientY === this.lastMousePosition.y ) {
5122 return;
5123 }
5124
5125 this.lastMousePosition = {
5126 x: event.clientX,
5127 y: event.clientY
5128 };
5129
5130 var actualTarget = $( event.target ).closest( ".ui-menu-item" ),
5131 target = $( event.currentTarget );
5132
5133 // Ignore bubbled events on parent items, see #11641
5134 if ( actualTarget[ 0 ] !== target[ 0 ] ) {
5135 return;
5136 }
5137
5138 // If the item is already active, there's nothing to do
5139 if ( target.is( ".ui-state-active" ) ) {
5140 return;
5141 }
5142
5143 // Remove ui-state-active class from siblings of the newly focused menu item
5144 // to avoid a jump caused by adjacent elements both having a class with a border
5145 this._removeClass( target.siblings().children( ".ui-state-active" ),
5146 null, "ui-state-active" );
5147 this.focus( event, target );
5148 },
5149
5150 _destroy: function() {
5151 var items = this.element.find( ".ui-menu-item" )
5152 .removeAttr( "role aria-disabled" ),
5153 submenus = items.children( ".ui-menu-item-wrapper" )
5154 .removeUniqueId()
5155 .removeAttr( "tabIndex role aria-haspopup" );
5156
5157 // Destroy (sub)menus
5158 this.element
5159 .removeAttr( "aria-activedescendant" )
5160 .find( ".ui-menu" ).addBack()
5161 .removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " +
5162 "tabIndex" )
5163 .removeUniqueId()
5164 .show();
5165
5166 submenus.children().each( function() {
5167 var elem = $( this );
5168 if ( elem.data( "ui-menu-submenu-caret" ) ) {
5169 elem.remove();
5170 }
5171 } );
5172 },
5173
5174 _keydown: function( event ) {
5175 var match, prev, character, skip,
5176 preventDefault = true;
5177
5178 switch ( event.keyCode ) {
5179 case $.ui.keyCode.PAGE_UP:
5180 this.previousPage( event );
5181 break;
5182 case $.ui.keyCode.PAGE_DOWN:
5183 this.nextPage( event );
5184 break;
5185 case $.ui.keyCode.HOME:
5186 this._move( "first", "first", event );
5187 break;
5188 case $.ui.keyCode.END:
5189 this._move( "last", "last", event );
5190 break;
5191 case $.ui.keyCode.UP:
5192 this.previous( event );
5193 break;
5194 case $.ui.keyCode.DOWN:
5195 this.next( event );
5196 break;
5197 case $.ui.keyCode.LEFT:
5198 this.collapse( event );
5199 break;
5200 case $.ui.keyCode.RIGHT:
5201 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
5202 this.expand( event );
5203 }
5204 break;
5205 case $.ui.keyCode.ENTER:
5206 case $.ui.keyCode.SPACE:
5207 this._activate( event );
5208 break;
5209 case $.ui.keyCode.ESCAPE:
5210 this.collapse( event );
5211 break;
5212 default:
5213 preventDefault = false;
5214 prev = this.previousFilter || "";
5215 skip = false;
5216
5217 // Support number pad values
5218 character = event.keyCode >= 96 && event.keyCode <= 105 ?
5219 ( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode );
5220
5221 clearTimeout( this.filterTimer );
5222
5223 if ( character === prev ) {
5224 skip = true;
5225 } else {
5226 character = prev + character;
5227 }
5228
5229 match = this._filterMenuItems( character );
5230 match = skip && match.index( this.active.next() ) !== -1 ?
5231 this.active.nextAll( ".ui-menu-item" ) :
5232 match;
5233
5234 // If no matches on the current filter, reset to the last character pressed
5235 // to move down the menu to the first item that starts with that character
5236 if ( !match.length ) {
5237 character = String.fromCharCode( event.keyCode );
5238 match = this._filterMenuItems( character );
5239 }
5240
5241 if ( match.length ) {
5242 this.focus( event, match );
5243 this.previousFilter = character;
5244 this.filterTimer = this._delay( function() {
5245 delete this.previousFilter;
5246 }, 1000 );
5247 } else {
5248 delete this.previousFilter;
5249 }
5250 }
5251
5252 if ( preventDefault ) {
5253 event.preventDefault();
5254 }
5255 },
5256
5257 _activate: function( event ) {
5258 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
5259 if ( this.active.children( "[aria-haspopup='true']" ).length ) {
5260 this.expand( event );
5261 } else {
5262 this.select( event );
5263 }
5264 }
5265 },
5266
5267 refresh: function() {
5268 var menus, items, newSubmenus, newItems, newWrappers,
5269 that = this,
5270 icon = this.options.icons.submenu,
5271 submenus = this.element.find( this.options.menus );
5272
5273 this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length );
5274
5275 // Initialize nested menus
5276 newSubmenus = submenus.filter( ":not(.ui-menu)" )
5277 .hide()
5278 .attr( {
5279 role: this.options.role,
5280 "aria-hidden": "true",
5281 "aria-expanded": "false"
5282 } )
5283 .each( function() {
5284 var menu = $( this ),
5285 item = menu.prev(),
5286 submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true );
5287
5288 that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon );
5289 item
5290 .attr( "aria-haspopup", "true" )
5291 .prepend( submenuCaret );
5292 menu.attr( "aria-labelledby", item.attr( "id" ) );
5293 } );
5294
5295 this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" );
5296
5297 menus = submenus.add( this.element );
5298 items = menus.find( this.options.items );
5299
5300 // Initialize menu-items containing spaces and/or dashes only as dividers
5301 items.not( ".ui-menu-item" ).each( function() {
5302 var item = $( this );
5303 if ( that._isDivider( item ) ) {
5304 that._addClass( item, "ui-menu-divider", "ui-widget-content" );
5305 }
5306 } );
5307
5308 // Don't refresh list items that are already adapted
5309 newItems = items.not( ".ui-menu-item, .ui-menu-divider" );
5310 newWrappers = newItems.children()
5311 .not( ".ui-menu" )
5312 .uniqueId()
5313 .attr( {
5314 tabIndex: -1,
5315 role: this._itemRole()
5316 } );
5317 this._addClass( newItems, "ui-menu-item" )
5318 ._addClass( newWrappers, "ui-menu-item-wrapper" );
5319
5320 // Add aria-disabled attribute to any disabled menu item
5321 items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
5322
5323 // If the active item has been removed, blur the menu
5324 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
5325 this.blur();
5326 }
5327 },
5328
5329 _itemRole: function() {
5330 return {
5331 menu: "menuitem",
5332 listbox: "option"
5333 }[ this.options.role ];
5334 },
5335
5336 _setOption: function( key, value ) {
5337 if ( key === "icons" ) {
5338 var icons = this.element.find( ".ui-menu-icon" );
5339 this._removeClass( icons, null, this.options.icons.submenu )
5340 ._addClass( icons, null, value.submenu );
5341 }
5342 this._super( key, value );
5343 },
5344
5345 _setOptionDisabled: function( value ) {
5346 this._super( value );
5347
5348 this.element.attr( "aria-disabled", String( value ) );
5349 this._toggleClass( null, "ui-state-disabled", !!value );
5350 },
5351
5352 focus: function( event, item ) {
5353 var nested, focused, activeParent;
5354 this.blur( event, event && event.type === "focus" );
5355
5356 this._scrollIntoView( item );
5357
5358 this.active = item.first();
5359
5360 focused = this.active.children( ".ui-menu-item-wrapper" );
5361 this._addClass( focused, null, "ui-state-active" );
5362
5363 // Only update aria-activedescendant if there's a role
5364 // otherwise we assume focus is managed elsewhere
5365 if ( this.options.role ) {
5366 this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
5367 }
5368
5369 // Highlight active parent menu item, if any
5370 activeParent = this.active
5371 .parent()
5372 .closest( ".ui-menu-item" )
5373 .children( ".ui-menu-item-wrapper" );
5374 this._addClass( activeParent, null, "ui-state-active" );
5375
5376 if ( event && event.type === "keydown" ) {
5377 this._close();
5378 } else {
5379 this.timer = this._delay( function() {
5380 this._close();
5381 }, this.delay );
5382 }
5383
5384 nested = item.children( ".ui-menu" );
5385 if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
5386 this._startOpening( nested );
5387 }
5388 this.activeMenu = item.parent();
5389
5390 this._trigger( "focus", event, { item: item } );
5391 },
5392
5393 _scrollIntoView: function( item ) {
5394 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
5395 if ( this._hasScroll() ) {
5396 borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0;
5397 paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0;
5398 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
5399 scroll = this.activeMenu.scrollTop();
5400 elementHeight = this.activeMenu.height();
5401 itemHeight = item.outerHeight();
5402
5403 if ( offset < 0 ) {
5404 this.activeMenu.scrollTop( scroll + offset );
5405 } else if ( offset + itemHeight > elementHeight ) {
5406 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
5407 }
5408 }
5409 },
5410
5411 blur: function( event, fromFocus ) {
5412 if ( !fromFocus ) {
5413 clearTimeout( this.timer );
5414 }
5415
5416 if ( !this.active ) {
5417 return;
5418 }
5419
5420 this._removeClass( this.active.children( ".ui-menu-item-wrapper" ),
5421 null, "ui-state-active" );
5422
5423 this._trigger( "blur", event, { item: this.active } );
5424 this.active = null;
5425 },
5426
5427 _startOpening: function( submenu ) {
5428 clearTimeout( this.timer );
5429
5430 // Don't open if already open fixes a Firefox bug that caused a .5 pixel
5431 // shift in the submenu position when mousing over the caret icon
5432 if ( submenu.attr( "aria-hidden" ) !== "true" ) {
5433 return;
5434 }
5435
5436 this.timer = this._delay( function() {
5437 this._close();
5438 this._open( submenu );
5439 }, this.delay );
5440 },
5441
5442 _open: function( submenu ) {
5443 var position = $.extend( {
5444 of: this.active
5445 }, this.options.position );
5446
5447 clearTimeout( this.timer );
5448 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
5449 .hide()
5450 .attr( "aria-hidden", "true" );
5451
5452 submenu
5453 .show()
5454 .removeAttr( "aria-hidden" )
5455 .attr( "aria-expanded", "true" )
5456 .position( position );
5457 },
5458
5459 collapseAll: function( event, all ) {
5460 clearTimeout( this.timer );
5461 this.timer = this._delay( function() {
5462
5463 // If we were passed an event, look for the submenu that contains the event
5464 var currentMenu = all ? this.element :
5465 $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
5466
5467 // If we found no valid submenu ancestor, use the main menu to close all
5468 // sub menus anyway
5469 if ( !currentMenu.length ) {
5470 currentMenu = this.element;
5471 }
5472
5473 this._close( currentMenu );
5474
5475 this.blur( event );
5476
5477 // Work around active item staying active after menu is blurred
5478 this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" );
5479
5480 this.activeMenu = currentMenu;
5481 }, all ? 0 : this.delay );
5482 },
5483
5484 // With no arguments, closes the currently active menu - if nothing is active
5485 // it closes all menus. If passed an argument, it will search for menus BELOW
5486 _close: function( startMenu ) {
5487 if ( !startMenu ) {
5488 startMenu = this.active ? this.active.parent() : this.element;
5489 }
5490
5491 startMenu.find( ".ui-menu" )
5492 .hide()
5493 .attr( "aria-hidden", "true" )
5494 .attr( "aria-expanded", "false" );
5495 },
5496
5497 _closeOnDocumentClick: function( event ) {
5498 return !$( event.target ).closest( ".ui-menu" ).length;
5499 },
5500
5501 _isDivider: function( item ) {
5502
5503 // Match hyphen, em dash, en dash
5504 return !/[^\-\u2014\u2013\s]/.test( item.text() );
5505 },
5506
5507 collapse: function( event ) {
5508 var newItem = this.active &&
5509 this.active.parent().closest( ".ui-menu-item", this.element );
5510 if ( newItem && newItem.length ) {
5511 this._close();
5512 this.focus( event, newItem );
5513 }
5514 },
5515
5516 expand: function( event ) {
5517 var newItem = this.active && this._menuItems( this.active.children( ".ui-menu" ) ).first();
5518
5519 if ( newItem && newItem.length ) {
5520 this._open( newItem.parent() );
5521
5522 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
5523 this._delay( function() {
5524 this.focus( event, newItem );
5525 } );
5526 }
5527 },
5528
5529 next: function( event ) {
5530 this._move( "next", "first", event );
5531 },
5532
5533 previous: function( event ) {
5534 this._move( "prev", "last", event );
5535 },
5536
5537 isFirstItem: function() {
5538 return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
5539 },
5540
5541 isLastItem: function() {
5542 return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
5543 },
5544
5545 _menuItems: function( menu ) {
5546 return ( menu || this.element )
5547 .find( this.options.items )
5548 .filter( ".ui-menu-item" );
5549 },
5550
5551 _move: function( direction, filter, event ) {
5552 var next;
5553 if ( this.active ) {
5554 if ( direction === "first" || direction === "last" ) {
5555 next = this.active
5556 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
5557 .last();
5558 } else {
5559 next = this.active
5560 [ direction + "All" ]( ".ui-menu-item" )
5561 .first();
5562 }
5563 }
5564 if ( !next || !next.length || !this.active ) {
5565 next = this._menuItems( this.activeMenu )[ filter ]();
5566 }
5567
5568 this.focus( event, next );
5569 },
5570
5571 nextPage: function( event ) {
5572 var item, base, height;
5573
5574 if ( !this.active ) {
5575 this.next( event );
5576 return;
5577 }
5578 if ( this.isLastItem() ) {
5579 return;
5580 }
5581 if ( this._hasScroll() ) {
5582 base = this.active.offset().top;
5583 height = this.element.innerHeight();
5584
5585 // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back.
5586 if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) {
5587 height += this.element[ 0 ].offsetHeight - this.element.outerHeight();
5588 }
5589
5590 this.active.nextAll( ".ui-menu-item" ).each( function() {
5591 item = $( this );
5592 return item.offset().top - base - height < 0;
5593 } );
5594
5595 this.focus( event, item );
5596 } else {
5597 this.focus( event, this._menuItems( this.activeMenu )
5598 [ !this.active ? "first" : "last" ]() );
5599 }
5600 },
5601
5602 previousPage: function( event ) {
5603 var item, base, height;
5604 if ( !this.active ) {
5605 this.next( event );
5606 return;
5607 }
5608 if ( this.isFirstItem() ) {
5609 return;
5610 }
5611 if ( this._hasScroll() ) {
5612 base = this.active.offset().top;
5613 height = this.element.innerHeight();
5614
5615 // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back.
5616 if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) {
5617 height += this.element[ 0 ].offsetHeight - this.element.outerHeight();
5618 }
5619
5620 this.active.prevAll( ".ui-menu-item" ).each( function() {
5621 item = $( this );
5622 return item.offset().top - base + height > 0;
5623 } );
5624
5625 this.focus( event, item );
5626 } else {
5627 this.focus( event, this._menuItems( this.activeMenu ).first() );
5628 }
5629 },
5630
5631 _hasScroll: function() {
5632 return this.element.outerHeight() < this.element.prop( "scrollHeight" );
5633 },
5634
5635 select: function( event ) {
5636
5637 // TODO: It should never be possible to not have an active item at this
5638 // point, but the tests don't trigger mouseenter before click.
5639 this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
5640 var ui = { item: this.active };
5641 if ( !this.active.has( ".ui-menu" ).length ) {
5642 this.collapseAll( event, true );
5643 }
5644 this._trigger( "select", event, ui );
5645 },
5646
5647 _filterMenuItems: function( character ) {
5648 var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
5649 regex = new RegExp( "^" + escapedCharacter, "i" );
5650
5651 return this.activeMenu
5652 .find( this.options.items )
5653
5654 // Only match on items, not dividers or other content (#10571)
5655 .filter( ".ui-menu-item" )
5656 .filter( function() {
5657 return regex.test(
5658 String.prototype.trim.call(
5659 $( this ).children( ".ui-menu-item-wrapper" ).text() ) );
5660 } );
5661 }
5662 } );
5663
5664
5665 /*!
5666 * jQuery UI Autocomplete 1.13.2
5667 * http://jqueryui.com
5668 *
5669 * Copyright jQuery Foundation and other contributors
5670 * Released under the MIT license.
5671 * http://jquery.org/license
5672 */
5673
5674 //>>label: Autocomplete
5675 //>>group: Widgets
5676 //>>description: Lists suggested words as the user is typing.
5677 //>>docs: http://api.jqueryui.com/autocomplete/
5678 //>>demos: http://jqueryui.com/autocomplete/
5679 //>>css.structure: ../../themes/base/core.css
5680 //>>css.structure: ../../themes/base/autocomplete.css
5681 //>>css.theme: ../../themes/base/theme.css
5682
5683
5684 $.widget( "ui.autocomplete", {
5685 version: "1.13.2",
5686 defaultElement: "<input>",
5687 options: {
5688 appendTo: null,
5689 autoFocus: false,
5690 delay: 300,
5691 minLength: 1,
5692 position: {
5693 my: "left top",
5694 at: "left bottom",
5695 collision: "none"
5696 },
5697 source: null,
5698
5699 // Callbacks
5700 change: null,
5701 close: null,
5702 focus: null,
5703 open: null,
5704 response: null,
5705 search: null,
5706 select: null
5707 },
5708
5709 requestIndex: 0,
5710 pending: 0,
5711 liveRegionTimer: null,
5712
5713 _create: function() {
5714
5715 // Some browsers only repeat keydown events, not keypress events,
5716 // so we use the suppressKeyPress flag to determine if we've already
5717 // handled the keydown event. #7269
5718 // Unfortunately the code for & in keypress is the same as the up arrow,
5719 // so we use the suppressKeyPressRepeat flag to avoid handling keypress
5720 // events when we know the keydown event was used to modify the
5721 // search term. #7799
5722 var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
5723 nodeName = this.element[ 0 ].nodeName.toLowerCase(),
5724 isTextarea = nodeName === "textarea",
5725 isInput = nodeName === "input";
5726
5727 // Textareas are always multi-line
5728 // Inputs are always single-line, even if inside a contentEditable element
5729 // IE also treats inputs as contentEditable
5730 // All other element types are determined by whether or not they're contentEditable
5731 this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element );
5732
5733 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
5734 this.isNewMenu = true;
5735
5736 this._addClass( "ui-autocomplete-input" );
5737 this.element.attr( "autocomplete", "off" );
5738
5739 this._on( this.element, {
5740 keydown: function( event ) {
5741 if ( this.element.prop( "readOnly" ) ) {
5742 suppressKeyPress = true;
5743 suppressInput = true;
5744 suppressKeyPressRepeat = true;
5745 return;
5746 }
5747
5748 suppressKeyPress = false;
5749 suppressInput = false;
5750 suppressKeyPressRepeat = false;
5751 var keyCode = $.ui.keyCode;
5752 switch ( event.keyCode ) {
5753 case keyCode.PAGE_UP:
5754 suppressKeyPress = true;
5755 this._move( "previousPage", event );
5756 break;
5757 case keyCode.PAGE_DOWN:
5758 suppressKeyPress = true;
5759 this._move( "nextPage", event );
5760 break;
5761 case keyCode.UP:
5762 suppressKeyPress = true;
5763 this._keyEvent( "previous", event );
5764 break;
5765 case keyCode.DOWN:
5766 suppressKeyPress = true;
5767 this._keyEvent( "next", event );
5768 break;
5769 case keyCode.ENTER:
5770
5771 // when menu is open and has focus
5772 if ( this.menu.active ) {
5773
5774 // #6055 - Opera still allows the keypress to occur
5775 // which causes forms to submit
5776 suppressKeyPress = true;
5777 event.preventDefault();
5778 this.menu.select( event );
5779 }
5780 break;
5781 case keyCode.TAB:
5782 if ( this.menu.active ) {
5783 this.menu.select( event );
5784 }
5785 break;
5786 case keyCode.ESCAPE:
5787 if ( this.menu.element.is( ":visible" ) ) {
5788 if ( !this.isMultiLine ) {
5789 this._value( this.term );
5790 }
5791 this.close( event );
5792
5793 // Different browsers have different default behavior for escape
5794 // Single press can mean undo or clear
5795 // Double press in IE means clear the whole form
5796 event.preventDefault();
5797 }
5798 break;
5799 default:
5800 suppressKeyPressRepeat = true;
5801
5802 // search timeout should be triggered before the input value is changed
5803 this._searchTimeout( event );
5804 break;
5805 }
5806 },
5807 keypress: function( event ) {
5808 if ( suppressKeyPress ) {
5809 suppressKeyPress = false;
5810 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
5811 event.preventDefault();
5812 }
5813 return;
5814 }
5815 if ( suppressKeyPressRepeat ) {
5816 return;
5817 }
5818
5819 // Replicate some key handlers to allow them to repeat in Firefox and Opera
5820 var keyCode = $.ui.keyCode;
5821 switch ( event.keyCode ) {
5822 case keyCode.PAGE_UP:
5823 this._move( "previousPage", event );
5824 break;
5825 case keyCode.PAGE_DOWN:
5826 this._move( "nextPage", event );
5827 break;
5828 case keyCode.UP:
5829 this._keyEvent( "previous", event );
5830 break;
5831 case keyCode.DOWN:
5832 this._keyEvent( "next", event );
5833 break;
5834 }
5835 },
5836 input: function( event ) {
5837 if ( suppressInput ) {
5838 suppressInput = false;
5839 event.preventDefault();
5840 return;
5841 }
5842 this._searchTimeout( event );
5843 },
5844 focus: function() {
5845 this.selectedItem = null;
5846 this.previous = this._value();
5847 },
5848 blur: function( event ) {
5849 clearTimeout( this.searching );
5850 this.close( event );
5851 this._change( event );
5852 }
5853 } );
5854
5855 this._initSource();
5856 this.menu = $( "<ul>" )
5857 .appendTo( this._appendTo() )
5858 .menu( {
5859
5860 // disable ARIA support, the live region takes care of that
5861 role: null
5862 } )
5863 .hide()
5864
5865 // Support: IE 11 only, Edge <= 14
5866 // For other browsers, we preventDefault() on the mousedown event
5867 // to keep the dropdown from taking focus from the input. This doesn't
5868 // work for IE/Edge, causing problems with selection and scrolling (#9638)
5869 // Happily, IE and Edge support an "unselectable" attribute that
5870 // prevents an element from receiving focus, exactly what we want here.
5871 .attr( {
5872 "unselectable": "on"
5873 } )
5874 .menu( "instance" );
5875
5876 this._addClass( this.menu.element, "ui-autocomplete", "ui-front" );
5877 this._on( this.menu.element, {
5878 mousedown: function( event ) {
5879
5880 // Prevent moving focus out of the text field
5881 event.preventDefault();
5882 },
5883 menufocus: function( event, ui ) {
5884 var label, item;
5885
5886 // support: Firefox
5887 // Prevent accidental activation of menu items in Firefox (#7024 #9118)
5888 if ( this.isNewMenu ) {
5889 this.isNewMenu = false;
5890 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
5891 this.menu.blur();
5892
5893 this.document.one( "mousemove", function() {
5894 $( event.target ).trigger( event.originalEvent );
5895 } );
5896
5897 return;
5898 }
5899 }
5900
5901 item = ui.item.data( "ui-autocomplete-item" );
5902 if ( false !== this._trigger( "focus", event, { item: item } ) ) {
5903
5904 // use value to match what will end up in the input, if it was a key event
5905 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
5906 this._value( item.value );
5907 }
5908 }
5909
5910 // Announce the value in the liveRegion
5911 label = ui.item.attr( "aria-label" ) || item.value;
5912 if ( label && String.prototype.trim.call( label ).length ) {
5913 clearTimeout( this.liveRegionTimer );
5914 this.liveRegionTimer = this._delay( function() {
5915 this.liveRegion.html( $( "<div>" ).text( label ) );
5916 }, 100 );
5917 }
5918 },
5919 menuselect: function( event, ui ) {
5920 var item = ui.item.data( "ui-autocomplete-item" ),
5921 previous = this.previous;
5922
5923 // Only trigger when focus was lost (click on menu)
5924 if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
5925 this.element.trigger( "focus" );
5926 this.previous = previous;
5927
5928 // #6109 - IE triggers two focus events and the second
5929 // is asynchronous, so we need to reset the previous
5930 // term synchronously and asynchronously :-(
5931 this._delay( function() {
5932 this.previous = previous;
5933 this.selectedItem = item;
5934 } );
5935 }
5936
5937 if ( false !== this._trigger( "select", event, { item: item } ) ) {
5938 this._value( item.value );
5939 }
5940
5941 // reset the term after the select event
5942 // this allows custom select handling to work properly
5943 this.term = this._value();
5944
5945 this.close( event );
5946 this.selectedItem = item;
5947 }
5948 } );
5949
5950 this.liveRegion = $( "<div>", {
5951 role: "status",
5952 "aria-live": "assertive",
5953 "aria-relevant": "additions"
5954 } )
5955 .appendTo( this.document[ 0 ].body );
5956
5957 this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
5958
5959 // Turning off autocomplete prevents the browser from remembering the
5960 // value when navigating through history, so we re-enable autocomplete
5961 // if the page is unloaded before the widget is destroyed. #7790
5962 this._on( this.window, {
5963 beforeunload: function() {
5964 this.element.removeAttr( "autocomplete" );
5965 }
5966 } );
5967 },
5968
5969 _destroy: function() {
5970 clearTimeout( this.searching );
5971 this.element.removeAttr( "autocomplete" );
5972 this.menu.element.remove();
5973 this.liveRegion.remove();
5974 },
5975
5976 _setOption: function( key, value ) {
5977 this._super( key, value );
5978 if ( key === "source" ) {
5979 this._initSource();
5980 }
5981 if ( key === "appendTo" ) {
5982 this.menu.element.appendTo( this._appendTo() );
5983 }
5984 if ( key === "disabled" && value && this.xhr ) {
5985 this.xhr.abort();
5986 }
5987 },
5988
5989 _isEventTargetInWidget: function( event ) {
5990 var menuElement = this.menu.element[ 0 ];
5991
5992 return event.target === this.element[ 0 ] ||
5993 event.target === menuElement ||
5994 $.contains( menuElement, event.target );
5995 },
5996
5997 _closeOnClickOutside: function( event ) {
5998 if ( !this._isEventTargetInWidget( event ) ) {
5999 this.close();
6000 }
6001 },
6002
6003 _appendTo: function() {
6004 var element = this.options.appendTo;
6005
6006 if ( element ) {
6007 element = element.jquery || element.nodeType ?
6008 $( element ) :
6009 this.document.find( element ).eq( 0 );
6010 }
6011
6012 if ( !element || !element[ 0 ] ) {
6013 element = this.element.closest( ".ui-front, dialog" );
6014 }
6015
6016 if ( !element.length ) {
6017 element = this.document[ 0 ].body;
6018 }
6019
6020 return element;
6021 },
6022
6023 _initSource: function() {
6024 var array, url,
6025 that = this;
6026 if ( Array.isArray( this.options.source ) ) {
6027 array = this.options.source;
6028 this.source = function( request, response ) {
6029 response( $.ui.autocomplete.filter( array, request.term ) );
6030 };
6031 } else if ( typeof this.options.source === "string" ) {
6032 url = this.options.source;
6033 this.source = function( request, response ) {
6034 if ( that.xhr ) {
6035 that.xhr.abort();
6036 }
6037 that.xhr = $.ajax( {
6038 url: url,
6039 data: request,
6040 dataType: "json",
6041 success: function( data ) {
6042 response( data );
6043 },
6044 error: function() {
6045 response( [] );
6046 }
6047 } );
6048 };
6049 } else {
6050 this.source = this.options.source;
6051 }
6052 },
6053
6054 _searchTimeout: function( event ) {
6055 clearTimeout( this.searching );
6056 this.searching = this._delay( function() {
6057
6058 // Search if the value has changed, or if the user retypes the same value (see #7434)
6059 var equalValues = this.term === this._value(),
6060 menuVisible = this.menu.element.is( ":visible" ),
6061 modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
6062
6063 if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
6064 this.selectedItem = null;
6065 this.search( null, event );
6066 }
6067 }, this.options.delay );
6068 },
6069
6070 search: function( value, event ) {
6071 value = value != null ? value : this._value();
6072
6073 // Always save the actual value, not the one passed as an argument
6074 this.term = this._value();
6075
6076 if ( value.length < this.options.minLength ) {
6077 return this.close( event );
6078 }
6079
6080 if ( this._trigger( "search", event ) === false ) {
6081 return;
6082 }
6083
6084 return this._search( value );
6085 },
6086
6087 _search: function( value ) {
6088 this.pending++;
6089 this._addClass( "ui-autocomplete-loading" );
6090 this.cancelSearch = false;
6091
6092 this.source( { term: value }, this._response() );
6093 },
6094
6095 _response: function() {
6096 var index = ++this.requestIndex;
6097
6098 return function( content ) {
6099 if ( index === this.requestIndex ) {
6100 this.__response( content );
6101 }
6102
6103 this.pending--;
6104 if ( !this.pending ) {
6105 this._removeClass( "ui-autocomplete-loading" );
6106 }
6107 }.bind( this );
6108 },
6109
6110 __response: function( content ) {
6111 if ( content ) {
6112 content = this._normalize( content );
6113 }
6114 this._trigger( "response", null, { content: content } );
6115 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
6116 this._suggest( content );
6117 this._trigger( "open" );
6118 } else {
6119
6120 // use ._close() instead of .close() so we don't cancel future searches
6121 this._close();
6122 }
6123 },
6124
6125 close: function( event ) {
6126 this.cancelSearch = true;
6127 this._close( event );
6128 },
6129
6130 _close: function( event ) {
6131
6132 // Remove the handler that closes the menu on outside clicks
6133 this._off( this.document, "mousedown" );
6134
6135 if ( this.menu.element.is( ":visible" ) ) {
6136 this.menu.element.hide();
6137 this.menu.blur();
6138 this.isNewMenu = true;
6139 this._trigger( "close", event );
6140 }
6141 },
6142
6143 _change: function( event ) {
6144 if ( this.previous !== this._value() ) {
6145 this._trigger( "change", event, { item: this.selectedItem } );
6146 }
6147 },
6148
6149 _normalize: function( items ) {
6150
6151 // assume all items have the right format when the first item is complete
6152 if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
6153 return items;
6154 }
6155 return $.map( items, function( item ) {
6156 if ( typeof item === "string" ) {
6157 return {
6158 label: item,
6159 value: item
6160 };
6161 }
6162 return $.extend( {}, item, {
6163 label: item.label || item.value,
6164 value: item.value || item.label
6165 } );
6166 } );
6167 },
6168
6169 _suggest: function( items ) {
6170 var ul = this.menu.element.empty();
6171 this._renderMenu( ul, items );
6172 this.isNewMenu = true;
6173 this.menu.refresh();
6174
6175 // Size and position menu
6176 ul.show();
6177 this._resizeMenu();
6178 ul.position( $.extend( {
6179 of: this.element
6180 }, this.options.position ) );
6181
6182 if ( this.options.autoFocus ) {
6183 this.menu.next();
6184 }
6185
6186 // Listen for interactions outside of the widget (#6642)
6187 this._on( this.document, {
6188 mousedown: "_closeOnClickOutside"
6189 } );
6190 },
6191
6192 _resizeMenu: function() {
6193 var ul = this.menu.element;
6194 ul.outerWidth( Math.max(
6195
6196 // Firefox wraps long text (possibly a rounding bug)
6197 // so we add 1px to avoid the wrapping (#7513)
6198 ul.width( "" ).outerWidth() + 1,
6199 this.element.outerWidth()
6200 ) );
6201 },
6202
6203 _renderMenu: function( ul, items ) {
6204 var that = this;
6205 $.each( items, function( index, item ) {
6206 that._renderItemData( ul, item );
6207 } );
6208 },
6209
6210 _renderItemData: function( ul, item ) {
6211 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
6212 },
6213
6214 _renderItem: function( ul, item ) {
6215 return $( "<li>" )
6216 .append( $( "<div>" ).text( item.label ) )
6217 .appendTo( ul );
6218 },
6219
6220 _move: function( direction, event ) {
6221 if ( !this.menu.element.is( ":visible" ) ) {
6222 this.search( null, event );
6223 return;
6224 }
6225 if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
6226 this.menu.isLastItem() && /^next/.test( direction ) ) {
6227
6228 if ( !this.isMultiLine ) {
6229 this._value( this.term );
6230 }
6231
6232 this.menu.blur();
6233 return;
6234 }
6235 this.menu[ direction ]( event );
6236 },
6237
6238 widget: function() {
6239 return this.menu.element;
6240 },
6241
6242 _value: function() {
6243 return this.valueMethod.apply( this.element, arguments );
6244 },
6245
6246 _keyEvent: function( keyEvent, event ) {
6247 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
6248 this._move( keyEvent, event );
6249
6250 // Prevents moving cursor to beginning/end of the text field in some browsers
6251 event.preventDefault();
6252 }
6253 },
6254
6255 // Support: Chrome <=50
6256 // We should be able to just use this.element.prop( "isContentEditable" )
6257 // but hidden elements always report false in Chrome.
6258 // https://code.google.com/p/chromium/issues/detail?id=313082
6259 _isContentEditable: function( element ) {
6260 if ( !element.length ) {
6261 return false;
6262 }
6263
6264 var editable = element.prop( "contentEditable" );
6265
6266 if ( editable === "inherit" ) {
6267 return this._isContentEditable( element.parent() );
6268 }
6269
6270 return editable === "true";
6271 }
6272 } );
6273
6274 $.extend( $.ui.autocomplete, {
6275 escapeRegex: function( value ) {
6276 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
6277 },
6278 filter: function( array, term ) {
6279 var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
6280 return $.grep( array, function( value ) {
6281 return matcher.test( value.label || value.value || value );
6282 } );
6283 }
6284 } );
6285
6286 // Live region extension, adding a `messages` option
6287 // NOTE: This is an experimental API. We are still investigating
6288 // a full solution for string manipulation and internationalization.
6289 $.widget( "ui.autocomplete", $.ui.autocomplete, {
6290 options: {
6291 messages: {
6292 noResults: "No search results.",
6293 results: function( amount ) {
6294 return amount + ( amount > 1 ? " results are" : " result is" ) +
6295 " available, use up and down arrow keys to navigate.";
6296 }
6297 }
6298 },
6299
6300 __response: function( content ) {
6301 var message;
6302 this._superApply( arguments );
6303 if ( this.options.disabled || this.cancelSearch ) {
6304 return;
6305 }
6306 if ( content && content.length ) {
6307 message = this.options.messages.results( content.length );
6308 } else {
6309 message = this.options.messages.noResults;
6310 }
6311 clearTimeout( this.liveRegionTimer );
6312 this.liveRegionTimer = this._delay( function() {
6313 this.liveRegion.html( $( "<div>" ).text( message ) );
6314 }, 100 );
6315 }
6316 } );
6317
6318 var widgetsAutocomplete = $.ui.autocomplete;
6319
6320
6321 /*!
6322 * jQuery UI Controlgroup 1.13.2
6323 * http://jqueryui.com
6324 *
6325 * Copyright jQuery Foundation and other contributors
6326 * Released under the MIT license.
6327 * http://jquery.org/license
6328 */
6329
6330 //>>label: Controlgroup
6331 //>>group: Widgets
6332 //>>description: Visually groups form control widgets
6333 //>>docs: http://api.jqueryui.com/controlgroup/
6334 //>>demos: http://jqueryui.com/controlgroup/
6335 //>>css.structure: ../../themes/base/core.css
6336 //>>css.structure: ../../themes/base/controlgroup.css
6337 //>>css.theme: ../../themes/base/theme.css
6338
6339
6340 var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g;
6341
6342 var widgetsControlgroup = $.widget( "ui.controlgroup", {
6343 version: "1.13.2",
6344 defaultElement: "<div>",
6345 options: {
6346 direction: "horizontal",
6347 disabled: null,
6348 onlyVisible: true,
6349 items: {
6350 "button": "input[type=button], input[type=submit], input[type=reset], button, a",
6351 "controlgroupLabel": ".ui-controlgroup-label",
6352 "checkboxradio": "input[type='checkbox'], input[type='radio']",
6353 "selectmenu": "select",
6354 "spinner": ".ui-spinner-input"
6355 }
6356 },
6357
6358 _create: function() {
6359 this._enhance();
6360 },
6361
6362 // To support the enhanced option in jQuery Mobile, we isolate DOM manipulation
6363 _enhance: function() {
6364 this.element.attr( "role", "toolbar" );
6365 this.refresh();
6366 },
6367
6368 _destroy: function() {
6369 this._callChildMethod( "destroy" );
6370 this.childWidgets.removeData( "ui-controlgroup-data" );
6371 this.element.removeAttr( "role" );
6372 if ( this.options.items.controlgroupLabel ) {
6373 this.element
6374 .find( this.options.items.controlgroupLabel )
6375 .find( ".ui-controlgroup-label-contents" )
6376 .contents().unwrap();
6377 }
6378 },
6379
6380 _initWidgets: function() {
6381 var that = this,
6382 childWidgets = [];
6383
6384 // First we iterate over each of the items options
6385 $.each( this.options.items, function( widget, selector ) {
6386 var labels;
6387 var options = {};
6388
6389 // Make sure the widget has a selector set
6390 if ( !selector ) {
6391 return;
6392 }
6393
6394 if ( widget === "controlgroupLabel" ) {
6395 labels = that.element.find( selector );
6396 labels.each( function() {
6397 var element = $( this );
6398
6399 if ( element.children( ".ui-controlgroup-label-contents" ).length ) {
6400 return;
6401 }
6402 element.contents()
6403 .wrapAll( "<span class='ui-controlgroup-label-contents'></span>" );
6404 } );
6405 that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" );
6406 childWidgets = childWidgets.concat( labels.get() );
6407 return;
6408 }
6409
6410 // Make sure the widget actually exists
6411 if ( !$.fn[ widget ] ) {
6412 return;
6413 }
6414
6415 // We assume everything is in the middle to start because we can't determine
6416 // first / last elements until all enhancments are done.
6417 if ( that[ "_" + widget + "Options" ] ) {
6418 options = that[ "_" + widget + "Options" ]( "middle" );
6419 } else {
6420 options = { classes: {} };
6421 }
6422
6423 // Find instances of this widget inside controlgroup and init them
6424 that.element
6425 .find( selector )
6426 .each( function() {
6427 var element = $( this );
6428 var instance = element[ widget ]( "instance" );
6429
6430 // We need to clone the default options for this type of widget to avoid
6431 // polluting the variable options which has a wider scope than a single widget.
6432 var instanceOptions = $.widget.extend( {}, options );
6433
6434 // If the button is the child of a spinner ignore it
6435 // TODO: Find a more generic solution
6436 if ( widget === "button" && element.parent( ".ui-spinner" ).length ) {
6437 return;
6438 }
6439
6440 // Create the widget if it doesn't exist
6441 if ( !instance ) {
6442 instance = element[ widget ]()[ widget ]( "instance" );
6443 }
6444 if ( instance ) {
6445 instanceOptions.classes =
6446 that._resolveClassesValues( instanceOptions.classes, instance );
6447 }
6448 element[ widget ]( instanceOptions );
6449
6450 // Store an instance of the controlgroup to be able to reference
6451 // from the outermost element for changing options and refresh
6452 var widgetElement = element[ widget ]( "widget" );
6453 $.data( widgetElement[ 0 ], "ui-controlgroup-data",
6454 instance ? instance : element[ widget ]( "instance" ) );
6455
6456 childWidgets.push( widgetElement[ 0 ] );
6457 } );
6458 } );
6459
6460 this.childWidgets = $( $.uniqueSort( childWidgets ) );
6461 this._addClass( this.childWidgets, "ui-controlgroup-item" );
6462 },
6463
6464 _callChildMethod: function( method ) {
6465 this.childWidgets.each( function() {
6466 var element = $( this ),
6467 data = element.data( "ui-controlgroup-data" );
6468 if ( data && data[ method ] ) {
6469 data[ method ]();
6470 }
6471 } );
6472 },
6473
6474 _updateCornerClass: function( element, position ) {
6475 var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all";
6476 var add = this._buildSimpleOptions( position, "label" ).classes.label;
6477
6478 this._removeClass( element, null, remove );
6479 this._addClass( element, null, add );
6480 },
6481
6482 _buildSimpleOptions: function( position, key ) {
6483 var direction = this.options.direction === "vertical";
6484 var result = {
6485 classes: {}
6486 };
6487 result.classes[ key ] = {
6488 "middle": "",
6489 "first": "ui-corner-" + ( direction ? "top" : "left" ),
6490 "last": "ui-corner-" + ( direction ? "bottom" : "right" ),
6491 "only": "ui-corner-all"
6492 }[ position ];
6493
6494 return result;
6495 },
6496
6497 _spinnerOptions: function( position ) {
6498 var options = this._buildSimpleOptions( position, "ui-spinner" );
6499
6500 options.classes[ "ui-spinner-up" ] = "";
6501 options.classes[ "ui-spinner-down" ] = "";
6502
6503 return options;
6504 },
6505
6506 _buttonOptions: function( position ) {
6507 return this._buildSimpleOptions( position, "ui-button" );
6508 },
6509
6510 _checkboxradioOptions: function( position ) {
6511 return this._buildSimpleOptions( position, "ui-checkboxradio-label" );
6512 },
6513
6514 _selectmenuOptions: function( position ) {
6515 var direction = this.options.direction === "vertical";
6516 return {
6517 width: direction ? "auto" : false,
6518 classes: {
6519 middle: {
6520 "ui-selectmenu-button-open": "",
6521 "ui-selectmenu-button-closed": ""
6522 },
6523 first: {
6524 "ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ),
6525 "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" )
6526 },
6527 last: {
6528 "ui-selectmenu-button-open": direction ? "" : "ui-corner-tr",
6529 "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" )
6530 },
6531 only: {
6532 "ui-selectmenu-button-open": "ui-corner-top",
6533 "ui-selectmenu-button-closed": "ui-corner-all"
6534 }
6535
6536 }[ position ]
6537 };
6538 },
6539
6540 _resolveClassesValues: function( classes, instance ) {
6541 var result = {};
6542 $.each( classes, function( key ) {
6543 var current = instance.options.classes[ key ] || "";
6544 current = String.prototype.trim.call( current.replace( controlgroupCornerRegex, "" ) );
6545 result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " );
6546 } );
6547 return result;
6548 },
6549
6550 _setOption: function( key, value ) {
6551 if ( key === "direction" ) {
6552 this._removeClass( "ui-controlgroup-" + this.options.direction );
6553 }
6554
6555 this._super( key, value );
6556 if ( key === "disabled" ) {
6557 this._callChildMethod( value ? "disable" : "enable" );
6558 return;
6559 }
6560
6561 this.refresh();
6562 },
6563
6564 refresh: function() {
6565 var children,
6566 that = this;
6567
6568 this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction );
6569
6570 if ( this.options.direction === "horizontal" ) {
6571 this._addClass( null, "ui-helper-clearfix" );
6572 }
6573 this._initWidgets();
6574
6575 children = this.childWidgets;
6576
6577 // We filter here because we need to track all childWidgets not just the visible ones
6578 if ( this.options.onlyVisible ) {
6579 children = children.filter( ":visible" );
6580 }
6581
6582 if ( children.length ) {
6583
6584 // We do this last because we need to make sure all enhancment is done
6585 // before determining first and last
6586 $.each( [ "first", "last" ], function( index, value ) {
6587 var instance = children[ value ]().data( "ui-controlgroup-data" );
6588
6589 if ( instance && that[ "_" + instance.widgetName + "Options" ] ) {
6590 var options = that[ "_" + instance.widgetName + "Options" ](
6591 children.length === 1 ? "only" : value
6592 );
6593 options.classes = that._resolveClassesValues( options.classes, instance );
6594 instance.element[ instance.widgetName ]( options );
6595 } else {
6596 that._updateCornerClass( children[ value ](), value );
6597 }
6598 } );
6599
6600 // Finally call the refresh method on each of the child widgets.
6601 this._callChildMethod( "refresh" );
6602 }
6603 }
6604 } );
6605
6606 /*!
6607 * jQuery UI Checkboxradio 1.13.2
6608 * http://jqueryui.com
6609 *
6610 * Copyright jQuery Foundation and other contributors
6611 * Released under the MIT license.
6612 * http://jquery.org/license
6613 */
6614
6615 //>>label: Checkboxradio
6616 //>>group: Widgets
6617 //>>description: Enhances a form with multiple themeable checkboxes or radio buttons.
6618 //>>docs: http://api.jqueryui.com/checkboxradio/
6619 //>>demos: http://jqueryui.com/checkboxradio/
6620 //>>css.structure: ../../themes/base/core.css
6621 //>>css.structure: ../../themes/base/button.css
6622 //>>css.structure: ../../themes/base/checkboxradio.css
6623 //>>css.theme: ../../themes/base/theme.css
6624
6625
6626 $.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
6627 version: "1.13.2",
6628 options: {
6629 disabled: null,
6630 label: null,
6631 icon: true,
6632 classes: {
6633 "ui-checkboxradio-label": "ui-corner-all",
6634 "ui-checkboxradio-icon": "ui-corner-all"
6635 }
6636 },
6637
6638 _getCreateOptions: function() {
6639 var disabled, labels, labelContents;
6640 var options = this._super() || {};
6641
6642 // We read the type here, because it makes more sense to throw a element type error first,
6643 // rather then the error for lack of a label. Often if its the wrong type, it
6644 // won't have a label (e.g. calling on a div, btn, etc)
6645 this._readType();
6646
6647 labels = this.element.labels();
6648
6649 // If there are multiple labels, use the last one
6650 this.label = $( labels[ labels.length - 1 ] );
6651 if ( !this.label.length ) {
6652 $.error( "No label found for checkboxradio widget" );
6653 }
6654
6655 this.originalLabel = "";
6656
6657 // We need to get the label text but this may also need to make sure it does not contain the
6658 // input itself.
6659 // The label contents could be text, html, or a mix. We wrap all elements
6660 // and read the wrapper's `innerHTML` to get a string representation of
6661 // the label, without the input as part of it.
6662 labelContents = this.label.contents().not( this.element[ 0 ] );
6663
6664 if ( labelContents.length ) {
6665 this.originalLabel += labelContents
6666 .clone()
6667 .wrapAll( "<div></div>" )
6668 .parent()
6669 .html();
6670 }
6671
6672 // Set the label option if we found label text
6673 if ( this.originalLabel ) {
6674 options.label = this.originalLabel;
6675 }
6676
6677 disabled = this.element[ 0 ].disabled;
6678 if ( disabled != null ) {
6679 options.disabled = disabled;
6680 }
6681 return options;
6682 },
6683
6684 _create: function() {
6685 var checked = this.element[ 0 ].checked;
6686
6687 this._bindFormResetHandler();
6688
6689 if ( this.options.disabled == null ) {
6690 this.options.disabled = this.element[ 0 ].disabled;
6691 }
6692
6693 this._setOption( "disabled", this.options.disabled );
6694 this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" );
6695 this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" );
6696
6697 if ( this.type === "radio" ) {
6698 this._addClass( this.label, "ui-checkboxradio-radio-label" );
6699 }
6700
6701 if ( this.options.label && this.options.label !== this.originalLabel ) {
6702 this._updateLabel();
6703 } else if ( this.originalLabel ) {
6704 this.options.label = this.originalLabel;
6705 }
6706
6707 this._enhance();
6708
6709 if ( checked ) {
6710 this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" );
6711 }
6712
6713 this._on( {
6714 change: "_toggleClasses",
6715 focus: function() {
6716 this._addClass( this.label, null, "ui-state-focus ui-visual-focus" );
6717 },
6718 blur: function() {
6719 this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" );
6720 }
6721 } );
6722 },
6723
6724 _readType: function() {
6725 var nodeName = this.element[ 0 ].nodeName.toLowerCase();
6726 this.type = this.element[ 0 ].type;
6727 if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) {
6728 $.error( "Can't create checkboxradio on element.nodeName=" + nodeName +
6729 " and element.type=" + this.type );
6730 }
6731 },
6732
6733 // Support jQuery Mobile enhanced option
6734 _enhance: function() {
6735 this._updateIcon( this.element[ 0 ].checked );
6736 },
6737
6738 widget: function() {
6739 return this.label;
6740 },
6741
6742 _getRadioGroup: function() {
6743 var group;
6744 var name = this.element[ 0 ].name;
6745 var nameSelector = "input[name='" + $.escapeSelector( name ) + "']";
6746
6747 if ( !name ) {
6748 return $( [] );
6749 }
6750
6751 if ( this.form.length ) {
6752 group = $( this.form[ 0 ].elements ).filter( nameSelector );
6753 } else {
6754
6755 // Not inside a form, check all inputs that also are not inside a form
6756 group = $( nameSelector ).filter( function() {
6757 return $( this )._form().length === 0;
6758 } );
6759 }
6760
6761 return group.not( this.element );
6762 },
6763
6764 _toggleClasses: function() {
6765 var checked = this.element[ 0 ].checked;
6766 this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
6767
6768 if ( this.options.icon && this.type === "checkbox" ) {
6769 this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked )
6770 ._toggleClass( this.icon, null, "ui-icon-blank", !checked );
6771 }
6772
6773 if ( this.type === "radio" ) {
6774 this._getRadioGroup()
6775 .each( function() {
6776 var instance = $( this ).checkboxradio( "instance" );
6777
6778 if ( instance ) {
6779 instance._removeClass( instance.label,
6780 "ui-checkboxradio-checked", "ui-state-active" );
6781 }
6782 } );
6783 }
6784 },
6785
6786 _destroy: function() {
6787 this._unbindFormResetHandler();
6788
6789 if ( this.icon ) {
6790 this.icon.remove();
6791 this.iconSpace.remove();
6792 }
6793 },
6794
6795 _setOption: function( key, value ) {
6796
6797 // We don't allow the value to be set to nothing
6798 if ( key === "label" && !value ) {
6799 return;
6800 }
6801
6802 this._super( key, value );
6803
6804 if ( key === "disabled" ) {
6805 this._toggleClass( this.label, null, "ui-state-disabled", value );
6806 this.element[ 0 ].disabled = value;
6807
6808 // Don't refresh when setting disabled
6809 return;
6810 }
6811 this.refresh();
6812 },
6813
6814 _updateIcon: function( checked ) {
6815 var toAdd = "ui-icon ui-icon-background ";
6816
6817 if ( this.options.icon ) {
6818 if ( !this.icon ) {
6819 this.icon = $( "<span>" );
6820 this.iconSpace = $( "<span> </span>" );
6821 this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" );
6822 }
6823
6824 if ( this.type === "checkbox" ) {
6825 toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank";
6826 this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" );
6827 } else {
6828 toAdd += "ui-icon-blank";
6829 }
6830 this._addClass( this.icon, "ui-checkboxradio-icon", toAdd );
6831 if ( !checked ) {
6832 this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" );
6833 }
6834 this.icon.prependTo( this.label ).after( this.iconSpace );
6835 } else if ( this.icon !== undefined ) {
6836 this.icon.remove();
6837 this.iconSpace.remove();
6838 delete this.icon;
6839 }
6840 },
6841
6842 _updateLabel: function() {
6843
6844 // Remove the contents of the label ( minus the icon, icon space, and input )
6845 var contents = this.label.contents().not( this.element[ 0 ] );
6846 if ( this.icon ) {
6847 contents = contents.not( this.icon[ 0 ] );
6848 }
6849 if ( this.iconSpace ) {
6850 contents = contents.not( this.iconSpace[ 0 ] );
6851 }
6852 contents.remove();
6853
6854 this.label.append( this.options.label );
6855 },
6856
6857 refresh: function() {
6858 var checked = this.element[ 0 ].checked,
6859 isDisabled = this.element[ 0 ].disabled;
6860
6861 this._updateIcon( checked );
6862 this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
6863 if ( this.options.label !== null ) {
6864 this._updateLabel();
6865 }
6866
6867 if ( isDisabled !== this.options.disabled ) {
6868 this._setOptions( { "disabled": isDisabled } );
6869 }
6870 }
6871
6872 } ] );
6873
6874 var widgetsCheckboxradio = $.ui.checkboxradio;
6875
6876
6877 /*!
6878 * jQuery UI Button 1.13.2
6879 * http://jqueryui.com
6880 *
6881 * Copyright jQuery Foundation and other contributors
6882 * Released under the MIT license.
6883 * http://jquery.org/license
6884 */
6885
6886 //>>label: Button
6887 //>>group: Widgets
6888 //>>description: Enhances a form with themeable buttons.
6889 //>>docs: http://api.jqueryui.com/button/
6890 //>>demos: http://jqueryui.com/button/
6891 //>>css.structure: ../../themes/base/core.css
6892 //>>css.structure: ../../themes/base/button.css
6893 //>>css.theme: ../../themes/base/theme.css
6894
6895
6896 $.widget( "ui.button", {
6897 version: "1.13.2",
6898 defaultElement: "<button>",
6899 options: {
6900 classes: {
6901 "ui-button": "ui-corner-all"
6902 },
6903 disabled: null,
6904 icon: null,
6905 iconPosition: "beginning",
6906 label: null,
6907 showLabel: true
6908 },
6909
6910 _getCreateOptions: function() {
6911 var disabled,
6912
6913 // This is to support cases like in jQuery Mobile where the base widget does have
6914 // an implementation of _getCreateOptions
6915 options = this._super() || {};
6916
6917 this.isInput = this.element.is( "input" );
6918
6919 disabled = this.element[ 0 ].disabled;
6920 if ( disabled != null ) {
6921 options.disabled = disabled;
6922 }
6923
6924 this.originalLabel = this.isInput ? this.element.val() : this.element.html();
6925 if ( this.originalLabel ) {
6926 options.label = this.originalLabel;
6927 }
6928
6929 return options;
6930 },
6931
6932 _create: function() {
6933 if ( !this.option.showLabel & !this.options.icon ) {
6934 this.options.showLabel = true;
6935 }
6936
6937 // We have to check the option again here even though we did in _getCreateOptions,
6938 // because null may have been passed on init which would override what was set in
6939 // _getCreateOptions
6940 if ( this.options.disabled == null ) {
6941 this.options.disabled = this.element[ 0 ].disabled || false;
6942 }
6943
6944 this.hasTitle = !!this.element.attr( "title" );
6945
6946 // Check to see if the label needs to be set or if its already correct
6947 if ( this.options.label && this.options.label !== this.originalLabel ) {
6948 if ( this.isInput ) {
6949 this.element.val( this.options.label );
6950 } else {
6951 this.element.html( this.options.label );
6952 }
6953 }
6954 this._addClass( "ui-button", "ui-widget" );
6955 this._setOption( "disabled", this.options.disabled );
6956 this._enhance();
6957
6958 if ( this.element.is( "a" ) ) {
6959 this._on( {
6960 "keyup": function( event ) {
6961 if ( event.keyCode === $.ui.keyCode.SPACE ) {
6962 event.preventDefault();
6963
6964 // Support: PhantomJS <= 1.9, IE 8 Only
6965 // If a native click is available use it so we actually cause navigation
6966 // otherwise just trigger a click event
6967 if ( this.element[ 0 ].click ) {
6968 this.element[ 0 ].click();
6969 } else {
6970 this.element.trigger( "click" );
6971 }
6972 }
6973 }
6974 } );
6975 }
6976 },
6977
6978 _enhance: function() {
6979 if ( !this.element.is( "button" ) ) {
6980 this.element.attr( "role", "button" );
6981 }
6982
6983 if ( this.options.icon ) {
6984 this._updateIcon( "icon", this.options.icon );
6985 this._updateTooltip();
6986 }
6987 },
6988
6989 _updateTooltip: function() {
6990 this.title = this.element.attr( "title" );
6991
6992 if ( !this.options.showLabel && !this.title ) {
6993 this.element.attr( "title", this.options.label );
6994 }
6995 },
6996
6997 _updateIcon: function( option, value ) {
6998 var icon = option !== "iconPosition",
6999 position = icon ? this.options.iconPosition : value,
7000 displayBlock = position === "top" || position === "bottom";
7001
7002 // Create icon
7003 if ( !this.icon ) {
7004 this.icon = $( "<span>" );
7005
7006 this._addClass( this.icon, "ui-button-icon", "ui-icon" );
7007
7008 if ( !this.options.showLabel ) {
7009 this._addClass( "ui-button-icon-only" );
7010 }
7011 } else if ( icon ) {
7012
7013 // If we are updating the icon remove the old icon class
7014 this._removeClass( this.icon, null, this.options.icon );
7015 }
7016
7017 // If we are updating the icon add the new icon class
7018 if ( icon ) {
7019 this._addClass( this.icon, null, value );
7020 }
7021
7022 this._attachIcon( position );
7023
7024 // If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove
7025 // the iconSpace if there is one.
7026 if ( displayBlock ) {
7027 this._addClass( this.icon, null, "ui-widget-icon-block" );
7028 if ( this.iconSpace ) {
7029 this.iconSpace.remove();
7030 }
7031 } else {
7032
7033 // Position is beginning or end so remove the ui-widget-icon-block class and add the
7034 // space if it does not exist
7035 if ( !this.iconSpace ) {
7036 this.iconSpace = $( "<span> </span>" );
7037 this._addClass( this.iconSpace, "ui-button-icon-space" );
7038 }
7039 this._removeClass( this.icon, null, "ui-wiget-icon-block" );
7040 this._attachIconSpace( position );
7041 }
7042 },
7043
7044 _destroy: function() {
7045 this.element.removeAttr( "role" );
7046
7047 if ( this.icon ) {
7048 this.icon.remove();
7049 }
7050 if ( this.iconSpace ) {
7051 this.iconSpace.remove();
7052 }
7053 if ( !this.hasTitle ) {
7054 this.element.removeAttr( "title" );
7055 }
7056 },
7057
7058 _attachIconSpace: function( iconPosition ) {
7059 this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace );
7060 },
7061
7062 _attachIcon: function( iconPosition ) {
7063 this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon );
7064 },
7065
7066 _setOptions: function( options ) {
7067 var newShowLabel = options.showLabel === undefined ?
7068 this.options.showLabel :
7069 options.showLabel,
7070 newIcon = options.icon === undefined ? this.options.icon : options.icon;
7071
7072 if ( !newShowLabel && !newIcon ) {
7073 options.showLabel = true;
7074 }
7075 this._super( options );
7076 },
7077
7078 _setOption: function( key, value ) {
7079 if ( key === "icon" ) {
7080 if ( value ) {
7081 this._updateIcon( key, value );
7082 } else if ( this.icon ) {
7083 this.icon.remove();
7084 if ( this.iconSpace ) {
7085 this.iconSpace.remove();
7086 }
7087 }
7088 }
7089
7090 if ( key === "iconPosition" ) {
7091 this._updateIcon( key, value );
7092 }
7093
7094 // Make sure we can't end up with a button that has neither text nor icon
7095 if ( key === "showLabel" ) {
7096 this._toggleClass( "ui-button-icon-only", null, !value );
7097 this._updateTooltip();
7098 }
7099
7100 if ( key === "label" ) {
7101 if ( this.isInput ) {
7102 this.element.val( value );
7103 } else {
7104
7105 // If there is an icon, append it, else nothing then append the value
7106 // this avoids removal of the icon when setting label text
7107 this.element.html( value );
7108 if ( this.icon ) {
7109 this._attachIcon( this.options.iconPosition );
7110 this._attachIconSpace( this.options.iconPosition );
7111 }
7112 }
7113 }
7114
7115 this._super( key, value );
7116
7117 if ( key === "disabled" ) {
7118 this._toggleClass( null, "ui-state-disabled", value );
7119 this.element[ 0 ].disabled = value;
7120 if ( value ) {
7121 this.element.trigger( "blur" );
7122 }
7123 }
7124 },
7125
7126 refresh: function() {
7127
7128 // Make sure to only check disabled if its an element that supports this otherwise
7129 // check for the disabled class to determine state
7130 var isDisabled = this.element.is( "input, button" ) ?
7131 this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" );
7132
7133 if ( isDisabled !== this.options.disabled ) {
7134 this._setOptions( { disabled: isDisabled } );
7135 }
7136
7137 this._updateTooltip();
7138 }
7139 } );
7140
7141 // DEPRECATED
7142 if ( $.uiBackCompat !== false ) {
7143
7144 // Text and Icons options
7145 $.widget( "ui.button", $.ui.button, {
7146 options: {
7147 text: true,
7148 icons: {
7149 primary: null,
7150 secondary: null
7151 }
7152 },
7153
7154 _create: function() {
7155 if ( this.options.showLabel && !this.options.text ) {
7156 this.options.showLabel = this.options.text;
7157 }
7158 if ( !this.options.showLabel && this.options.text ) {
7159 this.options.text = this.options.showLabel;
7160 }
7161 if ( !this.options.icon && ( this.options.icons.primary ||
7162 this.options.icons.secondary ) ) {
7163 if ( this.options.icons.primary ) {
7164 this.options.icon = this.options.icons.primary;
7165 } else {
7166 this.options.icon = this.options.icons.secondary;
7167 this.options.iconPosition = "end";
7168 }
7169 } else if ( this.options.icon ) {
7170 this.options.icons.primary = this.options.icon;
7171 }
7172 this._super();
7173 },
7174
7175 _setOption: function( key, value ) {
7176 if ( key === "text" ) {
7177 this._super( "showLabel", value );
7178 return;
7179 }
7180 if ( key === "showLabel" ) {
7181 this.options.text = value;
7182 }
7183 if ( key === "icon" ) {
7184 this.options.icons.primary = value;
7185 }
7186 if ( key === "icons" ) {
7187 if ( value.primary ) {
7188 this._super( "icon", value.primary );
7189 this._super( "iconPosition", "beginning" );
7190 } else if ( value.secondary ) {
7191 this._super( "icon", value.secondary );
7192 this._super( "iconPosition", "end" );
7193 }
7194 }
7195 this._superApply( arguments );
7196 }
7197 } );
7198
7199 $.fn.button = ( function( orig ) {
7200 return function( options ) {
7201 var isMethodCall = typeof options === "string";
7202 var args = Array.prototype.slice.call( arguments, 1 );
7203 var returnValue = this;
7204
7205 if ( isMethodCall ) {
7206
7207 // If this is an empty collection, we need to have the instance method
7208 // return undefined instead of the jQuery instance
7209 if ( !this.length && options === "instance" ) {
7210 returnValue = undefined;
7211 } else {
7212 this.each( function() {
7213 var methodValue;
7214 var type = $( this ).attr( "type" );
7215 var name = type !== "checkbox" && type !== "radio" ?
7216 "button" :
7217 "checkboxradio";
7218 var instance = $.data( this, "ui-" + name );
7219
7220 if ( options === "instance" ) {
7221 returnValue = instance;
7222 return false;
7223 }
7224
7225 if ( !instance ) {
7226 return $.error( "cannot call methods on button" +
7227 " prior to initialization; " +
7228 "attempted to call method '" + options + "'" );
7229 }
7230
7231 if ( typeof instance[ options ] !== "function" ||
7232 options.charAt( 0 ) === "_" ) {
7233 return $.error( "no such method '" + options + "' for button" +
7234 " widget instance" );
7235 }
7236
7237 methodValue = instance[ options ].apply( instance, args );
7238
7239 if ( methodValue !== instance && methodValue !== undefined ) {
7240 returnValue = methodValue && methodValue.jquery ?
7241 returnValue.pushStack( methodValue.get() ) :
7242 methodValue;
7243 return false;
7244 }
7245 } );
7246 }
7247 } else {
7248
7249 // Allow multiple hashes to be passed on init
7250 if ( args.length ) {
7251 options = $.widget.extend.apply( null, [ options ].concat( args ) );
7252 }
7253
7254 this.each( function() {
7255 var type = $( this ).attr( "type" );
7256 var name = type !== "checkbox" && type !== "radio" ? "button" : "checkboxradio";
7257 var instance = $.data( this, "ui-" + name );
7258
7259 if ( instance ) {
7260 instance.option( options || {} );
7261 if ( instance._init ) {
7262 instance._init();
7263 }
7264 } else {
7265 if ( name === "button" ) {
7266 orig.call( $( this ), options );
7267 return;
7268 }
7269
7270 $( this ).checkboxradio( $.extend( { icon: false }, options ) );
7271 }
7272 } );
7273 }
7274
7275 return returnValue;
7276 };
7277 } )( $.fn.button );
7278
7279 $.fn.buttonset = function() {
7280 if ( !$.ui.controlgroup ) {
7281 $.error( "Controlgroup widget missing" );
7282 }
7283 if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) {
7284 return this.controlgroup.apply( this,
7285 [ arguments[ 0 ], "items.button", arguments[ 2 ] ] );
7286 }
7287 if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) {
7288 return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] );
7289 }
7290 if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) {
7291 arguments[ 0 ].items = {
7292 button: arguments[ 0 ].items
7293 };
7294 }
7295 return this.controlgroup.apply( this, arguments );
7296 };
7297 }
7298
7299 var widgetsButton = $.ui.button;
7300
7301
7302 /* eslint-disable max-len, camelcase */
7303 /*!
7304 * jQuery UI Datepicker 1.13.2
7305 * http://jqueryui.com
7306 *
7307 * Copyright jQuery Foundation and other contributors
7308 * Released under the MIT license.
7309 * http://jquery.org/license
7310 */
7311
7312 //>>label: Datepicker
7313 //>>group: Widgets
7314 //>>description: Displays a calendar from an input or inline for selecting dates.
7315 //>>docs: http://api.jqueryui.com/datepicker/
7316 //>>demos: http://jqueryui.com/datepicker/
7317 //>>css.structure: ../../themes/base/core.css
7318 //>>css.structure: ../../themes/base/datepicker.css
7319 //>>css.theme: ../../themes/base/theme.css
7320
7321
7322 $.extend( $.ui, { datepicker: { version: "1.13.2" } } );
7323
7324 var datepicker_instActive;
7325
7326 function datepicker_getZindex( elem ) {
7327 var position, value;
7328 while ( elem.length && elem[ 0 ] !== document ) {
7329
7330 // Ignore z-index if position is set to a value where z-index is ignored by the browser
7331 // This makes behavior of this function consistent across browsers
7332 // WebKit always returns auto if the element is positioned
7333 position = elem.css( "position" );
7334 if ( position === "absolute" || position === "relative" || position === "fixed" ) {
7335
7336 // IE returns 0 when zIndex is not specified
7337 // other browsers return a string
7338 // we ignore the case of nested elements with an explicit value of 0
7339 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
7340 value = parseInt( elem.css( "zIndex" ), 10 );
7341 if ( !isNaN( value ) && value !== 0 ) {
7342 return value;
7343 }
7344 }
7345 elem = elem.parent();
7346 }
7347
7348 return 0;
7349 }
7350
7351 /* Date picker manager.
7352 Use the singleton instance of this class, $.datepicker, to interact with the date picker.
7353 Settings for (groups of) date pickers are maintained in an instance object,
7354 allowing multiple different settings on the same page. */
7355
7356 function Datepicker() {
7357 this._curInst = null; // The current instance in use
7358 this._keyEvent = false; // If the last event was a key event
7359 this._disabledInputs = []; // List of date picker inputs that have been disabled
7360 this._datepickerShowing = false; // True if the popup picker is showing , false if not
7361 this._inDialog = false; // True if showing within a "dialog", false if not
7362 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
7363 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
7364 this._appendClass = "ui-datepicker-append"; // The name of the append marker class
7365 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
7366 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
7367 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
7368 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
7369 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
7370 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
7371 this.regional = []; // Available regional settings, indexed by language code
7372 this.regional[ "" ] = { // Default regional settings
7373 closeText: "Done", // Display text for close link
7374 prevText: "Prev", // Display text for previous month link
7375 nextText: "Next", // Display text for next month link
7376 currentText: "Today", // Display text for current month link
7377 monthNames: [ "January", "February", "March", "April", "May", "June",
7378 "July", "August", "September", "October", "November", "December" ], // Names of months for drop-down and formatting
7379 monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting
7380 dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting
7381 dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting
7382 dayNamesMin: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ], // Column headings for days starting at Sunday
7383 weekHeader: "Wk", // Column header for week of the year
7384 dateFormat: "mm/dd/yy", // See format options on parseDate
7385 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
7386 isRTL: false, // True if right-to-left language, false if left-to-right
7387 showMonthAfterYear: false, // True if the year select precedes month, false for month then year
7388 yearSuffix: "", // Additional text to append to the year in the month headers,
7389 selectMonthLabel: "Select month", // Invisible label for month selector
7390 selectYearLabel: "Select year" // Invisible label for year selector
7391 };
7392 this._defaults = { // Global defaults for all the date picker instances
7393 showOn: "focus", // "focus" for popup on focus,
7394 // "button" for trigger button, or "both" for either
7395 showAnim: "fadeIn", // Name of jQuery animation for popup
7396 showOptions: {}, // Options for enhanced animations
7397 defaultDate: null, // Used when field is blank: actual date,
7398 // +/-number for offset from today, null for today
7399 appendText: "", // Display text following the input box, e.g. showing the format
7400 buttonText: "...", // Text for trigger button
7401 buttonImage: "", // URL for trigger button image
7402 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
7403 hideIfNoPrevNext: false, // True to hide next/previous month links
7404 // if not applicable, false to just disable them
7405 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
7406 gotoCurrent: false, // True if today link goes back to current selection instead
7407 changeMonth: false, // True if month can be selected directly, false if only prev/next
7408 changeYear: false, // True if year can be selected directly, false if only prev/next
7409 yearRange: "c-10:c+10", // Range of years to display in drop-down,
7410 // either relative to today's year (-nn:+nn), relative to currently displayed year
7411 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
7412 showOtherMonths: false, // True to show dates in other months, false to leave blank
7413 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
7414 showWeek: false, // True to show week of the year, false to not show it
7415 calculateWeek: this.iso8601Week, // How to calculate the week of the year,
7416 // takes a Date and returns the number of the week for it
7417 shortYearCutoff: "+10", // Short year values < this are in the current century,
7418 // > this are in the previous century,
7419 // string value starting with "+" for current year + value
7420 minDate: null, // The earliest selectable date, or null for no limit
7421 maxDate: null, // The latest selectable date, or null for no limit
7422 duration: "fast", // Duration of display/closure
7423 beforeShowDay: null, // Function that takes a date and returns an array with
7424 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
7425 // [2] = cell title (optional), e.g. $.datepicker.noWeekends
7426 beforeShow: null, // Function that takes an input field and
7427 // returns a set of custom settings for the date picker
7428 onSelect: null, // Define a callback function when a date is selected
7429 onChangeMonthYear: null, // Define a callback function when the month or year is changed
7430 onClose: null, // Define a callback function when the datepicker is closed
7431 onUpdateDatepicker: null, // Define a callback function when the datepicker is updated
7432 numberOfMonths: 1, // Number of months to show at a time
7433 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
7434 stepMonths: 1, // Number of months to step back/forward
7435 stepBigMonths: 12, // Number of months to step back/forward for the big links
7436 altField: "", // Selector for an alternate field to store selected dates into
7437 altFormat: "", // The date format to use for the alternate field
7438 constrainInput: true, // The input is constrained by the current date format
7439 showButtonPanel: false, // True to show button panel, false to not show it
7440 autoSize: false, // True to size the input for the date format, false to leave as is
7441 disabled: false // The initial disabled state
7442 };
7443 $.extend( this._defaults, this.regional[ "" ] );
7444 this.regional.en = $.extend( true, {}, this.regional[ "" ] );
7445 this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
7446 this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) );
7447 }
7448
7449 $.extend( Datepicker.prototype, {
7450
7451 /* Class name added to elements to indicate already configured with a date picker. */
7452 markerClassName: "hasDatepicker",
7453
7454 //Keep track of the maximum number of rows displayed (see #7043)
7455 maxRows: 4,
7456
7457 // TODO rename to "widget" when switching to widget factory
7458 _widgetDatepicker: function() {
7459 return this.dpDiv;
7460 },
7461
7462 /* Override the default settings for all instances of the date picker.
7463 * @param settings object - the new settings to use as defaults (anonymous object)
7464 * @return the manager object
7465 */
7466 setDefaults: function( settings ) {
7467 datepicker_extendRemove( this._defaults, settings || {} );
7468 return this;
7469 },
7470
7471 /* Attach the date picker to a jQuery selection.
7472 * @param target element - the target input field or division or span
7473 * @param settings object - the new settings to use for this date picker instance (anonymous)
7474 */
7475 _attachDatepicker: function( target, settings ) {
7476 var nodeName, inline, inst;
7477 nodeName = target.nodeName.toLowerCase();
7478 inline = ( nodeName === "div" || nodeName === "span" );
7479 if ( !target.id ) {
7480 this.uuid += 1;
7481 target.id = "dp" + this.uuid;
7482 }
7483 inst = this._newInst( $( target ), inline );
7484 inst.settings = $.extend( {}, settings || {} );
7485 if ( nodeName === "input" ) {
7486 this._connectDatepicker( target, inst );
7487 } else if ( inline ) {
7488 this._inlineDatepicker( target, inst );
7489 }
7490 },
7491
7492 /* Create a new instance object. */
7493 _newInst: function( target, inline ) {
7494 var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars
7495 return { id: id, input: target, // associated target
7496 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
7497 drawMonth: 0, drawYear: 0, // month being drawn
7498 inline: inline, // is datepicker inline or not
7499 dpDiv: ( !inline ? this.dpDiv : // presentation div
7500 datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) };
7501 },
7502
7503 /* Attach the date picker to an input field. */
7504 _connectDatepicker: function( target, inst ) {
7505 var input = $( target );
7506 inst.append = $( [] );
7507 inst.trigger = $( [] );
7508 if ( input.hasClass( this.markerClassName ) ) {
7509 return;
7510 }
7511 this._attachments( input, inst );
7512 input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ).
7513 on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp );
7514 this._autoSize( inst );
7515 $.data( target, "datepicker", inst );
7516
7517 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
7518 if ( inst.settings.disabled ) {
7519 this._disableDatepicker( target );
7520 }
7521 },
7522
7523 /* Make attachments based on settings. */
7524 _attachments: function( input, inst ) {
7525 var showOn, buttonText, buttonImage,
7526 appendText = this._get( inst, "appendText" ),
7527 isRTL = this._get( inst, "isRTL" );
7528
7529 if ( inst.append ) {
7530 inst.append.remove();
7531 }
7532 if ( appendText ) {
7533 inst.append = $( "<span>" )
7534 .addClass( this._appendClass )
7535 .text( appendText );
7536 input[ isRTL ? "before" : "after" ]( inst.append );
7537 }
7538
7539 input.off( "focus", this._showDatepicker );
7540
7541 if ( inst.trigger ) {
7542 inst.trigger.remove();
7543 }
7544
7545 showOn = this._get( inst, "showOn" );
7546 if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field
7547 input.on( "focus", this._showDatepicker );
7548 }
7549 if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked
7550 buttonText = this._get( inst, "buttonText" );
7551 buttonImage = this._get( inst, "buttonImage" );
7552
7553 if ( this._get( inst, "buttonImageOnly" ) ) {
7554 inst.trigger = $( "<img>" )
7555 .addClass( this._triggerClass )
7556 .attr( {
7557 src: buttonImage,
7558 alt: buttonText,
7559 title: buttonText
7560 } );
7561 } else {
7562 inst.trigger = $( "<button type='button'>" )
7563 .addClass( this._triggerClass );
7564 if ( buttonImage ) {
7565 inst.trigger.html(
7566 $( "<img>" )
7567 .attr( {
7568 src: buttonImage,
7569 alt: buttonText,
7570 title: buttonText
7571 } )
7572 );
7573 } else {
7574 inst.trigger.text( buttonText );
7575 }
7576 }
7577
7578 input[ isRTL ? "before" : "after" ]( inst.trigger );
7579 inst.trigger.on( "click", function() {
7580 if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) {
7581 $.datepicker._hideDatepicker();
7582 } else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) {
7583 $.datepicker._hideDatepicker();
7584 $.datepicker._showDatepicker( input[ 0 ] );
7585 } else {
7586 $.datepicker._showDatepicker( input[ 0 ] );
7587 }
7588 return false;
7589 } );
7590 }
7591 },
7592
7593 /* Apply the maximum length for the date format. */
7594 _autoSize: function( inst ) {
7595 if ( this._get( inst, "autoSize" ) && !inst.inline ) {
7596 var findMax, max, maxI, i,
7597 date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits
7598 dateFormat = this._get( inst, "dateFormat" );
7599
7600 if ( dateFormat.match( /[DM]/ ) ) {
7601 findMax = function( names ) {
7602 max = 0;
7603 maxI = 0;
7604 for ( i = 0; i < names.length; i++ ) {
7605 if ( names[ i ].length > max ) {
7606 max = names[ i ].length;
7607 maxI = i;
7608 }
7609 }
7610 return maxI;
7611 };
7612 date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ?
7613 "monthNames" : "monthNamesShort" ) ) ) );
7614 date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ?
7615 "dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() );
7616 }
7617 inst.input.attr( "size", this._formatDate( inst, date ).length );
7618 }
7619 },
7620
7621 /* Attach an inline date picker to a div. */
7622 _inlineDatepicker: function( target, inst ) {
7623 var divSpan = $( target );
7624 if ( divSpan.hasClass( this.markerClassName ) ) {
7625 return;
7626 }
7627 divSpan.addClass( this.markerClassName ).append( inst.dpDiv );
7628 $.data( target, "datepicker", inst );
7629 this._setDate( inst, this._getDefaultDate( inst ), true );
7630 this._updateDatepicker( inst );
7631 this._updateAlternate( inst );
7632
7633 //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7634 if ( inst.settings.disabled ) {
7635 this._disableDatepicker( target );
7636 }
7637
7638 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7639 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7640 inst.dpDiv.css( "display", "block" );
7641 },
7642
7643 /* Pop-up the date picker in a "dialog" box.
7644 * @param input element - ignored
7645 * @param date string or Date - the initial date to display
7646 * @param onSelect function - the function to call when a date is selected
7647 * @param settings object - update the dialog date picker instance's settings (anonymous object)
7648 * @param pos int[2] - coordinates for the dialog's position within the screen or
7649 * event - with x/y coordinates or
7650 * leave empty for default (screen centre)
7651 * @return the manager object
7652 */
7653 _dialogDatepicker: function( input, date, onSelect, settings, pos ) {
7654 var id, browserWidth, browserHeight, scrollX, scrollY,
7655 inst = this._dialogInst; // internal instance
7656
7657 if ( !inst ) {
7658 this.uuid += 1;
7659 id = "dp" + this.uuid;
7660 this._dialogInput = $( "<input type='text' id='" + id +
7661 "' style='position: absolute; top: -100px; width: 0px;'/>" );
7662 this._dialogInput.on( "keydown", this._doKeyDown );
7663 $( "body" ).append( this._dialogInput );
7664 inst = this._dialogInst = this._newInst( this._dialogInput, false );
7665 inst.settings = {};
7666 $.data( this._dialogInput[ 0 ], "datepicker", inst );
7667 }
7668 datepicker_extendRemove( inst.settings, settings || {} );
7669 date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date );
7670 this._dialogInput.val( date );
7671
7672 this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null );
7673 if ( !this._pos ) {
7674 browserWidth = document.documentElement.clientWidth;
7675 browserHeight = document.documentElement.clientHeight;
7676 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7677 scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7678 this._pos = // should use actual width/height below
7679 [ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ];
7680 }
7681
7682 // Move input on screen for focus, but hidden behind dialog
7683 this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" );
7684 inst.settings.onSelect = onSelect;
7685 this._inDialog = true;
7686 this.dpDiv.addClass( this._dialogClass );
7687 this._showDatepicker( this._dialogInput[ 0 ] );
7688 if ( $.blockUI ) {
7689 $.blockUI( this.dpDiv );
7690 }
7691 $.data( this._dialogInput[ 0 ], "datepicker", inst );
7692 return this;
7693 },
7694
7695 /* Detach a datepicker from its control.
7696 * @param target element - the target input field or division or span
7697 */
7698 _destroyDatepicker: function( target ) {
7699 var nodeName,
7700 $target = $( target ),
7701 inst = $.data( target, "datepicker" );
7702
7703 if ( !$target.hasClass( this.markerClassName ) ) {
7704 return;
7705 }
7706
7707 nodeName = target.nodeName.toLowerCase();
7708 $.removeData( target, "datepicker" );
7709 if ( nodeName === "input" ) {
7710 inst.append.remove();
7711 inst.trigger.remove();
7712 $target.removeClass( this.markerClassName ).
7713 off( "focus", this._showDatepicker ).
7714 off( "keydown", this._doKeyDown ).
7715 off( "keypress", this._doKeyPress ).
7716 off( "keyup", this._doKeyUp );
7717 } else if ( nodeName === "div" || nodeName === "span" ) {
7718 $target.removeClass( this.markerClassName ).empty();
7719 }
7720
7721 if ( datepicker_instActive === inst ) {
7722 datepicker_instActive = null;
7723 this._curInst = null;
7724 }
7725 },
7726
7727 /* Enable the date picker to a jQuery selection.
7728 * @param target element - the target input field or division or span
7729 */
7730 _enableDatepicker: function( target ) {
7731 var nodeName, inline,
7732 $target = $( target ),
7733 inst = $.data( target, "datepicker" );
7734
7735 if ( !$target.hasClass( this.markerClassName ) ) {
7736 return;
7737 }
7738
7739 nodeName = target.nodeName.toLowerCase();
7740 if ( nodeName === "input" ) {
7741 target.disabled = false;
7742 inst.trigger.filter( "button" ).
7743 each( function() {
7744 this.disabled = false;
7745 } ).end().
7746 filter( "img" ).css( { opacity: "1.0", cursor: "" } );
7747 } else if ( nodeName === "div" || nodeName === "span" ) {
7748 inline = $target.children( "." + this._inlineClass );
7749 inline.children().removeClass( "ui-state-disabled" );
7750 inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
7751 prop( "disabled", false );
7752 }
7753 this._disabledInputs = $.map( this._disabledInputs,
7754
7755 // Delete entry
7756 function( value ) {
7757 return ( value === target ? null : value );
7758 } );
7759 },
7760
7761 /* Disable the date picker to a jQuery selection.
7762 * @param target element - the target input field or division or span
7763 */
7764 _disableDatepicker: function( target ) {
7765 var nodeName, inline,
7766 $target = $( target ),
7767 inst = $.data( target, "datepicker" );
7768
7769 if ( !$target.hasClass( this.markerClassName ) ) {
7770 return;
7771 }
7772
7773 nodeName = target.nodeName.toLowerCase();
7774 if ( nodeName === "input" ) {
7775 target.disabled = true;
7776 inst.trigger.filter( "button" ).
7777 each( function() {
7778 this.disabled = true;
7779 } ).end().
7780 filter( "img" ).css( { opacity: "0.5", cursor: "default" } );
7781 } else if ( nodeName === "div" || nodeName === "span" ) {
7782 inline = $target.children( "." + this._inlineClass );
7783 inline.children().addClass( "ui-state-disabled" );
7784 inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
7785 prop( "disabled", true );
7786 }
7787 this._disabledInputs = $.map( this._disabledInputs,
7788
7789 // Delete entry
7790 function( value ) {
7791 return ( value === target ? null : value );
7792 } );
7793 this._disabledInputs[ this._disabledInputs.length ] = target;
7794 },
7795
7796 /* Is the first field in a jQuery collection disabled as a datepicker?
7797 * @param target element - the target input field or division or span
7798 * @return boolean - true if disabled, false if enabled
7799 */
7800 _isDisabledDatepicker: function( target ) {
7801 if ( !target ) {
7802 return false;
7803 }
7804 for ( var i = 0; i < this._disabledInputs.length; i++ ) {
7805 if ( this._disabledInputs[ i ] === target ) {
7806 return true;
7807 }
7808 }
7809 return false;
7810 },
7811
7812 /* Retrieve the instance data for the target control.
7813 * @param target element - the target input field or division or span
7814 * @return object - the associated instance data
7815 * @throws error if a jQuery problem getting data
7816 */
7817 _getInst: function( target ) {
7818 try {
7819 return $.data( target, "datepicker" );
7820 } catch ( err ) {
7821 throw "Missing instance data for this datepicker";
7822 }
7823 },
7824
7825 /* Update or retrieve the settings for a date picker attached to an input field or division.
7826 * @param target element - the target input field or division or span
7827 * @param name object - the new settings to update or
7828 * string - the name of the setting to change or retrieve,
7829 * when retrieving also "all" for all instance settings or
7830 * "defaults" for all global defaults
7831 * @param value any - the new value for the setting
7832 * (omit if above is an object or to retrieve a value)
7833 */
7834 _optionDatepicker: function( target, name, value ) {
7835 var settings, date, minDate, maxDate,
7836 inst = this._getInst( target );
7837
7838 if ( arguments.length === 2 && typeof name === "string" ) {
7839 return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) :
7840 ( inst ? ( name === "all" ? $.extend( {}, inst.settings ) :
7841 this._get( inst, name ) ) : null ) );
7842 }
7843
7844 settings = name || {};
7845 if ( typeof name === "string" ) {
7846 settings = {};
7847 settings[ name ] = value;
7848 }
7849
7850 if ( inst ) {
7851 if ( this._curInst === inst ) {
7852 this._hideDatepicker();
7853 }
7854
7855 date = this._getDateDatepicker( target, true );
7856 minDate = this._getMinMaxDate( inst, "min" );
7857 maxDate = this._getMinMaxDate( inst, "max" );
7858 datepicker_extendRemove( inst.settings, settings );
7859
7860 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
7861 if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) {
7862 inst.settings.minDate = this._formatDate( inst, minDate );
7863 }
7864 if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) {
7865 inst.settings.maxDate = this._formatDate( inst, maxDate );
7866 }
7867 if ( "disabled" in settings ) {
7868 if ( settings.disabled ) {
7869 this._disableDatepicker( target );
7870 } else {
7871 this._enableDatepicker( target );
7872 }
7873 }
7874 this._attachments( $( target ), inst );
7875 this._autoSize( inst );
7876 this._setDate( inst, date );
7877 this._updateAlternate( inst );
7878 this._updateDatepicker( inst );
7879 }
7880 },
7881
7882 // Change method deprecated
7883 _changeDatepicker: function( target, name, value ) {
7884 this._optionDatepicker( target, name, value );
7885 },
7886
7887 /* Redraw the date picker attached to an input field or division.
7888 * @param target element - the target input field or division or span
7889 */
7890 _refreshDatepicker: function( target ) {
7891 var inst = this._getInst( target );
7892 if ( inst ) {
7893 this._updateDatepicker( inst );
7894 }
7895 },
7896
7897 /* Set the dates for a jQuery selection.
7898 * @param target element - the target input field or division or span
7899 * @param date Date - the new date
7900 */
7901 _setDateDatepicker: function( target, date ) {
7902 var inst = this._getInst( target );
7903 if ( inst ) {
7904 this._setDate( inst, date );
7905 this._updateDatepicker( inst );
7906 this._updateAlternate( inst );
7907 }
7908 },
7909
7910 /* Get the date(s) for the first entry in a jQuery selection.
7911 * @param target element - the target input field or division or span
7912 * @param noDefault boolean - true if no default date is to be used
7913 * @return Date - the current date
7914 */
7915 _getDateDatepicker: function( target, noDefault ) {
7916 var inst = this._getInst( target );
7917 if ( inst && !inst.inline ) {
7918 this._setDateFromField( inst, noDefault );
7919 }
7920 return ( inst ? this._getDate( inst ) : null );
7921 },
7922
7923 /* Handle keystrokes. */
7924 _doKeyDown: function( event ) {
7925 var onSelect, dateStr, sel,
7926 inst = $.datepicker._getInst( event.target ),
7927 handled = true,
7928 isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" );
7929
7930 inst._keyEvent = true;
7931 if ( $.datepicker._datepickerShowing ) {
7932 switch ( event.keyCode ) {
7933 case 9: $.datepicker._hideDatepicker();
7934 handled = false;
7935 break; // hide on tab out
7936 case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." +
7937 $.datepicker._currentClass + ")", inst.dpDiv );
7938 if ( sel[ 0 ] ) {
7939 $.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] );
7940 }
7941
7942 onSelect = $.datepicker._get( inst, "onSelect" );
7943 if ( onSelect ) {
7944 dateStr = $.datepicker._formatDate( inst );
7945
7946 // Trigger custom callback
7947 onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );
7948 } else {
7949 $.datepicker._hideDatepicker();
7950 }
7951
7952 return false; // don't submit the form
7953 case 27: $.datepicker._hideDatepicker();
7954 break; // hide on escape
7955 case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7956 -$.datepicker._get( inst, "stepBigMonths" ) :
7957 -$.datepicker._get( inst, "stepMonths" ) ), "M" );
7958 break; // previous month/year on page up/+ ctrl
7959 case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7960 +$.datepicker._get( inst, "stepBigMonths" ) :
7961 +$.datepicker._get( inst, "stepMonths" ) ), "M" );
7962 break; // next month/year on page down/+ ctrl
7963 case 35: if ( event.ctrlKey || event.metaKey ) {
7964 $.datepicker._clearDate( event.target );
7965 }
7966 handled = event.ctrlKey || event.metaKey;
7967 break; // clear on ctrl or command +end
7968 case 36: if ( event.ctrlKey || event.metaKey ) {
7969 $.datepicker._gotoToday( event.target );
7970 }
7971 handled = event.ctrlKey || event.metaKey;
7972 break; // current on ctrl or command +home
7973 case 37: if ( event.ctrlKey || event.metaKey ) {
7974 $.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" );
7975 }
7976 handled = event.ctrlKey || event.metaKey;
7977
7978 // -1 day on ctrl or command +left
7979 if ( event.originalEvent.altKey ) {
7980 $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7981 -$.datepicker._get( inst, "stepBigMonths" ) :
7982 -$.datepicker._get( inst, "stepMonths" ) ), "M" );
7983 }
7984
7985 // next month/year on alt +left on Mac
7986 break;
7987 case 38: if ( event.ctrlKey || event.metaKey ) {
7988 $.datepicker._adjustDate( event.target, -7, "D" );
7989 }
7990 handled = event.ctrlKey || event.metaKey;
7991 break; // -1 week on ctrl or command +up
7992 case 39: if ( event.ctrlKey || event.metaKey ) {
7993 $.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" );
7994 }
7995 handled = event.ctrlKey || event.metaKey;
7996
7997 // +1 day on ctrl or command +right
7998 if ( event.originalEvent.altKey ) {
7999 $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
8000 +$.datepicker._get( inst, "stepBigMonths" ) :
8001 +$.datepicker._get( inst, "stepMonths" ) ), "M" );
8002 }
8003
8004 // next month/year on alt +right
8005 break;
8006 case 40: if ( event.ctrlKey || event.metaKey ) {
8007 $.datepicker._adjustDate( event.target, +7, "D" );
8008 }
8009 handled = event.ctrlKey || event.metaKey;
8010 break; // +1 week on ctrl or command +down
8011 default: handled = false;
8012 }
8013 } else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home
8014 $.datepicker._showDatepicker( this );
8015 } else {
8016 handled = false;
8017 }
8018
8019 if ( handled ) {
8020 event.preventDefault();
8021 event.stopPropagation();
8022 }
8023 },
8024
8025 /* Filter entered characters - based on date format. */
8026 _doKeyPress: function( event ) {
8027 var chars, chr,
8028 inst = $.datepicker._getInst( event.target );
8029
8030 if ( $.datepicker._get( inst, "constrainInput" ) ) {
8031 chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) );
8032 chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode );
8033 return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 );
8034 }
8035 },
8036
8037 /* Synchronise manual entry and field/alternate field. */
8038 _doKeyUp: function( event ) {
8039 var date,
8040 inst = $.datepicker._getInst( event.target );
8041
8042 if ( inst.input.val() !== inst.lastVal ) {
8043 try {
8044 date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
8045 ( inst.input ? inst.input.val() : null ),
8046 $.datepicker._getFormatConfig( inst ) );
8047
8048 if ( date ) { // only if valid
8049 $.datepicker._setDateFromField( inst );
8050 $.datepicker._updateAlternate( inst );
8051 $.datepicker._updateDatepicker( inst );
8052 }
8053 } catch ( err ) {
8054 }
8055 }
8056 return true;
8057 },
8058
8059 /* Pop-up the date picker for a given input field.
8060 * If false returned from beforeShow event handler do not show.
8061 * @param input element - the input field attached to the date picker or
8062 * event - if triggered by focus
8063 */
8064 _showDatepicker: function( input ) {
8065 input = input.target || input;
8066 if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger
8067 input = $( "input", input.parentNode )[ 0 ];
8068 }
8069
8070 if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here
8071 return;
8072 }
8073
8074 var inst, beforeShow, beforeShowSettings, isFixed,
8075 offset, showAnim, duration;
8076
8077 inst = $.datepicker._getInst( input );
8078 if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) {
8079 $.datepicker._curInst.dpDiv.stop( true, true );
8080 if ( inst && $.datepicker._datepickerShowing ) {
8081 $.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] );
8082 }
8083 }
8084
8085 beforeShow = $.datepicker._get( inst, "beforeShow" );
8086 beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {};
8087 if ( beforeShowSettings === false ) {
8088 return;
8089 }
8090 datepicker_extendRemove( inst.settings, beforeShowSettings );
8091
8092 inst.lastVal = null;
8093 $.datepicker._lastInput = input;
8094 $.datepicker._setDateFromField( inst );
8095
8096 if ( $.datepicker._inDialog ) { // hide cursor
8097 input.value = "";
8098 }
8099 if ( !$.datepicker._pos ) { // position below input
8100 $.datepicker._pos = $.datepicker._findPos( input );
8101 $.datepicker._pos[ 1 ] += input.offsetHeight; // add the height
8102 }
8103
8104 isFixed = false;
8105 $( input ).parents().each( function() {
8106 isFixed |= $( this ).css( "position" ) === "fixed";
8107 return !isFixed;
8108 } );
8109
8110 offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] };
8111 $.datepicker._pos = null;
8112
8113 //to avoid flashes on Firefox
8114 inst.dpDiv.empty();
8115
8116 // determine sizing offscreen
8117 inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } );
8118 $.datepicker._updateDatepicker( inst );
8119
8120 // fix width for dynamic number of date pickers
8121 // and adjust position before showing
8122 offset = $.datepicker._checkOffset( inst, offset, isFixed );
8123 inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ?
8124 "static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none",
8125 left: offset.left + "px", top: offset.top + "px" } );
8126
8127 if ( !inst.inline ) {
8128 showAnim = $.datepicker._get( inst, "showAnim" );
8129 duration = $.datepicker._get( inst, "duration" );
8130 inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
8131 $.datepicker._datepickerShowing = true;
8132
8133 if ( $.effects && $.effects.effect[ showAnim ] ) {
8134 inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration );
8135 } else {
8136 inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null );
8137 }
8138
8139 if ( $.datepicker._shouldFocusInput( inst ) ) {
8140 inst.input.trigger( "focus" );
8141 }
8142
8143 $.datepicker._curInst = inst;
8144 }
8145 },
8146
8147 /* Generate the date picker content. */
8148 _updateDatepicker: function( inst ) {
8149 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
8150 datepicker_instActive = inst; // for delegate hover events
8151 inst.dpDiv.empty().append( this._generateHTML( inst ) );
8152 this._attachHandlers( inst );
8153
8154 var origyearshtml,
8155 numMonths = this._getNumberOfMonths( inst ),
8156 cols = numMonths[ 1 ],
8157 width = 17,
8158 activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ),
8159 onUpdateDatepicker = $.datepicker._get( inst, "onUpdateDatepicker" );
8160
8161 if ( activeCell.length > 0 ) {
8162 datepicker_handleMouseover.apply( activeCell.get( 0 ) );
8163 }
8164
8165 inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" );
8166 if ( cols > 1 ) {
8167 inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" );
8168 }
8169 inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) +
8170 "Class" ]( "ui-datepicker-multi" );
8171 inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) +
8172 "Class" ]( "ui-datepicker-rtl" );
8173
8174 if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
8175 inst.input.trigger( "focus" );
8176 }
8177
8178 // Deffered render of the years select (to avoid flashes on Firefox)
8179 if ( inst.yearshtml ) {
8180 origyearshtml = inst.yearshtml;
8181 setTimeout( function() {
8182
8183 //assure that inst.yearshtml didn't change.
8184 if ( origyearshtml === inst.yearshtml && inst.yearshtml ) {
8185 inst.dpDiv.find( "select.ui-datepicker-year" ).first().replaceWith( inst.yearshtml );
8186 }
8187 origyearshtml = inst.yearshtml = null;
8188 }, 0 );
8189 }
8190
8191 if ( onUpdateDatepicker ) {
8192 onUpdateDatepicker.apply( ( inst.input ? inst.input[ 0 ] : null ), [ inst ] );
8193 }
8194 },
8195
8196 // #6694 - don't focus the input if it's already focused
8197 // this breaks the change event in IE
8198 // Support: IE and jQuery <1.9
8199 _shouldFocusInput: function( inst ) {
8200 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
8201 },
8202
8203 /* Check positioning to remain on screen. */
8204 _checkOffset: function( inst, offset, isFixed ) {
8205 var dpWidth = inst.dpDiv.outerWidth(),
8206 dpHeight = inst.dpDiv.outerHeight(),
8207 inputWidth = inst.input ? inst.input.outerWidth() : 0,
8208 inputHeight = inst.input ? inst.input.outerHeight() : 0,
8209 viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ),
8210 viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() );
8211
8212 offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 );
8213 offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0;
8214 offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0;
8215
8216 // Now check if datepicker is showing outside window viewport - move to a better place if so.
8217 offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ?
8218 Math.abs( offset.left + dpWidth - viewWidth ) : 0 );
8219 offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ?
8220 Math.abs( dpHeight + inputHeight ) : 0 );
8221
8222 return offset;
8223 },
8224
8225 /* Find an object's position on the screen. */
8226 _findPos: function( obj ) {
8227 var position,
8228 inst = this._getInst( obj ),
8229 isRTL = this._get( inst, "isRTL" );
8230
8231 while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.pseudos.hidden( obj ) ) ) {
8232 obj = obj[ isRTL ? "previousSibling" : "nextSibling" ];
8233 }
8234
8235 position = $( obj ).offset();
8236 return [ position.left, position.top ];
8237 },
8238
8239 /* Hide the date picker from view.
8240 * @param input element - the input field attached to the date picker
8241 */
8242 _hideDatepicker: function( input ) {
8243 var showAnim, duration, postProcess, onClose,
8244 inst = this._curInst;
8245
8246 if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) {
8247 return;
8248 }
8249
8250 if ( this._datepickerShowing ) {
8251 showAnim = this._get( inst, "showAnim" );
8252 duration = this._get( inst, "duration" );
8253 postProcess = function() {
8254 $.datepicker._tidyDialog( inst );
8255 };
8256
8257 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
8258 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
8259 inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess );
8260 } else {
8261 inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" :
8262 ( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess );
8263 }
8264
8265 if ( !showAnim ) {
8266 postProcess();
8267 }
8268 this._datepickerShowing = false;
8269
8270 onClose = this._get( inst, "onClose" );
8271 if ( onClose ) {
8272 onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] );
8273 }
8274
8275 this._lastInput = null;
8276 if ( this._inDialog ) {
8277 this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } );
8278 if ( $.blockUI ) {
8279 $.unblockUI();
8280 $( "body" ).append( this.dpDiv );
8281 }
8282 }
8283 this._inDialog = false;
8284 }
8285 },
8286
8287 /* Tidy up after a dialog display. */
8288 _tidyDialog: function( inst ) {
8289 inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" );
8290 },
8291
8292 /* Close date picker if clicked elsewhere. */
8293 _checkExternalClick: function( event ) {
8294 if ( !$.datepicker._curInst ) {
8295 return;
8296 }
8297
8298 var $target = $( event.target ),
8299 inst = $.datepicker._getInst( $target[ 0 ] );
8300
8301 if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId &&
8302 $target.parents( "#" + $.datepicker._mainDivId ).length === 0 &&
8303 !$target.hasClass( $.datepicker.markerClassName ) &&
8304 !$target.closest( "." + $.datepicker._triggerClass ).length &&
8305 $.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) ||
8306 ( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) {
8307 $.datepicker._hideDatepicker();
8308 }
8309 },
8310
8311 /* Adjust one of the date sub-fields. */
8312 _adjustDate: function( id, offset, period ) {
8313 var target = $( id ),
8314 inst = this._getInst( target[ 0 ] );
8315
8316 if ( this._isDisabledDatepicker( target[ 0 ] ) ) {
8317 return;
8318 }
8319 this._adjustInstDate( inst, offset, period );
8320 this._updateDatepicker( inst );
8321 },
8322
8323 /* Action for current link. */
8324 _gotoToday: function( id ) {
8325 var date,
8326 target = $( id ),
8327 inst = this._getInst( target[ 0 ] );
8328
8329 if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) {
8330 inst.selectedDay = inst.currentDay;
8331 inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8332 inst.drawYear = inst.selectedYear = inst.currentYear;
8333 } else {
8334 date = new Date();
8335 inst.selectedDay = date.getDate();
8336 inst.drawMonth = inst.selectedMonth = date.getMonth();
8337 inst.drawYear = inst.selectedYear = date.getFullYear();
8338 }
8339 this._notifyChange( inst );
8340 this._adjustDate( target );
8341 },
8342
8343 /* Action for selecting a new month/year. */
8344 _selectMonthYear: function( id, select, period ) {
8345 var target = $( id ),
8346 inst = this._getInst( target[ 0 ] );
8347
8348 inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] =
8349 inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] =
8350 parseInt( select.options[ select.selectedIndex ].value, 10 );
8351
8352 this._notifyChange( inst );
8353 this._adjustDate( target );
8354 },
8355
8356 /* Action for selecting a day. */
8357 _selectDay: function( id, month, year, td ) {
8358 var inst,
8359 target = $( id );
8360
8361 if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) {
8362 return;
8363 }
8364
8365 inst = this._getInst( target[ 0 ] );
8366 inst.selectedDay = inst.currentDay = parseInt( $( "a", td ).attr( "data-date" ) );
8367 inst.selectedMonth = inst.currentMonth = month;
8368 inst.selectedYear = inst.currentYear = year;
8369 this._selectDate( id, this._formatDate( inst,
8370 inst.currentDay, inst.currentMonth, inst.currentYear ) );
8371 },
8372
8373 /* Erase the input field and hide the date picker. */
8374 _clearDate: function( id ) {
8375 var target = $( id );
8376 this._selectDate( target, "" );
8377 },
8378
8379 /* Update the input field with the selected date. */
8380 _selectDate: function( id, dateStr ) {
8381 var onSelect,
8382 target = $( id ),
8383 inst = this._getInst( target[ 0 ] );
8384
8385 dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) );
8386 if ( inst.input ) {
8387 inst.input.val( dateStr );
8388 }
8389 this._updateAlternate( inst );
8390
8391 onSelect = this._get( inst, "onSelect" );
8392 if ( onSelect ) {
8393 onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); // trigger custom callback
8394 } else if ( inst.input ) {
8395 inst.input.trigger( "change" ); // fire the change event
8396 }
8397
8398 if ( inst.inline ) {
8399 this._updateDatepicker( inst );
8400 } else {
8401 this._hideDatepicker();
8402 this._lastInput = inst.input[ 0 ];
8403 if ( typeof( inst.input[ 0 ] ) !== "object" ) {
8404 inst.input.trigger( "focus" ); // restore focus
8405 }
8406 this._lastInput = null;
8407 }
8408 },
8409
8410 /* Update any alternate field to synchronise with the main field. */
8411 _updateAlternate: function( inst ) {
8412 var altFormat, date, dateStr,
8413 altField = this._get( inst, "altField" );
8414
8415 if ( altField ) { // update alternate field too
8416 altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" );
8417 date = this._getDate( inst );
8418 dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) );
8419 $( document ).find( altField ).val( dateStr );
8420 }
8421 },
8422
8423 /* Set as beforeShowDay function to prevent selection of weekends.
8424 * @param date Date - the date to customise
8425 * @return [boolean, string] - is this date selectable?, what is its CSS class?
8426 */
8427 noWeekends: function( date ) {
8428 var day = date.getDay();
8429 return [ ( day > 0 && day < 6 ), "" ];
8430 },
8431
8432 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
8433 * @param date Date - the date to get the week for
8434 * @return number - the number of the week within the year that contains this date
8435 */
8436 iso8601Week: function( date ) {
8437 var time,
8438 checkDate = new Date( date.getTime() );
8439
8440 // Find Thursday of this week starting on Monday
8441 checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) );
8442
8443 time = checkDate.getTime();
8444 checkDate.setMonth( 0 ); // Compare with Jan 1
8445 checkDate.setDate( 1 );
8446 return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1;
8447 },
8448
8449 /* Parse a string value into a date object.
8450 * See formatDate below for the possible formats.
8451 *
8452 * @param format string - the expected format of the date
8453 * @param value string - the date in the above format
8454 * @param settings Object - attributes include:
8455 * shortYearCutoff number - the cutoff year for determining the century (optional)
8456 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
8457 * dayNames string[7] - names of the days from Sunday (optional)
8458 * monthNamesShort string[12] - abbreviated names of the months (optional)
8459 * monthNames string[12] - names of the months (optional)
8460 * @return Date - the extracted date value or null if value is blank
8461 */
8462 parseDate: function( format, value, settings ) {
8463 if ( format == null || value == null ) {
8464 throw "Invalid arguments";
8465 }
8466
8467 value = ( typeof value === "object" ? value.toString() : value + "" );
8468 if ( value === "" ) {
8469 return null;
8470 }
8471
8472 var iFormat, dim, extra,
8473 iValue = 0,
8474 shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff,
8475 shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
8476 new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ),
8477 dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
8478 dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
8479 monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
8480 monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
8481 year = -1,
8482 month = -1,
8483 day = -1,
8484 doy = -1,
8485 literal = false,
8486 date,
8487
8488 // Check whether a format character is doubled
8489 lookAhead = function( match ) {
8490 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8491 if ( matches ) {
8492 iFormat++;
8493 }
8494 return matches;
8495 },
8496
8497 // Extract a number from the string value
8498 getNumber = function( match ) {
8499 var isDoubled = lookAhead( match ),
8500 size = ( match === "@" ? 14 : ( match === "!" ? 20 :
8501 ( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ),
8502 minSize = ( match === "y" ? size : 1 ),
8503 digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ),
8504 num = value.substring( iValue ).match( digits );
8505 if ( !num ) {
8506 throw "Missing number at position " + iValue;
8507 }
8508 iValue += num[ 0 ].length;
8509 return parseInt( num[ 0 ], 10 );
8510 },
8511
8512 // Extract a name from the string value and convert to an index
8513 getName = function( match, shortNames, longNames ) {
8514 var index = -1,
8515 names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) {
8516 return [ [ k, v ] ];
8517 } ).sort( function( a, b ) {
8518 return -( a[ 1 ].length - b[ 1 ].length );
8519 } );
8520
8521 $.each( names, function( i, pair ) {
8522 var name = pair[ 1 ];
8523 if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) {
8524 index = pair[ 0 ];
8525 iValue += name.length;
8526 return false;
8527 }
8528 } );
8529 if ( index !== -1 ) {
8530 return index + 1;
8531 } else {
8532 throw "Unknown name at position " + iValue;
8533 }
8534 },
8535
8536 // Confirm that a literal character matches the string value
8537 checkLiteral = function() {
8538 if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) {
8539 throw "Unexpected literal at position " + iValue;
8540 }
8541 iValue++;
8542 };
8543
8544 for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8545 if ( literal ) {
8546 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8547 literal = false;
8548 } else {
8549 checkLiteral();
8550 }
8551 } else {
8552 switch ( format.charAt( iFormat ) ) {
8553 case "d":
8554 day = getNumber( "d" );
8555 break;
8556 case "D":
8557 getName( "D", dayNamesShort, dayNames );
8558 break;
8559 case "o":
8560 doy = getNumber( "o" );
8561 break;
8562 case "m":
8563 month = getNumber( "m" );
8564 break;
8565 case "M":
8566 month = getName( "M", monthNamesShort, monthNames );
8567 break;
8568 case "y":
8569 year = getNumber( "y" );
8570 break;
8571 case "@":
8572 date = new Date( getNumber( "@" ) );
8573 year = date.getFullYear();
8574 month = date.getMonth() + 1;
8575 day = date.getDate();
8576 break;
8577 case "!":
8578 date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 );
8579 year = date.getFullYear();
8580 month = date.getMonth() + 1;
8581 day = date.getDate();
8582 break;
8583 case "'":
8584 if ( lookAhead( "'" ) ) {
8585 checkLiteral();
8586 } else {
8587 literal = true;
8588 }
8589 break;
8590 default:
8591 checkLiteral();
8592 }
8593 }
8594 }
8595
8596 if ( iValue < value.length ) {
8597 extra = value.substr( iValue );
8598 if ( !/^\s+/.test( extra ) ) {
8599 throw "Extra/unparsed characters found in date: " + extra;
8600 }
8601 }
8602
8603 if ( year === -1 ) {
8604 year = new Date().getFullYear();
8605 } else if ( year < 100 ) {
8606 year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8607 ( year <= shortYearCutoff ? 0 : -100 );
8608 }
8609
8610 if ( doy > -1 ) {
8611 month = 1;
8612 day = doy;
8613 do {
8614 dim = this._getDaysInMonth( year, month - 1 );
8615 if ( day <= dim ) {
8616 break;
8617 }
8618 month++;
8619 day -= dim;
8620 } while ( true );
8621 }
8622
8623 date = this._daylightSavingAdjust( new Date( year, month - 1, day ) );
8624 if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) {
8625 throw "Invalid date"; // E.g. 31/02/00
8626 }
8627 return date;
8628 },
8629
8630 /* Standard date formats. */
8631 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
8632 COOKIE: "D, dd M yy",
8633 ISO_8601: "yy-mm-dd",
8634 RFC_822: "D, d M y",
8635 RFC_850: "DD, dd-M-y",
8636 RFC_1036: "D, d M y",
8637 RFC_1123: "D, d M yy",
8638 RFC_2822: "D, d M yy",
8639 RSS: "D, d M y", // RFC 822
8640 TICKS: "!",
8641 TIMESTAMP: "@",
8642 W3C: "yy-mm-dd", // ISO 8601
8643
8644 _ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) +
8645 Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ),
8646
8647 /* Format a date object into a string value.
8648 * The format can be combinations of the following:
8649 * d - day of month (no leading zero)
8650 * dd - day of month (two digit)
8651 * o - day of year (no leading zeros)
8652 * oo - day of year (three digit)
8653 * D - day name short
8654 * DD - day name long
8655 * m - month of year (no leading zero)
8656 * mm - month of year (two digit)
8657 * M - month name short
8658 * MM - month name long
8659 * y - year (two digit)
8660 * yy - year (four digit)
8661 * @ - Unix timestamp (ms since 01/01/1970)
8662 * ! - Windows ticks (100ns since 01/01/0001)
8663 * "..." - literal text
8664 * '' - single quote
8665 *
8666 * @param format string - the desired format of the date
8667 * @param date Date - the date value to format
8668 * @param settings Object - attributes include:
8669 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
8670 * dayNames string[7] - names of the days from Sunday (optional)
8671 * monthNamesShort string[12] - abbreviated names of the months (optional)
8672 * monthNames string[12] - names of the months (optional)
8673 * @return string - the date in the above format
8674 */
8675 formatDate: function( format, date, settings ) {
8676 if ( !date ) {
8677 return "";
8678 }
8679
8680 var iFormat,
8681 dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
8682 dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
8683 monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
8684 monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
8685
8686 // Check whether a format character is doubled
8687 lookAhead = function( match ) {
8688 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8689 if ( matches ) {
8690 iFormat++;
8691 }
8692 return matches;
8693 },
8694
8695 // Format a number, with leading zero if necessary
8696 formatNumber = function( match, value, len ) {
8697 var num = "" + value;
8698 if ( lookAhead( match ) ) {
8699 while ( num.length < len ) {
8700 num = "0" + num;
8701 }
8702 }
8703 return num;
8704 },
8705
8706 // Format a name, short or long as requested
8707 formatName = function( match, value, shortNames, longNames ) {
8708 return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] );
8709 },
8710 output = "",
8711 literal = false;
8712
8713 if ( date ) {
8714 for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8715 if ( literal ) {
8716 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8717 literal = false;
8718 } else {
8719 output += format.charAt( iFormat );
8720 }
8721 } else {
8722 switch ( format.charAt( iFormat ) ) {
8723 case "d":
8724 output += formatNumber( "d", date.getDate(), 2 );
8725 break;
8726 case "D":
8727 output += formatName( "D", date.getDay(), dayNamesShort, dayNames );
8728 break;
8729 case "o":
8730 output += formatNumber( "o",
8731 Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 );
8732 break;
8733 case "m":
8734 output += formatNumber( "m", date.getMonth() + 1, 2 );
8735 break;
8736 case "M":
8737 output += formatName( "M", date.getMonth(), monthNamesShort, monthNames );
8738 break;
8739 case "y":
8740 output += ( lookAhead( "y" ) ? date.getFullYear() :
8741 ( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 );
8742 break;
8743 case "@":
8744 output += date.getTime();
8745 break;
8746 case "!":
8747 output += date.getTime() * 10000 + this._ticksTo1970;
8748 break;
8749 case "'":
8750 if ( lookAhead( "'" ) ) {
8751 output += "'";
8752 } else {
8753 literal = true;
8754 }
8755 break;
8756 default:
8757 output += format.charAt( iFormat );
8758 }
8759 }
8760 }
8761 }
8762 return output;
8763 },
8764
8765 /* Extract all possible characters from the date format. */
8766 _possibleChars: function( format ) {
8767 var iFormat,
8768 chars = "",
8769 literal = false,
8770
8771 // Check whether a format character is doubled
8772 lookAhead = function( match ) {
8773 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8774 if ( matches ) {
8775 iFormat++;
8776 }
8777 return matches;
8778 };
8779
8780 for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8781 if ( literal ) {
8782 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8783 literal = false;
8784 } else {
8785 chars += format.charAt( iFormat );
8786 }
8787 } else {
8788 switch ( format.charAt( iFormat ) ) {
8789 case "d": case "m": case "y": case "@":
8790 chars += "0123456789";
8791 break;
8792 case "D": case "M":
8793 return null; // Accept anything
8794 case "'":
8795 if ( lookAhead( "'" ) ) {
8796 chars += "'";
8797 } else {
8798 literal = true;
8799 }
8800 break;
8801 default:
8802 chars += format.charAt( iFormat );
8803 }
8804 }
8805 }
8806 return chars;
8807 },
8808
8809 /* Get a setting value, defaulting if necessary. */
8810 _get: function( inst, name ) {
8811 return inst.settings[ name ] !== undefined ?
8812 inst.settings[ name ] : this._defaults[ name ];
8813 },
8814
8815 /* Parse existing date and initialise date picker. */
8816 _setDateFromField: function( inst, noDefault ) {
8817 if ( inst.input.val() === inst.lastVal ) {
8818 return;
8819 }
8820
8821 var dateFormat = this._get( inst, "dateFormat" ),
8822 dates = inst.lastVal = inst.input ? inst.input.val() : null,
8823 defaultDate = this._getDefaultDate( inst ),
8824 date = defaultDate,
8825 settings = this._getFormatConfig( inst );
8826
8827 try {
8828 date = this.parseDate( dateFormat, dates, settings ) || defaultDate;
8829 } catch ( event ) {
8830 dates = ( noDefault ? "" : dates );
8831 }
8832 inst.selectedDay = date.getDate();
8833 inst.drawMonth = inst.selectedMonth = date.getMonth();
8834 inst.drawYear = inst.selectedYear = date.getFullYear();
8835 inst.currentDay = ( dates ? date.getDate() : 0 );
8836 inst.currentMonth = ( dates ? date.getMonth() : 0 );
8837 inst.currentYear = ( dates ? date.getFullYear() : 0 );
8838 this._adjustInstDate( inst );
8839 },
8840
8841 /* Retrieve the default date shown on opening. */
8842 _getDefaultDate: function( inst ) {
8843 return this._restrictMinMax( inst,
8844 this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) );
8845 },
8846
8847 /* A date may be specified as an exact value or a relative one. */
8848 _determineDate: function( inst, date, defaultDate ) {
8849 var offsetNumeric = function( offset ) {
8850 var date = new Date();
8851 date.setDate( date.getDate() + offset );
8852 return date;
8853 },
8854 offsetString = function( offset ) {
8855 try {
8856 return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
8857 offset, $.datepicker._getFormatConfig( inst ) );
8858 } catch ( e ) {
8859
8860 // Ignore
8861 }
8862
8863 var date = ( offset.toLowerCase().match( /^c/ ) ?
8864 $.datepicker._getDate( inst ) : null ) || new Date(),
8865 year = date.getFullYear(),
8866 month = date.getMonth(),
8867 day = date.getDate(),
8868 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
8869 matches = pattern.exec( offset );
8870
8871 while ( matches ) {
8872 switch ( matches[ 2 ] || "d" ) {
8873 case "d" : case "D" :
8874 day += parseInt( matches[ 1 ], 10 ); break;
8875 case "w" : case "W" :
8876 day += parseInt( matches[ 1 ], 10 ) * 7; break;
8877 case "m" : case "M" :
8878 month += parseInt( matches[ 1 ], 10 );
8879 day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
8880 break;
8881 case "y": case "Y" :
8882 year += parseInt( matches[ 1 ], 10 );
8883 day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
8884 break;
8885 }
8886 matches = pattern.exec( offset );
8887 }
8888 return new Date( year, month, day );
8889 },
8890 newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) :
8891 ( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) );
8892
8893 newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate );
8894 if ( newDate ) {
8895 newDate.setHours( 0 );
8896 newDate.setMinutes( 0 );
8897 newDate.setSeconds( 0 );
8898 newDate.setMilliseconds( 0 );
8899 }
8900 return this._daylightSavingAdjust( newDate );
8901 },
8902
8903 /* Handle switch to/from daylight saving.
8904 * Hours may be non-zero on daylight saving cut-over:
8905 * > 12 when midnight changeover, but then cannot generate
8906 * midnight datetime, so jump to 1AM, otherwise reset.
8907 * @param date (Date) the date to check
8908 * @return (Date) the corrected date
8909 */
8910 _daylightSavingAdjust: function( date ) {
8911 if ( !date ) {
8912 return null;
8913 }
8914 date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 );
8915 return date;
8916 },
8917
8918 /* Set the date(s) directly. */
8919 _setDate: function( inst, date, noChange ) {
8920 var clear = !date,
8921 origMonth = inst.selectedMonth,
8922 origYear = inst.selectedYear,
8923 newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) );
8924
8925 inst.selectedDay = inst.currentDay = newDate.getDate();
8926 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
8927 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
8928 if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) {
8929 this._notifyChange( inst );
8930 }
8931 this._adjustInstDate( inst );
8932 if ( inst.input ) {
8933 inst.input.val( clear ? "" : this._formatDate( inst ) );
8934 }
8935 },
8936
8937 /* Retrieve the date(s) directly. */
8938 _getDate: function( inst ) {
8939 var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null :
8940 this._daylightSavingAdjust( new Date(
8941 inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
8942 return startDate;
8943 },
8944
8945 /* Attach the onxxx handlers. These are declared statically so
8946 * they work with static code transformers like Caja.
8947 */
8948 _attachHandlers: function( inst ) {
8949 var stepMonths = this._get( inst, "stepMonths" ),
8950 id = "#" + inst.id.replace( /\\\\/g, "\\" );
8951 inst.dpDiv.find( "[data-handler]" ).map( function() {
8952 var handler = {
8953 prev: function() {
8954 $.datepicker._adjustDate( id, -stepMonths, "M" );
8955 },
8956 next: function() {
8957 $.datepicker._adjustDate( id, +stepMonths, "M" );
8958 },
8959 hide: function() {
8960 $.datepicker._hideDatepicker();
8961 },
8962 today: function() {
8963 $.datepicker._gotoToday( id );
8964 },
8965 selectDay: function() {
8966 $.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this );
8967 return false;
8968 },
8969 selectMonth: function() {
8970 $.datepicker._selectMonthYear( id, this, "M" );
8971 return false;
8972 },
8973 selectYear: function() {
8974 $.datepicker._selectMonthYear( id, this, "Y" );
8975 return false;
8976 }
8977 };
8978 $( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] );
8979 } );
8980 },
8981
8982 /* Generate the HTML for the current state of the date picker. */
8983 _generateHTML: function( inst ) {
8984 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
8985 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
8986 monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
8987 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
8988 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
8989 printDate, dRow, tbody, daySettings, otherMonth, unselectable,
8990 tempDate = new Date(),
8991 today = this._daylightSavingAdjust(
8992 new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time
8993 isRTL = this._get( inst, "isRTL" ),
8994 showButtonPanel = this._get( inst, "showButtonPanel" ),
8995 hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ),
8996 navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ),
8997 numMonths = this._getNumberOfMonths( inst ),
8998 showCurrentAtPos = this._get( inst, "showCurrentAtPos" ),
8999 stepMonths = this._get( inst, "stepMonths" ),
9000 isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ),
9001 currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) :
9002 new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ),
9003 minDate = this._getMinMaxDate( inst, "min" ),
9004 maxDate = this._getMinMaxDate( inst, "max" ),
9005 drawMonth = inst.drawMonth - showCurrentAtPos,
9006 drawYear = inst.drawYear;
9007
9008 if ( drawMonth < 0 ) {
9009 drawMonth += 12;
9010 drawYear--;
9011 }
9012 if ( maxDate ) {
9013 maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(),
9014 maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) );
9015 maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw );
9016 while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) {
9017 drawMonth--;
9018 if ( drawMonth < 0 ) {
9019 drawMonth = 11;
9020 drawYear--;
9021 }
9022 }
9023 }
9024 inst.drawMonth = drawMonth;
9025 inst.drawYear = drawYear;
9026
9027 prevText = this._get( inst, "prevText" );
9028 prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText,
9029 this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ),
9030 this._getFormatConfig( inst ) ) );
9031
9032 if ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ) {
9033 prev = $( "<a>" )
9034 .attr( {
9035 "class": "ui-datepicker-prev ui-corner-all",
9036 "data-handler": "prev",
9037 "data-event": "click",
9038 title: prevText
9039 } )
9040 .append(
9041 $( "<span>" )
9042 .addClass( "ui-icon ui-icon-circle-triangle-" +
9043 ( isRTL ? "e" : "w" ) )
9044 .text( prevText )
9045 )[ 0 ].outerHTML;
9046 } else if ( hideIfNoPrevNext ) {
9047 prev = "";
9048 } else {
9049 prev = $( "<a>" )
9050 .attr( {
9051 "class": "ui-datepicker-prev ui-corner-all ui-state-disabled",
9052 title: prevText
9053 } )
9054 .append(
9055 $( "<span>" )
9056 .addClass( "ui-icon ui-icon-circle-triangle-" +
9057 ( isRTL ? "e" : "w" ) )
9058 .text( prevText )
9059 )[ 0 ].outerHTML;
9060 }
9061
9062 nextText = this._get( inst, "nextText" );
9063 nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText,
9064 this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ),
9065 this._getFormatConfig( inst ) ) );
9066
9067 if ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ) {
9068 next = $( "<a>" )
9069 .attr( {
9070 "class": "ui-datepicker-next ui-corner-all",
9071 "data-handler": "next",
9072 "data-event": "click",
9073 title: nextText
9074 } )
9075 .append(
9076 $( "<span>" )
9077 .addClass( "ui-icon ui-icon-circle-triangle-" +
9078 ( isRTL ? "w" : "e" ) )
9079 .text( nextText )
9080 )[ 0 ].outerHTML;
9081 } else if ( hideIfNoPrevNext ) {
9082 next = "";
9083 } else {
9084 next = $( "<a>" )
9085 .attr( {
9086 "class": "ui-datepicker-next ui-corner-all ui-state-disabled",
9087 title: nextText
9088 } )
9089 .append(
9090 $( "<span>" )
9091 .attr( "class", "ui-icon ui-icon-circle-triangle-" +
9092 ( isRTL ? "w" : "e" ) )
9093 .text( nextText )
9094 )[ 0 ].outerHTML;
9095 }
9096
9097 currentText = this._get( inst, "currentText" );
9098 gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today );
9099 currentText = ( !navigationAsDateFormat ? currentText :
9100 this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) );
9101
9102 controls = "";
9103 if ( !inst.inline ) {
9104 controls = $( "<button>" )
9105 .attr( {
9106 type: "button",
9107 "class": "ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all",
9108 "data-handler": "hide",
9109 "data-event": "click"
9110 } )
9111 .text( this._get( inst, "closeText" ) )[ 0 ].outerHTML;
9112 }
9113
9114 buttonPanel = "";
9115 if ( showButtonPanel ) {
9116 buttonPanel = $( "<div class='ui-datepicker-buttonpane ui-widget-content'>" )
9117 .append( isRTL ? controls : "" )
9118 .append( this._isInRange( inst, gotoDate ) ?
9119 $( "<button>" )
9120 .attr( {
9121 type: "button",
9122 "class": "ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all",
9123 "data-handler": "today",
9124 "data-event": "click"
9125 } )
9126 .text( currentText ) :
9127 "" )
9128 .append( isRTL ? "" : controls )[ 0 ].outerHTML;
9129 }
9130
9131 firstDay = parseInt( this._get( inst, "firstDay" ), 10 );
9132 firstDay = ( isNaN( firstDay ) ? 0 : firstDay );
9133
9134 showWeek = this._get( inst, "showWeek" );
9135 dayNames = this._get( inst, "dayNames" );
9136 dayNamesMin = this._get( inst, "dayNamesMin" );
9137 monthNames = this._get( inst, "monthNames" );
9138 monthNamesShort = this._get( inst, "monthNamesShort" );
9139 beforeShowDay = this._get( inst, "beforeShowDay" );
9140 showOtherMonths = this._get( inst, "showOtherMonths" );
9141 selectOtherMonths = this._get( inst, "selectOtherMonths" );
9142 defaultDate = this._getDefaultDate( inst );
9143 html = "";
9144
9145 for ( row = 0; row < numMonths[ 0 ]; row++ ) {
9146 group = "";
9147 this.maxRows = 4;
9148 for ( col = 0; col < numMonths[ 1 ]; col++ ) {
9149 selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) );
9150 cornerClass = " ui-corner-all";
9151 calender = "";
9152 if ( isMultiMonth ) {
9153 calender += "<div class='ui-datepicker-group";
9154 if ( numMonths[ 1 ] > 1 ) {
9155 switch ( col ) {
9156 case 0: calender += " ui-datepicker-group-first";
9157 cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break;
9158 case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last";
9159 cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break;
9160 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
9161 }
9162 }
9163 calender += "'>";
9164 }
9165 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
9166 ( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) +
9167 ( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) +
9168 this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate,
9169 row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers
9170 "</div><table class='ui-datepicker-calendar'><thead>" +
9171 "<tr>";
9172 thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" );
9173 for ( dow = 0; dow < 7; dow++ ) { // days of the week
9174 day = ( dow + firstDay ) % 7;
9175 thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" +
9176 "<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>";
9177 }
9178 calender += thead + "</tr></thead><tbody>";
9179 daysInMonth = this._getDaysInMonth( drawYear, drawMonth );
9180 if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) {
9181 inst.selectedDay = Math.min( inst.selectedDay, daysInMonth );
9182 }
9183 leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7;
9184 curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate
9185 numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043)
9186 this.maxRows = numRows;
9187 printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) );
9188 for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows
9189 calender += "<tr>";
9190 tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
9191 this._get( inst, "calculateWeek" )( printDate ) + "</td>" );
9192 for ( dow = 0; dow < 7; dow++ ) { // create date picker days
9193 daySettings = ( beforeShowDay ?
9194 beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] );
9195 otherMonth = ( printDate.getMonth() !== drawMonth );
9196 unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] ||
9197 ( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate );
9198 tbody += "<td class='" +
9199 ( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends
9200 ( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months
9201 ( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key
9202 ( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ?
9203
9204 // or defaultDate is current printedDate and defaultDate is selectedDate
9205 " " + this._dayOverClass : "" ) + // highlight selected day
9206 ( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) + // highlight unselectable days
9207 ( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates
9208 ( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day
9209 ( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different)
9210 ( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "&#39;" ) + "'" : "" ) + // cell title
9211 ( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions
9212 ( otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
9213 ( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
9214 ( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) +
9215 ( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day
9216 ( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months
9217 "' href='#' aria-current='" + ( printDate.getTime() === currentDate.getTime() ? "true" : "false" ) + // mark date as selected for screen reader
9218 "' data-date='" + printDate.getDate() + // store date as data
9219 "'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date
9220 printDate.setDate( printDate.getDate() + 1 );
9221 printDate = this._daylightSavingAdjust( printDate );
9222 }
9223 calender += tbody + "</tr>";
9224 }
9225 drawMonth++;
9226 if ( drawMonth > 11 ) {
9227 drawMonth = 0;
9228 drawYear++;
9229 }
9230 calender += "</tbody></table>" + ( isMultiMonth ? "</div>" +
9231 ( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" );
9232 group += calender;
9233 }
9234 html += group;
9235 }
9236 html += buttonPanel;
9237 inst._keyEvent = false;
9238 return html;
9239 },
9240
9241 /* Generate the month and year header. */
9242 _generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate,
9243 secondary, monthNames, monthNamesShort ) {
9244
9245 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
9246 changeMonth = this._get( inst, "changeMonth" ),
9247 changeYear = this._get( inst, "changeYear" ),
9248 showMonthAfterYear = this._get( inst, "showMonthAfterYear" ),
9249 selectMonthLabel = this._get( inst, "selectMonthLabel" ),
9250 selectYearLabel = this._get( inst, "selectYearLabel" ),
9251 html = "<div class='ui-datepicker-title'>",
9252 monthHtml = "";
9253
9254 // Month selection
9255 if ( secondary || !changeMonth ) {
9256 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>";
9257 } else {
9258 inMinYear = ( minDate && minDate.getFullYear() === drawYear );
9259 inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear );
9260 monthHtml += "<select class='ui-datepicker-month' aria-label='" + selectMonthLabel + "' data-handler='selectMonth' data-event='change'>";
9261 for ( month = 0; month < 12; month++ ) {
9262 if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) {
9263 monthHtml += "<option value='" + month + "'" +
9264 ( month === drawMonth ? " selected='selected'" : "" ) +
9265 ">" + monthNamesShort[ month ] + "</option>";
9266 }
9267 }
9268 monthHtml += "</select>";
9269 }
9270
9271 if ( !showMonthAfterYear ) {
9272 html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" );
9273 }
9274
9275 // Year selection
9276 if ( !inst.yearshtml ) {
9277 inst.yearshtml = "";
9278 if ( secondary || !changeYear ) {
9279 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
9280 } else {
9281
9282 // determine range of years to display
9283 years = this._get( inst, "yearRange" ).split( ":" );
9284 thisYear = new Date().getFullYear();
9285 determineYear = function( value ) {
9286 var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) :
9287 ( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) :
9288 parseInt( value, 10 ) ) );
9289 return ( isNaN( year ) ? thisYear : year );
9290 };
9291 year = determineYear( years[ 0 ] );
9292 endYear = Math.max( year, determineYear( years[ 1 ] || "" ) );
9293 year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year );
9294 endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear );
9295 inst.yearshtml += "<select class='ui-datepicker-year' aria-label='" + selectYearLabel + "' data-handler='selectYear' data-event='change'>";
9296 for ( ; year <= endYear; year++ ) {
9297 inst.yearshtml += "<option value='" + year + "'" +
9298 ( year === drawYear ? " selected='selected'" : "" ) +
9299 ">" + year + "</option>";
9300 }
9301 inst.yearshtml += "</select>";
9302
9303 html += inst.yearshtml;
9304 inst.yearshtml = null;
9305 }
9306 }
9307
9308 html += this._get( inst, "yearSuffix" );
9309 if ( showMonthAfterYear ) {
9310 html += ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" ) + monthHtml;
9311 }
9312 html += "</div>"; // Close datepicker_header
9313 return html;
9314 },
9315
9316 /* Adjust one of the date sub-fields. */
9317 _adjustInstDate: function( inst, offset, period ) {
9318 var year = inst.selectedYear + ( period === "Y" ? offset : 0 ),
9319 month = inst.selectedMonth + ( period === "M" ? offset : 0 ),
9320 day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ),
9321 date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) );
9322
9323 inst.selectedDay = date.getDate();
9324 inst.drawMonth = inst.selectedMonth = date.getMonth();
9325 inst.drawYear = inst.selectedYear = date.getFullYear();
9326 if ( period === "M" || period === "Y" ) {
9327 this._notifyChange( inst );
9328 }
9329 },
9330
9331 /* Ensure a date is within any min/max bounds. */
9332 _restrictMinMax: function( inst, date ) {
9333 var minDate = this._getMinMaxDate( inst, "min" ),
9334 maxDate = this._getMinMaxDate( inst, "max" ),
9335 newDate = ( minDate && date < minDate ? minDate : date );
9336 return ( maxDate && newDate > maxDate ? maxDate : newDate );
9337 },
9338
9339 /* Notify change of month/year. */
9340 _notifyChange: function( inst ) {
9341 var onChange = this._get( inst, "onChangeMonthYear" );
9342 if ( onChange ) {
9343 onChange.apply( ( inst.input ? inst.input[ 0 ] : null ),
9344 [ inst.selectedYear, inst.selectedMonth + 1, inst ] );
9345 }
9346 },
9347
9348 /* Determine the number of months to show. */
9349 _getNumberOfMonths: function( inst ) {
9350 var numMonths = this._get( inst, "numberOfMonths" );
9351 return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) );
9352 },
9353
9354 /* Determine the current maximum date - ensure no time components are set. */
9355 _getMinMaxDate: function( inst, minMax ) {
9356 return this._determineDate( inst, this._get( inst, minMax + "Date" ), null );
9357 },
9358
9359 /* Find the number of days in a given month. */
9360 _getDaysInMonth: function( year, month ) {
9361 return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate();
9362 },
9363
9364 /* Find the day of the week of the first of a month. */
9365 _getFirstDayOfMonth: function( year, month ) {
9366 return new Date( year, month, 1 ).getDay();
9367 },
9368
9369 /* Determines if we should allow a "next/prev" month display change. */
9370 _canAdjustMonth: function( inst, offset, curYear, curMonth ) {
9371 var numMonths = this._getNumberOfMonths( inst ),
9372 date = this._daylightSavingAdjust( new Date( curYear,
9373 curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) );
9374
9375 if ( offset < 0 ) {
9376 date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) );
9377 }
9378 return this._isInRange( inst, date );
9379 },
9380
9381 /* Is the given date in the accepted range? */
9382 _isInRange: function( inst, date ) {
9383 var yearSplit, currentYear,
9384 minDate = this._getMinMaxDate( inst, "min" ),
9385 maxDate = this._getMinMaxDate( inst, "max" ),
9386 minYear = null,
9387 maxYear = null,
9388 years = this._get( inst, "yearRange" );
9389 if ( years ) {
9390 yearSplit = years.split( ":" );
9391 currentYear = new Date().getFullYear();
9392 minYear = parseInt( yearSplit[ 0 ], 10 );
9393 maxYear = parseInt( yearSplit[ 1 ], 10 );
9394 if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) {
9395 minYear += currentYear;
9396 }
9397 if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) {
9398 maxYear += currentYear;
9399 }
9400 }
9401
9402 return ( ( !minDate || date.getTime() >= minDate.getTime() ) &&
9403 ( !maxDate || date.getTime() <= maxDate.getTime() ) &&
9404 ( !minYear || date.getFullYear() >= minYear ) &&
9405 ( !maxYear || date.getFullYear() <= maxYear ) );
9406 },
9407
9408 /* Provide the configuration settings for formatting/parsing. */
9409 _getFormatConfig: function( inst ) {
9410 var shortYearCutoff = this._get( inst, "shortYearCutoff" );
9411 shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff :
9412 new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) );
9413 return { shortYearCutoff: shortYearCutoff,
9414 dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ),
9415 monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) };
9416 },
9417
9418 /* Format the given date for display. */
9419 _formatDate: function( inst, day, month, year ) {
9420 if ( !day ) {
9421 inst.currentDay = inst.selectedDay;
9422 inst.currentMonth = inst.selectedMonth;
9423 inst.currentYear = inst.selectedYear;
9424 }
9425 var date = ( day ? ( typeof day === "object" ? day :
9426 this._daylightSavingAdjust( new Date( year, month, day ) ) ) :
9427 this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
9428 return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) );
9429 }
9430 } );
9431
9432 /*
9433 * Bind hover events for datepicker elements.
9434 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9435 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9436 */
9437 function datepicker_bindHover( dpDiv ) {
9438 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
9439 return dpDiv.on( "mouseout", selector, function() {
9440 $( this ).removeClass( "ui-state-hover" );
9441 if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
9442 $( this ).removeClass( "ui-datepicker-prev-hover" );
9443 }
9444 if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
9445 $( this ).removeClass( "ui-datepicker-next-hover" );
9446 }
9447 } )
9448 .on( "mouseover", selector, datepicker_handleMouseover );
9449 }
9450
9451 function datepicker_handleMouseover() {
9452 if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) {
9453 $( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" );
9454 $( this ).addClass( "ui-state-hover" );
9455 if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
9456 $( this ).addClass( "ui-datepicker-prev-hover" );
9457 }
9458 if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
9459 $( this ).addClass( "ui-datepicker-next-hover" );
9460 }
9461 }
9462 }
9463
9464 /* jQuery extend now ignores nulls! */
9465 function datepicker_extendRemove( target, props ) {
9466 $.extend( target, props );
9467 for ( var name in props ) {
9468 if ( props[ name ] == null ) {
9469 target[ name ] = props[ name ];
9470 }
9471 }
9472 return target;
9473 }
9474
9475 /* Invoke the datepicker functionality.
9476 @param options string - a command, optionally followed by additional parameters or
9477 Object - settings for attaching new datepicker functionality
9478 @return jQuery object */
9479 $.fn.datepicker = function( options ) {
9480
9481 /* Verify an empty collection wasn't passed - Fixes #6976 */
9482 if ( !this.length ) {
9483 return this;
9484 }
9485
9486 /* Initialise the date picker. */
9487 if ( !$.datepicker.initialized ) {
9488 $( document ).on( "mousedown", $.datepicker._checkExternalClick );
9489 $.datepicker.initialized = true;
9490 }
9491
9492 /* Append datepicker main container to body if not exist. */
9493 if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) {
9494 $( "body" ).append( $.datepicker.dpDiv );
9495 }
9496
9497 var otherArgs = Array.prototype.slice.call( arguments, 1 );
9498 if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) {
9499 return $.datepicker[ "_" + options + "Datepicker" ].
9500 apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
9501 }
9502 if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) {
9503 return $.datepicker[ "_" + options + "Datepicker" ].
9504 apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
9505 }
9506 return this.each( function() {
9507 if ( typeof options === "string" ) {
9508 $.datepicker[ "_" + options + "Datepicker" ]
9509 .apply( $.datepicker, [ this ].concat( otherArgs ) );
9510 } else {
9511 $.datepicker._attachDatepicker( this, options );
9512 }
9513 } );
9514 };
9515
9516 $.datepicker = new Datepicker(); // singleton instance
9517 $.datepicker.initialized = false;
9518 $.datepicker.uuid = new Date().getTime();
9519 $.datepicker.version = "1.13.2";
9520
9521 var widgetsDatepicker = $.datepicker;
9522
9523
9524
9525 // This file is deprecated
9526 var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
9527
9528 /*!
9529 * jQuery UI Mouse 1.13.2
9530 * http://jqueryui.com
9531 *
9532 * Copyright jQuery Foundation and other contributors
9533 * Released under the MIT license.
9534 * http://jquery.org/license
9535 */
9536
9537 //>>label: Mouse
9538 //>>group: Widgets
9539 //>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
9540 //>>docs: http://api.jqueryui.com/mouse/
9541
9542
9543 var mouseHandled = false;
9544 $( document ).on( "mouseup", function() {
9545 mouseHandled = false;
9546 } );
9547
9548 var widgetsMouse = $.widget( "ui.mouse", {
9549 version: "1.13.2",
9550 options: {
9551 cancel: "input, textarea, button, select, option",
9552 distance: 1,
9553 delay: 0
9554 },
9555 _mouseInit: function() {
9556 var that = this;
9557
9558 this.element
9559 .on( "mousedown." + this.widgetName, function( event ) {
9560 return that._mouseDown( event );
9561 } )
9562 .on( "click." + this.widgetName, function( event ) {
9563 if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
9564 $.removeData( event.target, that.widgetName + ".preventClickEvent" );
9565 event.stopImmediatePropagation();
9566 return false;
9567 }
9568 } );
9569
9570 this.started = false;
9571 },
9572
9573 // TODO: make sure destroying one instance of mouse doesn't mess with
9574 // other instances of mouse
9575 _mouseDestroy: function() {
9576 this.element.off( "." + this.widgetName );
9577 if ( this._mouseMoveDelegate ) {
9578 this.document
9579 .off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9580 .off( "mouseup." + this.widgetName, this._mouseUpDelegate );
9581 }
9582 },
9583
9584 _mouseDown: function( event ) {
9585
9586 // don't let more than one widget handle mouseStart
9587 if ( mouseHandled ) {
9588 return;
9589 }
9590
9591 this._mouseMoved = false;
9592
9593 // We may have missed mouseup (out of window)
9594 if ( this._mouseStarted ) {
9595 this._mouseUp( event );
9596 }
9597
9598 this._mouseDownEvent = event;
9599
9600 var that = this,
9601 btnIsLeft = ( event.which === 1 ),
9602
9603 // event.target.nodeName works around a bug in IE 8 with
9604 // disabled inputs (#7620)
9605 elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
9606 $( event.target ).closest( this.options.cancel ).length : false );
9607 if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
9608 return true;
9609 }
9610
9611 this.mouseDelayMet = !this.options.delay;
9612 if ( !this.mouseDelayMet ) {
9613 this._mouseDelayTimer = setTimeout( function() {
9614 that.mouseDelayMet = true;
9615 }, this.options.delay );
9616 }
9617
9618 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
9619 this._mouseStarted = ( this._mouseStart( event ) !== false );
9620 if ( !this._mouseStarted ) {
9621 event.preventDefault();
9622 return true;
9623 }
9624 }
9625
9626 // Click event may never have fired (Gecko & Opera)
9627 if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
9628 $.removeData( event.target, this.widgetName + ".preventClickEvent" );
9629 }
9630
9631 // These delegates are required to keep context
9632 this._mouseMoveDelegate = function( event ) {
9633 return that._mouseMove( event );
9634 };
9635 this._mouseUpDelegate = function( event ) {
9636 return that._mouseUp( event );
9637 };
9638
9639 this.document
9640 .on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9641 .on( "mouseup." + this.widgetName, this._mouseUpDelegate );
9642
9643 event.preventDefault();
9644
9645 mouseHandled = true;
9646 return true;
9647 },
9648
9649 _mouseMove: function( event ) {
9650
9651 // Only check for mouseups outside the document if you've moved inside the document
9652 // at least once. This prevents the firing of mouseup in the case of IE<9, which will
9653 // fire a mousemove event if content is placed under the cursor. See #7778
9654 // Support: IE <9
9655 if ( this._mouseMoved ) {
9656
9657 // IE mouseup check - mouseup happened when mouse was out of window
9658 if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
9659 !event.button ) {
9660 return this._mouseUp( event );
9661
9662 // Iframe mouseup check - mouseup occurred in another document
9663 } else if ( !event.which ) {
9664
9665 // Support: Safari <=8 - 9
9666 // Safari sets which to 0 if you press any of the following keys
9667 // during a drag (#14461)
9668 if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
9669 event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
9670 this.ignoreMissingWhich = true;
9671 } else if ( !this.ignoreMissingWhich ) {
9672 return this._mouseUp( event );
9673 }
9674 }
9675 }
9676
9677 if ( event.which || event.button ) {
9678 this._mouseMoved = true;
9679 }
9680
9681 if ( this._mouseStarted ) {
9682 this._mouseDrag( event );
9683 return event.preventDefault();
9684 }
9685
9686 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
9687 this._mouseStarted =
9688 ( this._mouseStart( this._mouseDownEvent, event ) !== false );
9689 if ( this._mouseStarted ) {
9690 this._mouseDrag( event );
9691 } else {
9692 this._mouseUp( event );
9693 }
9694 }
9695
9696 return !this._mouseStarted;
9697 },
9698
9699 _mouseUp: function( event ) {
9700 this.document
9701 .off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9702 .off( "mouseup." + this.widgetName, this._mouseUpDelegate );
9703
9704 if ( this._mouseStarted ) {
9705 this._mouseStarted = false;
9706
9707 if ( event.target === this._mouseDownEvent.target ) {
9708 $.data( event.target, this.widgetName + ".preventClickEvent", true );
9709 }
9710
9711 this._mouseStop( event );
9712 }
9713
9714 if ( this._mouseDelayTimer ) {
9715 clearTimeout( this._mouseDelayTimer );
9716 delete this._mouseDelayTimer;
9717 }
9718
9719 this.ignoreMissingWhich = false;
9720 mouseHandled = false;
9721 event.preventDefault();
9722 },
9723
9724 _mouseDistanceMet: function( event ) {
9725 return ( Math.max(
9726 Math.abs( this._mouseDownEvent.pageX - event.pageX ),
9727 Math.abs( this._mouseDownEvent.pageY - event.pageY )
9728 ) >= this.options.distance
9729 );
9730 },
9731
9732 _mouseDelayMet: function( /* event */ ) {
9733 return this.mouseDelayMet;
9734 },
9735
9736 // These are placeholder methods, to be overriden by extending plugin
9737 _mouseStart: function( /* event */ ) {},
9738 _mouseDrag: function( /* event */ ) {},
9739 _mouseStop: function( /* event */ ) {},
9740 _mouseCapture: function( /* event */ ) {
9741 return true;
9742 }
9743 } );
9744
9745
9746
9747 // $.ui.plugin is deprecated. Use $.widget() extensions instead.
9748 var plugin = $.ui.plugin = {
9749 add: function( module, option, set ) {
9750 var i,
9751 proto = $.ui[ module ].prototype;
9752 for ( i in set ) {
9753 proto.plugins[ i ] = proto.plugins[ i ] || [];
9754 proto.plugins[ i ].push( [ option, set[ i ] ] );
9755 }
9756 },
9757 call: function( instance, name, args, allowDisconnected ) {
9758 var i,
9759 set = instance.plugins[ name ];
9760
9761 if ( !set ) {
9762 return;
9763 }
9764
9765 if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
9766 instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
9767 return;
9768 }
9769
9770 for ( i = 0; i < set.length; i++ ) {
9771 if ( instance.options[ set[ i ][ 0 ] ] ) {
9772 set[ i ][ 1 ].apply( instance.element, args );
9773 }
9774 }
9775 }
9776 };
9777
9778
9779
9780 var safeBlur = $.ui.safeBlur = function( element ) {
9781
9782 // Support: IE9 - 10 only
9783 // If the <body> is blurred, IE will switch windows, see #9420
9784 if ( element && element.nodeName.toLowerCase() !== "body" ) {
9785 $( element ).trigger( "blur" );
9786 }
9787 };
9788
9789
9790 /*!
9791 * jQuery UI Draggable 1.13.2
9792 * http://jqueryui.com
9793 *
9794 * Copyright jQuery Foundation and other contributors
9795 * Released under the MIT license.
9796 * http://jquery.org/license
9797 */
9798
9799 //>>label: Draggable
9800 //>>group: Interactions
9801 //>>description: Enables dragging functionality for any element.
9802 //>>docs: http://api.jqueryui.com/draggable/
9803 //>>demos: http://jqueryui.com/draggable/
9804 //>>css.structure: ../../themes/base/draggable.css
9805
9806
9807 $.widget( "ui.draggable", $.ui.mouse, {
9808 version: "1.13.2",
9809 widgetEventPrefix: "drag",
9810 options: {
9811 addClasses: true,
9812 appendTo: "parent",
9813 axis: false,
9814 connectToSortable: false,
9815 containment: false,
9816 cursor: "auto",
9817 cursorAt: false,
9818 grid: false,
9819 handle: false,
9820 helper: "original",
9821 iframeFix: false,
9822 opacity: false,
9823 refreshPositions: false,
9824 revert: false,
9825 revertDuration: 500,
9826 scope: "default",
9827 scroll: true,
9828 scrollSensitivity: 20,
9829 scrollSpeed: 20,
9830 snap: false,
9831 snapMode: "both",
9832 snapTolerance: 20,
9833 stack: false,
9834 zIndex: false,
9835
9836 // Callbacks
9837 drag: null,
9838 start: null,
9839 stop: null
9840 },
9841 _create: function() {
9842
9843 if ( this.options.helper === "original" ) {
9844 this._setPositionRelative();
9845 }
9846 if ( this.options.addClasses ) {
9847 this._addClass( "ui-draggable" );
9848 }
9849 this._setHandleClassName();
9850
9851 this._mouseInit();
9852 },
9853
9854 _setOption: function( key, value ) {
9855 this._super( key, value );
9856 if ( key === "handle" ) {
9857 this._removeHandleClassName();
9858 this._setHandleClassName();
9859 }
9860 },
9861
9862 _destroy: function() {
9863 if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
9864 this.destroyOnClear = true;
9865 return;
9866 }
9867 this._removeHandleClassName();
9868 this._mouseDestroy();
9869 },
9870
9871 _mouseCapture: function( event ) {
9872 var o = this.options;
9873
9874 // Among others, prevent a drag on a resizable-handle
9875 if ( this.helper || o.disabled ||
9876 $( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
9877 return false;
9878 }
9879
9880 //Quit if we're not on a valid handle
9881 this.handle = this._getHandle( event );
9882 if ( !this.handle ) {
9883 return false;
9884 }
9885
9886 this._blurActiveElement( event );
9887
9888 this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
9889
9890 return true;
9891
9892 },
9893
9894 _blockFrames: function( selector ) {
9895 this.iframeBlocks = this.document.find( selector ).map( function() {
9896 var iframe = $( this );
9897
9898 return $( "<div>" )
9899 .css( "position", "absolute" )
9900 .appendTo( iframe.parent() )
9901 .outerWidth( iframe.outerWidth() )
9902 .outerHeight( iframe.outerHeight() )
9903 .offset( iframe.offset() )[ 0 ];
9904 } );
9905 },
9906
9907 _unblockFrames: function() {
9908 if ( this.iframeBlocks ) {
9909 this.iframeBlocks.remove();
9910 delete this.iframeBlocks;
9911 }
9912 },
9913
9914 _blurActiveElement: function( event ) {
9915 var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
9916 target = $( event.target );
9917
9918 // Don't blur if the event occurred on an element that is within
9919 // the currently focused element
9920 // See #10527, #12472
9921 if ( target.closest( activeElement ).length ) {
9922 return;
9923 }
9924
9925 // Blur any element that currently has focus, see #4261
9926 $.ui.safeBlur( activeElement );
9927 },
9928
9929 _mouseStart: function( event ) {
9930
9931 var o = this.options;
9932
9933 //Create and append the visible helper
9934 this.helper = this._createHelper( event );
9935
9936 this._addClass( this.helper, "ui-draggable-dragging" );
9937
9938 //Cache the helper size
9939 this._cacheHelperProportions();
9940
9941 //If ddmanager is used for droppables, set the global draggable
9942 if ( $.ui.ddmanager ) {
9943 $.ui.ddmanager.current = this;
9944 }
9945
9946 /*
9947 * - Position generation -
9948 * This block generates everything position related - it's the core of draggables.
9949 */
9950
9951 //Cache the margins of the original element
9952 this._cacheMargins();
9953
9954 //Store the helper's css position
9955 this.cssPosition = this.helper.css( "position" );
9956 this.scrollParent = this.helper.scrollParent( true );
9957 this.offsetParent = this.helper.offsetParent();
9958 this.hasFixedAncestor = this.helper.parents().filter( function() {
9959 return $( this ).css( "position" ) === "fixed";
9960 } ).length > 0;
9961
9962 //The element's absolute position on the page minus margins
9963 this.positionAbs = this.element.offset();
9964 this._refreshOffsets( event );
9965
9966 //Generate the original position
9967 this.originalPosition = this.position = this._generatePosition( event, false );
9968 this.originalPageX = event.pageX;
9969 this.originalPageY = event.pageY;
9970
9971 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
9972 if ( o.cursorAt ) {
9973 this._adjustOffsetFromHelper( o.cursorAt );
9974 }
9975
9976 //Set a containment if given in the options
9977 this._setContainment();
9978
9979 //Trigger event + callbacks
9980 if ( this._trigger( "start", event ) === false ) {
9981 this._clear();
9982 return false;
9983 }
9984
9985 //Recache the helper size
9986 this._cacheHelperProportions();
9987
9988 //Prepare the droppable offsets
9989 if ( $.ui.ddmanager && !o.dropBehaviour ) {
9990 $.ui.ddmanager.prepareOffsets( this, event );
9991 }
9992
9993 // Execute the drag once - this causes the helper not to be visible before getting its
9994 // correct position
9995 this._mouseDrag( event, true );
9996
9997 // If the ddmanager is used for droppables, inform the manager that dragging has started
9998 // (see #5003)
9999 if ( $.ui.ddmanager ) {
10000 $.ui.ddmanager.dragStart( this, event );
10001 }
10002
10003 return true;
10004 },
10005
10006 _refreshOffsets: function( event ) {
10007 this.offset = {
10008 top: this.positionAbs.top - this.margins.top,
10009 left: this.positionAbs.left - this.margins.left,
10010 scroll: false,
10011 parent: this._getParentOffset(),
10012 relative: this._getRelativeOffset()
10013 };
10014
10015 this.offset.click = {
10016 left: event.pageX - this.offset.left,
10017 top: event.pageY - this.offset.top
10018 };
10019 },
10020
10021 _mouseDrag: function( event, noPropagation ) {
10022
10023 // reset any necessary cached properties (see #5009)
10024 if ( this.hasFixedAncestor ) {
10025 this.offset.parent = this._getParentOffset();
10026 }
10027
10028 //Compute the helpers position
10029 this.position = this._generatePosition( event, true );
10030 this.positionAbs = this._convertPositionTo( "absolute" );
10031
10032 //Call plugins and callbacks and use the resulting position if something is returned
10033 if ( !noPropagation ) {
10034 var ui = this._uiHash();
10035 if ( this._trigger( "drag", event, ui ) === false ) {
10036 this._mouseUp( new $.Event( "mouseup", event ) );
10037 return false;
10038 }
10039 this.position = ui.position;
10040 }
10041
10042 this.helper[ 0 ].style.left = this.position.left + "px";
10043 this.helper[ 0 ].style.top = this.position.top + "px";
10044
10045 if ( $.ui.ddmanager ) {
10046 $.ui.ddmanager.drag( this, event );
10047 }
10048
10049 return false;
10050 },
10051
10052 _mouseStop: function( event ) {
10053
10054 //If we are using droppables, inform the manager about the drop
10055 var that = this,
10056 dropped = false;
10057 if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
10058 dropped = $.ui.ddmanager.drop( this, event );
10059 }
10060
10061 //if a drop comes from outside (a sortable)
10062 if ( this.dropped ) {
10063 dropped = this.dropped;
10064 this.dropped = false;
10065 }
10066
10067 if ( ( this.options.revert === "invalid" && !dropped ) ||
10068 ( this.options.revert === "valid" && dropped ) ||
10069 this.options.revert === true || ( typeof this.options.revert === "function" &&
10070 this.options.revert.call( this.element, dropped ) )
10071 ) {
10072 $( this.helper ).animate(
10073 this.originalPosition,
10074 parseInt( this.options.revertDuration, 10 ),
10075 function() {
10076 if ( that._trigger( "stop", event ) !== false ) {
10077 that._clear();
10078 }
10079 }
10080 );
10081 } else {
10082 if ( this._trigger( "stop", event ) !== false ) {
10083 this._clear();
10084 }
10085 }
10086
10087 return false;
10088 },
10089
10090 _mouseUp: function( event ) {
10091 this._unblockFrames();
10092
10093 // If the ddmanager is used for droppables, inform the manager that dragging has stopped
10094 // (see #5003)
10095 if ( $.ui.ddmanager ) {
10096 $.ui.ddmanager.dragStop( this, event );
10097 }
10098
10099 // Only need to focus if the event occurred on the draggable itself, see #10527
10100 if ( this.handleElement.is( event.target ) ) {
10101
10102 // The interaction is over; whether or not the click resulted in a drag,
10103 // focus the element
10104 this.element.trigger( "focus" );
10105 }
10106
10107 return $.ui.mouse.prototype._mouseUp.call( this, event );
10108 },
10109
10110 cancel: function() {
10111
10112 if ( this.helper.is( ".ui-draggable-dragging" ) ) {
10113 this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
10114 } else {
10115 this._clear();
10116 }
10117
10118 return this;
10119
10120 },
10121
10122 _getHandle: function( event ) {
10123 return this.options.handle ?
10124 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
10125 true;
10126 },
10127
10128 _setHandleClassName: function() {
10129 this.handleElement = this.options.handle ?
10130 this.element.find( this.options.handle ) : this.element;
10131 this._addClass( this.handleElement, "ui-draggable-handle" );
10132 },
10133
10134 _removeHandleClassName: function() {
10135 this._removeClass( this.handleElement, "ui-draggable-handle" );
10136 },
10137
10138 _createHelper: function( event ) {
10139
10140 var o = this.options,
10141 helperIsFunction = typeof o.helper === "function",
10142 helper = helperIsFunction ?
10143 $( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
10144 ( o.helper === "clone" ?
10145 this.element.clone().removeAttr( "id" ) :
10146 this.element );
10147
10148 if ( !helper.parents( "body" ).length ) {
10149 helper.appendTo( ( o.appendTo === "parent" ?
10150 this.element[ 0 ].parentNode :
10151 o.appendTo ) );
10152 }
10153
10154 // Http://bugs.jqueryui.com/ticket/9446
10155 // a helper function can return the original element
10156 // which wouldn't have been set to relative in _create
10157 if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
10158 this._setPositionRelative();
10159 }
10160
10161 if ( helper[ 0 ] !== this.element[ 0 ] &&
10162 !( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
10163 helper.css( "position", "absolute" );
10164 }
10165
10166 return helper;
10167
10168 },
10169
10170 _setPositionRelative: function() {
10171 if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
10172 this.element[ 0 ].style.position = "relative";
10173 }
10174 },
10175
10176 _adjustOffsetFromHelper: function( obj ) {
10177 if ( typeof obj === "string" ) {
10178 obj = obj.split( " " );
10179 }
10180 if ( Array.isArray( obj ) ) {
10181 obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
10182 }
10183 if ( "left" in obj ) {
10184 this.offset.click.left = obj.left + this.margins.left;
10185 }
10186 if ( "right" in obj ) {
10187 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
10188 }
10189 if ( "top" in obj ) {
10190 this.offset.click.top = obj.top + this.margins.top;
10191 }
10192 if ( "bottom" in obj ) {
10193 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
10194 }
10195 },
10196
10197 _isRootNode: function( element ) {
10198 return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
10199 },
10200
10201 _getParentOffset: function() {
10202
10203 //Get the offsetParent and cache its position
10204 var po = this.offsetParent.offset(),
10205 document = this.document[ 0 ];
10206
10207 // This is a special case where we need to modify a offset calculated on start, since the
10208 // following happened:
10209 // 1. The position of the helper is absolute, so it's position is calculated based on the
10210 // next positioned parent
10211 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
10212 // the document, which means that the scroll is included in the initial calculation of the
10213 // offset of the parent, and never recalculated upon drag
10214 if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
10215 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
10216 po.left += this.scrollParent.scrollLeft();
10217 po.top += this.scrollParent.scrollTop();
10218 }
10219
10220 if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
10221 po = { top: 0, left: 0 };
10222 }
10223
10224 return {
10225 top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
10226 left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
10227 };
10228
10229 },
10230
10231 _getRelativeOffset: function() {
10232 if ( this.cssPosition !== "relative" ) {
10233 return { top: 0, left: 0 };
10234 }
10235
10236 var p = this.element.position(),
10237 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
10238
10239 return {
10240 top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
10241 ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
10242 left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
10243 ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
10244 };
10245
10246 },
10247
10248 _cacheMargins: function() {
10249 this.margins = {
10250 left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
10251 top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
10252 right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
10253 bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
10254 };
10255 },
10256
10257 _cacheHelperProportions: function() {
10258 this.helperProportions = {
10259 width: this.helper.outerWidth(),
10260 height: this.helper.outerHeight()
10261 };
10262 },
10263
10264 _setContainment: function() {
10265
10266 var isUserScrollable, c, ce,
10267 o = this.options,
10268 document = this.document[ 0 ];
10269
10270 this.relativeContainer = null;
10271
10272 if ( !o.containment ) {
10273 this.containment = null;
10274 return;
10275 }
10276
10277 if ( o.containment === "window" ) {
10278 this.containment = [
10279 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
10280 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
10281 $( window ).scrollLeft() + $( window ).width() -
10282 this.helperProportions.width - this.margins.left,
10283 $( window ).scrollTop() +
10284 ( $( window ).height() || document.body.parentNode.scrollHeight ) -
10285 this.helperProportions.height - this.margins.top
10286 ];
10287 return;
10288 }
10289
10290 if ( o.containment === "document" ) {
10291 this.containment = [
10292 0,
10293 0,
10294 $( document ).width() - this.helperProportions.width - this.margins.left,
10295 ( $( document ).height() || document.body.parentNode.scrollHeight ) -
10296 this.helperProportions.height - this.margins.top
10297 ];
10298 return;
10299 }
10300
10301 if ( o.containment.constructor === Array ) {
10302 this.containment = o.containment;
10303 return;
10304 }
10305
10306 if ( o.containment === "parent" ) {
10307 o.containment = this.helper[ 0 ].parentNode;
10308 }
10309
10310 c = $( o.containment );
10311 ce = c[ 0 ];
10312
10313 if ( !ce ) {
10314 return;
10315 }
10316
10317 isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
10318
10319 this.containment = [
10320 ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
10321 ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
10322 ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
10323 ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
10324 ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
10325 ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
10326 ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
10327 this.helperProportions.width -
10328 this.margins.left -
10329 this.margins.right,
10330 ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
10331 ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
10332 ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
10333 this.helperProportions.height -
10334 this.margins.top -
10335 this.margins.bottom
10336 ];
10337 this.relativeContainer = c;
10338 },
10339
10340 _convertPositionTo: function( d, pos ) {
10341
10342 if ( !pos ) {
10343 pos = this.position;
10344 }
10345
10346 var mod = d === "absolute" ? 1 : -1,
10347 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
10348
10349 return {
10350 top: (
10351
10352 // The absolute mouse position
10353 pos.top +
10354
10355 // Only for relative positioned nodes: Relative offset from element to offset parent
10356 this.offset.relative.top * mod +
10357
10358 // The offsetParent's offset without borders (offset + border)
10359 this.offset.parent.top * mod -
10360 ( ( this.cssPosition === "fixed" ?
10361 -this.offset.scroll.top :
10362 ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
10363 ),
10364 left: (
10365
10366 // The absolute mouse position
10367 pos.left +
10368
10369 // Only for relative positioned nodes: Relative offset from element to offset parent
10370 this.offset.relative.left * mod +
10371
10372 // The offsetParent's offset without borders (offset + border)
10373 this.offset.parent.left * mod -
10374 ( ( this.cssPosition === "fixed" ?
10375 -this.offset.scroll.left :
10376 ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
10377 )
10378 };
10379
10380 },
10381
10382 _generatePosition: function( event, constrainPosition ) {
10383
10384 var containment, co, top, left,
10385 o = this.options,
10386 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
10387 pageX = event.pageX,
10388 pageY = event.pageY;
10389
10390 // Cache the scroll
10391 if ( !scrollIsRootNode || !this.offset.scroll ) {
10392 this.offset.scroll = {
10393 top: this.scrollParent.scrollTop(),
10394 left: this.scrollParent.scrollLeft()
10395 };
10396 }
10397
10398 /*
10399 * - Position constraining -
10400 * Constrain the position to a mix of grid, containment.
10401 */
10402
10403 // If we are not dragging yet, we won't check for options
10404 if ( constrainPosition ) {
10405 if ( this.containment ) {
10406 if ( this.relativeContainer ) {
10407 co = this.relativeContainer.offset();
10408 containment = [
10409 this.containment[ 0 ] + co.left,
10410 this.containment[ 1 ] + co.top,
10411 this.containment[ 2 ] + co.left,
10412 this.containment[ 3 ] + co.top
10413 ];
10414 } else {
10415 containment = this.containment;
10416 }
10417
10418 if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
10419 pageX = containment[ 0 ] + this.offset.click.left;
10420 }
10421 if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
10422 pageY = containment[ 1 ] + this.offset.click.top;
10423 }
10424 if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
10425 pageX = containment[ 2 ] + this.offset.click.left;
10426 }
10427 if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
10428 pageY = containment[ 3 ] + this.offset.click.top;
10429 }
10430 }
10431
10432 if ( o.grid ) {
10433
10434 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid
10435 // argument errors in IE (see ticket #6950)
10436 top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
10437 this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
10438 pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
10439 top - this.offset.click.top > containment[ 3 ] ) ?
10440 top :
10441 ( ( top - this.offset.click.top >= containment[ 1 ] ) ?
10442 top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
10443
10444 left = o.grid[ 0 ] ? this.originalPageX +
10445 Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
10446 this.originalPageX;
10447 pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
10448 left - this.offset.click.left > containment[ 2 ] ) ?
10449 left :
10450 ( ( left - this.offset.click.left >= containment[ 0 ] ) ?
10451 left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
10452 }
10453
10454 if ( o.axis === "y" ) {
10455 pageX = this.originalPageX;
10456 }
10457
10458 if ( o.axis === "x" ) {
10459 pageY = this.originalPageY;
10460 }
10461 }
10462
10463 return {
10464 top: (
10465
10466 // The absolute mouse position
10467 pageY -
10468
10469 // Click offset (relative to the element)
10470 this.offset.click.top -
10471
10472 // Only for relative positioned nodes: Relative offset from element to offset parent
10473 this.offset.relative.top -
10474
10475 // The offsetParent's offset without borders (offset + border)
10476 this.offset.parent.top +
10477 ( this.cssPosition === "fixed" ?
10478 -this.offset.scroll.top :
10479 ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
10480 ),
10481 left: (
10482
10483 // The absolute mouse position
10484 pageX -
10485
10486 // Click offset (relative to the element)
10487 this.offset.click.left -
10488
10489 // Only for relative positioned nodes: Relative offset from element to offset parent
10490 this.offset.relative.left -
10491
10492 // The offsetParent's offset without borders (offset + border)
10493 this.offset.parent.left +
10494 ( this.cssPosition === "fixed" ?
10495 -this.offset.scroll.left :
10496 ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
10497 )
10498 };
10499
10500 },
10501
10502 _clear: function() {
10503 this._removeClass( this.helper, "ui-draggable-dragging" );
10504 if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
10505 this.helper.remove();
10506 }
10507 this.helper = null;
10508 this.cancelHelperRemoval = false;
10509 if ( this.destroyOnClear ) {
10510 this.destroy();
10511 }
10512 },
10513
10514 // From now on bulk stuff - mainly helpers
10515
10516 _trigger: function( type, event, ui ) {
10517 ui = ui || this._uiHash();
10518 $.ui.plugin.call( this, type, [ event, ui, this ], true );
10519
10520 // Absolute position and offset (see #6884 ) have to be recalculated after plugins
10521 if ( /^(drag|start|stop)/.test( type ) ) {
10522 this.positionAbs = this._convertPositionTo( "absolute" );
10523 ui.offset = this.positionAbs;
10524 }
10525 return $.Widget.prototype._trigger.call( this, type, event, ui );
10526 },
10527
10528 plugins: {},
10529
10530 _uiHash: function() {
10531 return {
10532 helper: this.helper,
10533 position: this.position,
10534 originalPosition: this.originalPosition,
10535 offset: this.positionAbs
10536 };
10537 }
10538
10539 } );
10540
10541 $.ui.plugin.add( "draggable", "connectToSortable", {
10542 start: function( event, ui, draggable ) {
10543 var uiSortable = $.extend( {}, ui, {
10544 item: draggable.element
10545 } );
10546
10547 draggable.sortables = [];
10548 $( draggable.options.connectToSortable ).each( function() {
10549 var sortable = $( this ).sortable( "instance" );
10550
10551 if ( sortable && !sortable.options.disabled ) {
10552 draggable.sortables.push( sortable );
10553
10554 // RefreshPositions is called at drag start to refresh the containerCache
10555 // which is used in drag. This ensures it's initialized and synchronized
10556 // with any changes that might have happened on the page since initialization.
10557 sortable.refreshPositions();
10558 sortable._trigger( "activate", event, uiSortable );
10559 }
10560 } );
10561 },
10562 stop: function( event, ui, draggable ) {
10563 var uiSortable = $.extend( {}, ui, {
10564 item: draggable.element
10565 } );
10566
10567 draggable.cancelHelperRemoval = false;
10568
10569 $.each( draggable.sortables, function() {
10570 var sortable = this;
10571
10572 if ( sortable.isOver ) {
10573 sortable.isOver = 0;
10574
10575 // Allow this sortable to handle removing the helper
10576 draggable.cancelHelperRemoval = true;
10577 sortable.cancelHelperRemoval = false;
10578
10579 // Use _storedCSS To restore properties in the sortable,
10580 // as this also handles revert (#9675) since the draggable
10581 // may have modified them in unexpected ways (#8809)
10582 sortable._storedCSS = {
10583 position: sortable.placeholder.css( "position" ),
10584 top: sortable.placeholder.css( "top" ),
10585 left: sortable.placeholder.css( "left" )
10586 };
10587
10588 sortable._mouseStop( event );
10589
10590 // Once drag has ended, the sortable should return to using
10591 // its original helper, not the shared helper from draggable
10592 sortable.options.helper = sortable.options._helper;
10593 } else {
10594
10595 // Prevent this Sortable from removing the helper.
10596 // However, don't set the draggable to remove the helper
10597 // either as another connected Sortable may yet handle the removal.
10598 sortable.cancelHelperRemoval = true;
10599
10600 sortable._trigger( "deactivate", event, uiSortable );
10601 }
10602 } );
10603 },
10604 drag: function( event, ui, draggable ) {
10605 $.each( draggable.sortables, function() {
10606 var innermostIntersecting = false,
10607 sortable = this;
10608
10609 // Copy over variables that sortable's _intersectsWith uses
10610 sortable.positionAbs = draggable.positionAbs;
10611 sortable.helperProportions = draggable.helperProportions;
10612 sortable.offset.click = draggable.offset.click;
10613
10614 if ( sortable._intersectsWith( sortable.containerCache ) ) {
10615 innermostIntersecting = true;
10616
10617 $.each( draggable.sortables, function() {
10618
10619 // Copy over variables that sortable's _intersectsWith uses
10620 this.positionAbs = draggable.positionAbs;
10621 this.helperProportions = draggable.helperProportions;
10622 this.offset.click = draggable.offset.click;
10623
10624 if ( this !== sortable &&
10625 this._intersectsWith( this.containerCache ) &&
10626 $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
10627 innermostIntersecting = false;
10628 }
10629
10630 return innermostIntersecting;
10631 } );
10632 }
10633
10634 if ( innermostIntersecting ) {
10635
10636 // If it intersects, we use a little isOver variable and set it once,
10637 // so that the move-in stuff gets fired only once.
10638 if ( !sortable.isOver ) {
10639 sortable.isOver = 1;
10640
10641 // Store draggable's parent in case we need to reappend to it later.
10642 draggable._parent = ui.helper.parent();
10643
10644 sortable.currentItem = ui.helper
10645 .appendTo( sortable.element )
10646 .data( "ui-sortable-item", true );
10647
10648 // Store helper option to later restore it
10649 sortable.options._helper = sortable.options.helper;
10650
10651 sortable.options.helper = function() {
10652 return ui.helper[ 0 ];
10653 };
10654
10655 // Fire the start events of the sortable with our passed browser event,
10656 // and our own helper (so it doesn't create a new one)
10657 event.target = sortable.currentItem[ 0 ];
10658 sortable._mouseCapture( event, true );
10659 sortable._mouseStart( event, true, true );
10660
10661 // Because the browser event is way off the new appended portlet,
10662 // modify necessary variables to reflect the changes
10663 sortable.offset.click.top = draggable.offset.click.top;
10664 sortable.offset.click.left = draggable.offset.click.left;
10665 sortable.offset.parent.left -= draggable.offset.parent.left -
10666 sortable.offset.parent.left;
10667 sortable.offset.parent.top -= draggable.offset.parent.top -
10668 sortable.offset.parent.top;
10669
10670 draggable._trigger( "toSortable", event );
10671
10672 // Inform draggable that the helper is in a valid drop zone,
10673 // used solely in the revert option to handle "valid/invalid".
10674 draggable.dropped = sortable.element;
10675
10676 // Need to refreshPositions of all sortables in the case that
10677 // adding to one sortable changes the location of the other sortables (#9675)
10678 $.each( draggable.sortables, function() {
10679 this.refreshPositions();
10680 } );
10681
10682 // Hack so receive/update callbacks work (mostly)
10683 draggable.currentItem = draggable.element;
10684 sortable.fromOutside = draggable;
10685 }
10686
10687 if ( sortable.currentItem ) {
10688 sortable._mouseDrag( event );
10689
10690 // Copy the sortable's position because the draggable's can potentially reflect
10691 // a relative position, while sortable is always absolute, which the dragged
10692 // element has now become. (#8809)
10693 ui.position = sortable.position;
10694 }
10695 } else {
10696
10697 // If it doesn't intersect with the sortable, and it intersected before,
10698 // we fake the drag stop of the sortable, but make sure it doesn't remove
10699 // the helper by using cancelHelperRemoval.
10700 if ( sortable.isOver ) {
10701
10702 sortable.isOver = 0;
10703 sortable.cancelHelperRemoval = true;
10704
10705 // Calling sortable's mouseStop would trigger a revert,
10706 // so revert must be temporarily false until after mouseStop is called.
10707 sortable.options._revert = sortable.options.revert;
10708 sortable.options.revert = false;
10709
10710 sortable._trigger( "out", event, sortable._uiHash( sortable ) );
10711 sortable._mouseStop( event, true );
10712
10713 // Restore sortable behaviors that were modfied
10714 // when the draggable entered the sortable area (#9481)
10715 sortable.options.revert = sortable.options._revert;
10716 sortable.options.helper = sortable.options._helper;
10717
10718 if ( sortable.placeholder ) {
10719 sortable.placeholder.remove();
10720 }
10721
10722 // Restore and recalculate the draggable's offset considering the sortable
10723 // may have modified them in unexpected ways. (#8809, #10669)
10724 ui.helper.appendTo( draggable._parent );
10725 draggable._refreshOffsets( event );
10726 ui.position = draggable._generatePosition( event, true );
10727
10728 draggable._trigger( "fromSortable", event );
10729
10730 // Inform draggable that the helper is no longer in a valid drop zone
10731 draggable.dropped = false;
10732
10733 // Need to refreshPositions of all sortables just in case removing
10734 // from one sortable changes the location of other sortables (#9675)
10735 $.each( draggable.sortables, function() {
10736 this.refreshPositions();
10737 } );
10738 }
10739 }
10740 } );
10741 }
10742 } );
10743
10744 $.ui.plugin.add( "draggable", "cursor", {
10745 start: function( event, ui, instance ) {
10746 var t = $( "body" ),
10747 o = instance.options;
10748
10749 if ( t.css( "cursor" ) ) {
10750 o._cursor = t.css( "cursor" );
10751 }
10752 t.css( "cursor", o.cursor );
10753 },
10754 stop: function( event, ui, instance ) {
10755 var o = instance.options;
10756 if ( o._cursor ) {
10757 $( "body" ).css( "cursor", o._cursor );
10758 }
10759 }
10760 } );
10761
10762 $.ui.plugin.add( "draggable", "opacity", {
10763 start: function( event, ui, instance ) {
10764 var t = $( ui.helper ),
10765 o = instance.options;
10766 if ( t.css( "opacity" ) ) {
10767 o._opacity = t.css( "opacity" );
10768 }
10769 t.css( "opacity", o.opacity );
10770 },
10771 stop: function( event, ui, instance ) {
10772 var o = instance.options;
10773 if ( o._opacity ) {
10774 $( ui.helper ).css( "opacity", o._opacity );
10775 }
10776 }
10777 } );
10778
10779 $.ui.plugin.add( "draggable", "scroll", {
10780 start: function( event, ui, i ) {
10781 if ( !i.scrollParentNotHidden ) {
10782 i.scrollParentNotHidden = i.helper.scrollParent( false );
10783 }
10784
10785 if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
10786 i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
10787 i.overflowOffset = i.scrollParentNotHidden.offset();
10788 }
10789 },
10790 drag: function( event, ui, i ) {
10791
10792 var o = i.options,
10793 scrolled = false,
10794 scrollParent = i.scrollParentNotHidden[ 0 ],
10795 document = i.document[ 0 ];
10796
10797 if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
10798 if ( !o.axis || o.axis !== "x" ) {
10799 if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
10800 o.scrollSensitivity ) {
10801 scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
10802 } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
10803 scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
10804 }
10805 }
10806
10807 if ( !o.axis || o.axis !== "y" ) {
10808 if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
10809 o.scrollSensitivity ) {
10810 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
10811 } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
10812 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
10813 }
10814 }
10815
10816 } else {
10817
10818 if ( !o.axis || o.axis !== "x" ) {
10819 if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
10820 scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
10821 } else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
10822 o.scrollSensitivity ) {
10823 scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
10824 }
10825 }
10826
10827 if ( !o.axis || o.axis !== "y" ) {
10828 if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
10829 scrolled = $( document ).scrollLeft(
10830 $( document ).scrollLeft() - o.scrollSpeed
10831 );
10832 } else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
10833 o.scrollSensitivity ) {
10834 scrolled = $( document ).scrollLeft(
10835 $( document ).scrollLeft() + o.scrollSpeed
10836 );
10837 }
10838 }
10839
10840 }
10841
10842 if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
10843 $.ui.ddmanager.prepareOffsets( i, event );
10844 }
10845
10846 }
10847 } );
10848
10849 $.ui.plugin.add( "draggable", "snap", {
10850 start: function( event, ui, i ) {
10851
10852 var o = i.options;
10853
10854 i.snapElements = [];
10855
10856 $( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
10857 .each( function() {
10858 var $t = $( this ),
10859 $o = $t.offset();
10860 if ( this !== i.element[ 0 ] ) {
10861 i.snapElements.push( {
10862 item: this,
10863 width: $t.outerWidth(), height: $t.outerHeight(),
10864 top: $o.top, left: $o.left
10865 } );
10866 }
10867 } );
10868
10869 },
10870 drag: function( event, ui, inst ) {
10871
10872 var ts, bs, ls, rs, l, r, t, b, i, first,
10873 o = inst.options,
10874 d = o.snapTolerance,
10875 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
10876 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
10877
10878 for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
10879
10880 l = inst.snapElements[ i ].left - inst.margins.left;
10881 r = l + inst.snapElements[ i ].width;
10882 t = inst.snapElements[ i ].top - inst.margins.top;
10883 b = t + inst.snapElements[ i ].height;
10884
10885 if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
10886 !$.contains( inst.snapElements[ i ].item.ownerDocument,
10887 inst.snapElements[ i ].item ) ) {
10888 if ( inst.snapElements[ i ].snapping ) {
10889 if ( inst.options.snap.release ) {
10890 inst.options.snap.release.call(
10891 inst.element,
10892 event,
10893 $.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
10894 );
10895 }
10896 }
10897 inst.snapElements[ i ].snapping = false;
10898 continue;
10899 }
10900
10901 if ( o.snapMode !== "inner" ) {
10902 ts = Math.abs( t - y2 ) <= d;
10903 bs = Math.abs( b - y1 ) <= d;
10904 ls = Math.abs( l - x2 ) <= d;
10905 rs = Math.abs( r - x1 ) <= d;
10906 if ( ts ) {
10907 ui.position.top = inst._convertPositionTo( "relative", {
10908 top: t - inst.helperProportions.height,
10909 left: 0
10910 } ).top;
10911 }
10912 if ( bs ) {
10913 ui.position.top = inst._convertPositionTo( "relative", {
10914 top: b,
10915 left: 0
10916 } ).top;
10917 }
10918 if ( ls ) {
10919 ui.position.left = inst._convertPositionTo( "relative", {
10920 top: 0,
10921 left: l - inst.helperProportions.width
10922 } ).left;
10923 }
10924 if ( rs ) {
10925 ui.position.left = inst._convertPositionTo( "relative", {
10926 top: 0,
10927 left: r
10928 } ).left;
10929 }
10930 }
10931
10932 first = ( ts || bs || ls || rs );
10933
10934 if ( o.snapMode !== "outer" ) {
10935 ts = Math.abs( t - y1 ) <= d;
10936 bs = Math.abs( b - y2 ) <= d;
10937 ls = Math.abs( l - x1 ) <= d;
10938 rs = Math.abs( r - x2 ) <= d;
10939 if ( ts ) {
10940 ui.position.top = inst._convertPositionTo( "relative", {
10941 top: t,
10942 left: 0
10943 } ).top;
10944 }
10945 if ( bs ) {
10946 ui.position.top = inst._convertPositionTo( "relative", {
10947 top: b - inst.helperProportions.height,
10948 left: 0
10949 } ).top;
10950 }
10951 if ( ls ) {
10952 ui.position.left = inst._convertPositionTo( "relative", {
10953 top: 0,
10954 left: l
10955 } ).left;
10956 }
10957 if ( rs ) {
10958 ui.position.left = inst._convertPositionTo( "relative", {
10959 top: 0,
10960 left: r - inst.helperProportions.width
10961 } ).left;
10962 }
10963 }
10964
10965 if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
10966 if ( inst.options.snap.snap ) {
10967 inst.options.snap.snap.call(
10968 inst.element,
10969 event,
10970 $.extend( inst._uiHash(), {
10971 snapItem: inst.snapElements[ i ].item
10972 } ) );
10973 }
10974 }
10975 inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
10976
10977 }
10978
10979 }
10980 } );
10981
10982 $.ui.plugin.add( "draggable", "stack", {
10983 start: function( event, ui, instance ) {
10984 var min,
10985 o = instance.options,
10986 group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
10987 return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
10988 ( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
10989 } );
10990
10991 if ( !group.length ) {
10992 return;
10993 }
10994
10995 min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
10996 $( group ).each( function( i ) {
10997 $( this ).css( "zIndex", min + i );
10998 } );
10999 this.css( "zIndex", ( min + group.length ) );
11000 }
11001 } );
11002
11003 $.ui.plugin.add( "draggable", "zIndex", {
11004 start: function( event, ui, instance ) {
11005 var t = $( ui.helper ),
11006 o = instance.options;
11007
11008 if ( t.css( "zIndex" ) ) {
11009 o._zIndex = t.css( "zIndex" );
11010 }
11011 t.css( "zIndex", o.zIndex );
11012 },
11013 stop: function( event, ui, instance ) {
11014 var o = instance.options;
11015
11016 if ( o._zIndex ) {
11017 $( ui.helper ).css( "zIndex", o._zIndex );
11018 }
11019 }
11020 } );
11021
11022 var widgetsDraggable = $.ui.draggable;
11023
11024
11025 /*!
11026 * jQuery UI Resizable 1.13.2
11027 * http://jqueryui.com
11028 *
11029 * Copyright jQuery Foundation and other contributors
11030 * Released under the MIT license.
11031 * http://jquery.org/license
11032 */
11033
11034 //>>label: Resizable
11035 //>>group: Interactions
11036 //>>description: Enables resize functionality for any element.
11037 //>>docs: http://api.jqueryui.com/resizable/
11038 //>>demos: http://jqueryui.com/resizable/
11039 //>>css.structure: ../../themes/base/core.css
11040 //>>css.structure: ../../themes/base/resizable.css
11041 //>>css.theme: ../../themes/base/theme.css
11042
11043
11044 $.widget( "ui.resizable", $.ui.mouse, {
11045 version: "1.13.2",
11046 widgetEventPrefix: "resize",
11047 options: {
11048 alsoResize: false,
11049 animate: false,
11050 animateDuration: "slow",
11051 animateEasing: "swing",
11052 aspectRatio: false,
11053 autoHide: false,
11054 classes: {
11055 "ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se"
11056 },
11057 containment: false,
11058 ghost: false,
11059 grid: false,
11060 handles: "e,s,se",
11061 helper: false,
11062 maxHeight: null,
11063 maxWidth: null,
11064 minHeight: 10,
11065 minWidth: 10,
11066
11067 // See #7960
11068 zIndex: 90,
11069
11070 // Callbacks
11071 resize: null,
11072 start: null,
11073 stop: null
11074 },
11075
11076 _num: function( value ) {
11077 return parseFloat( value ) || 0;
11078 },
11079
11080 _isNumber: function( value ) {
11081 return !isNaN( parseFloat( value ) );
11082 },
11083
11084 _hasScroll: function( el, a ) {
11085
11086 if ( $( el ).css( "overflow" ) === "hidden" ) {
11087 return false;
11088 }
11089
11090 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
11091 has = false;
11092
11093 if ( el[ scroll ] > 0 ) {
11094 return true;
11095 }
11096
11097 // TODO: determine which cases actually cause this to happen
11098 // if the element doesn't have the scroll set, see if it's possible to
11099 // set the scroll
11100 try {
11101 el[ scroll ] = 1;
11102 has = ( el[ scroll ] > 0 );
11103 el[ scroll ] = 0;
11104 } catch ( e ) {
11105
11106 // `el` might be a string, then setting `scroll` will throw
11107 // an error in strict mode; ignore it.
11108 }
11109 return has;
11110 },
11111
11112 _create: function() {
11113
11114 var margins,
11115 o = this.options,
11116 that = this;
11117 this._addClass( "ui-resizable" );
11118
11119 $.extend( this, {
11120 _aspectRatio: !!( o.aspectRatio ),
11121 aspectRatio: o.aspectRatio,
11122 originalElement: this.element,
11123 _proportionallyResizeElements: [],
11124 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
11125 } );
11126
11127 // Wrap the element if it cannot hold child nodes
11128 if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) {
11129
11130 this.element.wrap(
11131 $( "<div class='ui-wrapper'></div>" ).css( {
11132 overflow: "hidden",
11133 position: this.element.css( "position" ),
11134 width: this.element.outerWidth(),
11135 height: this.element.outerHeight(),
11136 top: this.element.css( "top" ),
11137 left: this.element.css( "left" )
11138 } )
11139 );
11140
11141 this.element = this.element.parent().data(
11142 "ui-resizable", this.element.resizable( "instance" )
11143 );
11144
11145 this.elementIsWrapper = true;
11146
11147 margins = {
11148 marginTop: this.originalElement.css( "marginTop" ),
11149 marginRight: this.originalElement.css( "marginRight" ),
11150 marginBottom: this.originalElement.css( "marginBottom" ),
11151 marginLeft: this.originalElement.css( "marginLeft" )
11152 };
11153
11154 this.element.css( margins );
11155 this.originalElement.css( "margin", 0 );
11156
11157 // support: Safari
11158 // Prevent Safari textarea resize
11159 this.originalResizeStyle = this.originalElement.css( "resize" );
11160 this.originalElement.css( "resize", "none" );
11161
11162 this._proportionallyResizeElements.push( this.originalElement.css( {
11163 position: "static",
11164 zoom: 1,
11165 display: "block"
11166 } ) );
11167
11168 // Support: IE9
11169 // avoid IE jump (hard set the margin)
11170 this.originalElement.css( margins );
11171
11172 this._proportionallyResize();
11173 }
11174
11175 this._setupHandles();
11176
11177 if ( o.autoHide ) {
11178 $( this.element )
11179 .on( "mouseenter", function() {
11180 if ( o.disabled ) {
11181 return;
11182 }
11183 that._removeClass( "ui-resizable-autohide" );
11184 that._handles.show();
11185 } )
11186 .on( "mouseleave", function() {
11187 if ( o.disabled ) {
11188 return;
11189 }
11190 if ( !that.resizing ) {
11191 that._addClass( "ui-resizable-autohide" );
11192 that._handles.hide();
11193 }
11194 } );
11195 }
11196
11197 this._mouseInit();
11198 },
11199
11200 _destroy: function() {
11201
11202 this._mouseDestroy();
11203 this._addedHandles.remove();
11204
11205 var wrapper,
11206 _destroy = function( exp ) {
11207 $( exp )
11208 .removeData( "resizable" )
11209 .removeData( "ui-resizable" )
11210 .off( ".resizable" );
11211 };
11212
11213 // TODO: Unwrap at same DOM position
11214 if ( this.elementIsWrapper ) {
11215 _destroy( this.element );
11216 wrapper = this.element;
11217 this.originalElement.css( {
11218 position: wrapper.css( "position" ),
11219 width: wrapper.outerWidth(),
11220 height: wrapper.outerHeight(),
11221 top: wrapper.css( "top" ),
11222 left: wrapper.css( "left" )
11223 } ).insertAfter( wrapper );
11224 wrapper.remove();
11225 }
11226
11227 this.originalElement.css( "resize", this.originalResizeStyle );
11228 _destroy( this.originalElement );
11229
11230 return this;
11231 },
11232
11233 _setOption: function( key, value ) {
11234 this._super( key, value );
11235
11236 switch ( key ) {
11237 case "handles":
11238 this._removeHandles();
11239 this._setupHandles();
11240 break;
11241 case "aspectRatio":
11242 this._aspectRatio = !!value;
11243 break;
11244 default:
11245 break;
11246 }
11247 },
11248
11249 _setupHandles: function() {
11250 var o = this.options, handle, i, n, hname, axis, that = this;
11251 this.handles = o.handles ||
11252 ( !$( ".ui-resizable-handle", this.element ).length ?
11253 "e,s,se" : {
11254 n: ".ui-resizable-n",
11255 e: ".ui-resizable-e",
11256 s: ".ui-resizable-s",
11257 w: ".ui-resizable-w",
11258 se: ".ui-resizable-se",
11259 sw: ".ui-resizable-sw",
11260 ne: ".ui-resizable-ne",
11261 nw: ".ui-resizable-nw"
11262 } );
11263
11264 this._handles = $();
11265 this._addedHandles = $();
11266 if ( this.handles.constructor === String ) {
11267
11268 if ( this.handles === "all" ) {
11269 this.handles = "n,e,s,w,se,sw,ne,nw";
11270 }
11271
11272 n = this.handles.split( "," );
11273 this.handles = {};
11274
11275 for ( i = 0; i < n.length; i++ ) {
11276
11277 handle = String.prototype.trim.call( n[ i ] );
11278 hname = "ui-resizable-" + handle;
11279 axis = $( "<div>" );
11280 this._addClass( axis, "ui-resizable-handle " + hname );
11281
11282 axis.css( { zIndex: o.zIndex } );
11283
11284 this.handles[ handle ] = ".ui-resizable-" + handle;
11285 if ( !this.element.children( this.handles[ handle ] ).length ) {
11286 this.element.append( axis );
11287 this._addedHandles = this._addedHandles.add( axis );
11288 }
11289 }
11290
11291 }
11292
11293 this._renderAxis = function( target ) {
11294
11295 var i, axis, padPos, padWrapper;
11296
11297 target = target || this.element;
11298
11299 for ( i in this.handles ) {
11300
11301 if ( this.handles[ i ].constructor === String ) {
11302 this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show();
11303 } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
11304 this.handles[ i ] = $( this.handles[ i ] );
11305 this._on( this.handles[ i ], { "mousedown": that._mouseDown } );
11306 }
11307
11308 if ( this.elementIsWrapper &&
11309 this.originalElement[ 0 ]
11310 .nodeName
11311 .match( /^(textarea|input|select|button)$/i ) ) {
11312 axis = $( this.handles[ i ], this.element );
11313
11314 padWrapper = /sw|ne|nw|se|n|s/.test( i ) ?
11315 axis.outerHeight() :
11316 axis.outerWidth();
11317
11318 padPos = [ "padding",
11319 /ne|nw|n/.test( i ) ? "Top" :
11320 /se|sw|s/.test( i ) ? "Bottom" :
11321 /^e$/.test( i ) ? "Right" : "Left" ].join( "" );
11322
11323 target.css( padPos, padWrapper );
11324
11325 this._proportionallyResize();
11326 }
11327
11328 this._handles = this._handles.add( this.handles[ i ] );
11329 }
11330 };
11331
11332 // TODO: make renderAxis a prototype function
11333 this._renderAxis( this.element );
11334
11335 this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
11336 this._handles.disableSelection();
11337
11338 this._handles.on( "mouseover", function() {
11339 if ( !that.resizing ) {
11340 if ( this.className ) {
11341 axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i );
11342 }
11343 that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se";
11344 }
11345 } );
11346
11347 if ( o.autoHide ) {
11348 this._handles.hide();
11349 this._addClass( "ui-resizable-autohide" );
11350 }
11351 },
11352
11353 _removeHandles: function() {
11354 this._addedHandles.remove();
11355 },
11356
11357 _mouseCapture: function( event ) {
11358 var i, handle,
11359 capture = false;
11360
11361 for ( i in this.handles ) {
11362 handle = $( this.handles[ i ] )[ 0 ];
11363 if ( handle === event.target || $.contains( handle, event.target ) ) {
11364 capture = true;
11365 }
11366 }
11367
11368 return !this.options.disabled && capture;
11369 },
11370
11371 _mouseStart: function( event ) {
11372
11373 var curleft, curtop, cursor,
11374 o = this.options,
11375 el = this.element;
11376
11377 this.resizing = true;
11378
11379 this._renderProxy();
11380
11381 curleft = this._num( this.helper.css( "left" ) );
11382 curtop = this._num( this.helper.css( "top" ) );
11383
11384 if ( o.containment ) {
11385 curleft += $( o.containment ).scrollLeft() || 0;
11386 curtop += $( o.containment ).scrollTop() || 0;
11387 }
11388
11389 this.offset = this.helper.offset();
11390 this.position = { left: curleft, top: curtop };
11391
11392 this.size = this._helper ? {
11393 width: this.helper.width(),
11394 height: this.helper.height()
11395 } : {
11396 width: el.width(),
11397 height: el.height()
11398 };
11399
11400 this.originalSize = this._helper ? {
11401 width: el.outerWidth(),
11402 height: el.outerHeight()
11403 } : {
11404 width: el.width(),
11405 height: el.height()
11406 };
11407
11408 this.sizeDiff = {
11409 width: el.outerWidth() - el.width(),
11410 height: el.outerHeight() - el.height()
11411 };
11412
11413 this.originalPosition = { left: curleft, top: curtop };
11414 this.originalMousePosition = { left: event.pageX, top: event.pageY };
11415
11416 this.aspectRatio = ( typeof o.aspectRatio === "number" ) ?
11417 o.aspectRatio :
11418 ( ( this.originalSize.width / this.originalSize.height ) || 1 );
11419
11420 cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" );
11421 $( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor );
11422
11423 this._addClass( "ui-resizable-resizing" );
11424 this._propagate( "start", event );
11425 return true;
11426 },
11427
11428 _mouseDrag: function( event ) {
11429
11430 var data, props,
11431 smp = this.originalMousePosition,
11432 a = this.axis,
11433 dx = ( event.pageX - smp.left ) || 0,
11434 dy = ( event.pageY - smp.top ) || 0,
11435 trigger = this._change[ a ];
11436
11437 this._updatePrevProperties();
11438
11439 if ( !trigger ) {
11440 return false;
11441 }
11442
11443 data = trigger.apply( this, [ event, dx, dy ] );
11444
11445 this._updateVirtualBoundaries( event.shiftKey );
11446 if ( this._aspectRatio || event.shiftKey ) {
11447 data = this._updateRatio( data, event );
11448 }
11449
11450 data = this._respectSize( data, event );
11451
11452 this._updateCache( data );
11453
11454 this._propagate( "resize", event );
11455
11456 props = this._applyChanges();
11457
11458 if ( !this._helper && this._proportionallyResizeElements.length ) {
11459 this._proportionallyResize();
11460 }
11461
11462 if ( !$.isEmptyObject( props ) ) {
11463 this._updatePrevProperties();
11464 this._trigger( "resize", event, this.ui() );
11465 this._applyChanges();
11466 }
11467
11468 return false;
11469 },
11470
11471 _mouseStop: function( event ) {
11472
11473 this.resizing = false;
11474 var pr, ista, soffseth, soffsetw, s, left, top,
11475 o = this.options, that = this;
11476
11477 if ( this._helper ) {
11478
11479 pr = this._proportionallyResizeElements;
11480 ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName );
11481 soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height;
11482 soffsetw = ista ? 0 : that.sizeDiff.width;
11483
11484 s = {
11485 width: ( that.helper.width() - soffsetw ),
11486 height: ( that.helper.height() - soffseth )
11487 };
11488 left = ( parseFloat( that.element.css( "left" ) ) +
11489 ( that.position.left - that.originalPosition.left ) ) || null;
11490 top = ( parseFloat( that.element.css( "top" ) ) +
11491 ( that.position.top - that.originalPosition.top ) ) || null;
11492
11493 if ( !o.animate ) {
11494 this.element.css( $.extend( s, { top: top, left: left } ) );
11495 }
11496
11497 that.helper.height( that.size.height );
11498 that.helper.width( that.size.width );
11499
11500 if ( this._helper && !o.animate ) {
11501 this._proportionallyResize();
11502 }
11503 }
11504
11505 $( "body" ).css( "cursor", "auto" );
11506
11507 this._removeClass( "ui-resizable-resizing" );
11508
11509 this._propagate( "stop", event );
11510
11511 if ( this._helper ) {
11512 this.helper.remove();
11513 }
11514
11515 return false;
11516
11517 },
11518
11519 _updatePrevProperties: function() {
11520 this.prevPosition = {
11521 top: this.position.top,
11522 left: this.position.left
11523 };
11524 this.prevSize = {
11525 width: this.size.width,
11526 height: this.size.height
11527 };
11528 },
11529
11530 _applyChanges: function() {
11531 var props = {};
11532
11533 if ( this.position.top !== this.prevPosition.top ) {
11534 props.top = this.position.top + "px";
11535 }
11536 if ( this.position.left !== this.prevPosition.left ) {
11537 props.left = this.position.left + "px";
11538 }
11539 if ( this.size.width !== this.prevSize.width ) {
11540 props.width = this.size.width + "px";
11541 }
11542 if ( this.size.height !== this.prevSize.height ) {
11543 props.height = this.size.height + "px";
11544 }
11545
11546 this.helper.css( props );
11547
11548 return props;
11549 },
11550
11551 _updateVirtualBoundaries: function( forceAspectRatio ) {
11552 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
11553 o = this.options;
11554
11555 b = {
11556 minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0,
11557 maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity,
11558 minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0,
11559 maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity
11560 };
11561
11562 if ( this._aspectRatio || forceAspectRatio ) {
11563 pMinWidth = b.minHeight * this.aspectRatio;
11564 pMinHeight = b.minWidth / this.aspectRatio;
11565 pMaxWidth = b.maxHeight * this.aspectRatio;
11566 pMaxHeight = b.maxWidth / this.aspectRatio;
11567
11568 if ( pMinWidth > b.minWidth ) {
11569 b.minWidth = pMinWidth;
11570 }
11571 if ( pMinHeight > b.minHeight ) {
11572 b.minHeight = pMinHeight;
11573 }
11574 if ( pMaxWidth < b.maxWidth ) {
11575 b.maxWidth = pMaxWidth;
11576 }
11577 if ( pMaxHeight < b.maxHeight ) {
11578 b.maxHeight = pMaxHeight;
11579 }
11580 }
11581 this._vBoundaries = b;
11582 },
11583
11584 _updateCache: function( data ) {
11585 this.offset = this.helper.offset();
11586 if ( this._isNumber( data.left ) ) {
11587 this.position.left = data.left;
11588 }
11589 if ( this._isNumber( data.top ) ) {
11590 this.position.top = data.top;
11591 }
11592 if ( this._isNumber( data.height ) ) {
11593 this.size.height = data.height;
11594 }
11595 if ( this._isNumber( data.width ) ) {
11596 this.size.width = data.width;
11597 }
11598 },
11599
11600 _updateRatio: function( data ) {
11601
11602 var cpos = this.position,
11603 csize = this.size,
11604 a = this.axis;
11605
11606 if ( this._isNumber( data.height ) ) {
11607 data.width = ( data.height * this.aspectRatio );
11608 } else if ( this._isNumber( data.width ) ) {
11609 data.height = ( data.width / this.aspectRatio );
11610 }
11611
11612 if ( a === "sw" ) {
11613 data.left = cpos.left + ( csize.width - data.width );
11614 data.top = null;
11615 }
11616 if ( a === "nw" ) {
11617 data.top = cpos.top + ( csize.height - data.height );
11618 data.left = cpos.left + ( csize.width - data.width );
11619 }
11620
11621 return data;
11622 },
11623
11624 _respectSize: function( data ) {
11625
11626 var o = this._vBoundaries,
11627 a = this.axis,
11628 ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ),
11629 ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ),
11630 isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ),
11631 isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ),
11632 dw = this.originalPosition.left + this.originalSize.width,
11633 dh = this.originalPosition.top + this.originalSize.height,
11634 cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a );
11635 if ( isminw ) {
11636 data.width = o.minWidth;
11637 }
11638 if ( isminh ) {
11639 data.height = o.minHeight;
11640 }
11641 if ( ismaxw ) {
11642 data.width = o.maxWidth;
11643 }
11644 if ( ismaxh ) {
11645 data.height = o.maxHeight;
11646 }
11647
11648 if ( isminw && cw ) {
11649 data.left = dw - o.minWidth;
11650 }
11651 if ( ismaxw && cw ) {
11652 data.left = dw - o.maxWidth;
11653 }
11654 if ( isminh && ch ) {
11655 data.top = dh - o.minHeight;
11656 }
11657 if ( ismaxh && ch ) {
11658 data.top = dh - o.maxHeight;
11659 }
11660
11661 // Fixing jump error on top/left - bug #2330
11662 if ( !data.width && !data.height && !data.left && data.top ) {
11663 data.top = null;
11664 } else if ( !data.width && !data.height && !data.top && data.left ) {
11665 data.left = null;
11666 }
11667
11668 return data;
11669 },
11670
11671 _getPaddingPlusBorderDimensions: function( element ) {
11672 var i = 0,
11673 widths = [],
11674 borders = [
11675 element.css( "borderTopWidth" ),
11676 element.css( "borderRightWidth" ),
11677 element.css( "borderBottomWidth" ),
11678 element.css( "borderLeftWidth" )
11679 ],
11680 paddings = [
11681 element.css( "paddingTop" ),
11682 element.css( "paddingRight" ),
11683 element.css( "paddingBottom" ),
11684 element.css( "paddingLeft" )
11685 ];
11686
11687 for ( ; i < 4; i++ ) {
11688 widths[ i ] = ( parseFloat( borders[ i ] ) || 0 );
11689 widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 );
11690 }
11691
11692 return {
11693 height: widths[ 0 ] + widths[ 2 ],
11694 width: widths[ 1 ] + widths[ 3 ]
11695 };
11696 },
11697
11698 _proportionallyResize: function() {
11699
11700 if ( !this._proportionallyResizeElements.length ) {
11701 return;
11702 }
11703
11704 var prel,
11705 i = 0,
11706 element = this.helper || this.element;
11707
11708 for ( ; i < this._proportionallyResizeElements.length; i++ ) {
11709
11710 prel = this._proportionallyResizeElements[ i ];
11711
11712 // TODO: Seems like a bug to cache this.outerDimensions
11713 // considering that we are in a loop.
11714 if ( !this.outerDimensions ) {
11715 this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
11716 }
11717
11718 prel.css( {
11719 height: ( element.height() - this.outerDimensions.height ) || 0,
11720 width: ( element.width() - this.outerDimensions.width ) || 0
11721 } );
11722
11723 }
11724
11725 },
11726
11727 _renderProxy: function() {
11728
11729 var el = this.element, o = this.options;
11730 this.elementOffset = el.offset();
11731
11732 if ( this._helper ) {
11733
11734 this.helper = this.helper || $( "<div></div>" ).css( { overflow: "hidden" } );
11735
11736 this._addClass( this.helper, this._helper );
11737 this.helper.css( {
11738 width: this.element.outerWidth(),
11739 height: this.element.outerHeight(),
11740 position: "absolute",
11741 left: this.elementOffset.left + "px",
11742 top: this.elementOffset.top + "px",
11743 zIndex: ++o.zIndex //TODO: Don't modify option
11744 } );
11745
11746 this.helper
11747 .appendTo( "body" )
11748 .disableSelection();
11749
11750 } else {
11751 this.helper = this.element;
11752 }
11753
11754 },
11755
11756 _change: {
11757 e: function( event, dx ) {
11758 return { width: this.originalSize.width + dx };
11759 },
11760 w: function( event, dx ) {
11761 var cs = this.originalSize, sp = this.originalPosition;
11762 return { left: sp.left + dx, width: cs.width - dx };
11763 },
11764 n: function( event, dx, dy ) {
11765 var cs = this.originalSize, sp = this.originalPosition;
11766 return { top: sp.top + dy, height: cs.height - dy };
11767 },
11768 s: function( event, dx, dy ) {
11769 return { height: this.originalSize.height + dy };
11770 },
11771 se: function( event, dx, dy ) {
11772 return $.extend( this._change.s.apply( this, arguments ),
11773 this._change.e.apply( this, [ event, dx, dy ] ) );
11774 },
11775 sw: function( event, dx, dy ) {
11776 return $.extend( this._change.s.apply( this, arguments ),
11777 this._change.w.apply( this, [ event, dx, dy ] ) );
11778 },
11779 ne: function( event, dx, dy ) {
11780 return $.extend( this._change.n.apply( this, arguments ),
11781 this._change.e.apply( this, [ event, dx, dy ] ) );
11782 },
11783 nw: function( event, dx, dy ) {
11784 return $.extend( this._change.n.apply( this, arguments ),
11785 this._change.w.apply( this, [ event, dx, dy ] ) );
11786 }
11787 },
11788
11789 _propagate: function( n, event ) {
11790 $.ui.plugin.call( this, n, [ event, this.ui() ] );
11791 if ( n !== "resize" ) {
11792 this._trigger( n, event, this.ui() );
11793 }
11794 },
11795
11796 plugins: {},
11797
11798 ui: function() {
11799 return {
11800 originalElement: this.originalElement,
11801 element: this.element,
11802 helper: this.helper,
11803 position: this.position,
11804 size: this.size,
11805 originalSize: this.originalSize,
11806 originalPosition: this.originalPosition
11807 };
11808 }
11809
11810 } );
11811
11812 /*
11813 * Resizable Extensions
11814 */
11815
11816 $.ui.plugin.add( "resizable", "animate", {
11817
11818 stop: function( event ) {
11819 var that = $( this ).resizable( "instance" ),
11820 o = that.options,
11821 pr = that._proportionallyResizeElements,
11822 ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ),
11823 soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height,
11824 soffsetw = ista ? 0 : that.sizeDiff.width,
11825 style = {
11826 width: ( that.size.width - soffsetw ),
11827 height: ( that.size.height - soffseth )
11828 },
11829 left = ( parseFloat( that.element.css( "left" ) ) +
11830 ( that.position.left - that.originalPosition.left ) ) || null,
11831 top = ( parseFloat( that.element.css( "top" ) ) +
11832 ( that.position.top - that.originalPosition.top ) ) || null;
11833
11834 that.element.animate(
11835 $.extend( style, top && left ? { top: top, left: left } : {} ), {
11836 duration: o.animateDuration,
11837 easing: o.animateEasing,
11838 step: function() {
11839
11840 var data = {
11841 width: parseFloat( that.element.css( "width" ) ),
11842 height: parseFloat( that.element.css( "height" ) ),
11843 top: parseFloat( that.element.css( "top" ) ),
11844 left: parseFloat( that.element.css( "left" ) )
11845 };
11846
11847 if ( pr && pr.length ) {
11848 $( pr[ 0 ] ).css( { width: data.width, height: data.height } );
11849 }
11850
11851 // Propagating resize, and updating values for each animation step
11852 that._updateCache( data );
11853 that._propagate( "resize", event );
11854
11855 }
11856 }
11857 );
11858 }
11859
11860 } );
11861
11862 $.ui.plugin.add( "resizable", "containment", {
11863
11864 start: function() {
11865 var element, p, co, ch, cw, width, height,
11866 that = $( this ).resizable( "instance" ),
11867 o = that.options,
11868 el = that.element,
11869 oc = o.containment,
11870 ce = ( oc instanceof $ ) ?
11871 oc.get( 0 ) :
11872 ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
11873
11874 if ( !ce ) {
11875 return;
11876 }
11877
11878 that.containerElement = $( ce );
11879
11880 if ( /document/.test( oc ) || oc === document ) {
11881 that.containerOffset = {
11882 left: 0,
11883 top: 0
11884 };
11885 that.containerPosition = {
11886 left: 0,
11887 top: 0
11888 };
11889
11890 that.parentData = {
11891 element: $( document ),
11892 left: 0,
11893 top: 0,
11894 width: $( document ).width(),
11895 height: $( document ).height() || document.body.parentNode.scrollHeight
11896 };
11897 } else {
11898 element = $( ce );
11899 p = [];
11900 $( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) {
11901 p[ i ] = that._num( element.css( "padding" + name ) );
11902 } );
11903
11904 that.containerOffset = element.offset();
11905 that.containerPosition = element.position();
11906 that.containerSize = {
11907 height: ( element.innerHeight() - p[ 3 ] ),
11908 width: ( element.innerWidth() - p[ 1 ] )
11909 };
11910
11911 co = that.containerOffset;
11912 ch = that.containerSize.height;
11913 cw = that.containerSize.width;
11914 width = ( that._hasScroll( ce, "left" ) ? ce.scrollWidth : cw );
11915 height = ( that._hasScroll( ce ) ? ce.scrollHeight : ch );
11916
11917 that.parentData = {
11918 element: ce,
11919 left: co.left,
11920 top: co.top,
11921 width: width,
11922 height: height
11923 };
11924 }
11925 },
11926
11927 resize: function( event ) {
11928 var woset, hoset, isParent, isOffsetRelative,
11929 that = $( this ).resizable( "instance" ),
11930 o = that.options,
11931 co = that.containerOffset,
11932 cp = that.position,
11933 pRatio = that._aspectRatio || event.shiftKey,
11934 cop = {
11935 top: 0,
11936 left: 0
11937 },
11938 ce = that.containerElement,
11939 continueResize = true;
11940
11941 if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
11942 cop = co;
11943 }
11944
11945 if ( cp.left < ( that._helper ? co.left : 0 ) ) {
11946 that.size.width = that.size.width +
11947 ( that._helper ?
11948 ( that.position.left - co.left ) :
11949 ( that.position.left - cop.left ) );
11950
11951 if ( pRatio ) {
11952 that.size.height = that.size.width / that.aspectRatio;
11953 continueResize = false;
11954 }
11955 that.position.left = o.helper ? co.left : 0;
11956 }
11957
11958 if ( cp.top < ( that._helper ? co.top : 0 ) ) {
11959 that.size.height = that.size.height +
11960 ( that._helper ?
11961 ( that.position.top - co.top ) :
11962 that.position.top );
11963
11964 if ( pRatio ) {
11965 that.size.width = that.size.height * that.aspectRatio;
11966 continueResize = false;
11967 }
11968 that.position.top = that._helper ? co.top : 0;
11969 }
11970
11971 isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
11972 isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
11973
11974 if ( isParent && isOffsetRelative ) {
11975 that.offset.left = that.parentData.left + that.position.left;
11976 that.offset.top = that.parentData.top + that.position.top;
11977 } else {
11978 that.offset.left = that.element.offset().left;
11979 that.offset.top = that.element.offset().top;
11980 }
11981
11982 woset = Math.abs( that.sizeDiff.width +
11983 ( that._helper ?
11984 that.offset.left - cop.left :
11985 ( that.offset.left - co.left ) ) );
11986
11987 hoset = Math.abs( that.sizeDiff.height +
11988 ( that._helper ?
11989 that.offset.top - cop.top :
11990 ( that.offset.top - co.top ) ) );
11991
11992 if ( woset + that.size.width >= that.parentData.width ) {
11993 that.size.width = that.parentData.width - woset;
11994 if ( pRatio ) {
11995 that.size.height = that.size.width / that.aspectRatio;
11996 continueResize = false;
11997 }
11998 }
11999
12000 if ( hoset + that.size.height >= that.parentData.height ) {
12001 that.size.height = that.parentData.height - hoset;
12002 if ( pRatio ) {
12003 that.size.width = that.size.height * that.aspectRatio;
12004 continueResize = false;
12005 }
12006 }
12007
12008 if ( !continueResize ) {
12009 that.position.left = that.prevPosition.left;
12010 that.position.top = that.prevPosition.top;
12011 that.size.width = that.prevSize.width;
12012 that.size.height = that.prevSize.height;
12013 }
12014 },
12015
12016 stop: function() {
12017 var that = $( this ).resizable( "instance" ),
12018 o = that.options,
12019 co = that.containerOffset,
12020 cop = that.containerPosition,
12021 ce = that.containerElement,
12022 helper = $( that.helper ),
12023 ho = helper.offset(),
12024 w = helper.outerWidth() - that.sizeDiff.width,
12025 h = helper.outerHeight() - that.sizeDiff.height;
12026
12027 if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
12028 $( this ).css( {
12029 left: ho.left - cop.left - co.left,
12030 width: w,
12031 height: h
12032 } );
12033 }
12034
12035 if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
12036 $( this ).css( {
12037 left: ho.left - cop.left - co.left,
12038 width: w,
12039 height: h
12040 } );
12041 }
12042 }
12043 } );
12044
12045 $.ui.plugin.add( "resizable", "alsoResize", {
12046
12047 start: function() {
12048 var that = $( this ).resizable( "instance" ),
12049 o = that.options;
12050
12051 $( o.alsoResize ).each( function() {
12052 var el = $( this );
12053 el.data( "ui-resizable-alsoresize", {
12054 width: parseFloat( el.width() ), height: parseFloat( el.height() ),
12055 left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
12056 } );
12057 } );
12058 },
12059
12060 resize: function( event, ui ) {
12061 var that = $( this ).resizable( "instance" ),
12062 o = that.options,
12063 os = that.originalSize,
12064 op = that.originalPosition,
12065 delta = {
12066 height: ( that.size.height - os.height ) || 0,
12067 width: ( that.size.width - os.width ) || 0,
12068 top: ( that.position.top - op.top ) || 0,
12069 left: ( that.position.left - op.left ) || 0
12070 };
12071
12072 $( o.alsoResize ).each( function() {
12073 var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {},
12074 css = el.parents( ui.originalElement[ 0 ] ).length ?
12075 [ "width", "height" ] :
12076 [ "width", "height", "top", "left" ];
12077
12078 $.each( css, function( i, prop ) {
12079 var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 );
12080 if ( sum && sum >= 0 ) {
12081 style[ prop ] = sum || null;
12082 }
12083 } );
12084
12085 el.css( style );
12086 } );
12087 },
12088
12089 stop: function() {
12090 $( this ).removeData( "ui-resizable-alsoresize" );
12091 }
12092 } );
12093
12094 $.ui.plugin.add( "resizable", "ghost", {
12095
12096 start: function() {
12097
12098 var that = $( this ).resizable( "instance" ), cs = that.size;
12099
12100 that.ghost = that.originalElement.clone();
12101 that.ghost.css( {
12102 opacity: 0.25,
12103 display: "block",
12104 position: "relative",
12105 height: cs.height,
12106 width: cs.width,
12107 margin: 0,
12108 left: 0,
12109 top: 0
12110 } );
12111
12112 that._addClass( that.ghost, "ui-resizable-ghost" );
12113
12114 // DEPRECATED
12115 // TODO: remove after 1.12
12116 if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) {
12117
12118 // Ghost option
12119 that.ghost.addClass( this.options.ghost );
12120 }
12121
12122 that.ghost.appendTo( that.helper );
12123
12124 },
12125
12126 resize: function() {
12127 var that = $( this ).resizable( "instance" );
12128 if ( that.ghost ) {
12129 that.ghost.css( {
12130 position: "relative",
12131 height: that.size.height,
12132 width: that.size.width
12133 } );
12134 }
12135 },
12136
12137 stop: function() {
12138 var that = $( this ).resizable( "instance" );
12139 if ( that.ghost && that.helper ) {
12140 that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) );
12141 }
12142 }
12143
12144 } );
12145
12146 $.ui.plugin.add( "resizable", "grid", {
12147
12148 resize: function() {
12149 var outerDimensions,
12150 that = $( this ).resizable( "instance" ),
12151 o = that.options,
12152 cs = that.size,
12153 os = that.originalSize,
12154 op = that.originalPosition,
12155 a = that.axis,
12156 grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
12157 gridX = ( grid[ 0 ] || 1 ),
12158 gridY = ( grid[ 1 ] || 1 ),
12159 ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX,
12160 oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY,
12161 newWidth = os.width + ox,
12162 newHeight = os.height + oy,
12163 isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ),
12164 isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ),
12165 isMinWidth = o.minWidth && ( o.minWidth > newWidth ),
12166 isMinHeight = o.minHeight && ( o.minHeight > newHeight );
12167
12168 o.grid = grid;
12169
12170 if ( isMinWidth ) {
12171 newWidth += gridX;
12172 }
12173 if ( isMinHeight ) {
12174 newHeight += gridY;
12175 }
12176 if ( isMaxWidth ) {
12177 newWidth -= gridX;
12178 }
12179 if ( isMaxHeight ) {
12180 newHeight -= gridY;
12181 }
12182
12183 if ( /^(se|s|e)$/.test( a ) ) {
12184 that.size.width = newWidth;
12185 that.size.height = newHeight;
12186 } else if ( /^(ne)$/.test( a ) ) {
12187 that.size.width = newWidth;
12188 that.size.height = newHeight;
12189 that.position.top = op.top - oy;
12190 } else if ( /^(sw)$/.test( a ) ) {
12191 that.size.width = newWidth;
12192 that.size.height = newHeight;
12193 that.position.left = op.left - ox;
12194 } else {
12195 if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) {
12196 outerDimensions = that._getPaddingPlusBorderDimensions( this );
12197 }
12198
12199 if ( newHeight - gridY > 0 ) {
12200 that.size.height = newHeight;
12201 that.position.top = op.top - oy;
12202 } else {
12203 newHeight = gridY - outerDimensions.height;
12204 that.size.height = newHeight;
12205 that.position.top = op.top + os.height - newHeight;
12206 }
12207 if ( newWidth - gridX > 0 ) {
12208 that.size.width = newWidth;
12209 that.position.left = op.left - ox;
12210 } else {
12211 newWidth = gridX - outerDimensions.width;
12212 that.size.width = newWidth;
12213 that.position.left = op.left + os.width - newWidth;
12214 }
12215 }
12216 }
12217
12218 } );
12219
12220 var widgetsResizable = $.ui.resizable;
12221
12222
12223 /*!
12224 * jQuery UI Dialog 1.13.2
12225 * http://jqueryui.com
12226 *
12227 * Copyright jQuery Foundation and other contributors
12228 * Released under the MIT license.
12229 * http://jquery.org/license
12230 */
12231
12232 //>>label: Dialog
12233 //>>group: Widgets
12234 //>>description: Displays customizable dialog windows.
12235 //>>docs: http://api.jqueryui.com/dialog/
12236 //>>demos: http://jqueryui.com/dialog/
12237 //>>css.structure: ../../themes/base/core.css
12238 //>>css.structure: ../../themes/base/dialog.css
12239 //>>css.theme: ../../themes/base/theme.css
12240
12241
12242 $.widget( "ui.dialog", {
12243 version: "1.13.2",
12244 options: {
12245 appendTo: "body",
12246 autoOpen: true,
12247 buttons: [],
12248 classes: {
12249 "ui-dialog": "ui-corner-all",
12250 "ui-dialog-titlebar": "ui-corner-all"
12251 },
12252 closeOnEscape: true,
12253 closeText: "Close",
12254 draggable: true,
12255 hide: null,
12256 height: "auto",
12257 maxHeight: null,
12258 maxWidth: null,
12259 minHeight: 150,
12260 minWidth: 150,
12261 modal: false,
12262 position: {
12263 my: "center",
12264 at: "center",
12265 of: window,
12266 collision: "fit",
12267
12268 // Ensure the titlebar is always visible
12269 using: function( pos ) {
12270 var topOffset = $( this ).css( pos ).offset().top;
12271 if ( topOffset < 0 ) {
12272 $( this ).css( "top", pos.top - topOffset );
12273 }
12274 }
12275 },
12276 resizable: true,
12277 show: null,
12278 title: null,
12279 width: 300,
12280
12281 // Callbacks
12282 beforeClose: null,
12283 close: null,
12284 drag: null,
12285 dragStart: null,
12286 dragStop: null,
12287 focus: null,
12288 open: null,
12289 resize: null,
12290 resizeStart: null,
12291 resizeStop: null
12292 },
12293
12294 sizeRelatedOptions: {
12295 buttons: true,
12296 height: true,
12297 maxHeight: true,
12298 maxWidth: true,
12299 minHeight: true,
12300 minWidth: true,
12301 width: true
12302 },
12303
12304 resizableRelatedOptions: {
12305 maxHeight: true,
12306 maxWidth: true,
12307 minHeight: true,
12308 minWidth: true
12309 },
12310
12311 _create: function() {
12312 this.originalCss = {
12313 display: this.element[ 0 ].style.display,
12314 width: this.element[ 0 ].style.width,
12315 minHeight: this.element[ 0 ].style.minHeight,
12316 maxHeight: this.element[ 0 ].style.maxHeight,
12317 height: this.element[ 0 ].style.height
12318 };
12319 this.originalPosition = {
12320 parent: this.element.parent(),
12321 index: this.element.parent().children().index( this.element )
12322 };
12323 this.originalTitle = this.element.attr( "title" );
12324 if ( this.options.title == null && this.originalTitle != null ) {
12325 this.options.title = this.originalTitle;
12326 }
12327
12328 // Dialogs can't be disabled
12329 if ( this.options.disabled ) {
12330 this.options.disabled = false;
12331 }
12332
12333 this._createWrapper();
12334
12335 this.element
12336 .show()
12337 .removeAttr( "title" )
12338 .appendTo( this.uiDialog );
12339
12340 this._addClass( "ui-dialog-content", "ui-widget-content" );
12341
12342 this._createTitlebar();
12343 this._createButtonPane();
12344
12345 if ( this.options.draggable && $.fn.draggable ) {
12346 this._makeDraggable();
12347 }
12348 if ( this.options.resizable && $.fn.resizable ) {
12349 this._makeResizable();
12350 }
12351
12352 this._isOpen = false;
12353
12354 this._trackFocus();
12355 },
12356
12357 _init: function() {
12358 if ( this.options.autoOpen ) {
12359 this.open();
12360 }
12361 },
12362
12363 _appendTo: function() {
12364 var element = this.options.appendTo;
12365 if ( element && ( element.jquery || element.nodeType ) ) {
12366 return $( element );
12367 }
12368 return this.document.find( element || "body" ).eq( 0 );
12369 },
12370
12371 _destroy: function() {
12372 var next,
12373 originalPosition = this.originalPosition;
12374
12375 this._untrackInstance();
12376 this._destroyOverlay();
12377
12378 this.element
12379 .removeUniqueId()
12380 .css( this.originalCss )
12381
12382 // Without detaching first, the following becomes really slow
12383 .detach();
12384
12385 this.uiDialog.remove();
12386
12387 if ( this.originalTitle ) {
12388 this.element.attr( "title", this.originalTitle );
12389 }
12390
12391 next = originalPosition.parent.children().eq( originalPosition.index );
12392
12393 // Don't try to place the dialog next to itself (#8613)
12394 if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
12395 next.before( this.element );
12396 } else {
12397 originalPosition.parent.append( this.element );
12398 }
12399 },
12400
12401 widget: function() {
12402 return this.uiDialog;
12403 },
12404
12405 disable: $.noop,
12406 enable: $.noop,
12407
12408 close: function( event ) {
12409 var that = this;
12410
12411 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
12412 return;
12413 }
12414
12415 this._isOpen = false;
12416 this._focusedElement = null;
12417 this._destroyOverlay();
12418 this._untrackInstance();
12419
12420 if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) {
12421
12422 // Hiding a focused element doesn't trigger blur in WebKit
12423 // so in case we have nothing to focus on, explicitly blur the active element
12424 // https://bugs.webkit.org/show_bug.cgi?id=47182
12425 $.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) );
12426 }
12427
12428 this._hide( this.uiDialog, this.options.hide, function() {
12429 that._trigger( "close", event );
12430 } );
12431 },
12432
12433 isOpen: function() {
12434 return this._isOpen;
12435 },
12436
12437 moveToTop: function() {
12438 this._moveToTop();
12439 },
12440
12441 _moveToTop: function( event, silent ) {
12442 var moved = false,
12443 zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() {
12444 return +$( this ).css( "z-index" );
12445 } ).get(),
12446 zIndexMax = Math.max.apply( null, zIndices );
12447
12448 if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
12449 this.uiDialog.css( "z-index", zIndexMax + 1 );
12450 moved = true;
12451 }
12452
12453 if ( moved && !silent ) {
12454 this._trigger( "focus", event );
12455 }
12456 return moved;
12457 },
12458
12459 open: function() {
12460 var that = this;
12461 if ( this._isOpen ) {
12462 if ( this._moveToTop() ) {
12463 this._focusTabbable();
12464 }
12465 return;
12466 }
12467
12468 this._isOpen = true;
12469 this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
12470
12471 this._size();
12472 this._position();
12473 this._createOverlay();
12474 this._moveToTop( null, true );
12475
12476 // Ensure the overlay is moved to the top with the dialog, but only when
12477 // opening. The overlay shouldn't move after the dialog is open so that
12478 // modeless dialogs opened after the modal dialog stack properly.
12479 if ( this.overlay ) {
12480 this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
12481 }
12482
12483 this._show( this.uiDialog, this.options.show, function() {
12484 that._focusTabbable();
12485 that._trigger( "focus" );
12486 } );
12487
12488 // Track the dialog immediately upon opening in case a focus event
12489 // somehow occurs outside of the dialog before an element inside the
12490 // dialog is focused (#10152)
12491 this._makeFocusTarget();
12492
12493 this._trigger( "open" );
12494 },
12495
12496 _focusTabbable: function() {
12497
12498 // Set focus to the first match:
12499 // 1. An element that was focused previously
12500 // 2. First element inside the dialog matching [autofocus]
12501 // 3. Tabbable element inside the content element
12502 // 4. Tabbable element inside the buttonpane
12503 // 5. The close button
12504 // 6. The dialog itself
12505 var hasFocus = this._focusedElement;
12506 if ( !hasFocus ) {
12507 hasFocus = this.element.find( "[autofocus]" );
12508 }
12509 if ( !hasFocus.length ) {
12510 hasFocus = this.element.find( ":tabbable" );
12511 }
12512 if ( !hasFocus.length ) {
12513 hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
12514 }
12515 if ( !hasFocus.length ) {
12516 hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
12517 }
12518 if ( !hasFocus.length ) {
12519 hasFocus = this.uiDialog;
12520 }
12521 hasFocus.eq( 0 ).trigger( "focus" );
12522 },
12523
12524 _restoreTabbableFocus: function() {
12525 var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
12526 isActive = this.uiDialog[ 0 ] === activeElement ||
12527 $.contains( this.uiDialog[ 0 ], activeElement );
12528 if ( !isActive ) {
12529 this._focusTabbable();
12530 }
12531 },
12532
12533 _keepFocus: function( event ) {
12534 event.preventDefault();
12535 this._restoreTabbableFocus();
12536
12537 // support: IE
12538 // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
12539 // so we check again later
12540 this._delay( this._restoreTabbableFocus );
12541 },
12542
12543 _createWrapper: function() {
12544 this.uiDialog = $( "<div>" )
12545 .hide()
12546 .attr( {
12547
12548 // Setting tabIndex makes the div focusable
12549 tabIndex: -1,
12550 role: "dialog"
12551 } )
12552 .appendTo( this._appendTo() );
12553
12554 this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" );
12555 this._on( this.uiDialog, {
12556 keydown: function( event ) {
12557 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
12558 event.keyCode === $.ui.keyCode.ESCAPE ) {
12559 event.preventDefault();
12560 this.close( event );
12561 return;
12562 }
12563
12564 // Prevent tabbing out of dialogs
12565 if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
12566 return;
12567 }
12568 var tabbables = this.uiDialog.find( ":tabbable" ),
12569 first = tabbables.first(),
12570 last = tabbables.last();
12571
12572 if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) &&
12573 !event.shiftKey ) {
12574 this._delay( function() {
12575 first.trigger( "focus" );
12576 } );
12577 event.preventDefault();
12578 } else if ( ( event.target === first[ 0 ] ||
12579 event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) {
12580 this._delay( function() {
12581 last.trigger( "focus" );
12582 } );
12583 event.preventDefault();
12584 }
12585 },
12586 mousedown: function( event ) {
12587 if ( this._moveToTop( event ) ) {
12588 this._focusTabbable();
12589 }
12590 }
12591 } );
12592
12593 // We assume that any existing aria-describedby attribute means
12594 // that the dialog content is marked up properly
12595 // otherwise we brute force the content as the description
12596 if ( !this.element.find( "[aria-describedby]" ).length ) {
12597 this.uiDialog.attr( {
12598 "aria-describedby": this.element.uniqueId().attr( "id" )
12599 } );
12600 }
12601 },
12602
12603 _createTitlebar: function() {
12604 var uiDialogTitle;
12605
12606 this.uiDialogTitlebar = $( "<div>" );
12607 this._addClass( this.uiDialogTitlebar,
12608 "ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" );
12609 this._on( this.uiDialogTitlebar, {
12610 mousedown: function( event ) {
12611
12612 // Don't prevent click on close button (#8838)
12613 // Focusing a dialog that is partially scrolled out of view
12614 // causes the browser to scroll it into view, preventing the click event
12615 if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
12616
12617 // Dialog isn't getting focus when dragging (#8063)
12618 this.uiDialog.trigger( "focus" );
12619 }
12620 }
12621 } );
12622
12623 // Support: IE
12624 // Use type="button" to prevent enter keypresses in textboxes from closing the
12625 // dialog in IE (#9312)
12626 this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
12627 .button( {
12628 label: $( "<a>" ).text( this.options.closeText ).html(),
12629 icon: "ui-icon-closethick",
12630 showLabel: false
12631 } )
12632 .appendTo( this.uiDialogTitlebar );
12633
12634 this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" );
12635 this._on( this.uiDialogTitlebarClose, {
12636 click: function( event ) {
12637 event.preventDefault();
12638 this.close( event );
12639 }
12640 } );
12641
12642 uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar );
12643 this._addClass( uiDialogTitle, "ui-dialog-title" );
12644 this._title( uiDialogTitle );
12645
12646 this.uiDialogTitlebar.prependTo( this.uiDialog );
12647
12648 this.uiDialog.attr( {
12649 "aria-labelledby": uiDialogTitle.attr( "id" )
12650 } );
12651 },
12652
12653 _title: function( title ) {
12654 if ( this.options.title ) {
12655 title.text( this.options.title );
12656 } else {
12657 title.html( "&#160;" );
12658 }
12659 },
12660
12661 _createButtonPane: function() {
12662 this.uiDialogButtonPane = $( "<div>" );
12663 this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane",
12664 "ui-widget-content ui-helper-clearfix" );
12665
12666 this.uiButtonSet = $( "<div>" )
12667 .appendTo( this.uiDialogButtonPane );
12668 this._addClass( this.uiButtonSet, "ui-dialog-buttonset" );
12669
12670 this._createButtons();
12671 },
12672
12673 _createButtons: function() {
12674 var that = this,
12675 buttons = this.options.buttons;
12676
12677 // If we already have a button pane, remove it
12678 this.uiDialogButtonPane.remove();
12679 this.uiButtonSet.empty();
12680
12681 if ( $.isEmptyObject( buttons ) || ( Array.isArray( buttons ) && !buttons.length ) ) {
12682 this._removeClass( this.uiDialog, "ui-dialog-buttons" );
12683 return;
12684 }
12685
12686 $.each( buttons, function( name, props ) {
12687 var click, buttonOptions;
12688 props = typeof props === "function" ?
12689 { click: props, text: name } :
12690 props;
12691
12692 // Default to a non-submitting button
12693 props = $.extend( { type: "button" }, props );
12694
12695 // Change the context for the click callback to be the main element
12696 click = props.click;
12697 buttonOptions = {
12698 icon: props.icon,
12699 iconPosition: props.iconPosition,
12700 showLabel: props.showLabel,
12701
12702 // Deprecated options
12703 icons: props.icons,
12704 text: props.text
12705 };
12706
12707 delete props.click;
12708 delete props.icon;
12709 delete props.iconPosition;
12710 delete props.showLabel;
12711
12712 // Deprecated options
12713 delete props.icons;
12714 if ( typeof props.text === "boolean" ) {
12715 delete props.text;
12716 }
12717
12718 $( "<button></button>", props )
12719 .button( buttonOptions )
12720 .appendTo( that.uiButtonSet )
12721 .on( "click", function() {
12722 click.apply( that.element[ 0 ], arguments );
12723 } );
12724 } );
12725 this._addClass( this.uiDialog, "ui-dialog-buttons" );
12726 this.uiDialogButtonPane.appendTo( this.uiDialog );
12727 },
12728
12729 _makeDraggable: function() {
12730 var that = this,
12731 options = this.options;
12732
12733 function filteredUi( ui ) {
12734 return {
12735 position: ui.position,
12736 offset: ui.offset
12737 };
12738 }
12739
12740 this.uiDialog.draggable( {
12741 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
12742 handle: ".ui-dialog-titlebar",
12743 containment: "document",
12744 start: function( event, ui ) {
12745 that._addClass( $( this ), "ui-dialog-dragging" );
12746 that._blockFrames();
12747 that._trigger( "dragStart", event, filteredUi( ui ) );
12748 },
12749 drag: function( event, ui ) {
12750 that._trigger( "drag", event, filteredUi( ui ) );
12751 },
12752 stop: function( event, ui ) {
12753 var left = ui.offset.left - that.document.scrollLeft(),
12754 top = ui.offset.top - that.document.scrollTop();
12755
12756 options.position = {
12757 my: "left top",
12758 at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12759 "top" + ( top >= 0 ? "+" : "" ) + top,
12760 of: that.window
12761 };
12762 that._removeClass( $( this ), "ui-dialog-dragging" );
12763 that._unblockFrames();
12764 that._trigger( "dragStop", event, filteredUi( ui ) );
12765 }
12766 } );
12767 },
12768
12769 _makeResizable: function() {
12770 var that = this,
12771 options = this.options,
12772 handles = options.resizable,
12773
12774 // .ui-resizable has position: relative defined in the stylesheet
12775 // but dialogs have to use absolute or fixed positioning
12776 position = this.uiDialog.css( "position" ),
12777 resizeHandles = typeof handles === "string" ?
12778 handles :
12779 "n,e,s,w,se,sw,ne,nw";
12780
12781 function filteredUi( ui ) {
12782 return {
12783 originalPosition: ui.originalPosition,
12784 originalSize: ui.originalSize,
12785 position: ui.position,
12786 size: ui.size
12787 };
12788 }
12789
12790 this.uiDialog.resizable( {
12791 cancel: ".ui-dialog-content",
12792 containment: "document",
12793 alsoResize: this.element,
12794 maxWidth: options.maxWidth,
12795 maxHeight: options.maxHeight,
12796 minWidth: options.minWidth,
12797 minHeight: this._minHeight(),
12798 handles: resizeHandles,
12799 start: function( event, ui ) {
12800 that._addClass( $( this ), "ui-dialog-resizing" );
12801 that._blockFrames();
12802 that._trigger( "resizeStart", event, filteredUi( ui ) );
12803 },
12804 resize: function( event, ui ) {
12805 that._trigger( "resize", event, filteredUi( ui ) );
12806 },
12807 stop: function( event, ui ) {
12808 var offset = that.uiDialog.offset(),
12809 left = offset.left - that.document.scrollLeft(),
12810 top = offset.top - that.document.scrollTop();
12811
12812 options.height = that.uiDialog.height();
12813 options.width = that.uiDialog.width();
12814 options.position = {
12815 my: "left top",
12816 at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12817 "top" + ( top >= 0 ? "+" : "" ) + top,
12818 of: that.window
12819 };
12820 that._removeClass( $( this ), "ui-dialog-resizing" );
12821 that._unblockFrames();
12822 that._trigger( "resizeStop", event, filteredUi( ui ) );
12823 }
12824 } )
12825 .css( "position", position );
12826 },
12827
12828 _trackFocus: function() {
12829 this._on( this.widget(), {
12830 focusin: function( event ) {
12831 this._makeFocusTarget();
12832 this._focusedElement = $( event.target );
12833 }
12834 } );
12835 },
12836
12837 _makeFocusTarget: function() {
12838 this._untrackInstance();
12839 this._trackingInstances().unshift( this );
12840 },
12841
12842 _untrackInstance: function() {
12843 var instances = this._trackingInstances(),
12844 exists = $.inArray( this, instances );
12845 if ( exists !== -1 ) {
12846 instances.splice( exists, 1 );
12847 }
12848 },
12849
12850 _trackingInstances: function() {
12851 var instances = this.document.data( "ui-dialog-instances" );
12852 if ( !instances ) {
12853 instances = [];
12854 this.document.data( "ui-dialog-instances", instances );
12855 }
12856 return instances;
12857 },
12858
12859 _minHeight: function() {
12860 var options = this.options;
12861
12862 return options.height === "auto" ?
12863 options.minHeight :
12864 Math.min( options.minHeight, options.height );
12865 },
12866
12867 _position: function() {
12868
12869 // Need to show the dialog to get the actual offset in the position plugin
12870 var isVisible = this.uiDialog.is( ":visible" );
12871 if ( !isVisible ) {
12872 this.uiDialog.show();
12873 }
12874 this.uiDialog.position( this.options.position );
12875 if ( !isVisible ) {
12876 this.uiDialog.hide();
12877 }
12878 },
12879
12880 _setOptions: function( options ) {
12881 var that = this,
12882 resize = false,
12883 resizableOptions = {};
12884
12885 $.each( options, function( key, value ) {
12886 that._setOption( key, value );
12887
12888 if ( key in that.sizeRelatedOptions ) {
12889 resize = true;
12890 }
12891 if ( key in that.resizableRelatedOptions ) {
12892 resizableOptions[ key ] = value;
12893 }
12894 } );
12895
12896 if ( resize ) {
12897 this._size();
12898 this._position();
12899 }
12900 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12901 this.uiDialog.resizable( "option", resizableOptions );
12902 }
12903 },
12904
12905 _setOption: function( key, value ) {
12906 var isDraggable, isResizable,
12907 uiDialog = this.uiDialog;
12908
12909 if ( key === "disabled" ) {
12910 return;
12911 }
12912
12913 this._super( key, value );
12914
12915 if ( key === "appendTo" ) {
12916 this.uiDialog.appendTo( this._appendTo() );
12917 }
12918
12919 if ( key === "buttons" ) {
12920 this._createButtons();
12921 }
12922
12923 if ( key === "closeText" ) {
12924 this.uiDialogTitlebarClose.button( {
12925
12926 // Ensure that we always pass a string
12927 label: $( "<a>" ).text( "" + this.options.closeText ).html()
12928 } );
12929 }
12930
12931 if ( key === "draggable" ) {
12932 isDraggable = uiDialog.is( ":data(ui-draggable)" );
12933 if ( isDraggable && !value ) {
12934 uiDialog.draggable( "destroy" );
12935 }
12936
12937 if ( !isDraggable && value ) {
12938 this._makeDraggable();
12939 }
12940 }
12941
12942 if ( key === "position" ) {
12943 this._position();
12944 }
12945
12946 if ( key === "resizable" ) {
12947
12948 // currently resizable, becoming non-resizable
12949 isResizable = uiDialog.is( ":data(ui-resizable)" );
12950 if ( isResizable && !value ) {
12951 uiDialog.resizable( "destroy" );
12952 }
12953
12954 // Currently resizable, changing handles
12955 if ( isResizable && typeof value === "string" ) {
12956 uiDialog.resizable( "option", "handles", value );
12957 }
12958
12959 // Currently non-resizable, becoming resizable
12960 if ( !isResizable && value !== false ) {
12961 this._makeResizable();
12962 }
12963 }
12964
12965 if ( key === "title" ) {
12966 this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
12967 }
12968 },
12969
12970 _size: function() {
12971
12972 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
12973 // divs will both have width and height set, so we need to reset them
12974 var nonContentHeight, minContentHeight, maxContentHeight,
12975 options = this.options;
12976
12977 // Reset content sizing
12978 this.element.show().css( {
12979 width: "auto",
12980 minHeight: 0,
12981 maxHeight: "none",
12982 height: 0
12983 } );
12984
12985 if ( options.minWidth > options.width ) {
12986 options.width = options.minWidth;
12987 }
12988
12989 // Reset wrapper sizing
12990 // determine the height of all the non-content elements
12991 nonContentHeight = this.uiDialog.css( {
12992 height: "auto",
12993 width: options.width
12994 } )
12995 .outerHeight();
12996 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
12997 maxContentHeight = typeof options.maxHeight === "number" ?
12998 Math.max( 0, options.maxHeight - nonContentHeight ) :
12999 "none";
13000
13001 if ( options.height === "auto" ) {
13002 this.element.css( {
13003 minHeight: minContentHeight,
13004 maxHeight: maxContentHeight,
13005 height: "auto"
13006 } );
13007 } else {
13008 this.element.height( Math.max( 0, options.height - nonContentHeight ) );
13009 }
13010
13011 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
13012 this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
13013 }
13014 },
13015
13016 _blockFrames: function() {
13017 this.iframeBlocks = this.document.find( "iframe" ).map( function() {
13018 var iframe = $( this );
13019
13020 return $( "<div>" )
13021 .css( {
13022 position: "absolute",
13023 width: iframe.outerWidth(),
13024 height: iframe.outerHeight()
13025 } )
13026 .appendTo( iframe.parent() )
13027 .offset( iframe.offset() )[ 0 ];
13028 } );
13029 },
13030
13031 _unblockFrames: function() {
13032 if ( this.iframeBlocks ) {
13033 this.iframeBlocks.remove();
13034 delete this.iframeBlocks;
13035 }
13036 },
13037
13038 _allowInteraction: function( event ) {
13039 if ( $( event.target ).closest( ".ui-dialog" ).length ) {
13040 return true;
13041 }
13042
13043 // TODO: Remove hack when datepicker implements
13044 // the .ui-front logic (#8989)
13045 return !!$( event.target ).closest( ".ui-datepicker" ).length;
13046 },
13047
13048 _createOverlay: function() {
13049 if ( !this.options.modal ) {
13050 return;
13051 }
13052
13053 var jqMinor = $.fn.jquery.substring( 0, 4 );
13054
13055 // We use a delay in case the overlay is created from an
13056 // event that we're going to be cancelling (#2804)
13057 var isOpening = true;
13058 this._delay( function() {
13059 isOpening = false;
13060 } );
13061
13062 if ( !this.document.data( "ui-dialog-overlays" ) ) {
13063
13064 // Prevent use of anchors and inputs
13065 // This doesn't use `_on()` because it is a shared event handler
13066 // across all open modal dialogs.
13067 this.document.on( "focusin.ui-dialog", function( event ) {
13068 if ( isOpening ) {
13069 return;
13070 }
13071
13072 var instance = this._trackingInstances()[ 0 ];
13073 if ( !instance._allowInteraction( event ) ) {
13074 event.preventDefault();
13075 instance._focusTabbable();
13076
13077 // Support: jQuery >=3.4 <3.6 only
13078 // Focus re-triggering in jQuery 3.4/3.5 makes the original element
13079 // have its focus event propagated last, breaking the re-targeting.
13080 // Trigger focus in a delay in addition if needed to avoid the issue
13081 // See https://github.com/jquery/jquery/issues/4382
13082 if ( jqMinor === "3.4." || jqMinor === "3.5." ) {
13083 instance._delay( instance._restoreTabbableFocus );
13084 }
13085 }
13086 }.bind( this ) );
13087 }
13088
13089 this.overlay = $( "<div>" )
13090 .appendTo( this._appendTo() );
13091
13092 this._addClass( this.overlay, null, "ui-widget-overlay ui-front" );
13093 this._on( this.overlay, {
13094 mousedown: "_keepFocus"
13095 } );
13096 this.document.data( "ui-dialog-overlays",
13097 ( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 );
13098 },
13099
13100 _destroyOverlay: function() {
13101 if ( !this.options.modal ) {
13102 return;
13103 }
13104
13105 if ( this.overlay ) {
13106 var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
13107
13108 if ( !overlays ) {
13109 this.document.off( "focusin.ui-dialog" );
13110 this.document.removeData( "ui-dialog-overlays" );
13111 } else {
13112 this.document.data( "ui-dialog-overlays", overlays );
13113 }
13114
13115 this.overlay.remove();
13116 this.overlay = null;
13117 }
13118 }
13119 } );
13120
13121 // DEPRECATED
13122 // TODO: switch return back to widget declaration at top of file when this is removed
13123 if ( $.uiBackCompat !== false ) {
13124
13125 // Backcompat for dialogClass option
13126 $.widget( "ui.dialog", $.ui.dialog, {
13127 options: {
13128 dialogClass: ""
13129 },
13130 _createWrapper: function() {
13131 this._super();
13132 this.uiDialog.addClass( this.options.dialogClass );
13133 },
13134 _setOption: function( key, value ) {
13135 if ( key === "dialogClass" ) {
13136 this.uiDialog
13137 .removeClass( this.options.dialogClass )
13138 .addClass( value );
13139 }
13140 this._superApply( arguments );
13141 }
13142 } );
13143 }
13144
13145 var widgetsDialog = $.ui.dialog;
13146
13147
13148 /*!
13149 * jQuery UI Droppable 1.13.2
13150 * http://jqueryui.com
13151 *
13152 * Copyright jQuery Foundation and other contributors
13153 * Released under the MIT license.
13154 * http://jquery.org/license
13155 */
13156
13157 //>>label: Droppable
13158 //>>group: Interactions
13159 //>>description: Enables drop targets for draggable elements.
13160 //>>docs: http://api.jqueryui.com/droppable/
13161 //>>demos: http://jqueryui.com/droppable/
13162
13163
13164 $.widget( "ui.droppable", {
13165 version: "1.13.2",
13166 widgetEventPrefix: "drop",
13167 options: {
13168 accept: "*",
13169 addClasses: true,
13170 greedy: false,
13171 scope: "default",
13172 tolerance: "intersect",
13173
13174 // Callbacks
13175 activate: null,
13176 deactivate: null,
13177 drop: null,
13178 out: null,
13179 over: null
13180 },
13181 _create: function() {
13182
13183 var proportions,
13184 o = this.options,
13185 accept = o.accept;
13186
13187 this.isover = false;
13188 this.isout = true;
13189
13190 this.accept = typeof accept === "function" ? accept : function( d ) {
13191 return d.is( accept );
13192 };
13193
13194 this.proportions = function( /* valueToWrite */ ) {
13195 if ( arguments.length ) {
13196
13197 // Store the droppable's proportions
13198 proportions = arguments[ 0 ];
13199 } else {
13200
13201 // Retrieve or derive the droppable's proportions
13202 return proportions ?
13203 proportions :
13204 proportions = {
13205 width: this.element[ 0 ].offsetWidth,
13206 height: this.element[ 0 ].offsetHeight
13207 };
13208 }
13209 };
13210
13211 this._addToManager( o.scope );
13212
13213 if ( o.addClasses ) {
13214 this._addClass( "ui-droppable" );
13215 }
13216
13217 },
13218
13219 _addToManager: function( scope ) {
13220
13221 // Add the reference and positions to the manager
13222 $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
13223 $.ui.ddmanager.droppables[ scope ].push( this );
13224 },
13225
13226 _splice: function( drop ) {
13227 var i = 0;
13228 for ( ; i < drop.length; i++ ) {
13229 if ( drop[ i ] === this ) {
13230 drop.splice( i, 1 );
13231 }
13232 }
13233 },
13234
13235 _destroy: function() {
13236 var drop = $.ui.ddmanager.droppables[ this.options.scope ];
13237
13238 this._splice( drop );
13239 },
13240
13241 _setOption: function( key, value ) {
13242
13243 if ( key === "accept" ) {
13244 this.accept = typeof value === "function" ? value : function( d ) {
13245 return d.is( value );
13246 };
13247 } else if ( key === "scope" ) {
13248 var drop = $.ui.ddmanager.droppables[ this.options.scope ];
13249
13250 this._splice( drop );
13251 this._addToManager( value );
13252 }
13253
13254 this._super( key, value );
13255 },
13256
13257 _activate: function( event ) {
13258 var draggable = $.ui.ddmanager.current;
13259
13260 this._addActiveClass();
13261 if ( draggable ) {
13262 this._trigger( "activate", event, this.ui( draggable ) );
13263 }
13264 },
13265
13266 _deactivate: function( event ) {
13267 var draggable = $.ui.ddmanager.current;
13268
13269 this._removeActiveClass();
13270 if ( draggable ) {
13271 this._trigger( "deactivate", event, this.ui( draggable ) );
13272 }
13273 },
13274
13275 _over: function( event ) {
13276
13277 var draggable = $.ui.ddmanager.current;
13278
13279 // Bail if draggable and droppable are same element
13280 if ( !draggable || ( draggable.currentItem ||
13281 draggable.element )[ 0 ] === this.element[ 0 ] ) {
13282 return;
13283 }
13284
13285 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
13286 draggable.element ) ) ) {
13287 this._addHoverClass();
13288 this._trigger( "over", event, this.ui( draggable ) );
13289 }
13290
13291 },
13292
13293 _out: function( event ) {
13294
13295 var draggable = $.ui.ddmanager.current;
13296
13297 // Bail if draggable and droppable are same element
13298 if ( !draggable || ( draggable.currentItem ||
13299 draggable.element )[ 0 ] === this.element[ 0 ] ) {
13300 return;
13301 }
13302
13303 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
13304 draggable.element ) ) ) {
13305 this._removeHoverClass();
13306 this._trigger( "out", event, this.ui( draggable ) );
13307 }
13308
13309 },
13310
13311 _drop: function( event, custom ) {
13312
13313 var draggable = custom || $.ui.ddmanager.current,
13314 childrenIntersection = false;
13315
13316 // Bail if draggable and droppable are same element
13317 if ( !draggable || ( draggable.currentItem ||
13318 draggable.element )[ 0 ] === this.element[ 0 ] ) {
13319 return false;
13320 }
13321
13322 this.element
13323 .find( ":data(ui-droppable)" )
13324 .not( ".ui-draggable-dragging" )
13325 .each( function() {
13326 var inst = $( this ).droppable( "instance" );
13327 if (
13328 inst.options.greedy &&
13329 !inst.options.disabled &&
13330 inst.options.scope === draggable.options.scope &&
13331 inst.accept.call(
13332 inst.element[ 0 ], ( draggable.currentItem || draggable.element )
13333 ) &&
13334 $.ui.intersect(
13335 draggable,
13336 $.extend( inst, { offset: inst.element.offset() } ),
13337 inst.options.tolerance, event
13338 )
13339 ) {
13340 childrenIntersection = true;
13341 return false;
13342 }
13343 } );
13344 if ( childrenIntersection ) {
13345 return false;
13346 }
13347
13348 if ( this.accept.call( this.element[ 0 ],
13349 ( draggable.currentItem || draggable.element ) ) ) {
13350 this._removeActiveClass();
13351 this._removeHoverClass();
13352
13353 this._trigger( "drop", event, this.ui( draggable ) );
13354 return this.element;
13355 }
13356
13357 return false;
13358
13359 },
13360
13361 ui: function( c ) {
13362 return {
13363 draggable: ( c.currentItem || c.element ),
13364 helper: c.helper,
13365 position: c.position,
13366 offset: c.positionAbs
13367 };
13368 },
13369
13370 // Extension points just to make backcompat sane and avoid duplicating logic
13371 // TODO: Remove in 1.14 along with call to it below
13372 _addHoverClass: function() {
13373 this._addClass( "ui-droppable-hover" );
13374 },
13375
13376 _removeHoverClass: function() {
13377 this._removeClass( "ui-droppable-hover" );
13378 },
13379
13380 _addActiveClass: function() {
13381 this._addClass( "ui-droppable-active" );
13382 },
13383
13384 _removeActiveClass: function() {
13385 this._removeClass( "ui-droppable-active" );
13386 }
13387 } );
13388
13389 $.ui.intersect = ( function() {
13390 function isOverAxis( x, reference, size ) {
13391 return ( x >= reference ) && ( x < ( reference + size ) );
13392 }
13393
13394 return function( draggable, droppable, toleranceMode, event ) {
13395
13396 if ( !droppable.offset ) {
13397 return false;
13398 }
13399
13400 var x1 = ( draggable.positionAbs ||
13401 draggable.position.absolute ).left + draggable.margins.left,
13402 y1 = ( draggable.positionAbs ||
13403 draggable.position.absolute ).top + draggable.margins.top,
13404 x2 = x1 + draggable.helperProportions.width,
13405 y2 = y1 + draggable.helperProportions.height,
13406 l = droppable.offset.left,
13407 t = droppable.offset.top,
13408 r = l + droppable.proportions().width,
13409 b = t + droppable.proportions().height;
13410
13411 switch ( toleranceMode ) {
13412 case "fit":
13413 return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
13414 case "intersect":
13415 return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
13416 x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
13417 t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
13418 y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
13419 case "pointer":
13420 return isOverAxis( event.pageY, t, droppable.proportions().height ) &&
13421 isOverAxis( event.pageX, l, droppable.proportions().width );
13422 case "touch":
13423 return (
13424 ( y1 >= t && y1 <= b ) || // Top edge touching
13425 ( y2 >= t && y2 <= b ) || // Bottom edge touching
13426 ( y1 < t && y2 > b ) // Surrounded vertically
13427 ) && (
13428 ( x1 >= l && x1 <= r ) || // Left edge touching
13429 ( x2 >= l && x2 <= r ) || // Right edge touching
13430 ( x1 < l && x2 > r ) // Surrounded horizontally
13431 );
13432 default:
13433 return false;
13434 }
13435 };
13436 } )();
13437
13438 /*
13439 This manager tracks offsets of draggables and droppables
13440 */
13441 $.ui.ddmanager = {
13442 current: null,
13443 droppables: { "default": [] },
13444 prepareOffsets: function( t, event ) {
13445
13446 var i, j,
13447 m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
13448 type = event ? event.type : null, // workaround for #2317
13449 list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
13450
13451 droppablesLoop: for ( i = 0; i < m.length; i++ ) {
13452
13453 // No disabled and non-accepted
13454 if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ],
13455 ( t.currentItem || t.element ) ) ) ) {
13456 continue;
13457 }
13458
13459 // Filter out elements in the current dragged item
13460 for ( j = 0; j < list.length; j++ ) {
13461 if ( list[ j ] === m[ i ].element[ 0 ] ) {
13462 m[ i ].proportions().height = 0;
13463 continue droppablesLoop;
13464 }
13465 }
13466
13467 m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
13468 if ( !m[ i ].visible ) {
13469 continue;
13470 }
13471
13472 // Activate the droppable if used directly from draggables
13473 if ( type === "mousedown" ) {
13474 m[ i ]._activate.call( m[ i ], event );
13475 }
13476
13477 m[ i ].offset = m[ i ].element.offset();
13478 m[ i ].proportions( {
13479 width: m[ i ].element[ 0 ].offsetWidth,
13480 height: m[ i ].element[ 0 ].offsetHeight
13481 } );
13482
13483 }
13484
13485 },
13486 drop: function( draggable, event ) {
13487
13488 var dropped = false;
13489
13490 // Create a copy of the droppables in case the list changes during the drop (#9116)
13491 $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
13492
13493 if ( !this.options ) {
13494 return;
13495 }
13496 if ( !this.options.disabled && this.visible &&
13497 $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
13498 dropped = this._drop.call( this, event ) || dropped;
13499 }
13500
13501 if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ],
13502 ( draggable.currentItem || draggable.element ) ) ) {
13503 this.isout = true;
13504 this.isover = false;
13505 this._deactivate.call( this, event );
13506 }
13507
13508 } );
13509 return dropped;
13510
13511 },
13512 dragStart: function( draggable, event ) {
13513
13514 // Listen for scrolling so that if the dragging causes scrolling the position of the
13515 // droppables can be recalculated (see #5003)
13516 draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() {
13517 if ( !draggable.options.refreshPositions ) {
13518 $.ui.ddmanager.prepareOffsets( draggable, event );
13519 }
13520 } );
13521 },
13522 drag: function( draggable, event ) {
13523
13524 // If you have a highly dynamic page, you might try this option. It renders positions
13525 // every time you move the mouse.
13526 if ( draggable.options.refreshPositions ) {
13527 $.ui.ddmanager.prepareOffsets( draggable, event );
13528 }
13529
13530 // Run through all droppables and check their positions based on specific tolerance options
13531 $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
13532
13533 if ( this.options.disabled || this.greedyChild || !this.visible ) {
13534 return;
13535 }
13536
13537 var parentInstance, scope, parent,
13538 intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
13539 c = !intersects && this.isover ?
13540 "isout" :
13541 ( intersects && !this.isover ? "isover" : null );
13542 if ( !c ) {
13543 return;
13544 }
13545
13546 if ( this.options.greedy ) {
13547
13548 // find droppable parents with same scope
13549 scope = this.options.scope;
13550 parent = this.element.parents( ":data(ui-droppable)" ).filter( function() {
13551 return $( this ).droppable( "instance" ).options.scope === scope;
13552 } );
13553
13554 if ( parent.length ) {
13555 parentInstance = $( parent[ 0 ] ).droppable( "instance" );
13556 parentInstance.greedyChild = ( c === "isover" );
13557 }
13558 }
13559
13560 // We just moved into a greedy child
13561 if ( parentInstance && c === "isover" ) {
13562 parentInstance.isover = false;
13563 parentInstance.isout = true;
13564 parentInstance._out.call( parentInstance, event );
13565 }
13566
13567 this[ c ] = true;
13568 this[ c === "isout" ? "isover" : "isout" ] = false;
13569 this[ c === "isover" ? "_over" : "_out" ].call( this, event );
13570
13571 // We just moved out of a greedy child
13572 if ( parentInstance && c === "isout" ) {
13573 parentInstance.isout = false;
13574 parentInstance.isover = true;
13575 parentInstance._over.call( parentInstance, event );
13576 }
13577 } );
13578
13579 },
13580 dragStop: function( draggable, event ) {
13581 draggable.element.parentsUntil( "body" ).off( "scroll.droppable" );
13582
13583 // Call prepareOffsets one final time since IE does not fire return scroll events when
13584 // overflow was caused by drag (see #5003)
13585 if ( !draggable.options.refreshPositions ) {
13586 $.ui.ddmanager.prepareOffsets( draggable, event );
13587 }
13588 }
13589 };
13590
13591 // DEPRECATED
13592 // TODO: switch return back to widget declaration at top of file when this is removed
13593 if ( $.uiBackCompat !== false ) {
13594
13595 // Backcompat for activeClass and hoverClass options
13596 $.widget( "ui.droppable", $.ui.droppable, {
13597 options: {
13598 hoverClass: false,
13599 activeClass: false
13600 },
13601 _addActiveClass: function() {
13602 this._super();
13603 if ( this.options.activeClass ) {
13604 this.element.addClass( this.options.activeClass );
13605 }
13606 },
13607 _removeActiveClass: function() {
13608 this._super();
13609 if ( this.options.activeClass ) {
13610 this.element.removeClass( this.options.activeClass );
13611 }
13612 },
13613 _addHoverClass: function() {
13614 this._super();
13615 if ( this.options.hoverClass ) {
13616 this.element.addClass( this.options.hoverClass );
13617 }
13618 },
13619 _removeHoverClass: function() {
13620 this._super();
13621 if ( this.options.hoverClass ) {
13622 this.element.removeClass( this.options.hoverClass );
13623 }
13624 }
13625 } );
13626 }
13627
13628 var widgetsDroppable = $.ui.droppable;
13629
13630
13631 /*!
13632 * jQuery UI Progressbar 1.13.2
13633 * http://jqueryui.com
13634 *
13635 * Copyright jQuery Foundation and other contributors
13636 * Released under the MIT license.
13637 * http://jquery.org/license
13638 */
13639
13640 //>>label: Progressbar
13641 //>>group: Widgets
13642 /* eslint-disable max-len */
13643 //>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators.
13644 /* eslint-enable max-len */
13645 //>>docs: http://api.jqueryui.com/progressbar/
13646 //>>demos: http://jqueryui.com/progressbar/
13647 //>>css.structure: ../../themes/base/core.css
13648 //>>css.structure: ../../themes/base/progressbar.css
13649 //>>css.theme: ../../themes/base/theme.css
13650
13651
13652 var widgetsProgressbar = $.widget( "ui.progressbar", {
13653 version: "1.13.2",
13654 options: {
13655 classes: {
13656 "ui-progressbar": "ui-corner-all",
13657 "ui-progressbar-value": "ui-corner-left",
13658 "ui-progressbar-complete": "ui-corner-right"
13659 },
13660 max: 100,
13661 value: 0,
13662
13663 change: null,
13664 complete: null
13665 },
13666
13667 min: 0,
13668
13669 _create: function() {
13670
13671 // Constrain initial value
13672 this.oldValue = this.options.value = this._constrainedValue();
13673
13674 this.element.attr( {
13675
13676 // Only set static values; aria-valuenow and aria-valuemax are
13677 // set inside _refreshValue()
13678 role: "progressbar",
13679 "aria-valuemin": this.min
13680 } );
13681 this._addClass( "ui-progressbar", "ui-widget ui-widget-content" );
13682
13683 this.valueDiv = $( "<div>" ).appendTo( this.element );
13684 this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" );
13685 this._refreshValue();
13686 },
13687
13688 _destroy: function() {
13689 this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" );
13690
13691 this.valueDiv.remove();
13692 },
13693
13694 value: function( newValue ) {
13695 if ( newValue === undefined ) {
13696 return this.options.value;
13697 }
13698
13699 this.options.value = this._constrainedValue( newValue );
13700 this._refreshValue();
13701 },
13702
13703 _constrainedValue: function( newValue ) {
13704 if ( newValue === undefined ) {
13705 newValue = this.options.value;
13706 }
13707
13708 this.indeterminate = newValue === false;
13709
13710 // Sanitize value
13711 if ( typeof newValue !== "number" ) {
13712 newValue = 0;
13713 }
13714
13715 return this.indeterminate ? false :
13716 Math.min( this.options.max, Math.max( this.min, newValue ) );
13717 },
13718
13719 _setOptions: function( options ) {
13720
13721 // Ensure "value" option is set after other values (like max)
13722 var value = options.value;
13723 delete options.value;
13724
13725 this._super( options );
13726
13727 this.options.value = this._constrainedValue( value );
13728 this._refreshValue();
13729 },
13730
13731 _setOption: function( key, value ) {
13732 if ( key === "max" ) {
13733
13734 // Don't allow a max less than min
13735 value = Math.max( this.min, value );
13736 }
13737 this._super( key, value );
13738 },
13739
13740 _setOptionDisabled: function( value ) {
13741 this._super( value );
13742
13743 this.element.attr( "aria-disabled", value );
13744 this._toggleClass( null, "ui-state-disabled", !!value );
13745 },
13746
13747 _percentage: function() {
13748 return this.indeterminate ?
13749 100 :
13750 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
13751 },
13752
13753 _refreshValue: function() {
13754 var value = this.options.value,
13755 percentage = this._percentage();
13756
13757 this.valueDiv
13758 .toggle( this.indeterminate || value > this.min )
13759 .width( percentage.toFixed( 0 ) + "%" );
13760
13761 this
13762 ._toggleClass( this.valueDiv, "ui-progressbar-complete", null,
13763 value === this.options.max )
13764 ._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate );
13765
13766 if ( this.indeterminate ) {
13767 this.element.removeAttr( "aria-valuenow" );
13768 if ( !this.overlayDiv ) {
13769 this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv );
13770 this._addClass( this.overlayDiv, "ui-progressbar-overlay" );
13771 }
13772 } else {
13773 this.element.attr( {
13774 "aria-valuemax": this.options.max,
13775 "aria-valuenow": value
13776 } );
13777 if ( this.overlayDiv ) {
13778 this.overlayDiv.remove();
13779 this.overlayDiv = null;
13780 }
13781 }
13782
13783 if ( this.oldValue !== value ) {
13784 this.oldValue = value;
13785 this._trigger( "change" );
13786 }
13787 if ( value === this.options.max ) {
13788 this._trigger( "complete" );
13789 }
13790 }
13791 } );
13792
13793
13794 /*!
13795 * jQuery UI Selectable 1.13.2
13796 * http://jqueryui.com
13797 *
13798 * Copyright jQuery Foundation and other contributors
13799 * Released under the MIT license.
13800 * http://jquery.org/license
13801 */
13802
13803 //>>label: Selectable
13804 //>>group: Interactions
13805 //>>description: Allows groups of elements to be selected with the mouse.
13806 //>>docs: http://api.jqueryui.com/selectable/
13807 //>>demos: http://jqueryui.com/selectable/
13808 //>>css.structure: ../../themes/base/selectable.css
13809
13810
13811 var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, {
13812 version: "1.13.2",
13813 options: {
13814 appendTo: "body",
13815 autoRefresh: true,
13816 distance: 0,
13817 filter: "*",
13818 tolerance: "touch",
13819
13820 // Callbacks
13821 selected: null,
13822 selecting: null,
13823 start: null,
13824 stop: null,
13825 unselected: null,
13826 unselecting: null
13827 },
13828 _create: function() {
13829 var that = this;
13830
13831 this._addClass( "ui-selectable" );
13832
13833 this.dragged = false;
13834
13835 // Cache selectee children based on filter
13836 this.refresh = function() {
13837 that.elementPos = $( that.element[ 0 ] ).offset();
13838 that.selectees = $( that.options.filter, that.element[ 0 ] );
13839 that._addClass( that.selectees, "ui-selectee" );
13840 that.selectees.each( function() {
13841 var $this = $( this ),
13842 selecteeOffset = $this.offset(),
13843 pos = {
13844 left: selecteeOffset.left - that.elementPos.left,
13845 top: selecteeOffset.top - that.elementPos.top
13846 };
13847 $.data( this, "selectable-item", {
13848 element: this,
13849 $element: $this,
13850 left: pos.left,
13851 top: pos.top,
13852 right: pos.left + $this.outerWidth(),
13853 bottom: pos.top + $this.outerHeight(),
13854 startselected: false,
13855 selected: $this.hasClass( "ui-selected" ),
13856 selecting: $this.hasClass( "ui-selecting" ),
13857 unselecting: $this.hasClass( "ui-unselecting" )
13858 } );
13859 } );
13860 };
13861 this.refresh();
13862
13863 this._mouseInit();
13864
13865 this.helper = $( "<div>" );
13866 this._addClass( this.helper, "ui-selectable-helper" );
13867 },
13868
13869 _destroy: function() {
13870 this.selectees.removeData( "selectable-item" );
13871 this._mouseDestroy();
13872 },
13873
13874 _mouseStart: function( event ) {
13875 var that = this,
13876 options = this.options;
13877
13878 this.opos = [ event.pageX, event.pageY ];
13879 this.elementPos = $( this.element[ 0 ] ).offset();
13880
13881 if ( this.options.disabled ) {
13882 return;
13883 }
13884
13885 this.selectees = $( options.filter, this.element[ 0 ] );
13886
13887 this._trigger( "start", event );
13888
13889 $( options.appendTo ).append( this.helper );
13890
13891 // position helper (lasso)
13892 this.helper.css( {
13893 "left": event.pageX,
13894 "top": event.pageY,
13895 "width": 0,
13896 "height": 0
13897 } );
13898
13899 if ( options.autoRefresh ) {
13900 this.refresh();
13901 }
13902
13903 this.selectees.filter( ".ui-selected" ).each( function() {
13904 var selectee = $.data( this, "selectable-item" );
13905 selectee.startselected = true;
13906 if ( !event.metaKey && !event.ctrlKey ) {
13907 that._removeClass( selectee.$element, "ui-selected" );
13908 selectee.selected = false;
13909 that._addClass( selectee.$element, "ui-unselecting" );
13910 selectee.unselecting = true;
13911
13912 // selectable UNSELECTING callback
13913 that._trigger( "unselecting", event, {
13914 unselecting: selectee.element
13915 } );
13916 }
13917 } );
13918
13919 $( event.target ).parents().addBack().each( function() {
13920 var doSelect,
13921 selectee = $.data( this, "selectable-item" );
13922 if ( selectee ) {
13923 doSelect = ( !event.metaKey && !event.ctrlKey ) ||
13924 !selectee.$element.hasClass( "ui-selected" );
13925 that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
13926 ._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
13927 selectee.unselecting = !doSelect;
13928 selectee.selecting = doSelect;
13929 selectee.selected = doSelect;
13930
13931 // selectable (UN)SELECTING callback
13932 if ( doSelect ) {
13933 that._trigger( "selecting", event, {
13934 selecting: selectee.element
13935 } );
13936 } else {
13937 that._trigger( "unselecting", event, {
13938 unselecting: selectee.element
13939 } );
13940 }
13941 return false;
13942 }
13943 } );
13944
13945 },
13946
13947 _mouseDrag: function( event ) {
13948
13949 this.dragged = true;
13950
13951 if ( this.options.disabled ) {
13952 return;
13953 }
13954
13955 var tmp,
13956 that = this,
13957 options = this.options,
13958 x1 = this.opos[ 0 ],
13959 y1 = this.opos[ 1 ],
13960 x2 = event.pageX,
13961 y2 = event.pageY;
13962
13963 if ( x1 > x2 ) {
13964 tmp = x2; x2 = x1; x1 = tmp;
13965 }
13966 if ( y1 > y2 ) {
13967 tmp = y2; y2 = y1; y1 = tmp;
13968 }
13969 this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
13970
13971 this.selectees.each( function() {
13972 var selectee = $.data( this, "selectable-item" ),
13973 hit = false,
13974 offset = {};
13975
13976 //prevent helper from being selected if appendTo: selectable
13977 if ( !selectee || selectee.element === that.element[ 0 ] ) {
13978 return;
13979 }
13980
13981 offset.left = selectee.left + that.elementPos.left;
13982 offset.right = selectee.right + that.elementPos.left;
13983 offset.top = selectee.top + that.elementPos.top;
13984 offset.bottom = selectee.bottom + that.elementPos.top;
13985
13986 if ( options.tolerance === "touch" ) {
13987 hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
13988 offset.bottom < y1 ) );
13989 } else if ( options.tolerance === "fit" ) {
13990 hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
13991 offset.bottom < y2 );
13992 }
13993
13994 if ( hit ) {
13995
13996 // SELECT
13997 if ( selectee.selected ) {
13998 that._removeClass( selectee.$element, "ui-selected" );
13999 selectee.selected = false;
14000 }
14001 if ( selectee.unselecting ) {
14002 that._removeClass( selectee.$element, "ui-unselecting" );
14003 selectee.unselecting = false;
14004 }
14005 if ( !selectee.selecting ) {
14006 that._addClass( selectee.$element, "ui-selecting" );
14007 selectee.selecting = true;
14008
14009 // selectable SELECTING callback
14010 that._trigger( "selecting", event, {
14011 selecting: selectee.element
14012 } );
14013 }
14014 } else {
14015
14016 // UNSELECT
14017 if ( selectee.selecting ) {
14018 if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
14019 that._removeClass( selectee.$element, "ui-selecting" );
14020 selectee.selecting = false;
14021 that._addClass( selectee.$element, "ui-selected" );
14022 selectee.selected = true;
14023 } else {
14024 that._removeClass( selectee.$element, "ui-selecting" );
14025 selectee.selecting = false;
14026 if ( selectee.startselected ) {
14027 that._addClass( selectee.$element, "ui-unselecting" );
14028 selectee.unselecting = true;
14029 }
14030
14031 // selectable UNSELECTING callback
14032 that._trigger( "unselecting", event, {
14033 unselecting: selectee.element
14034 } );
14035 }
14036 }
14037 if ( selectee.selected ) {
14038 if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
14039 that._removeClass( selectee.$element, "ui-selected" );
14040 selectee.selected = false;
14041
14042 that._addClass( selectee.$element, "ui-unselecting" );
14043 selectee.unselecting = true;
14044
14045 // selectable UNSELECTING callback
14046 that._trigger( "unselecting", event, {
14047 unselecting: selectee.element
14048 } );
14049 }
14050 }
14051 }
14052 } );
14053
14054 return false;
14055 },
14056
14057 _mouseStop: function( event ) {
14058 var that = this;
14059
14060 this.dragged = false;
14061
14062 $( ".ui-unselecting", this.element[ 0 ] ).each( function() {
14063 var selectee = $.data( this, "selectable-item" );
14064 that._removeClass( selectee.$element, "ui-unselecting" );
14065 selectee.unselecting = false;
14066 selectee.startselected = false;
14067 that._trigger( "unselected", event, {
14068 unselected: selectee.element
14069 } );
14070 } );
14071 $( ".ui-selecting", this.element[ 0 ] ).each( function() {
14072 var selectee = $.data( this, "selectable-item" );
14073 that._removeClass( selectee.$element, "ui-selecting" )
14074 ._addClass( selectee.$element, "ui-selected" );
14075 selectee.selecting = false;
14076 selectee.selected = true;
14077 selectee.startselected = true;
14078 that._trigger( "selected", event, {
14079 selected: selectee.element
14080 } );
14081 } );
14082 this._trigger( "stop", event );
14083
14084 this.helper.remove();
14085
14086 return false;
14087 }
14088
14089 } );
14090
14091
14092 /*!
14093 * jQuery UI Selectmenu 1.13.2
14094 * http://jqueryui.com
14095 *
14096 * Copyright jQuery Foundation and other contributors
14097 * Released under the MIT license.
14098 * http://jquery.org/license
14099 */
14100
14101 //>>label: Selectmenu
14102 //>>group: Widgets
14103 /* eslint-disable max-len */
14104 //>>description: Duplicates and extends the functionality of a native HTML select element, allowing it to be customizable in behavior and appearance far beyond the limitations of a native select.
14105 /* eslint-enable max-len */
14106 //>>docs: http://api.jqueryui.com/selectmenu/
14107 //>>demos: http://jqueryui.com/selectmenu/
14108 //>>css.structure: ../../themes/base/core.css
14109 //>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css
14110 //>>css.theme: ../../themes/base/theme.css
14111
14112
14113 var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
14114 version: "1.13.2",
14115 defaultElement: "<select>",
14116 options: {
14117 appendTo: null,
14118 classes: {
14119 "ui-selectmenu-button-open": "ui-corner-top",
14120 "ui-selectmenu-button-closed": "ui-corner-all"
14121 },
14122 disabled: null,
14123 icons: {
14124 button: "ui-icon-triangle-1-s"
14125 },
14126 position: {
14127 my: "left top",
14128 at: "left bottom",
14129 collision: "none"
14130 },
14131 width: false,
14132
14133 // Callbacks
14134 change: null,
14135 close: null,
14136 focus: null,
14137 open: null,
14138 select: null
14139 },
14140
14141 _create: function() {
14142 var selectmenuId = this.element.uniqueId().attr( "id" );
14143 this.ids = {
14144 element: selectmenuId,
14145 button: selectmenuId + "-button",
14146 menu: selectmenuId + "-menu"
14147 };
14148
14149 this._drawButton();
14150 this._drawMenu();
14151 this._bindFormResetHandler();
14152
14153 this._rendered = false;
14154 this.menuItems = $();
14155 },
14156
14157 _drawButton: function() {
14158 var icon,
14159 that = this,
14160 item = this._parseOption(
14161 this.element.find( "option:selected" ),
14162 this.element[ 0 ].selectedIndex
14163 );
14164
14165 // Associate existing label with the new button
14166 this.labels = this.element.labels().attr( "for", this.ids.button );
14167 this._on( this.labels, {
14168 click: function( event ) {
14169 this.button.trigger( "focus" );
14170 event.preventDefault();
14171 }
14172 } );
14173
14174 // Hide original select element
14175 this.element.hide();
14176
14177 // Create button
14178 this.button = $( "<span>", {
14179 tabindex: this.options.disabled ? -1 : 0,
14180 id: this.ids.button,
14181 role: "combobox",
14182 "aria-expanded": "false",
14183 "aria-autocomplete": "list",
14184 "aria-owns": this.ids.menu,
14185 "aria-haspopup": "true",
14186 title: this.element.attr( "title" )
14187 } )
14188 .insertAfter( this.element );
14189
14190 this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed",
14191 "ui-button ui-widget" );
14192
14193 icon = $( "<span>" ).appendTo( this.button );
14194 this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button );
14195 this.buttonItem = this._renderButtonItem( item )
14196 .appendTo( this.button );
14197
14198 if ( this.options.width !== false ) {
14199 this._resizeButton();
14200 }
14201
14202 this._on( this.button, this._buttonEvents );
14203 this.button.one( "focusin", function() {
14204
14205 // Delay rendering the menu items until the button receives focus.
14206 // The menu may have already been rendered via a programmatic open.
14207 if ( !that._rendered ) {
14208 that._refreshMenu();
14209 }
14210 } );
14211 },
14212
14213 _drawMenu: function() {
14214 var that = this;
14215
14216 // Create menu
14217 this.menu = $( "<ul>", {
14218 "aria-hidden": "true",
14219 "aria-labelledby": this.ids.button,
14220 id: this.ids.menu
14221 } );
14222
14223 // Wrap menu
14224 this.menuWrap = $( "<div>" ).append( this.menu );
14225 this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" );
14226 this.menuWrap.appendTo( this._appendTo() );
14227
14228 // Initialize menu widget
14229 this.menuInstance = this.menu
14230 .menu( {
14231 classes: {
14232 "ui-menu": "ui-corner-bottom"
14233 },
14234 role: "listbox",
14235 select: function( event, ui ) {
14236 event.preventDefault();
14237
14238 // Support: IE8
14239 // If the item was selected via a click, the text selection
14240 // will be destroyed in IE
14241 that._setSelection();
14242
14243 that._select( ui.item.data( "ui-selectmenu-item" ), event );
14244 },
14245 focus: function( event, ui ) {
14246 var item = ui.item.data( "ui-selectmenu-item" );
14247
14248 // Prevent inital focus from firing and check if its a newly focused item
14249 if ( that.focusIndex != null && item.index !== that.focusIndex ) {
14250 that._trigger( "focus", event, { item: item } );
14251 if ( !that.isOpen ) {
14252 that._select( item, event );
14253 }
14254 }
14255 that.focusIndex = item.index;
14256
14257 that.button.attr( "aria-activedescendant",
14258 that.menuItems.eq( item.index ).attr( "id" ) );
14259 }
14260 } )
14261 .menu( "instance" );
14262
14263 // Don't close the menu on mouseleave
14264 this.menuInstance._off( this.menu, "mouseleave" );
14265
14266 // Cancel the menu's collapseAll on document click
14267 this.menuInstance._closeOnDocumentClick = function() {
14268 return false;
14269 };
14270
14271 // Selects often contain empty items, but never contain dividers
14272 this.menuInstance._isDivider = function() {
14273 return false;
14274 };
14275 },
14276
14277 refresh: function() {
14278 this._refreshMenu();
14279 this.buttonItem.replaceWith(
14280 this.buttonItem = this._renderButtonItem(
14281
14282 // Fall back to an empty object in case there are no options
14283 this._getSelectedItem().data( "ui-selectmenu-item" ) || {}
14284 )
14285 );
14286 if ( this.options.width === null ) {
14287 this._resizeButton();
14288 }
14289 },
14290
14291 _refreshMenu: function() {
14292 var item,
14293 options = this.element.find( "option" );
14294
14295 this.menu.empty();
14296
14297 this._parseOptions( options );
14298 this._renderMenu( this.menu, this.items );
14299
14300 this.menuInstance.refresh();
14301 this.menuItems = this.menu.find( "li" )
14302 .not( ".ui-selectmenu-optgroup" )
14303 .find( ".ui-menu-item-wrapper" );
14304
14305 this._rendered = true;
14306
14307 if ( !options.length ) {
14308 return;
14309 }
14310
14311 item = this._getSelectedItem();
14312
14313 // Update the menu to have the correct item focused
14314 this.menuInstance.focus( null, item );
14315 this._setAria( item.data( "ui-selectmenu-item" ) );
14316
14317 // Set disabled state
14318 this._setOption( "disabled", this.element.prop( "disabled" ) );
14319 },
14320
14321 open: function( event ) {
14322 if ( this.options.disabled ) {
14323 return;
14324 }
14325
14326 // If this is the first time the menu is being opened, render the items
14327 if ( !this._rendered ) {
14328 this._refreshMenu();
14329 } else {
14330
14331 // Menu clears focus on close, reset focus to selected item
14332 this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" );
14333 this.menuInstance.focus( null, this._getSelectedItem() );
14334 }
14335
14336 // If there are no options, don't open the menu
14337 if ( !this.menuItems.length ) {
14338 return;
14339 }
14340
14341 this.isOpen = true;
14342 this._toggleAttr();
14343 this._resizeMenu();
14344 this._position();
14345
14346 this._on( this.document, this._documentClick );
14347
14348 this._trigger( "open", event );
14349 },
14350
14351 _position: function() {
14352 this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
14353 },
14354
14355 close: function( event ) {
14356 if ( !this.isOpen ) {
14357 return;
14358 }
14359
14360 this.isOpen = false;
14361 this._toggleAttr();
14362
14363 this.range = null;
14364 this._off( this.document );
14365
14366 this._trigger( "close", event );
14367 },
14368
14369 widget: function() {
14370 return this.button;
14371 },
14372
14373 menuWidget: function() {
14374 return this.menu;
14375 },
14376
14377 _renderButtonItem: function( item ) {
14378 var buttonItem = $( "<span>" );
14379
14380 this._setText( buttonItem, item.label );
14381 this._addClass( buttonItem, "ui-selectmenu-text" );
14382
14383 return buttonItem;
14384 },
14385
14386 _renderMenu: function( ul, items ) {
14387 var that = this,
14388 currentOptgroup = "";
14389
14390 $.each( items, function( index, item ) {
14391 var li;
14392
14393 if ( item.optgroup !== currentOptgroup ) {
14394 li = $( "<li>", {
14395 text: item.optgroup
14396 } );
14397 that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" +
14398 ( item.element.parent( "optgroup" ).prop( "disabled" ) ?
14399 " ui-state-disabled" :
14400 "" ) );
14401
14402 li.appendTo( ul );
14403
14404 currentOptgroup = item.optgroup;
14405 }
14406
14407 that._renderItemData( ul, item );
14408 } );
14409 },
14410
14411 _renderItemData: function( ul, item ) {
14412 return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
14413 },
14414
14415 _renderItem: function( ul, item ) {
14416 var li = $( "<li>" ),
14417 wrapper = $( "<div>", {
14418 title: item.element.attr( "title" )
14419 } );
14420
14421 if ( item.disabled ) {
14422 this._addClass( li, null, "ui-state-disabled" );
14423 }
14424 this._setText( wrapper, item.label );
14425
14426 return li.append( wrapper ).appendTo( ul );
14427 },
14428
14429 _setText: function( element, value ) {
14430 if ( value ) {
14431 element.text( value );
14432 } else {
14433 element.html( "&#160;" );
14434 }
14435 },
14436
14437 _move: function( direction, event ) {
14438 var item, next,
14439 filter = ".ui-menu-item";
14440
14441 if ( this.isOpen ) {
14442 item = this.menuItems.eq( this.focusIndex ).parent( "li" );
14443 } else {
14444 item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
14445 filter += ":not(.ui-state-disabled)";
14446 }
14447
14448 if ( direction === "first" || direction === "last" ) {
14449 next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
14450 } else {
14451 next = item[ direction + "All" ]( filter ).eq( 0 );
14452 }
14453
14454 if ( next.length ) {
14455 this.menuInstance.focus( event, next );
14456 }
14457 },
14458
14459 _getSelectedItem: function() {
14460 return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
14461 },
14462
14463 _toggle: function( event ) {
14464 this[ this.isOpen ? "close" : "open" ]( event );
14465 },
14466
14467 _setSelection: function() {
14468 var selection;
14469
14470 if ( !this.range ) {
14471 return;
14472 }
14473
14474 if ( window.getSelection ) {
14475 selection = window.getSelection();
14476 selection.removeAllRanges();
14477 selection.addRange( this.range );
14478
14479 // Support: IE8
14480 } else {
14481 this.range.select();
14482 }
14483
14484 // Support: IE
14485 // Setting the text selection kills the button focus in IE, but
14486 // restoring the focus doesn't kill the selection.
14487 this.button.trigger( "focus" );
14488 },
14489
14490 _documentClick: {
14491 mousedown: function( event ) {
14492 if ( !this.isOpen ) {
14493 return;
14494 }
14495
14496 if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" +
14497 $.escapeSelector( this.ids.button ) ).length ) {
14498 this.close( event );
14499 }
14500 }
14501 },
14502
14503 _buttonEvents: {
14504
14505 // Prevent text selection from being reset when interacting with the selectmenu (#10144)
14506 mousedown: function() {
14507 var selection;
14508
14509 if ( window.getSelection ) {
14510 selection = window.getSelection();
14511 if ( selection.rangeCount ) {
14512 this.range = selection.getRangeAt( 0 );
14513 }
14514
14515 // Support: IE8
14516 } else {
14517 this.range = document.selection.createRange();
14518 }
14519 },
14520
14521 click: function( event ) {
14522 this._setSelection();
14523 this._toggle( event );
14524 },
14525
14526 keydown: function( event ) {
14527 var preventDefault = true;
14528 switch ( event.keyCode ) {
14529 case $.ui.keyCode.TAB:
14530 case $.ui.keyCode.ESCAPE:
14531 this.close( event );
14532 preventDefault = false;
14533 break;
14534 case $.ui.keyCode.ENTER:
14535 if ( this.isOpen ) {
14536 this._selectFocusedItem( event );
14537 }
14538 break;
14539 case $.ui.keyCode.UP:
14540 if ( event.altKey ) {
14541 this._toggle( event );
14542 } else {
14543 this._move( "prev", event );
14544 }
14545 break;
14546 case $.ui.keyCode.DOWN:
14547 if ( event.altKey ) {
14548 this._toggle( event );
14549 } else {
14550 this._move( "next", event );
14551 }
14552 break;
14553 case $.ui.keyCode.SPACE:
14554 if ( this.isOpen ) {
14555 this._selectFocusedItem( event );
14556 } else {
14557 this._toggle( event );
14558 }
14559 break;
14560 case $.ui.keyCode.LEFT:
14561 this._move( "prev", event );
14562 break;
14563 case $.ui.keyCode.RIGHT:
14564 this._move( "next", event );
14565 break;
14566 case $.ui.keyCode.HOME:
14567 case $.ui.keyCode.PAGE_UP:
14568 this._move( "first", event );
14569 break;
14570 case $.ui.keyCode.END:
14571 case $.ui.keyCode.PAGE_DOWN:
14572 this._move( "last", event );
14573 break;
14574 default:
14575 this.menu.trigger( event );
14576 preventDefault = false;
14577 }
14578
14579 if ( preventDefault ) {
14580 event.preventDefault();
14581 }
14582 }
14583 },
14584
14585 _selectFocusedItem: function( event ) {
14586 var item = this.menuItems.eq( this.focusIndex ).parent( "li" );
14587 if ( !item.hasClass( "ui-state-disabled" ) ) {
14588 this._select( item.data( "ui-selectmenu-item" ), event );
14589 }
14590 },
14591
14592 _select: function( item, event ) {
14593 var oldIndex = this.element[ 0 ].selectedIndex;
14594
14595 // Change native select element
14596 this.element[ 0 ].selectedIndex = item.index;
14597 this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) );
14598 this._setAria( item );
14599 this._trigger( "select", event, { item: item } );
14600
14601 if ( item.index !== oldIndex ) {
14602 this._trigger( "change", event, { item: item } );
14603 }
14604
14605 this.close( event );
14606 },
14607
14608 _setAria: function( item ) {
14609 var id = this.menuItems.eq( item.index ).attr( "id" );
14610
14611 this.button.attr( {
14612 "aria-labelledby": id,
14613 "aria-activedescendant": id
14614 } );
14615 this.menu.attr( "aria-activedescendant", id );
14616 },
14617
14618 _setOption: function( key, value ) {
14619 if ( key === "icons" ) {
14620 var icon = this.button.find( "span.ui-icon" );
14621 this._removeClass( icon, null, this.options.icons.button )
14622 ._addClass( icon, null, value.button );
14623 }
14624
14625 this._super( key, value );
14626
14627 if ( key === "appendTo" ) {
14628 this.menuWrap.appendTo( this._appendTo() );
14629 }
14630
14631 if ( key === "width" ) {
14632 this._resizeButton();
14633 }
14634 },
14635
14636 _setOptionDisabled: function( value ) {
14637 this._super( value );
14638
14639 this.menuInstance.option( "disabled", value );
14640 this.button.attr( "aria-disabled", value );
14641 this._toggleClass( this.button, null, "ui-state-disabled", value );
14642
14643 this.element.prop( "disabled", value );
14644 if ( value ) {
14645 this.button.attr( "tabindex", -1 );
14646 this.close();
14647 } else {
14648 this.button.attr( "tabindex", 0 );
14649 }
14650 },
14651
14652 _appendTo: function() {
14653 var element = this.options.appendTo;
14654
14655 if ( element ) {
14656 element = element.jquery || element.nodeType ?
14657 $( element ) :
14658 this.document.find( element ).eq( 0 );
14659 }
14660
14661 if ( !element || !element[ 0 ] ) {
14662 element = this.element.closest( ".ui-front, dialog" );
14663 }
14664
14665 if ( !element.length ) {
14666 element = this.document[ 0 ].body;
14667 }
14668
14669 return element;
14670 },
14671
14672 _toggleAttr: function() {
14673 this.button.attr( "aria-expanded", this.isOpen );
14674
14675 // We can't use two _toggleClass() calls here, because we need to make sure
14676 // we always remove classes first and add them second, otherwise if both classes have the
14677 // same theme class, it will be removed after we add it.
14678 this._removeClass( this.button, "ui-selectmenu-button-" +
14679 ( this.isOpen ? "closed" : "open" ) )
14680 ._addClass( this.button, "ui-selectmenu-button-" +
14681 ( this.isOpen ? "open" : "closed" ) )
14682 ._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen );
14683
14684 this.menu.attr( "aria-hidden", !this.isOpen );
14685 },
14686
14687 _resizeButton: function() {
14688 var width = this.options.width;
14689
14690 // For `width: false`, just remove inline style and stop
14691 if ( width === false ) {
14692 this.button.css( "width", "" );
14693 return;
14694 }
14695
14696 // For `width: null`, match the width of the original element
14697 if ( width === null ) {
14698 width = this.element.show().outerWidth();
14699 this.element.hide();
14700 }
14701
14702 this.button.outerWidth( width );
14703 },
14704
14705 _resizeMenu: function() {
14706 this.menu.outerWidth( Math.max(
14707 this.button.outerWidth(),
14708
14709 // Support: IE10
14710 // IE10 wraps long text (possibly a rounding bug)
14711 // so we add 1px to avoid the wrapping
14712 this.menu.width( "" ).outerWidth() + 1
14713 ) );
14714 },
14715
14716 _getCreateOptions: function() {
14717 var options = this._super();
14718
14719 options.disabled = this.element.prop( "disabled" );
14720
14721 return options;
14722 },
14723
14724 _parseOptions: function( options ) {
14725 var that = this,
14726 data = [];
14727 options.each( function( index, item ) {
14728 if ( item.hidden ) {
14729 return;
14730 }
14731
14732 data.push( that._parseOption( $( item ), index ) );
14733 } );
14734 this.items = data;
14735 },
14736
14737 _parseOption: function( option, index ) {
14738 var optgroup = option.parent( "optgroup" );
14739
14740 return {
14741 element: option,
14742 index: index,
14743 value: option.val(),
14744 label: option.text(),
14745 optgroup: optgroup.attr( "label" ) || "",
14746 disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
14747 };
14748 },
14749
14750 _destroy: function() {
14751 this._unbindFormResetHandler();
14752 this.menuWrap.remove();
14753 this.button.remove();
14754 this.element.show();
14755 this.element.removeUniqueId();
14756 this.labels.attr( "for", this.ids.element );
14757 }
14758 } ] );
14759
14760
14761 /*!
14762 * jQuery UI Slider 1.13.2
14763 * http://jqueryui.com
14764 *
14765 * Copyright jQuery Foundation and other contributors
14766 * Released under the MIT license.
14767 * http://jquery.org/license
14768 */
14769
14770 //>>label: Slider
14771 //>>group: Widgets
14772 //>>description: Displays a flexible slider with ranges and accessibility via keyboard.
14773 //>>docs: http://api.jqueryui.com/slider/
14774 //>>demos: http://jqueryui.com/slider/
14775 //>>css.structure: ../../themes/base/core.css
14776 //>>css.structure: ../../themes/base/slider.css
14777 //>>css.theme: ../../themes/base/theme.css
14778
14779
14780 var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, {
14781 version: "1.13.2",
14782 widgetEventPrefix: "slide",
14783
14784 options: {
14785 animate: false,
14786 classes: {
14787 "ui-slider": "ui-corner-all",
14788 "ui-slider-handle": "ui-corner-all",
14789
14790 // Note: ui-widget-header isn't the most fittingly semantic framework class for this
14791 // element, but worked best visually with a variety of themes
14792 "ui-slider-range": "ui-corner-all ui-widget-header"
14793 },
14794 distance: 0,
14795 max: 100,
14796 min: 0,
14797 orientation: "horizontal",
14798 range: false,
14799 step: 1,
14800 value: 0,
14801 values: null,
14802
14803 // Callbacks
14804 change: null,
14805 slide: null,
14806 start: null,
14807 stop: null
14808 },
14809
14810 // Number of pages in a slider
14811 // (how many times can you page up/down to go through the whole range)
14812 numPages: 5,
14813
14814 _create: function() {
14815 this._keySliding = false;
14816 this._mouseSliding = false;
14817 this._animateOff = true;
14818 this._handleIndex = null;
14819 this._detectOrientation();
14820 this._mouseInit();
14821 this._calculateNewMax();
14822
14823 this._addClass( "ui-slider ui-slider-" + this.orientation,
14824 "ui-widget ui-widget-content" );
14825
14826 this._refresh();
14827
14828 this._animateOff = false;
14829 },
14830
14831 _refresh: function() {
14832 this._createRange();
14833 this._createHandles();
14834 this._setupEvents();
14835 this._refreshValue();
14836 },
14837
14838 _createHandles: function() {
14839 var i, handleCount,
14840 options = this.options,
14841 existingHandles = this.element.find( ".ui-slider-handle" ),
14842 handle = "<span tabindex='0'></span>",
14843 handles = [];
14844
14845 handleCount = ( options.values && options.values.length ) || 1;
14846
14847 if ( existingHandles.length > handleCount ) {
14848 existingHandles.slice( handleCount ).remove();
14849 existingHandles = existingHandles.slice( 0, handleCount );
14850 }
14851
14852 for ( i = existingHandles.length; i < handleCount; i++ ) {
14853 handles.push( handle );
14854 }
14855
14856 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
14857
14858 this._addClass( this.handles, "ui-slider-handle", "ui-state-default" );
14859
14860 this.handle = this.handles.eq( 0 );
14861
14862 this.handles.each( function( i ) {
14863 $( this )
14864 .data( "ui-slider-handle-index", i )
14865 .attr( "tabIndex", 0 );
14866 } );
14867 },
14868
14869 _createRange: function() {
14870 var options = this.options;
14871
14872 if ( options.range ) {
14873 if ( options.range === true ) {
14874 if ( !options.values ) {
14875 options.values = [ this._valueMin(), this._valueMin() ];
14876 } else if ( options.values.length && options.values.length !== 2 ) {
14877 options.values = [ options.values[ 0 ], options.values[ 0 ] ];
14878 } else if ( Array.isArray( options.values ) ) {
14879 options.values = options.values.slice( 0 );
14880 }
14881 }
14882
14883 if ( !this.range || !this.range.length ) {
14884 this.range = $( "<div>" )
14885 .appendTo( this.element );
14886
14887 this._addClass( this.range, "ui-slider-range" );
14888 } else {
14889 this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" );
14890
14891 // Handle range switching from true to min/max
14892 this.range.css( {
14893 "left": "",
14894 "bottom": ""
14895 } );
14896 }
14897 if ( options.range === "min" || options.range === "max" ) {
14898 this._addClass( this.range, "ui-slider-range-" + options.range );
14899 }
14900 } else {
14901 if ( this.range ) {
14902 this.range.remove();
14903 }
14904 this.range = null;
14905 }
14906 },
14907
14908 _setupEvents: function() {
14909 this._off( this.handles );
14910 this._on( this.handles, this._handleEvents );
14911 this._hoverable( this.handles );
14912 this._focusable( this.handles );
14913 },
14914
14915 _destroy: function() {
14916 this.handles.remove();
14917 if ( this.range ) {
14918 this.range.remove();
14919 }
14920
14921 this._mouseDestroy();
14922 },
14923
14924 _mouseCapture: function( event ) {
14925 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
14926 that = this,
14927 o = this.options;
14928
14929 if ( o.disabled ) {
14930 return false;
14931 }
14932
14933 this.elementSize = {
14934 width: this.element.outerWidth(),
14935 height: this.element.outerHeight()
14936 };
14937 this.elementOffset = this.element.offset();
14938
14939 position = { x: event.pageX, y: event.pageY };
14940 normValue = this._normValueFromMouse( position );
14941 distance = this._valueMax() - this._valueMin() + 1;
14942 this.handles.each( function( i ) {
14943 var thisDistance = Math.abs( normValue - that.values( i ) );
14944 if ( ( distance > thisDistance ) ||
14945 ( distance === thisDistance &&
14946 ( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) {
14947 distance = thisDistance;
14948 closestHandle = $( this );
14949 index = i;
14950 }
14951 } );
14952
14953 allowed = this._start( event, index );
14954 if ( allowed === false ) {
14955 return false;
14956 }
14957 this._mouseSliding = true;
14958
14959 this._handleIndex = index;
14960
14961 this._addClass( closestHandle, null, "ui-state-active" );
14962 closestHandle.trigger( "focus" );
14963
14964 offset = closestHandle.offset();
14965 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
14966 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
14967 left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
14968 top: event.pageY - offset.top -
14969 ( closestHandle.height() / 2 ) -
14970 ( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) -
14971 ( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) +
14972 ( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 )
14973 };
14974
14975 if ( !this.handles.hasClass( "ui-state-hover" ) ) {
14976 this._slide( event, index, normValue );
14977 }
14978 this._animateOff = true;
14979 return true;
14980 },
14981
14982 _mouseStart: function() {
14983 return true;
14984 },
14985
14986 _mouseDrag: function( event ) {
14987 var position = { x: event.pageX, y: event.pageY },
14988 normValue = this._normValueFromMouse( position );
14989
14990 this._slide( event, this._handleIndex, normValue );
14991
14992 return false;
14993 },
14994
14995 _mouseStop: function( event ) {
14996 this._removeClass( this.handles, null, "ui-state-active" );
14997 this._mouseSliding = false;
14998
14999 this._stop( event, this._handleIndex );
15000 this._change( event, this._handleIndex );
15001
15002 this._handleIndex = null;
15003 this._clickOffset = null;
15004 this._animateOff = false;
15005
15006 return false;
15007 },
15008
15009 _detectOrientation: function() {
15010 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
15011 },
15012
15013 _normValueFromMouse: function( position ) {
15014 var pixelTotal,
15015 pixelMouse,
15016 percentMouse,
15017 valueTotal,
15018 valueMouse;
15019
15020 if ( this.orientation === "horizontal" ) {
15021 pixelTotal = this.elementSize.width;
15022 pixelMouse = position.x - this.elementOffset.left -
15023 ( this._clickOffset ? this._clickOffset.left : 0 );
15024 } else {
15025 pixelTotal = this.elementSize.height;
15026 pixelMouse = position.y - this.elementOffset.top -
15027 ( this._clickOffset ? this._clickOffset.top : 0 );
15028 }
15029
15030 percentMouse = ( pixelMouse / pixelTotal );
15031 if ( percentMouse > 1 ) {
15032 percentMouse = 1;
15033 }
15034 if ( percentMouse < 0 ) {
15035 percentMouse = 0;
15036 }
15037 if ( this.orientation === "vertical" ) {
15038 percentMouse = 1 - percentMouse;
15039 }
15040
15041 valueTotal = this._valueMax() - this._valueMin();
15042 valueMouse = this._valueMin() + percentMouse * valueTotal;
15043
15044 return this._trimAlignValue( valueMouse );
15045 },
15046
15047 _uiHash: function( index, value, values ) {
15048 var uiHash = {
15049 handle: this.handles[ index ],
15050 handleIndex: index,
15051 value: value !== undefined ? value : this.value()
15052 };
15053
15054 if ( this._hasMultipleValues() ) {
15055 uiHash.value = value !== undefined ? value : this.values( index );
15056 uiHash.values = values || this.values();
15057 }
15058
15059 return uiHash;
15060 },
15061
15062 _hasMultipleValues: function() {
15063 return this.options.values && this.options.values.length;
15064 },
15065
15066 _start: function( event, index ) {
15067 return this._trigger( "start", event, this._uiHash( index ) );
15068 },
15069
15070 _slide: function( event, index, newVal ) {
15071 var allowed, otherVal,
15072 currentValue = this.value(),
15073 newValues = this.values();
15074
15075 if ( this._hasMultipleValues() ) {
15076 otherVal = this.values( index ? 0 : 1 );
15077 currentValue = this.values( index );
15078
15079 if ( this.options.values.length === 2 && this.options.range === true ) {
15080 newVal = index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal );
15081 }
15082
15083 newValues[ index ] = newVal;
15084 }
15085
15086 if ( newVal === currentValue ) {
15087 return;
15088 }
15089
15090 allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) );
15091
15092 // A slide can be canceled by returning false from the slide callback
15093 if ( allowed === false ) {
15094 return;
15095 }
15096
15097 if ( this._hasMultipleValues() ) {
15098 this.values( index, newVal );
15099 } else {
15100 this.value( newVal );
15101 }
15102 },
15103
15104 _stop: function( event, index ) {
15105 this._trigger( "stop", event, this._uiHash( index ) );
15106 },
15107
15108 _change: function( event, index ) {
15109 if ( !this._keySliding && !this._mouseSliding ) {
15110
15111 //store the last changed value index for reference when handles overlap
15112 this._lastChangedValue = index;
15113 this._trigger( "change", event, this._uiHash( index ) );
15114 }
15115 },
15116
15117 value: function( newValue ) {
15118 if ( arguments.length ) {
15119 this.options.value = this._trimAlignValue( newValue );
15120 this._refreshValue();
15121 this._change( null, 0 );
15122 return;
15123 }
15124
15125 return this._value();
15126 },
15127
15128 values: function( index, newValue ) {
15129 var vals,
15130 newValues,
15131 i;
15132
15133 if ( arguments.length > 1 ) {
15134 this.options.values[ index ] = this._trimAlignValue( newValue );
15135 this._refreshValue();
15136 this._change( null, index );
15137 return;
15138 }
15139
15140 if ( arguments.length ) {
15141 if ( Array.isArray( arguments[ 0 ] ) ) {
15142 vals = this.options.values;
15143 newValues = arguments[ 0 ];
15144 for ( i = 0; i < vals.length; i += 1 ) {
15145 vals[ i ] = this._trimAlignValue( newValues[ i ] );
15146 this._change( null, i );
15147 }
15148 this._refreshValue();
15149 } else {
15150 if ( this._hasMultipleValues() ) {
15151 return this._values( index );
15152 } else {
15153 return this.value();
15154 }
15155 }
15156 } else {
15157 return this._values();
15158 }
15159 },
15160
15161 _setOption: function( key, value ) {
15162 var i,
15163 valsLength = 0;
15164
15165 if ( key === "range" && this.options.range === true ) {
15166 if ( value === "min" ) {
15167 this.options.value = this._values( 0 );
15168 this.options.values = null;
15169 } else if ( value === "max" ) {
15170 this.options.value = this._values( this.options.values.length - 1 );
15171 this.options.values = null;
15172 }
15173 }
15174
15175 if ( Array.isArray( this.options.values ) ) {
15176 valsLength = this.options.values.length;
15177 }
15178
15179 this._super( key, value );
15180
15181 switch ( key ) {
15182 case "orientation":
15183 this._detectOrientation();
15184 this._removeClass( "ui-slider-horizontal ui-slider-vertical" )
15185 ._addClass( "ui-slider-" + this.orientation );
15186 this._refreshValue();
15187 if ( this.options.range ) {
15188 this._refreshRange( value );
15189 }
15190
15191 // Reset positioning from previous orientation
15192 this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
15193 break;
15194 case "value":
15195 this._animateOff = true;
15196 this._refreshValue();
15197 this._change( null, 0 );
15198 this._animateOff = false;
15199 break;
15200 case "values":
15201 this._animateOff = true;
15202 this._refreshValue();
15203
15204 // Start from the last handle to prevent unreachable handles (#9046)
15205 for ( i = valsLength - 1; i >= 0; i-- ) {
15206 this._change( null, i );
15207 }
15208 this._animateOff = false;
15209 break;
15210 case "step":
15211 case "min":
15212 case "max":
15213 this._animateOff = true;
15214 this._calculateNewMax();
15215 this._refreshValue();
15216 this._animateOff = false;
15217 break;
15218 case "range":
15219 this._animateOff = true;
15220 this._refresh();
15221 this._animateOff = false;
15222 break;
15223 }
15224 },
15225
15226 _setOptionDisabled: function( value ) {
15227 this._super( value );
15228
15229 this._toggleClass( null, "ui-state-disabled", !!value );
15230 },
15231
15232 //internal value getter
15233 // _value() returns value trimmed by min and max, aligned by step
15234 _value: function() {
15235 var val = this.options.value;
15236 val = this._trimAlignValue( val );
15237
15238 return val;
15239 },
15240
15241 //internal values getter
15242 // _values() returns array of values trimmed by min and max, aligned by step
15243 // _values( index ) returns single value trimmed by min and max, aligned by step
15244 _values: function( index ) {
15245 var val,
15246 vals,
15247 i;
15248
15249 if ( arguments.length ) {
15250 val = this.options.values[ index ];
15251 val = this._trimAlignValue( val );
15252
15253 return val;
15254 } else if ( this._hasMultipleValues() ) {
15255
15256 // .slice() creates a copy of the array
15257 // this copy gets trimmed by min and max and then returned
15258 vals = this.options.values.slice();
15259 for ( i = 0; i < vals.length; i += 1 ) {
15260 vals[ i ] = this._trimAlignValue( vals[ i ] );
15261 }
15262
15263 return vals;
15264 } else {
15265 return [];
15266 }
15267 },
15268
15269 // Returns the step-aligned value that val is closest to, between (inclusive) min and max
15270 _trimAlignValue: function( val ) {
15271 if ( val <= this._valueMin() ) {
15272 return this._valueMin();
15273 }
15274 if ( val >= this._valueMax() ) {
15275 return this._valueMax();
15276 }
15277 var step = ( this.options.step > 0 ) ? this.options.step : 1,
15278 valModStep = ( val - this._valueMin() ) % step,
15279 alignValue = val - valModStep;
15280
15281 if ( Math.abs( valModStep ) * 2 >= step ) {
15282 alignValue += ( valModStep > 0 ) ? step : ( -step );
15283 }
15284
15285 // Since JavaScript has problems with large floats, round
15286 // the final value to 5 digits after the decimal point (see #4124)
15287 return parseFloat( alignValue.toFixed( 5 ) );
15288 },
15289
15290 _calculateNewMax: function() {
15291 var max = this.options.max,
15292 min = this._valueMin(),
15293 step = this.options.step,
15294 aboveMin = Math.round( ( max - min ) / step ) * step;
15295 max = aboveMin + min;
15296 if ( max > this.options.max ) {
15297
15298 //If max is not divisible by step, rounding off may increase its value
15299 max -= step;
15300 }
15301 this.max = parseFloat( max.toFixed( this._precision() ) );
15302 },
15303
15304 _precision: function() {
15305 var precision = this._precisionOf( this.options.step );
15306 if ( this.options.min !== null ) {
15307 precision = Math.max( precision, this._precisionOf( this.options.min ) );
15308 }
15309 return precision;
15310 },
15311
15312 _precisionOf: function( num ) {
15313 var str = num.toString(),
15314 decimal = str.indexOf( "." );
15315 return decimal === -1 ? 0 : str.length - decimal - 1;
15316 },
15317
15318 _valueMin: function() {
15319 return this.options.min;
15320 },
15321
15322 _valueMax: function() {
15323 return this.max;
15324 },
15325
15326 _refreshRange: function( orientation ) {
15327 if ( orientation === "vertical" ) {
15328 this.range.css( { "width": "", "left": "" } );
15329 }
15330 if ( orientation === "horizontal" ) {
15331 this.range.css( { "height": "", "bottom": "" } );
15332 }
15333 },
15334
15335 _refreshValue: function() {
15336 var lastValPercent, valPercent, value, valueMin, valueMax,
15337 oRange = this.options.range,
15338 o = this.options,
15339 that = this,
15340 animate = ( !this._animateOff ) ? o.animate : false,
15341 _set = {};
15342
15343 if ( this._hasMultipleValues() ) {
15344 this.handles.each( function( i ) {
15345 valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() -
15346 that._valueMin() ) * 100;
15347 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
15348 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
15349 if ( that.options.range === true ) {
15350 if ( that.orientation === "horizontal" ) {
15351 if ( i === 0 ) {
15352 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15353 left: valPercent + "%"
15354 }, o.animate );
15355 }
15356 if ( i === 1 ) {
15357 that.range[ animate ? "animate" : "css" ]( {
15358 width: ( valPercent - lastValPercent ) + "%"
15359 }, {
15360 queue: false,
15361 duration: o.animate
15362 } );
15363 }
15364 } else {
15365 if ( i === 0 ) {
15366 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15367 bottom: ( valPercent ) + "%"
15368 }, o.animate );
15369 }
15370 if ( i === 1 ) {
15371 that.range[ animate ? "animate" : "css" ]( {
15372 height: ( valPercent - lastValPercent ) + "%"
15373 }, {
15374 queue: false,
15375 duration: o.animate
15376 } );
15377 }
15378 }
15379 }
15380 lastValPercent = valPercent;
15381 } );
15382 } else {
15383 value = this.value();
15384 valueMin = this._valueMin();
15385 valueMax = this._valueMax();
15386 valPercent = ( valueMax !== valueMin ) ?
15387 ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
15388 0;
15389 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
15390 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
15391
15392 if ( oRange === "min" && this.orientation === "horizontal" ) {
15393 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15394 width: valPercent + "%"
15395 }, o.animate );
15396 }
15397 if ( oRange === "max" && this.orientation === "horizontal" ) {
15398 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15399 width: ( 100 - valPercent ) + "%"
15400 }, o.animate );
15401 }
15402 if ( oRange === "min" && this.orientation === "vertical" ) {
15403 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15404 height: valPercent + "%"
15405 }, o.animate );
15406 }
15407 if ( oRange === "max" && this.orientation === "vertical" ) {
15408 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15409 height: ( 100 - valPercent ) + "%"
15410 }, o.animate );
15411 }
15412 }
15413 },
15414
15415 _handleEvents: {
15416 keydown: function( event ) {
15417 var allowed, curVal, newVal, step,
15418 index = $( event.target ).data( "ui-slider-handle-index" );
15419
15420 switch ( event.keyCode ) {
15421 case $.ui.keyCode.HOME:
15422 case $.ui.keyCode.END:
15423 case $.ui.keyCode.PAGE_UP:
15424 case $.ui.keyCode.PAGE_DOWN:
15425 case $.ui.keyCode.UP:
15426 case $.ui.keyCode.RIGHT:
15427 case $.ui.keyCode.DOWN:
15428 case $.ui.keyCode.LEFT:
15429 event.preventDefault();
15430 if ( !this._keySliding ) {
15431 this._keySliding = true;
15432 this._addClass( $( event.target ), null, "ui-state-active" );
15433 allowed = this._start( event, index );
15434 if ( allowed === false ) {
15435 return;
15436 }
15437 }
15438 break;
15439 }
15440
15441 step = this.options.step;
15442 if ( this._hasMultipleValues() ) {
15443 curVal = newVal = this.values( index );
15444 } else {
15445 curVal = newVal = this.value();
15446 }
15447
15448 switch ( event.keyCode ) {
15449 case $.ui.keyCode.HOME:
15450 newVal = this._valueMin();
15451 break;
15452 case $.ui.keyCode.END:
15453 newVal = this._valueMax();
15454 break;
15455 case $.ui.keyCode.PAGE_UP:
15456 newVal = this._trimAlignValue(
15457 curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
15458 );
15459 break;
15460 case $.ui.keyCode.PAGE_DOWN:
15461 newVal = this._trimAlignValue(
15462 curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) );
15463 break;
15464 case $.ui.keyCode.UP:
15465 case $.ui.keyCode.RIGHT:
15466 if ( curVal === this._valueMax() ) {
15467 return;
15468 }
15469 newVal = this._trimAlignValue( curVal + step );
15470 break;
15471 case $.ui.keyCode.DOWN:
15472 case $.ui.keyCode.LEFT:
15473 if ( curVal === this._valueMin() ) {
15474 return;
15475 }
15476 newVal = this._trimAlignValue( curVal - step );
15477 break;
15478 }
15479
15480 this._slide( event, index, newVal );
15481 },
15482 keyup: function( event ) {
15483 var index = $( event.target ).data( "ui-slider-handle-index" );
15484
15485 if ( this._keySliding ) {
15486 this._keySliding = false;
15487 this._stop( event, index );
15488 this._change( event, index );
15489 this._removeClass( $( event.target ), null, "ui-state-active" );
15490 }
15491 }
15492 }
15493 } );
15494
15495
15496 /*!
15497 * jQuery UI Sortable 1.13.2
15498 * http://jqueryui.com
15499 *
15500 * Copyright jQuery Foundation and other contributors
15501 * Released under the MIT license.
15502 * http://jquery.org/license
15503 */
15504
15505 //>>label: Sortable
15506 //>>group: Interactions
15507 //>>description: Enables items in a list to be sorted using the mouse.
15508 //>>docs: http://api.jqueryui.com/sortable/
15509 //>>demos: http://jqueryui.com/sortable/
15510 //>>css.structure: ../../themes/base/sortable.css
15511
15512
15513 var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, {
15514 version: "1.13.2",
15515 widgetEventPrefix: "sort",
15516 ready: false,
15517 options: {
15518 appendTo: "parent",
15519 axis: false,
15520 connectWith: false,
15521 containment: false,
15522 cursor: "auto",
15523 cursorAt: false,
15524 dropOnEmpty: true,
15525 forcePlaceholderSize: false,
15526 forceHelperSize: false,
15527 grid: false,
15528 handle: false,
15529 helper: "original",
15530 items: "> *",
15531 opacity: false,
15532 placeholder: false,
15533 revert: false,
15534 scroll: true,
15535 scrollSensitivity: 20,
15536 scrollSpeed: 20,
15537 scope: "default",
15538 tolerance: "intersect",
15539 zIndex: 1000,
15540
15541 // Callbacks
15542 activate: null,
15543 beforeStop: null,
15544 change: null,
15545 deactivate: null,
15546 out: null,
15547 over: null,
15548 receive: null,
15549 remove: null,
15550 sort: null,
15551 start: null,
15552 stop: null,
15553 update: null
15554 },
15555
15556 _isOverAxis: function( x, reference, size ) {
15557 return ( x >= reference ) && ( x < ( reference + size ) );
15558 },
15559
15560 _isFloating: function( item ) {
15561 return ( /left|right/ ).test( item.css( "float" ) ) ||
15562 ( /inline|table-cell/ ).test( item.css( "display" ) );
15563 },
15564
15565 _create: function() {
15566 this.containerCache = {};
15567 this._addClass( "ui-sortable" );
15568
15569 //Get the items
15570 this.refresh();
15571
15572 //Let's determine the parent's offset
15573 this.offset = this.element.offset();
15574
15575 //Initialize mouse events for interaction
15576 this._mouseInit();
15577
15578 this._setHandleClassName();
15579
15580 //We're ready to go
15581 this.ready = true;
15582
15583 },
15584
15585 _setOption: function( key, value ) {
15586 this._super( key, value );
15587
15588 if ( key === "handle" ) {
15589 this._setHandleClassName();
15590 }
15591 },
15592
15593 _setHandleClassName: function() {
15594 var that = this;
15595 this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" );
15596 $.each( this.items, function() {
15597 that._addClass(
15598 this.instance.options.handle ?
15599 this.item.find( this.instance.options.handle ) :
15600 this.item,
15601 "ui-sortable-handle"
15602 );
15603 } );
15604 },
15605
15606 _destroy: function() {
15607 this._mouseDestroy();
15608
15609 for ( var i = this.items.length - 1; i >= 0; i-- ) {
15610 this.items[ i ].item.removeData( this.widgetName + "-item" );
15611 }
15612
15613 return this;
15614 },
15615
15616 _mouseCapture: function( event, overrideHandle ) {
15617 var currentItem = null,
15618 validHandle = false,
15619 that = this;
15620
15621 if ( this.reverting ) {
15622 return false;
15623 }
15624
15625 if ( this.options.disabled || this.options.type === "static" ) {
15626 return false;
15627 }
15628
15629 //We have to refresh the items data once first
15630 this._refreshItems( event );
15631
15632 //Find out if the clicked node (or one of its parents) is a actual item in this.items
15633 $( event.target ).parents().each( function() {
15634 if ( $.data( this, that.widgetName + "-item" ) === that ) {
15635 currentItem = $( this );
15636 return false;
15637 }
15638 } );
15639 if ( $.data( event.target, that.widgetName + "-item" ) === that ) {
15640 currentItem = $( event.target );
15641 }
15642
15643 if ( !currentItem ) {
15644 return false;
15645 }
15646 if ( this.options.handle && !overrideHandle ) {
15647 $( this.options.handle, currentItem ).find( "*" ).addBack().each( function() {
15648 if ( this === event.target ) {
15649 validHandle = true;
15650 }
15651 } );
15652 if ( !validHandle ) {
15653 return false;
15654 }
15655 }
15656
15657 this.currentItem = currentItem;
15658 this._removeCurrentsFromItems();
15659 return true;
15660
15661 },
15662
15663 _mouseStart: function( event, overrideHandle, noActivation ) {
15664
15665 var i, body,
15666 o = this.options;
15667
15668 this.currentContainer = this;
15669
15670 //We only need to call refreshPositions, because the refreshItems call has been moved to
15671 // mouseCapture
15672 this.refreshPositions();
15673
15674 //Prepare the dragged items parent
15675 this.appendTo = $( o.appendTo !== "parent" ?
15676 o.appendTo :
15677 this.currentItem.parent() );
15678
15679 //Create and append the visible helper
15680 this.helper = this._createHelper( event );
15681
15682 //Cache the helper size
15683 this._cacheHelperProportions();
15684
15685 /*
15686 * - Position generation -
15687 * This block generates everything position related - it's the core of draggables.
15688 */
15689
15690 //Cache the margins of the original element
15691 this._cacheMargins();
15692
15693 //The element's absolute position on the page minus margins
15694 this.offset = this.currentItem.offset();
15695 this.offset = {
15696 top: this.offset.top - this.margins.top,
15697 left: this.offset.left - this.margins.left
15698 };
15699
15700 $.extend( this.offset, {
15701 click: { //Where the click happened, relative to the element
15702 left: event.pageX - this.offset.left,
15703 top: event.pageY - this.offset.top
15704 },
15705
15706 // This is a relative to absolute position minus the actual position calculation -
15707 // only used for relative positioned helper
15708 relative: this._getRelativeOffset()
15709 } );
15710
15711 // After we get the helper offset, but before we get the parent offset we can
15712 // change the helper's position to absolute
15713 // TODO: Still need to figure out a way to make relative sorting possible
15714 this.helper.css( "position", "absolute" );
15715 this.cssPosition = this.helper.css( "position" );
15716
15717 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
15718 if ( o.cursorAt ) {
15719 this._adjustOffsetFromHelper( o.cursorAt );
15720 }
15721
15722 //Cache the former DOM position
15723 this.domPosition = {
15724 prev: this.currentItem.prev()[ 0 ],
15725 parent: this.currentItem.parent()[ 0 ]
15726 };
15727
15728 // If the helper is not the original, hide the original so it's not playing any role during
15729 // the drag, won't cause anything bad this way
15730 if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
15731 this.currentItem.hide();
15732 }
15733
15734 //Create the placeholder
15735 this._createPlaceholder();
15736
15737 //Get the next scrolling parent
15738 this.scrollParent = this.placeholder.scrollParent();
15739
15740 $.extend( this.offset, {
15741 parent: this._getParentOffset()
15742 } );
15743
15744 //Set a containment if given in the options
15745 if ( o.containment ) {
15746 this._setContainment();
15747 }
15748
15749 if ( o.cursor && o.cursor !== "auto" ) { // cursor option
15750 body = this.document.find( "body" );
15751
15752 // Support: IE
15753 this.storedCursor = body.css( "cursor" );
15754 body.css( "cursor", o.cursor );
15755
15756 this.storedStylesheet =
15757 $( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body );
15758 }
15759
15760 // We need to make sure to grab the zIndex before setting the
15761 // opacity, because setting the opacity to anything lower than 1
15762 // causes the zIndex to change from "auto" to 0.
15763 if ( o.zIndex ) { // zIndex option
15764 if ( this.helper.css( "zIndex" ) ) {
15765 this._storedZIndex = this.helper.css( "zIndex" );
15766 }
15767 this.helper.css( "zIndex", o.zIndex );
15768 }
15769
15770 if ( o.opacity ) { // opacity option
15771 if ( this.helper.css( "opacity" ) ) {
15772 this._storedOpacity = this.helper.css( "opacity" );
15773 }
15774 this.helper.css( "opacity", o.opacity );
15775 }
15776
15777 //Prepare scrolling
15778 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
15779 this.scrollParent[ 0 ].tagName !== "HTML" ) {
15780 this.overflowOffset = this.scrollParent.offset();
15781 }
15782
15783 //Call callbacks
15784 this._trigger( "start", event, this._uiHash() );
15785
15786 //Recache the helper size
15787 if ( !this._preserveHelperProportions ) {
15788 this._cacheHelperProportions();
15789 }
15790
15791 //Post "activate" events to possible containers
15792 if ( !noActivation ) {
15793 for ( i = this.containers.length - 1; i >= 0; i-- ) {
15794 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
15795 }
15796 }
15797
15798 //Prepare possible droppables
15799 if ( $.ui.ddmanager ) {
15800 $.ui.ddmanager.current = this;
15801 }
15802
15803 if ( $.ui.ddmanager && !o.dropBehaviour ) {
15804 $.ui.ddmanager.prepareOffsets( this, event );
15805 }
15806
15807 this.dragging = true;
15808
15809 this._addClass( this.helper, "ui-sortable-helper" );
15810
15811 //Move the helper, if needed
15812 if ( !this.helper.parent().is( this.appendTo ) ) {
15813 this.helper.detach().appendTo( this.appendTo );
15814
15815 //Update position
15816 this.offset.parent = this._getParentOffset();
15817 }
15818
15819 //Generate the original position
15820 this.position = this.originalPosition = this._generatePosition( event );
15821 this.originalPageX = event.pageX;
15822 this.originalPageY = event.pageY;
15823 this.lastPositionAbs = this.positionAbs = this._convertPositionTo( "absolute" );
15824
15825 this._mouseDrag( event );
15826
15827 return true;
15828
15829 },
15830
15831 _scroll: function( event ) {
15832 var o = this.options,
15833 scrolled = false;
15834
15835 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
15836 this.scrollParent[ 0 ].tagName !== "HTML" ) {
15837
15838 if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -
15839 event.pageY < o.scrollSensitivity ) {
15840 this.scrollParent[ 0 ].scrollTop =
15841 scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;
15842 } else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {
15843 this.scrollParent[ 0 ].scrollTop =
15844 scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;
15845 }
15846
15847 if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -
15848 event.pageX < o.scrollSensitivity ) {
15849 this.scrollParent[ 0 ].scrollLeft = scrolled =
15850 this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;
15851 } else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {
15852 this.scrollParent[ 0 ].scrollLeft = scrolled =
15853 this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;
15854 }
15855
15856 } else {
15857
15858 if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {
15859 scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );
15860 } else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <
15861 o.scrollSensitivity ) {
15862 scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );
15863 }
15864
15865 if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {
15866 scrolled = this.document.scrollLeft(
15867 this.document.scrollLeft() - o.scrollSpeed
15868 );
15869 } else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <
15870 o.scrollSensitivity ) {
15871 scrolled = this.document.scrollLeft(
15872 this.document.scrollLeft() + o.scrollSpeed
15873 );
15874 }
15875
15876 }
15877
15878 return scrolled;
15879 },
15880
15881 _mouseDrag: function( event ) {
15882 var i, item, itemElement, intersection,
15883 o = this.options;
15884
15885 //Compute the helpers position
15886 this.position = this._generatePosition( event );
15887 this.positionAbs = this._convertPositionTo( "absolute" );
15888
15889 //Set the helper position
15890 if ( !this.options.axis || this.options.axis !== "y" ) {
15891 this.helper[ 0 ].style.left = this.position.left + "px";
15892 }
15893 if ( !this.options.axis || this.options.axis !== "x" ) {
15894 this.helper[ 0 ].style.top = this.position.top + "px";
15895 }
15896
15897 //Do scrolling
15898 if ( o.scroll ) {
15899 if ( this._scroll( event ) !== false ) {
15900
15901 //Update item positions used in position checks
15902 this._refreshItemPositions( true );
15903
15904 if ( $.ui.ddmanager && !o.dropBehaviour ) {
15905 $.ui.ddmanager.prepareOffsets( this, event );
15906 }
15907 }
15908 }
15909
15910 this.dragDirection = {
15911 vertical: this._getDragVerticalDirection(),
15912 horizontal: this._getDragHorizontalDirection()
15913 };
15914
15915 //Rearrange
15916 for ( i = this.items.length - 1; i >= 0; i-- ) {
15917
15918 //Cache variables and intersection, continue if no intersection
15919 item = this.items[ i ];
15920 itemElement = item.item[ 0 ];
15921 intersection = this._intersectsWithPointer( item );
15922 if ( !intersection ) {
15923 continue;
15924 }
15925
15926 // Only put the placeholder inside the current Container, skip all
15927 // items from other containers. This works because when moving
15928 // an item from one container to another the
15929 // currentContainer is switched before the placeholder is moved.
15930 //
15931 // Without this, moving items in "sub-sortables" can cause
15932 // the placeholder to jitter between the outer and inner container.
15933 if ( item.instance !== this.currentContainer ) {
15934 continue;
15935 }
15936
15937 // Cannot intersect with itself
15938 // no useless actions that have been done before
15939 // no action if the item moved is the parent of the item checked
15940 if ( itemElement !== this.currentItem[ 0 ] &&
15941 this.placeholder[ intersection === 1 ?
15942 "next" : "prev" ]()[ 0 ] !== itemElement &&
15943 !$.contains( this.placeholder[ 0 ], itemElement ) &&
15944 ( this.options.type === "semi-dynamic" ?
15945 !$.contains( this.element[ 0 ], itemElement ) :
15946 true
15947 )
15948 ) {
15949
15950 this.direction = intersection === 1 ? "down" : "up";
15951
15952 if ( this.options.tolerance === "pointer" ||
15953 this._intersectsWithSides( item ) ) {
15954 this._rearrange( event, item );
15955 } else {
15956 break;
15957 }
15958
15959 this._trigger( "change", event, this._uiHash() );
15960 break;
15961 }
15962 }
15963
15964 //Post events to containers
15965 this._contactContainers( event );
15966
15967 //Interconnect with droppables
15968 if ( $.ui.ddmanager ) {
15969 $.ui.ddmanager.drag( this, event );
15970 }
15971
15972 //Call callbacks
15973 this._trigger( "sort", event, this._uiHash() );
15974
15975 this.lastPositionAbs = this.positionAbs;
15976 return false;
15977
15978 },
15979
15980 _mouseStop: function( event, noPropagation ) {
15981
15982 if ( !event ) {
15983 return;
15984 }
15985
15986 //If we are using droppables, inform the manager about the drop
15987 if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
15988 $.ui.ddmanager.drop( this, event );
15989 }
15990
15991 if ( this.options.revert ) {
15992 var that = this,
15993 cur = this.placeholder.offset(),
15994 axis = this.options.axis,
15995 animation = {};
15996
15997 if ( !axis || axis === "x" ) {
15998 animation.left = cur.left - this.offset.parent.left - this.margins.left +
15999 ( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
16000 0 :
16001 this.offsetParent[ 0 ].scrollLeft
16002 );
16003 }
16004 if ( !axis || axis === "y" ) {
16005 animation.top = cur.top - this.offset.parent.top - this.margins.top +
16006 ( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
16007 0 :
16008 this.offsetParent[ 0 ].scrollTop
16009 );
16010 }
16011 this.reverting = true;
16012 $( this.helper ).animate(
16013 animation,
16014 parseInt( this.options.revert, 10 ) || 500,
16015 function() {
16016 that._clear( event );
16017 }
16018 );
16019 } else {
16020 this._clear( event, noPropagation );
16021 }
16022
16023 return false;
16024
16025 },
16026
16027 cancel: function() {
16028
16029 if ( this.dragging ) {
16030
16031 this._mouseUp( new $.Event( "mouseup", { target: null } ) );
16032
16033 if ( this.options.helper === "original" ) {
16034 this.currentItem.css( this._storedCSS );
16035 this._removeClass( this.currentItem, "ui-sortable-helper" );
16036 } else {
16037 this.currentItem.show();
16038 }
16039
16040 //Post deactivating events to containers
16041 for ( var i = this.containers.length - 1; i >= 0; i-- ) {
16042 this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) );
16043 if ( this.containers[ i ].containerCache.over ) {
16044 this.containers[ i ]._trigger( "out", null, this._uiHash( this ) );
16045 this.containers[ i ].containerCache.over = 0;
16046 }
16047 }
16048
16049 }
16050
16051 if ( this.placeholder ) {
16052
16053 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
16054 // it unbinds ALL events from the original node!
16055 if ( this.placeholder[ 0 ].parentNode ) {
16056 this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
16057 }
16058 if ( this.options.helper !== "original" && this.helper &&
16059 this.helper[ 0 ].parentNode ) {
16060 this.helper.remove();
16061 }
16062
16063 $.extend( this, {
16064 helper: null,
16065 dragging: false,
16066 reverting: false,
16067 _noFinalSort: null
16068 } );
16069
16070 if ( this.domPosition.prev ) {
16071 $( this.domPosition.prev ).after( this.currentItem );
16072 } else {
16073 $( this.domPosition.parent ).prepend( this.currentItem );
16074 }
16075 }
16076
16077 return this;
16078
16079 },
16080
16081 serialize: function( o ) {
16082
16083 var items = this._getItemsAsjQuery( o && o.connected ),
16084 str = [];
16085 o = o || {};
16086
16087 $( items ).each( function() {
16088 var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" )
16089 .match( o.expression || ( /(.+)[\-=_](.+)/ ) );
16090 if ( res ) {
16091 str.push(
16092 ( o.key || res[ 1 ] + "[]" ) +
16093 "=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );
16094 }
16095 } );
16096
16097 if ( !str.length && o.key ) {
16098 str.push( o.key + "=" );
16099 }
16100
16101 return str.join( "&" );
16102
16103 },
16104
16105 toArray: function( o ) {
16106
16107 var items = this._getItemsAsjQuery( o && o.connected ),
16108 ret = [];
16109
16110 o = o || {};
16111
16112 items.each( function() {
16113 ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" );
16114 } );
16115 return ret;
16116
16117 },
16118
16119 /* Be careful with the following core functions */
16120 _intersectsWith: function( item ) {
16121
16122 var x1 = this.positionAbs.left,
16123 x2 = x1 + this.helperProportions.width,
16124 y1 = this.positionAbs.top,
16125 y2 = y1 + this.helperProportions.height,
16126 l = item.left,
16127 r = l + item.width,
16128 t = item.top,
16129 b = t + item.height,
16130 dyClick = this.offset.click.top,
16131 dxClick = this.offset.click.left,
16132 isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t &&
16133 ( y1 + dyClick ) < b ),
16134 isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l &&
16135 ( x1 + dxClick ) < r ),
16136 isOverElement = isOverElementHeight && isOverElementWidth;
16137
16138 if ( this.options.tolerance === "pointer" ||
16139 this.options.forcePointerForContainers ||
16140 ( this.options.tolerance !== "pointer" &&
16141 this.helperProportions[ this.floating ? "width" : "height" ] >
16142 item[ this.floating ? "width" : "height" ] )
16143 ) {
16144 return isOverElement;
16145 } else {
16146
16147 return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half
16148 x2 - ( this.helperProportions.width / 2 ) < r && // Left Half
16149 t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half
16150 y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half
16151
16152 }
16153 },
16154
16155 _intersectsWithPointer: function( item ) {
16156 var verticalDirection, horizontalDirection,
16157 isOverElementHeight = ( this.options.axis === "x" ) ||
16158 this._isOverAxis(
16159 this.positionAbs.top + this.offset.click.top, item.top, item.height ),
16160 isOverElementWidth = ( this.options.axis === "y" ) ||
16161 this._isOverAxis(
16162 this.positionAbs.left + this.offset.click.left, item.left, item.width ),
16163 isOverElement = isOverElementHeight && isOverElementWidth;
16164
16165 if ( !isOverElement ) {
16166 return false;
16167 }
16168
16169 verticalDirection = this.dragDirection.vertical;
16170 horizontalDirection = this.dragDirection.horizontal;
16171
16172 return this.floating ?
16173 ( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 ) :
16174 ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) );
16175
16176 },
16177
16178 _intersectsWithSides: function( item ) {
16179
16180 var isOverBottomHalf = this._isOverAxis( this.positionAbs.top +
16181 this.offset.click.top, item.top + ( item.height / 2 ), item.height ),
16182 isOverRightHalf = this._isOverAxis( this.positionAbs.left +
16183 this.offset.click.left, item.left + ( item.width / 2 ), item.width ),
16184 verticalDirection = this.dragDirection.vertical,
16185 horizontalDirection = this.dragDirection.horizontal;
16186
16187 if ( this.floating && horizontalDirection ) {
16188 return ( ( horizontalDirection === "right" && isOverRightHalf ) ||
16189 ( horizontalDirection === "left" && !isOverRightHalf ) );
16190 } else {
16191 return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) ||
16192 ( verticalDirection === "up" && !isOverBottomHalf ) );
16193 }
16194
16195 },
16196
16197 _getDragVerticalDirection: function() {
16198 var delta = this.positionAbs.top - this.lastPositionAbs.top;
16199 return delta !== 0 && ( delta > 0 ? "down" : "up" );
16200 },
16201
16202 _getDragHorizontalDirection: function() {
16203 var delta = this.positionAbs.left - this.lastPositionAbs.left;
16204 return delta !== 0 && ( delta > 0 ? "right" : "left" );
16205 },
16206
16207 refresh: function( event ) {
16208 this._refreshItems( event );
16209 this._setHandleClassName();
16210 this.refreshPositions();
16211 return this;
16212 },
16213
16214 _connectWith: function() {
16215 var options = this.options;
16216 return options.connectWith.constructor === String ?
16217 [ options.connectWith ] :
16218 options.connectWith;
16219 },
16220
16221 _getItemsAsjQuery: function( connected ) {
16222
16223 var i, j, cur, inst,
16224 items = [],
16225 queries = [],
16226 connectWith = this._connectWith();
16227
16228 if ( connectWith && connected ) {
16229 for ( i = connectWith.length - 1; i >= 0; i-- ) {
16230 cur = $( connectWith[ i ], this.document[ 0 ] );
16231 for ( j = cur.length - 1; j >= 0; j-- ) {
16232 inst = $.data( cur[ j ], this.widgetFullName );
16233 if ( inst && inst !== this && !inst.options.disabled ) {
16234 queries.push( [ typeof inst.options.items === "function" ?
16235 inst.options.items.call( inst.element ) :
16236 $( inst.options.items, inst.element )
16237 .not( ".ui-sortable-helper" )
16238 .not( ".ui-sortable-placeholder" ), inst ] );
16239 }
16240 }
16241 }
16242 }
16243
16244 queries.push( [ typeof this.options.items === "function" ?
16245 this.options.items
16246 .call( this.element, null, { options: this.options, item: this.currentItem } ) :
16247 $( this.options.items, this.element )
16248 .not( ".ui-sortable-helper" )
16249 .not( ".ui-sortable-placeholder" ), this ] );
16250
16251 function addItems() {
16252 items.push( this );
16253 }
16254 for ( i = queries.length - 1; i >= 0; i-- ) {
16255 queries[ i ][ 0 ].each( addItems );
16256 }
16257
16258 return $( items );
16259
16260 },
16261
16262 _removeCurrentsFromItems: function() {
16263
16264 var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" );
16265
16266 this.items = $.grep( this.items, function( item ) {
16267 for ( var j = 0; j < list.length; j++ ) {
16268 if ( list[ j ] === item.item[ 0 ] ) {
16269 return false;
16270 }
16271 }
16272 return true;
16273 } );
16274
16275 },
16276
16277 _refreshItems: function( event ) {
16278
16279 this.items = [];
16280 this.containers = [ this ];
16281
16282 var i, j, cur, inst, targetData, _queries, item, queriesLength,
16283 items = this.items,
16284 queries = [ [ typeof this.options.items === "function" ?
16285 this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :
16286 $( this.options.items, this.element ), this ] ],
16287 connectWith = this._connectWith();
16288
16289 //Shouldn't be run the first time through due to massive slow-down
16290 if ( connectWith && this.ready ) {
16291 for ( i = connectWith.length - 1; i >= 0; i-- ) {
16292 cur = $( connectWith[ i ], this.document[ 0 ] );
16293 for ( j = cur.length - 1; j >= 0; j-- ) {
16294 inst = $.data( cur[ j ], this.widgetFullName );
16295 if ( inst && inst !== this && !inst.options.disabled ) {
16296 queries.push( [ typeof inst.options.items === "function" ?
16297 inst.options.items
16298 .call( inst.element[ 0 ], event, { item: this.currentItem } ) :
16299 $( inst.options.items, inst.element ), inst ] );
16300 this.containers.push( inst );
16301 }
16302 }
16303 }
16304 }
16305
16306 for ( i = queries.length - 1; i >= 0; i-- ) {
16307 targetData = queries[ i ][ 1 ];
16308 _queries = queries[ i ][ 0 ];
16309
16310 for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {
16311 item = $( _queries[ j ] );
16312
16313 // Data for target checking (mouse manager)
16314 item.data( this.widgetName + "-item", targetData );
16315
16316 items.push( {
16317 item: item,
16318 instance: targetData,
16319 width: 0, height: 0,
16320 left: 0, top: 0
16321 } );
16322 }
16323 }
16324
16325 },
16326
16327 _refreshItemPositions: function( fast ) {
16328 var i, item, t, p;
16329
16330 for ( i = this.items.length - 1; i >= 0; i-- ) {
16331 item = this.items[ i ];
16332
16333 //We ignore calculating positions of all connected containers when we're not over them
16334 if ( this.currentContainer && item.instance !== this.currentContainer &&
16335 item.item[ 0 ] !== this.currentItem[ 0 ] ) {
16336 continue;
16337 }
16338
16339 t = this.options.toleranceElement ?
16340 $( this.options.toleranceElement, item.item ) :
16341 item.item;
16342
16343 if ( !fast ) {
16344 item.width = t.outerWidth();
16345 item.height = t.outerHeight();
16346 }
16347
16348 p = t.offset();
16349 item.left = p.left;
16350 item.top = p.top;
16351 }
16352 },
16353
16354 refreshPositions: function( fast ) {
16355
16356 // Determine whether items are being displayed horizontally
16357 this.floating = this.items.length ?
16358 this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
16359 false;
16360
16361 // This has to be redone because due to the item being moved out/into the offsetParent,
16362 // the offsetParent's position will change
16363 if ( this.offsetParent && this.helper ) {
16364 this.offset.parent = this._getParentOffset();
16365 }
16366
16367 this._refreshItemPositions( fast );
16368
16369 var i, p;
16370
16371 if ( this.options.custom && this.options.custom.refreshContainers ) {
16372 this.options.custom.refreshContainers.call( this );
16373 } else {
16374 for ( i = this.containers.length - 1; i >= 0; i-- ) {
16375 p = this.containers[ i ].element.offset();
16376 this.containers[ i ].containerCache.left = p.left;
16377 this.containers[ i ].containerCache.top = p.top;
16378 this.containers[ i ].containerCache.width =
16379 this.containers[ i ].element.outerWidth();
16380 this.containers[ i ].containerCache.height =
16381 this.containers[ i ].element.outerHeight();
16382 }
16383 }
16384
16385 return this;
16386 },
16387
16388 _createPlaceholder: function( that ) {
16389 that = that || this;
16390 var className, nodeName,
16391 o = that.options;
16392
16393 if ( !o.placeholder || o.placeholder.constructor === String ) {
16394 className = o.placeholder;
16395 nodeName = that.currentItem[ 0 ].nodeName.toLowerCase();
16396 o.placeholder = {
16397 element: function() {
16398
16399 var element = $( "<" + nodeName + ">", that.document[ 0 ] );
16400
16401 that._addClass( element, "ui-sortable-placeholder",
16402 className || that.currentItem[ 0 ].className )
16403 ._removeClass( element, "ui-sortable-helper" );
16404
16405 if ( nodeName === "tbody" ) {
16406 that._createTrPlaceholder(
16407 that.currentItem.find( "tr" ).eq( 0 ),
16408 $( "<tr>", that.document[ 0 ] ).appendTo( element )
16409 );
16410 } else if ( nodeName === "tr" ) {
16411 that._createTrPlaceholder( that.currentItem, element );
16412 } else if ( nodeName === "img" ) {
16413 element.attr( "src", that.currentItem.attr( "src" ) );
16414 }
16415
16416 if ( !className ) {
16417 element.css( "visibility", "hidden" );
16418 }
16419
16420 return element;
16421 },
16422 update: function( container, p ) {
16423
16424 // 1. If a className is set as 'placeholder option, we don't force sizes -
16425 // the class is responsible for that
16426 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a
16427 // class name is specified
16428 if ( className && !o.forcePlaceholderSize ) {
16429 return;
16430 }
16431
16432 // If the element doesn't have a actual height or width by itself (without
16433 // styles coming from a stylesheet), it receives the inline height and width
16434 // from the dragged item. Or, if it's a tbody or tr, it's going to have a height
16435 // anyway since we're populating them with <td>s above, but they're unlikely to
16436 // be the correct height on their own if the row heights are dynamic, so we'll
16437 // always assign the height of the dragged item given forcePlaceholderSize
16438 // is true.
16439 if ( !p.height() || ( o.forcePlaceholderSize &&
16440 ( nodeName === "tbody" || nodeName === "tr" ) ) ) {
16441 p.height(
16442 that.currentItem.innerHeight() -
16443 parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) -
16444 parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) );
16445 }
16446 if ( !p.width() ) {
16447 p.width(
16448 that.currentItem.innerWidth() -
16449 parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) -
16450 parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) );
16451 }
16452 }
16453 };
16454 }
16455
16456 //Create the placeholder
16457 that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );
16458
16459 //Append it after the actual current item
16460 that.currentItem.after( that.placeholder );
16461
16462 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
16463 o.placeholder.update( that, that.placeholder );
16464
16465 },
16466
16467 _createTrPlaceholder: function( sourceTr, targetTr ) {
16468 var that = this;
16469
16470 sourceTr.children().each( function() {
16471 $( "<td>&#160;</td>", that.document[ 0 ] )
16472 .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
16473 .appendTo( targetTr );
16474 } );
16475 },
16476
16477 _contactContainers: function( event ) {
16478 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
16479 floating, axis,
16480 innermostContainer = null,
16481 innermostIndex = null;
16482
16483 // Get innermost container that intersects with item
16484 for ( i = this.containers.length - 1; i >= 0; i-- ) {
16485
16486 // Never consider a container that's located within the item itself
16487 if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {
16488 continue;
16489 }
16490
16491 if ( this._intersectsWith( this.containers[ i ].containerCache ) ) {
16492
16493 // If we've already found a container and it's more "inner" than this, then continue
16494 if ( innermostContainer &&
16495 $.contains(
16496 this.containers[ i ].element[ 0 ],
16497 innermostContainer.element[ 0 ] ) ) {
16498 continue;
16499 }
16500
16501 innermostContainer = this.containers[ i ];
16502 innermostIndex = i;
16503
16504 } else {
16505
16506 // container doesn't intersect. trigger "out" event if necessary
16507 if ( this.containers[ i ].containerCache.over ) {
16508 this.containers[ i ]._trigger( "out", event, this._uiHash( this ) );
16509 this.containers[ i ].containerCache.over = 0;
16510 }
16511 }
16512
16513 }
16514
16515 // If no intersecting containers found, return
16516 if ( !innermostContainer ) {
16517 return;
16518 }
16519
16520 // Move the item into the container if it's not there already
16521 if ( this.containers.length === 1 ) {
16522 if ( !this.containers[ innermostIndex ].containerCache.over ) {
16523 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
16524 this.containers[ innermostIndex ].containerCache.over = 1;
16525 }
16526 } else {
16527
16528 // When entering a new container, we will find the item with the least distance and
16529 // append our item near it
16530 dist = 10000;
16531 itemWithLeastDistance = null;
16532 floating = innermostContainer.floating || this._isFloating( this.currentItem );
16533 posProperty = floating ? "left" : "top";
16534 sizeProperty = floating ? "width" : "height";
16535 axis = floating ? "pageX" : "pageY";
16536
16537 for ( j = this.items.length - 1; j >= 0; j-- ) {
16538 if ( !$.contains(
16539 this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )
16540 ) {
16541 continue;
16542 }
16543 if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {
16544 continue;
16545 }
16546
16547 cur = this.items[ j ].item.offset()[ posProperty ];
16548 nearBottom = false;
16549 if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
16550 nearBottom = true;
16551 }
16552
16553 if ( Math.abs( event[ axis ] - cur ) < dist ) {
16554 dist = Math.abs( event[ axis ] - cur );
16555 itemWithLeastDistance = this.items[ j ];
16556 this.direction = nearBottom ? "up" : "down";
16557 }
16558 }
16559
16560 //Check if dropOnEmpty is enabled
16561 if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {
16562 return;
16563 }
16564
16565 if ( this.currentContainer === this.containers[ innermostIndex ] ) {
16566 if ( !this.currentContainer.containerCache.over ) {
16567 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
16568 this.currentContainer.containerCache.over = 1;
16569 }
16570 return;
16571 }
16572
16573 if ( itemWithLeastDistance ) {
16574 this._rearrange( event, itemWithLeastDistance, null, true );
16575 } else {
16576 this._rearrange( event, null, this.containers[ innermostIndex ].element, true );
16577 }
16578 this._trigger( "change", event, this._uiHash() );
16579 this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) );
16580 this.currentContainer = this.containers[ innermostIndex ];
16581
16582 //Update the placeholder
16583 this.options.placeholder.update( this.currentContainer, this.placeholder );
16584
16585 //Update scrollParent
16586 this.scrollParent = this.placeholder.scrollParent();
16587
16588 //Update overflowOffset
16589 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16590 this.scrollParent[ 0 ].tagName !== "HTML" ) {
16591 this.overflowOffset = this.scrollParent.offset();
16592 }
16593
16594 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
16595 this.containers[ innermostIndex ].containerCache.over = 1;
16596 }
16597
16598 },
16599
16600 _createHelper: function( event ) {
16601
16602 var o = this.options,
16603 helper = typeof o.helper === "function" ?
16604 $( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :
16605 ( o.helper === "clone" ? this.currentItem.clone() : this.currentItem );
16606
16607 //Add the helper to the DOM if that didn't happen already
16608 if ( !helper.parents( "body" ).length ) {
16609 this.appendTo[ 0 ].appendChild( helper[ 0 ] );
16610 }
16611
16612 if ( helper[ 0 ] === this.currentItem[ 0 ] ) {
16613 this._storedCSS = {
16614 width: this.currentItem[ 0 ].style.width,
16615 height: this.currentItem[ 0 ].style.height,
16616 position: this.currentItem.css( "position" ),
16617 top: this.currentItem.css( "top" ),
16618 left: this.currentItem.css( "left" )
16619 };
16620 }
16621
16622 if ( !helper[ 0 ].style.width || o.forceHelperSize ) {
16623 helper.width( this.currentItem.width() );
16624 }
16625 if ( !helper[ 0 ].style.height || o.forceHelperSize ) {
16626 helper.height( this.currentItem.height() );
16627 }
16628
16629 return helper;
16630
16631 },
16632
16633 _adjustOffsetFromHelper: function( obj ) {
16634 if ( typeof obj === "string" ) {
16635 obj = obj.split( " " );
16636 }
16637 if ( Array.isArray( obj ) ) {
16638 obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
16639 }
16640 if ( "left" in obj ) {
16641 this.offset.click.left = obj.left + this.margins.left;
16642 }
16643 if ( "right" in obj ) {
16644 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
16645 }
16646 if ( "top" in obj ) {
16647 this.offset.click.top = obj.top + this.margins.top;
16648 }
16649 if ( "bottom" in obj ) {
16650 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
16651 }
16652 },
16653
16654 _getParentOffset: function() {
16655
16656 //Get the offsetParent and cache its position
16657 this.offsetParent = this.helper.offsetParent();
16658 var po = this.offsetParent.offset();
16659
16660 // This is a special case where we need to modify a offset calculated on start, since the
16661 // following happened:
16662 // 1. The position of the helper is absolute, so it's position is calculated based on the
16663 // next positioned parent
16664 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
16665 // the document, which means that the scroll is included in the initial calculation of the
16666 // offset of the parent, and never recalculated upon drag
16667 if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16668 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
16669 po.left += this.scrollParent.scrollLeft();
16670 po.top += this.scrollParent.scrollTop();
16671 }
16672
16673 // This needs to be actually done for all browsers, since pageX/pageY includes this
16674 // information with an ugly IE fix
16675 if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ||
16676 ( this.offsetParent[ 0 ].tagName &&
16677 this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) {
16678 po = { top: 0, left: 0 };
16679 }
16680
16681 return {
16682 top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
16683 left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
16684 };
16685
16686 },
16687
16688 _getRelativeOffset: function() {
16689
16690 if ( this.cssPosition === "relative" ) {
16691 var p = this.currentItem.position();
16692 return {
16693 top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
16694 this.scrollParent.scrollTop(),
16695 left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
16696 this.scrollParent.scrollLeft()
16697 };
16698 } else {
16699 return { top: 0, left: 0 };
16700 }
16701
16702 },
16703
16704 _cacheMargins: function() {
16705 this.margins = {
16706 left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ),
16707 top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 )
16708 };
16709 },
16710
16711 _cacheHelperProportions: function() {
16712 this.helperProportions = {
16713 width: this.helper.outerWidth(),
16714 height: this.helper.outerHeight()
16715 };
16716 },
16717
16718 _setContainment: function() {
16719
16720 var ce, co, over,
16721 o = this.options;
16722 if ( o.containment === "parent" ) {
16723 o.containment = this.helper[ 0 ].parentNode;
16724 }
16725 if ( o.containment === "document" || o.containment === "window" ) {
16726 this.containment = [
16727 0 - this.offset.relative.left - this.offset.parent.left,
16728 0 - this.offset.relative.top - this.offset.parent.top,
16729 o.containment === "document" ?
16730 this.document.width() :
16731 this.window.width() - this.helperProportions.width - this.margins.left,
16732 ( o.containment === "document" ?
16733 ( this.document.height() || document.body.parentNode.scrollHeight ) :
16734 this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight
16735 ) - this.helperProportions.height - this.margins.top
16736 ];
16737 }
16738
16739 if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {
16740 ce = $( o.containment )[ 0 ];
16741 co = $( o.containment ).offset();
16742 over = ( $( ce ).css( "overflow" ) !== "hidden" );
16743
16744 this.containment = [
16745 co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) +
16746 ( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left,
16747 co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) +
16748 ( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top,
16749 co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
16750 ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) -
16751 ( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) -
16752 this.helperProportions.width - this.margins.left,
16753 co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
16754 ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) -
16755 ( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) -
16756 this.helperProportions.height - this.margins.top
16757 ];
16758 }
16759
16760 },
16761
16762 _convertPositionTo: function( d, pos ) {
16763
16764 if ( !pos ) {
16765 pos = this.position;
16766 }
16767 var mod = d === "absolute" ? 1 : -1,
16768 scroll = this.cssPosition === "absolute" &&
16769 !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16770 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
16771 this.offsetParent :
16772 this.scrollParent,
16773 scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
16774
16775 return {
16776 top: (
16777
16778 // The absolute mouse position
16779 pos.top +
16780
16781 // Only for relative positioned nodes: Relative offset from element to offset parent
16782 this.offset.relative.top * mod +
16783
16784 // The offsetParent's offset without borders (offset + border)
16785 this.offset.parent.top * mod -
16786 ( ( this.cssPosition === "fixed" ?
16787 -this.scrollParent.scrollTop() :
16788 ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )
16789 ),
16790 left: (
16791
16792 // The absolute mouse position
16793 pos.left +
16794
16795 // Only for relative positioned nodes: Relative offset from element to offset parent
16796 this.offset.relative.left * mod +
16797
16798 // The offsetParent's offset without borders (offset + border)
16799 this.offset.parent.left * mod -
16800 ( ( this.cssPosition === "fixed" ?
16801 -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
16802 scroll.scrollLeft() ) * mod )
16803 )
16804 };
16805
16806 },
16807
16808 _generatePosition: function( event ) {
16809
16810 var top, left,
16811 o = this.options,
16812 pageX = event.pageX,
16813 pageY = event.pageY,
16814 scroll = this.cssPosition === "absolute" &&
16815 !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16816 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
16817 this.offsetParent :
16818 this.scrollParent,
16819 scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
16820
16821 // This is another very weird special case that only happens for relative elements:
16822 // 1. If the css position is relative
16823 // 2. and the scroll parent is the document or similar to the offset parent
16824 // we have to refresh the relative offset during the scroll so there are no jumps
16825 if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16826 this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {
16827 this.offset.relative = this._getRelativeOffset();
16828 }
16829
16830 /*
16831 * - Position constraining -
16832 * Constrain the position to a mix of grid, containment.
16833 */
16834
16835 if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options
16836
16837 if ( this.containment ) {
16838 if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {
16839 pageX = this.containment[ 0 ] + this.offset.click.left;
16840 }
16841 if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {
16842 pageY = this.containment[ 1 ] + this.offset.click.top;
16843 }
16844 if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {
16845 pageX = this.containment[ 2 ] + this.offset.click.left;
16846 }
16847 if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {
16848 pageY = this.containment[ 3 ] + this.offset.click.top;
16849 }
16850 }
16851
16852 if ( o.grid ) {
16853 top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /
16854 o.grid[ 1 ] ) * o.grid[ 1 ];
16855 pageY = this.containment ?
16856 ( ( top - this.offset.click.top >= this.containment[ 1 ] &&
16857 top - this.offset.click.top <= this.containment[ 3 ] ) ?
16858 top :
16859 ( ( top - this.offset.click.top >= this.containment[ 1 ] ) ?
16860 top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) :
16861 top;
16862
16863 left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /
16864 o.grid[ 0 ] ) * o.grid[ 0 ];
16865 pageX = this.containment ?
16866 ( ( left - this.offset.click.left >= this.containment[ 0 ] &&
16867 left - this.offset.click.left <= this.containment[ 2 ] ) ?
16868 left :
16869 ( ( left - this.offset.click.left >= this.containment[ 0 ] ) ?
16870 left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) :
16871 left;
16872 }
16873
16874 }
16875
16876 return {
16877 top: (
16878
16879 // The absolute mouse position
16880 pageY -
16881
16882 // Click offset (relative to the element)
16883 this.offset.click.top -
16884
16885 // Only for relative positioned nodes: Relative offset from element to offset parent
16886 this.offset.relative.top -
16887
16888 // The offsetParent's offset without borders (offset + border)
16889 this.offset.parent.top +
16890 ( ( this.cssPosition === "fixed" ?
16891 -this.scrollParent.scrollTop() :
16892 ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )
16893 ),
16894 left: (
16895
16896 // The absolute mouse position
16897 pageX -
16898
16899 // Click offset (relative to the element)
16900 this.offset.click.left -
16901
16902 // Only for relative positioned nodes: Relative offset from element to offset parent
16903 this.offset.relative.left -
16904
16905 // The offsetParent's offset without borders (offset + border)
16906 this.offset.parent.left +
16907 ( ( this.cssPosition === "fixed" ?
16908 -this.scrollParent.scrollLeft() :
16909 scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
16910 )
16911 };
16912
16913 },
16914
16915 _rearrange: function( event, i, a, hardRefresh ) {
16916
16917 if ( a ) {
16918 a[ 0 ].appendChild( this.placeholder[ 0 ] );
16919 } else {
16920 i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ],
16921 ( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) );
16922 }
16923
16924 //Various things done here to improve the performance:
16925 // 1. we create a setTimeout, that calls refreshPositions
16926 // 2. on the instance, we have a counter variable, that get's higher after every append
16927 // 3. on the local scope, we copy the counter variable, and check in the timeout,
16928 // if it's still the same
16929 // 4. this lets only the last addition to the timeout stack through
16930 this.counter = this.counter ? ++this.counter : 1;
16931 var counter = this.counter;
16932
16933 this._delay( function() {
16934 if ( counter === this.counter ) {
16935
16936 //Precompute after each DOM insertion, NOT on mousemove
16937 this.refreshPositions( !hardRefresh );
16938 }
16939 } );
16940
16941 },
16942
16943 _clear: function( event, noPropagation ) {
16944
16945 this.reverting = false;
16946
16947 // We delay all events that have to be triggered to after the point where the placeholder
16948 // has been removed and everything else normalized again
16949 var i,
16950 delayedTriggers = [];
16951
16952 // We first have to update the dom position of the actual currentItem
16953 // Note: don't do it if the current item is already removed (by a user), or it gets
16954 // reappended (see #4088)
16955 if ( !this._noFinalSort && this.currentItem.parent().length ) {
16956 this.placeholder.before( this.currentItem );
16957 }
16958 this._noFinalSort = null;
16959
16960 if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {
16961 for ( i in this._storedCSS ) {
16962 if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) {
16963 this._storedCSS[ i ] = "";
16964 }
16965 }
16966 this.currentItem.css( this._storedCSS );
16967 this._removeClass( this.currentItem, "ui-sortable-helper" );
16968 } else {
16969 this.currentItem.show();
16970 }
16971
16972 if ( this.fromOutside && !noPropagation ) {
16973 delayedTriggers.push( function( event ) {
16974 this._trigger( "receive", event, this._uiHash( this.fromOutside ) );
16975 } );
16976 }
16977 if ( ( this.fromOutside ||
16978 this.domPosition.prev !==
16979 this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] ||
16980 this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {
16981
16982 // Trigger update callback if the DOM position has changed
16983 delayedTriggers.push( function( event ) {
16984 this._trigger( "update", event, this._uiHash() );
16985 } );
16986 }
16987
16988 // Check if the items Container has Changed and trigger appropriate
16989 // events.
16990 if ( this !== this.currentContainer ) {
16991 if ( !noPropagation ) {
16992 delayedTriggers.push( function( event ) {
16993 this._trigger( "remove", event, this._uiHash() );
16994 } );
16995 delayedTriggers.push( ( function( c ) {
16996 return function( event ) {
16997 c._trigger( "receive", event, this._uiHash( this ) );
16998 };
16999 } ).call( this, this.currentContainer ) );
17000 delayedTriggers.push( ( function( c ) {
17001 return function( event ) {
17002 c._trigger( "update", event, this._uiHash( this ) );
17003 };
17004 } ).call( this, this.currentContainer ) );
17005 }
17006 }
17007
17008 //Post events to containers
17009 function delayEvent( type, instance, container ) {
17010 return function( event ) {
17011 container._trigger( type, event, instance._uiHash( instance ) );
17012 };
17013 }
17014 for ( i = this.containers.length - 1; i >= 0; i-- ) {
17015 if ( !noPropagation ) {
17016 delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
17017 }
17018 if ( this.containers[ i ].containerCache.over ) {
17019 delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
17020 this.containers[ i ].containerCache.over = 0;
17021 }
17022 }
17023
17024 //Do what was originally in plugins
17025 if ( this.storedCursor ) {
17026 this.document.find( "body" ).css( "cursor", this.storedCursor );
17027 this.storedStylesheet.remove();
17028 }
17029 if ( this._storedOpacity ) {
17030 this.helper.css( "opacity", this._storedOpacity );
17031 }
17032 if ( this._storedZIndex ) {
17033 this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex );
17034 }
17035
17036 this.dragging = false;
17037
17038 if ( !noPropagation ) {
17039 this._trigger( "beforeStop", event, this._uiHash() );
17040 }
17041
17042 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
17043 // it unbinds ALL events from the original node!
17044 this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
17045
17046 if ( !this.cancelHelperRemoval ) {
17047 if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
17048 this.helper.remove();
17049 }
17050 this.helper = null;
17051 }
17052
17053 if ( !noPropagation ) {
17054 for ( i = 0; i < delayedTriggers.length; i++ ) {
17055
17056 // Trigger all delayed events
17057 delayedTriggers[ i ].call( this, event );
17058 }
17059 this._trigger( "stop", event, this._uiHash() );
17060 }
17061
17062 this.fromOutside = false;
17063 return !this.cancelHelperRemoval;
17064
17065 },
17066
17067 _trigger: function() {
17068 if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {
17069 this.cancel();
17070 }
17071 },
17072
17073 _uiHash: function( _inst ) {
17074 var inst = _inst || this;
17075 return {
17076 helper: inst.helper,
17077 placeholder: inst.placeholder || $( [] ),
17078 position: inst.position,
17079 originalPosition: inst.originalPosition,
17080 offset: inst.positionAbs,
17081 item: inst.currentItem,
17082 sender: _inst ? _inst.element : null
17083 };
17084 }
17085
17086 } );
17087
17088
17089 /*!
17090 * jQuery UI Spinner 1.13.2
17091 * http://jqueryui.com
17092 *
17093 * Copyright jQuery Foundation and other contributors
17094 * Released under the MIT license.
17095 * http://jquery.org/license
17096 */
17097
17098 //>>label: Spinner
17099 //>>group: Widgets
17100 //>>description: Displays buttons to easily input numbers via the keyboard or mouse.
17101 //>>docs: http://api.jqueryui.com/spinner/
17102 //>>demos: http://jqueryui.com/spinner/
17103 //>>css.structure: ../../themes/base/core.css
17104 //>>css.structure: ../../themes/base/spinner.css
17105 //>>css.theme: ../../themes/base/theme.css
17106
17107
17108 function spinnerModifier( fn ) {
17109 return function() {
17110 var previous = this.element.val();
17111 fn.apply( this, arguments );
17112 this._refresh();
17113 if ( previous !== this.element.val() ) {
17114 this._trigger( "change" );
17115 }
17116 };
17117 }
17118
17119 $.widget( "ui.spinner", {
17120 version: "1.13.2",
17121 defaultElement: "<input>",
17122 widgetEventPrefix: "spin",
17123 options: {
17124 classes: {
17125 "ui-spinner": "ui-corner-all",
17126 "ui-spinner-down": "ui-corner-br",
17127 "ui-spinner-up": "ui-corner-tr"
17128 },
17129 culture: null,
17130 icons: {
17131 down: "ui-icon-triangle-1-s",
17132 up: "ui-icon-triangle-1-n"
17133 },
17134 incremental: true,
17135 max: null,
17136 min: null,
17137 numberFormat: null,
17138 page: 10,
17139 step: 1,
17140
17141 change: null,
17142 spin: null,
17143 start: null,
17144 stop: null
17145 },
17146
17147 _create: function() {
17148
17149 // handle string values that need to be parsed
17150 this._setOption( "max", this.options.max );
17151 this._setOption( "min", this.options.min );
17152 this._setOption( "step", this.options.step );
17153
17154 // Only format if there is a value, prevents the field from being marked
17155 // as invalid in Firefox, see #9573.
17156 if ( this.value() !== "" ) {
17157
17158 // Format the value, but don't constrain.
17159 this._value( this.element.val(), true );
17160 }
17161
17162 this._draw();
17163 this._on( this._events );
17164 this._refresh();
17165
17166 // Turning off autocomplete prevents the browser from remembering the
17167 // value when navigating through history, so we re-enable autocomplete
17168 // if the page is unloaded before the widget is destroyed. #7790
17169 this._on( this.window, {
17170 beforeunload: function() {
17171 this.element.removeAttr( "autocomplete" );
17172 }
17173 } );
17174 },
17175
17176 _getCreateOptions: function() {
17177 var options = this._super();
17178 var element = this.element;
17179
17180 $.each( [ "min", "max", "step" ], function( i, option ) {
17181 var value = element.attr( option );
17182 if ( value != null && value.length ) {
17183 options[ option ] = value;
17184 }
17185 } );
17186
17187 return options;
17188 },
17189
17190 _events: {
17191 keydown: function( event ) {
17192 if ( this._start( event ) && this._keydown( event ) ) {
17193 event.preventDefault();
17194 }
17195 },
17196 keyup: "_stop",
17197 focus: function() {
17198 this.previous = this.element.val();
17199 },
17200 blur: function( event ) {
17201 if ( this.cancelBlur ) {
17202 delete this.cancelBlur;
17203 return;
17204 }
17205
17206 this._stop();
17207 this._refresh();
17208 if ( this.previous !== this.element.val() ) {
17209 this._trigger( "change", event );
17210 }
17211 },
17212 mousewheel: function( event, delta ) {
17213 var activeElement = $.ui.safeActiveElement( this.document[ 0 ] );
17214 var isActive = this.element[ 0 ] === activeElement;
17215
17216 if ( !isActive || !delta ) {
17217 return;
17218 }
17219
17220 if ( !this.spinning && !this._start( event ) ) {
17221 return false;
17222 }
17223
17224 this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event );
17225 clearTimeout( this.mousewheelTimer );
17226 this.mousewheelTimer = this._delay( function() {
17227 if ( this.spinning ) {
17228 this._stop( event );
17229 }
17230 }, 100 );
17231 event.preventDefault();
17232 },
17233 "mousedown .ui-spinner-button": function( event ) {
17234 var previous;
17235
17236 // We never want the buttons to have focus; whenever the user is
17237 // interacting with the spinner, the focus should be on the input.
17238 // If the input is focused then this.previous is properly set from
17239 // when the input first received focus. If the input is not focused
17240 // then we need to set this.previous based on the value before spinning.
17241 previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ?
17242 this.previous : this.element.val();
17243 function checkFocus() {
17244 var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] );
17245 if ( !isActive ) {
17246 this.element.trigger( "focus" );
17247 this.previous = previous;
17248
17249 // support: IE
17250 // IE sets focus asynchronously, so we need to check if focus
17251 // moved off of the input because the user clicked on the button.
17252 this._delay( function() {
17253 this.previous = previous;
17254 } );
17255 }
17256 }
17257
17258 // Ensure focus is on (or stays on) the text field
17259 event.preventDefault();
17260 checkFocus.call( this );
17261
17262 // Support: IE
17263 // IE doesn't prevent moving focus even with event.preventDefault()
17264 // so we set a flag to know when we should ignore the blur event
17265 // and check (again) if focus moved off of the input.
17266 this.cancelBlur = true;
17267 this._delay( function() {
17268 delete this.cancelBlur;
17269 checkFocus.call( this );
17270 } );
17271
17272 if ( this._start( event ) === false ) {
17273 return;
17274 }
17275
17276 this._repeat( null, $( event.currentTarget )
17277 .hasClass( "ui-spinner-up" ) ? 1 : -1, event );
17278 },
17279 "mouseup .ui-spinner-button": "_stop",
17280 "mouseenter .ui-spinner-button": function( event ) {
17281
17282 // button will add ui-state-active if mouse was down while mouseleave and kept down
17283 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
17284 return;
17285 }
17286
17287 if ( this._start( event ) === false ) {
17288 return false;
17289 }
17290 this._repeat( null, $( event.currentTarget )
17291 .hasClass( "ui-spinner-up" ) ? 1 : -1, event );
17292 },
17293
17294 // TODO: do we really want to consider this a stop?
17295 // shouldn't we just stop the repeater and wait until mouseup before
17296 // we trigger the stop event?
17297 "mouseleave .ui-spinner-button": "_stop"
17298 },
17299
17300 // Support mobile enhanced option and make backcompat more sane
17301 _enhance: function() {
17302 this.uiSpinner = this.element
17303 .attr( "autocomplete", "off" )
17304 .wrap( "<span>" )
17305 .parent()
17306
17307 // Add buttons
17308 .append(
17309 "<a></a><a></a>"
17310 );
17311 },
17312
17313 _draw: function() {
17314 this._enhance();
17315
17316 this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" );
17317 this._addClass( "ui-spinner-input" );
17318
17319 this.element.attr( "role", "spinbutton" );
17320
17321 // Button bindings
17322 this.buttons = this.uiSpinner.children( "a" )
17323 .attr( "tabIndex", -1 )
17324 .attr( "aria-hidden", true )
17325 .button( {
17326 classes: {
17327 "ui-button": ""
17328 }
17329 } );
17330
17331 // TODO: Right now button does not support classes this is already updated in button PR
17332 this._removeClass( this.buttons, "ui-corner-all" );
17333
17334 this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" );
17335 this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" );
17336 this.buttons.first().button( {
17337 "icon": this.options.icons.up,
17338 "showLabel": false
17339 } );
17340 this.buttons.last().button( {
17341 "icon": this.options.icons.down,
17342 "showLabel": false
17343 } );
17344
17345 // IE 6 doesn't understand height: 50% for the buttons
17346 // unless the wrapper has an explicit height
17347 if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) &&
17348 this.uiSpinner.height() > 0 ) {
17349 this.uiSpinner.height( this.uiSpinner.height() );
17350 }
17351 },
17352
17353 _keydown: function( event ) {
17354 var options = this.options,
17355 keyCode = $.ui.keyCode;
17356
17357 switch ( event.keyCode ) {
17358 case keyCode.UP:
17359 this._repeat( null, 1, event );
17360 return true;
17361 case keyCode.DOWN:
17362 this._repeat( null, -1, event );
17363 return true;
17364 case keyCode.PAGE_UP:
17365 this._repeat( null, options.page, event );
17366 return true;
17367 case keyCode.PAGE_DOWN:
17368 this._repeat( null, -options.page, event );
17369 return true;
17370 }
17371
17372 return false;
17373 },
17374
17375 _start: function( event ) {
17376 if ( !this.spinning && this._trigger( "start", event ) === false ) {
17377 return false;
17378 }
17379
17380 if ( !this.counter ) {
17381 this.counter = 1;
17382 }
17383 this.spinning = true;
17384 return true;
17385 },
17386
17387 _repeat: function( i, steps, event ) {
17388 i = i || 500;
17389
17390 clearTimeout( this.timer );
17391 this.timer = this._delay( function() {
17392 this._repeat( 40, steps, event );
17393 }, i );
17394
17395 this._spin( steps * this.options.step, event );
17396 },
17397
17398 _spin: function( step, event ) {
17399 var value = this.value() || 0;
17400
17401 if ( !this.counter ) {
17402 this.counter = 1;
17403 }
17404
17405 value = this._adjustValue( value + step * this._increment( this.counter ) );
17406
17407 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) {
17408 this._value( value );
17409 this.counter++;
17410 }
17411 },
17412
17413 _increment: function( i ) {
17414 var incremental = this.options.incremental;
17415
17416 if ( incremental ) {
17417 return typeof incremental === "function" ?
17418 incremental( i ) :
17419 Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
17420 }
17421
17422 return 1;
17423 },
17424
17425 _precision: function() {
17426 var precision = this._precisionOf( this.options.step );
17427 if ( this.options.min !== null ) {
17428 precision = Math.max( precision, this._precisionOf( this.options.min ) );
17429 }
17430 return precision;
17431 },
17432
17433 _precisionOf: function( num ) {
17434 var str = num.toString(),
17435 decimal = str.indexOf( "." );
17436 return decimal === -1 ? 0 : str.length - decimal - 1;
17437 },
17438
17439 _adjustValue: function( value ) {
17440 var base, aboveMin,
17441 options = this.options;
17442
17443 // Make sure we're at a valid step
17444 // - find out where we are relative to the base (min or 0)
17445 base = options.min !== null ? options.min : 0;
17446 aboveMin = value - base;
17447
17448 // - round to the nearest step
17449 aboveMin = Math.round( aboveMin / options.step ) * options.step;
17450
17451 // - rounding is based on 0, so adjust back to our base
17452 value = base + aboveMin;
17453
17454 // Fix precision from bad JS floating point math
17455 value = parseFloat( value.toFixed( this._precision() ) );
17456
17457 // Clamp the value
17458 if ( options.max !== null && value > options.max ) {
17459 return options.max;
17460 }
17461 if ( options.min !== null && value < options.min ) {
17462 return options.min;
17463 }
17464
17465 return value;
17466 },
17467
17468 _stop: function( event ) {
17469 if ( !this.spinning ) {
17470 return;
17471 }
17472
17473 clearTimeout( this.timer );
17474 clearTimeout( this.mousewheelTimer );
17475 this.counter = 0;
17476 this.spinning = false;
17477 this._trigger( "stop", event );
17478 },
17479
17480 _setOption: function( key, value ) {
17481 var prevValue, first, last;
17482
17483 if ( key === "culture" || key === "numberFormat" ) {
17484 prevValue = this._parse( this.element.val() );
17485 this.options[ key ] = value;
17486 this.element.val( this._format( prevValue ) );
17487 return;
17488 }
17489
17490 if ( key === "max" || key === "min" || key === "step" ) {
17491 if ( typeof value === "string" ) {
17492 value = this._parse( value );
17493 }
17494 }
17495 if ( key === "icons" ) {
17496 first = this.buttons.first().find( ".ui-icon" );
17497 this._removeClass( first, null, this.options.icons.up );
17498 this._addClass( first, null, value.up );
17499 last = this.buttons.last().find( ".ui-icon" );
17500 this._removeClass( last, null, this.options.icons.down );
17501 this._addClass( last, null, value.down );
17502 }
17503
17504 this._super( key, value );
17505 },
17506
17507 _setOptionDisabled: function( value ) {
17508 this._super( value );
17509
17510 this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value );
17511 this.element.prop( "disabled", !!value );
17512 this.buttons.button( value ? "disable" : "enable" );
17513 },
17514
17515 _setOptions: spinnerModifier( function( options ) {
17516 this._super( options );
17517 } ),
17518
17519 _parse: function( val ) {
17520 if ( typeof val === "string" && val !== "" ) {
17521 val = window.Globalize && this.options.numberFormat ?
17522 Globalize.parseFloat( val, 10, this.options.culture ) : +val;
17523 }
17524 return val === "" || isNaN( val ) ? null : val;
17525 },
17526
17527 _format: function( value ) {
17528 if ( value === "" ) {
17529 return "";
17530 }
17531 return window.Globalize && this.options.numberFormat ?
17532 Globalize.format( value, this.options.numberFormat, this.options.culture ) :
17533 value;
17534 },
17535
17536 _refresh: function() {
17537 this.element.attr( {
17538 "aria-valuemin": this.options.min,
17539 "aria-valuemax": this.options.max,
17540
17541 // TODO: what should we do with values that can't be parsed?
17542 "aria-valuenow": this._parse( this.element.val() )
17543 } );
17544 },
17545
17546 isValid: function() {
17547 var value = this.value();
17548
17549 // Null is invalid
17550 if ( value === null ) {
17551 return false;
17552 }
17553
17554 // If value gets adjusted, it's invalid
17555 return value === this._adjustValue( value );
17556 },
17557
17558 // Update the value without triggering change
17559 _value: function( value, allowAny ) {
17560 var parsed;
17561 if ( value !== "" ) {
17562 parsed = this._parse( value );
17563 if ( parsed !== null ) {
17564 if ( !allowAny ) {
17565 parsed = this._adjustValue( parsed );
17566 }
17567 value = this._format( parsed );
17568 }
17569 }
17570 this.element.val( value );
17571 this._refresh();
17572 },
17573
17574 _destroy: function() {
17575 this.element
17576 .prop( "disabled", false )
17577 .removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" );
17578
17579 this.uiSpinner.replaceWith( this.element );
17580 },
17581
17582 stepUp: spinnerModifier( function( steps ) {
17583 this._stepUp( steps );
17584 } ),
17585 _stepUp: function( steps ) {
17586 if ( this._start() ) {
17587 this._spin( ( steps || 1 ) * this.options.step );
17588 this._stop();
17589 }
17590 },
17591
17592 stepDown: spinnerModifier( function( steps ) {
17593 this._stepDown( steps );
17594 } ),
17595 _stepDown: function( steps ) {
17596 if ( this._start() ) {
17597 this._spin( ( steps || 1 ) * -this.options.step );
17598 this._stop();
17599 }
17600 },
17601
17602 pageUp: spinnerModifier( function( pages ) {
17603 this._stepUp( ( pages || 1 ) * this.options.page );
17604 } ),
17605
17606 pageDown: spinnerModifier( function( pages ) {
17607 this._stepDown( ( pages || 1 ) * this.options.page );
17608 } ),
17609
17610 value: function( newVal ) {
17611 if ( !arguments.length ) {
17612 return this._parse( this.element.val() );
17613 }
17614 spinnerModifier( this._value ).call( this, newVal );
17615 },
17616
17617 widget: function() {
17618 return this.uiSpinner;
17619 }
17620 } );
17621
17622 // DEPRECATED
17623 // TODO: switch return back to widget declaration at top of file when this is removed
17624 if ( $.uiBackCompat !== false ) {
17625
17626 // Backcompat for spinner html extension points
17627 $.widget( "ui.spinner", $.ui.spinner, {
17628 _enhance: function() {
17629 this.uiSpinner = this.element
17630 .attr( "autocomplete", "off" )
17631 .wrap( this._uiSpinnerHtml() )
17632 .parent()
17633
17634 // Add buttons
17635 .append( this._buttonHtml() );
17636 },
17637 _uiSpinnerHtml: function() {
17638 return "<span>";
17639 },
17640
17641 _buttonHtml: function() {
17642 return "<a></a><a></a>";
17643 }
17644 } );
17645 }
17646
17647 var widgetsSpinner = $.ui.spinner;
17648
17649
17650 /*!
17651 * jQuery UI Tabs 1.13.2
17652 * http://jqueryui.com
17653 *
17654 * Copyright jQuery Foundation and other contributors
17655 * Released under the MIT license.
17656 * http://jquery.org/license
17657 */
17658
17659 //>>label: Tabs
17660 //>>group: Widgets
17661 //>>description: Transforms a set of container elements into a tab structure.
17662 //>>docs: http://api.jqueryui.com/tabs/
17663 //>>demos: http://jqueryui.com/tabs/
17664 //>>css.structure: ../../themes/base/core.css
17665 //>>css.structure: ../../themes/base/tabs.css
17666 //>>css.theme: ../../themes/base/theme.css
17667
17668
17669 $.widget( "ui.tabs", {
17670 version: "1.13.2",
17671 delay: 300,
17672 options: {
17673 active: null,
17674 classes: {
17675 "ui-tabs": "ui-corner-all",
17676 "ui-tabs-nav": "ui-corner-all",
17677 "ui-tabs-panel": "ui-corner-bottom",
17678 "ui-tabs-tab": "ui-corner-top"
17679 },
17680 collapsible: false,
17681 event: "click",
17682 heightStyle: "content",
17683 hide: null,
17684 show: null,
17685
17686 // Callbacks
17687 activate: null,
17688 beforeActivate: null,
17689 beforeLoad: null,
17690 load: null
17691 },
17692
17693 _isLocal: ( function() {
17694 var rhash = /#.*$/;
17695
17696 return function( anchor ) {
17697 var anchorUrl, locationUrl;
17698
17699 anchorUrl = anchor.href.replace( rhash, "" );
17700 locationUrl = location.href.replace( rhash, "" );
17701
17702 // Decoding may throw an error if the URL isn't UTF-8 (#9518)
17703 try {
17704 anchorUrl = decodeURIComponent( anchorUrl );
17705 } catch ( error ) {}
17706 try {
17707 locationUrl = decodeURIComponent( locationUrl );
17708 } catch ( error ) {}
17709
17710 return anchor.hash.length > 1 && anchorUrl === locationUrl;
17711 };
17712 } )(),
17713
17714 _create: function() {
17715 var that = this,
17716 options = this.options;
17717
17718 this.running = false;
17719
17720 this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
17721 this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
17722
17723 this._processTabs();
17724 options.active = this._initialActive();
17725
17726 // Take disabling tabs via class attribute from HTML
17727 // into account and update option properly.
17728 if ( Array.isArray( options.disabled ) ) {
17729 options.disabled = $.uniqueSort( options.disabled.concat(
17730 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
17731 return that.tabs.index( li );
17732 } )
17733 ) ).sort();
17734 }
17735
17736 // Check for length avoids error when initializing empty list
17737 if ( this.options.active !== false && this.anchors.length ) {
17738 this.active = this._findActive( options.active );
17739 } else {
17740 this.active = $();
17741 }
17742
17743 this._refresh();
17744
17745 if ( this.active.length ) {
17746 this.load( options.active );
17747 }
17748 },
17749
17750 _initialActive: function() {
17751 var active = this.options.active,
17752 collapsible = this.options.collapsible,
17753 locationHash = location.hash.substring( 1 );
17754
17755 if ( active === null ) {
17756
17757 // check the fragment identifier in the URL
17758 if ( locationHash ) {
17759 this.tabs.each( function( i, tab ) {
17760 if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
17761 active = i;
17762 return false;
17763 }
17764 } );
17765 }
17766
17767 // Check for a tab marked active via a class
17768 if ( active === null ) {
17769 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
17770 }
17771
17772 // No active tab, set to false
17773 if ( active === null || active === -1 ) {
17774 active = this.tabs.length ? 0 : false;
17775 }
17776 }
17777
17778 // Handle numbers: negative, out of range
17779 if ( active !== false ) {
17780 active = this.tabs.index( this.tabs.eq( active ) );
17781 if ( active === -1 ) {
17782 active = collapsible ? false : 0;
17783 }
17784 }
17785
17786 // Don't allow collapsible: false and active: false
17787 if ( !collapsible && active === false && this.anchors.length ) {
17788 active = 0;
17789 }
17790
17791 return active;
17792 },
17793
17794 _getCreateEventData: function() {
17795 return {
17796 tab: this.active,
17797 panel: !this.active.length ? $() : this._getPanelForTab( this.active )
17798 };
17799 },
17800
17801 _tabKeydown: function( event ) {
17802 var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ),
17803 selectedIndex = this.tabs.index( focusedTab ),
17804 goingForward = true;
17805
17806 if ( this._handlePageNav( event ) ) {
17807 return;
17808 }
17809
17810 switch ( event.keyCode ) {
17811 case $.ui.keyCode.RIGHT:
17812 case $.ui.keyCode.DOWN:
17813 selectedIndex++;
17814 break;
17815 case $.ui.keyCode.UP:
17816 case $.ui.keyCode.LEFT:
17817 goingForward = false;
17818 selectedIndex--;
17819 break;
17820 case $.ui.keyCode.END:
17821 selectedIndex = this.anchors.length - 1;
17822 break;
17823 case $.ui.keyCode.HOME:
17824 selectedIndex = 0;
17825 break;
17826 case $.ui.keyCode.SPACE:
17827
17828 // Activate only, no collapsing
17829 event.preventDefault();
17830 clearTimeout( this.activating );
17831 this._activate( selectedIndex );
17832 return;
17833 case $.ui.keyCode.ENTER:
17834
17835 // Toggle (cancel delayed activation, allow collapsing)
17836 event.preventDefault();
17837 clearTimeout( this.activating );
17838
17839 // Determine if we should collapse or activate
17840 this._activate( selectedIndex === this.options.active ? false : selectedIndex );
17841 return;
17842 default:
17843 return;
17844 }
17845
17846 // Focus the appropriate tab, based on which key was pressed
17847 event.preventDefault();
17848 clearTimeout( this.activating );
17849 selectedIndex = this._focusNextTab( selectedIndex, goingForward );
17850
17851 // Navigating with control/command key will prevent automatic activation
17852 if ( !event.ctrlKey && !event.metaKey ) {
17853
17854 // Update aria-selected immediately so that AT think the tab is already selected.
17855 // Otherwise AT may confuse the user by stating that they need to activate the tab,
17856 // but the tab will already be activated by the time the announcement finishes.
17857 focusedTab.attr( "aria-selected", "false" );
17858 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
17859
17860 this.activating = this._delay( function() {
17861 this.option( "active", selectedIndex );
17862 }, this.delay );
17863 }
17864 },
17865
17866 _panelKeydown: function( event ) {
17867 if ( this._handlePageNav( event ) ) {
17868 return;
17869 }
17870
17871 // Ctrl+up moves focus to the current tab
17872 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
17873 event.preventDefault();
17874 this.active.trigger( "focus" );
17875 }
17876 },
17877
17878 // Alt+page up/down moves focus to the previous/next tab (and activates)
17879 _handlePageNav: function( event ) {
17880 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
17881 this._activate( this._focusNextTab( this.options.active - 1, false ) );
17882 return true;
17883 }
17884 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
17885 this._activate( this._focusNextTab( this.options.active + 1, true ) );
17886 return true;
17887 }
17888 },
17889
17890 _findNextTab: function( index, goingForward ) {
17891 var lastTabIndex = this.tabs.length - 1;
17892
17893 function constrain() {
17894 if ( index > lastTabIndex ) {
17895 index = 0;
17896 }
17897 if ( index < 0 ) {
17898 index = lastTabIndex;
17899 }
17900 return index;
17901 }
17902
17903 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
17904 index = goingForward ? index + 1 : index - 1;
17905 }
17906
17907 return index;
17908 },
17909
17910 _focusNextTab: function( index, goingForward ) {
17911 index = this._findNextTab( index, goingForward );
17912 this.tabs.eq( index ).trigger( "focus" );
17913 return index;
17914 },
17915
17916 _setOption: function( key, value ) {
17917 if ( key === "active" ) {
17918
17919 // _activate() will handle invalid values and update this.options
17920 this._activate( value );
17921 return;
17922 }
17923
17924 this._super( key, value );
17925
17926 if ( key === "collapsible" ) {
17927 this._toggleClass( "ui-tabs-collapsible", null, value );
17928
17929 // Setting collapsible: false while collapsed; open first panel
17930 if ( !value && this.options.active === false ) {
17931 this._activate( 0 );
17932 }
17933 }
17934
17935 if ( key === "event" ) {
17936 this._setupEvents( value );
17937 }
17938
17939 if ( key === "heightStyle" ) {
17940 this._setupHeightStyle( value );
17941 }
17942 },
17943
17944 _sanitizeSelector: function( hash ) {
17945 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
17946 },
17947
17948 refresh: function() {
17949 var options = this.options,
17950 lis = this.tablist.children( ":has(a[href])" );
17951
17952 // Get disabled tabs from class attribute from HTML
17953 // this will get converted to a boolean if needed in _refresh()
17954 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
17955 return lis.index( tab );
17956 } );
17957
17958 this._processTabs();
17959
17960 // Was collapsed or no tabs
17961 if ( options.active === false || !this.anchors.length ) {
17962 options.active = false;
17963 this.active = $();
17964
17965 // was active, but active tab is gone
17966 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
17967
17968 // all remaining tabs are disabled
17969 if ( this.tabs.length === options.disabled.length ) {
17970 options.active = false;
17971 this.active = $();
17972
17973 // activate previous tab
17974 } else {
17975 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
17976 }
17977
17978 // was active, active tab still exists
17979 } else {
17980
17981 // make sure active index is correct
17982 options.active = this.tabs.index( this.active );
17983 }
17984
17985 this._refresh();
17986 },
17987
17988 _refresh: function() {
17989 this._setOptionDisabled( this.options.disabled );
17990 this._setupEvents( this.options.event );
17991 this._setupHeightStyle( this.options.heightStyle );
17992
17993 this.tabs.not( this.active ).attr( {
17994 "aria-selected": "false",
17995 "aria-expanded": "false",
17996 tabIndex: -1
17997 } );
17998 this.panels.not( this._getPanelForTab( this.active ) )
17999 .hide()
18000 .attr( {
18001 "aria-hidden": "true"
18002 } );
18003
18004 // Make sure one tab is in the tab order
18005 if ( !this.active.length ) {
18006 this.tabs.eq( 0 ).attr( "tabIndex", 0 );
18007 } else {
18008 this.active
18009 .attr( {
18010 "aria-selected": "true",
18011 "aria-expanded": "true",
18012 tabIndex: 0
18013 } );
18014 this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
18015 this._getPanelForTab( this.active )
18016 .show()
18017 .attr( {
18018 "aria-hidden": "false"
18019 } );
18020 }
18021 },
18022
18023 _processTabs: function() {
18024 var that = this,
18025 prevTabs = this.tabs,
18026 prevAnchors = this.anchors,
18027 prevPanels = this.panels;
18028
18029 this.tablist = this._getList().attr( "role", "tablist" );
18030 this._addClass( this.tablist, "ui-tabs-nav",
18031 "ui-helper-reset ui-helper-clearfix ui-widget-header" );
18032
18033 // Prevent users from focusing disabled tabs via click
18034 this.tablist
18035 .on( "mousedown" + this.eventNamespace, "> li", function( event ) {
18036 if ( $( this ).is( ".ui-state-disabled" ) ) {
18037 event.preventDefault();
18038 }
18039 } )
18040
18041 // Support: IE <9
18042 // Preventing the default action in mousedown doesn't prevent IE
18043 // from focusing the element, so if the anchor gets focused, blur.
18044 // We don't have to worry about focusing the previously focused
18045 // element since clicking on a non-focusable element should focus
18046 // the body anyway.
18047 .on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() {
18048 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
18049 this.blur();
18050 }
18051 } );
18052
18053 this.tabs = this.tablist.find( "> li:has(a[href])" )
18054 .attr( {
18055 role: "tab",
18056 tabIndex: -1
18057 } );
18058 this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" );
18059
18060 this.anchors = this.tabs.map( function() {
18061 return $( "a", this )[ 0 ];
18062 } )
18063 .attr( {
18064 tabIndex: -1
18065 } );
18066 this._addClass( this.anchors, "ui-tabs-anchor" );
18067
18068 this.panels = $();
18069
18070 this.anchors.each( function( i, anchor ) {
18071 var selector, panel, panelId,
18072 anchorId = $( anchor ).uniqueId().attr( "id" ),
18073 tab = $( anchor ).closest( "li" ),
18074 originalAriaControls = tab.attr( "aria-controls" );
18075
18076 // Inline tab
18077 if ( that._isLocal( anchor ) ) {
18078 selector = anchor.hash;
18079 panelId = selector.substring( 1 );
18080 panel = that.element.find( that._sanitizeSelector( selector ) );
18081
18082 // remote tab
18083 } else {
18084
18085 // If the tab doesn't already have aria-controls,
18086 // generate an id by using a throw-away element
18087 panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
18088 selector = "#" + panelId;
18089 panel = that.element.find( selector );
18090 if ( !panel.length ) {
18091 panel = that._createPanel( panelId );
18092 panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
18093 }
18094 panel.attr( "aria-live", "polite" );
18095 }
18096
18097 if ( panel.length ) {
18098 that.panels = that.panels.add( panel );
18099 }
18100 if ( originalAriaControls ) {
18101 tab.data( "ui-tabs-aria-controls", originalAriaControls );
18102 }
18103 tab.attr( {
18104 "aria-controls": panelId,
18105 "aria-labelledby": anchorId
18106 } );
18107 panel.attr( "aria-labelledby", anchorId );
18108 } );
18109
18110 this.panels.attr( "role", "tabpanel" );
18111 this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
18112
18113 // Avoid memory leaks (#10056)
18114 if ( prevTabs ) {
18115 this._off( prevTabs.not( this.tabs ) );
18116 this._off( prevAnchors.not( this.anchors ) );
18117 this._off( prevPanels.not( this.panels ) );
18118 }
18119 },
18120
18121 // Allow overriding how to find the list for rare usage scenarios (#7715)
18122 _getList: function() {
18123 return this.tablist || this.element.find( "ol, ul" ).eq( 0 );
18124 },
18125
18126 _createPanel: function( id ) {
18127 return $( "<div>" )
18128 .attr( "id", id )
18129 .data( "ui-tabs-destroy", true );
18130 },
18131
18132 _setOptionDisabled: function( disabled ) {
18133 var currentItem, li, i;
18134
18135 if ( Array.isArray( disabled ) ) {
18136 if ( !disabled.length ) {
18137 disabled = false;
18138 } else if ( disabled.length === this.anchors.length ) {
18139 disabled = true;
18140 }
18141 }
18142
18143 // Disable tabs
18144 for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
18145 currentItem = $( li );
18146 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
18147 currentItem.attr( "aria-disabled", "true" );
18148 this._addClass( currentItem, null, "ui-state-disabled" );
18149 } else {
18150 currentItem.removeAttr( "aria-disabled" );
18151 this._removeClass( currentItem, null, "ui-state-disabled" );
18152 }
18153 }
18154
18155 this.options.disabled = disabled;
18156
18157 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null,
18158 disabled === true );
18159 },
18160
18161 _setupEvents: function( event ) {
18162 var events = {};
18163 if ( event ) {
18164 $.each( event.split( " " ), function( index, eventName ) {
18165 events[ eventName ] = "_eventHandler";
18166 } );
18167 }
18168
18169 this._off( this.anchors.add( this.tabs ).add( this.panels ) );
18170
18171 // Always prevent the default action, even when disabled
18172 this._on( true, this.anchors, {
18173 click: function( event ) {
18174 event.preventDefault();
18175 }
18176 } );
18177 this._on( this.anchors, events );
18178 this._on( this.tabs, { keydown: "_tabKeydown" } );
18179 this._on( this.panels, { keydown: "_panelKeydown" } );
18180
18181 this._focusable( this.tabs );
18182 this._hoverable( this.tabs );
18183 },
18184
18185 _setupHeightStyle: function( heightStyle ) {
18186 var maxHeight,
18187 parent = this.element.parent();
18188
18189 if ( heightStyle === "fill" ) {
18190 maxHeight = parent.height();
18191 maxHeight -= this.element.outerHeight() - this.element.height();
18192
18193 this.element.siblings( ":visible" ).each( function() {
18194 var elem = $( this ),
18195 position = elem.css( "position" );
18196
18197 if ( position === "absolute" || position === "fixed" ) {
18198 return;
18199 }
18200 maxHeight -= elem.outerHeight( true );
18201 } );
18202
18203 this.element.children().not( this.panels ).each( function() {
18204 maxHeight -= $( this ).outerHeight( true );
18205 } );
18206
18207 this.panels.each( function() {
18208 $( this ).height( Math.max( 0, maxHeight -
18209 $( this ).innerHeight() + $( this ).height() ) );
18210 } )
18211 .css( "overflow", "auto" );
18212 } else if ( heightStyle === "auto" ) {
18213 maxHeight = 0;
18214 this.panels.each( function() {
18215 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
18216 } ).height( maxHeight );
18217 }
18218 },
18219
18220 _eventHandler: function( event ) {
18221 var options = this.options,
18222 active = this.active,
18223 anchor = $( event.currentTarget ),
18224 tab = anchor.closest( "li" ),
18225 clickedIsActive = tab[ 0 ] === active[ 0 ],
18226 collapsing = clickedIsActive && options.collapsible,
18227 toShow = collapsing ? $() : this._getPanelForTab( tab ),
18228 toHide = !active.length ? $() : this._getPanelForTab( active ),
18229 eventData = {
18230 oldTab: active,
18231 oldPanel: toHide,
18232 newTab: collapsing ? $() : tab,
18233 newPanel: toShow
18234 };
18235
18236 event.preventDefault();
18237
18238 if ( tab.hasClass( "ui-state-disabled" ) ||
18239
18240 // tab is already loading
18241 tab.hasClass( "ui-tabs-loading" ) ||
18242
18243 // can't switch durning an animation
18244 this.running ||
18245
18246 // click on active header, but not collapsible
18247 ( clickedIsActive && !options.collapsible ) ||
18248
18249 // allow canceling activation
18250 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
18251 return;
18252 }
18253
18254 options.active = collapsing ? false : this.tabs.index( tab );
18255
18256 this.active = clickedIsActive ? $() : tab;
18257 if ( this.xhr ) {
18258 this.xhr.abort();
18259 }
18260
18261 if ( !toHide.length && !toShow.length ) {
18262 $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
18263 }
18264
18265 if ( toShow.length ) {
18266 this.load( this.tabs.index( tab ), event );
18267 }
18268 this._toggle( event, eventData );
18269 },
18270
18271 // Handles show/hide for selecting tabs
18272 _toggle: function( event, eventData ) {
18273 var that = this,
18274 toShow = eventData.newPanel,
18275 toHide = eventData.oldPanel;
18276
18277 this.running = true;
18278
18279 function complete() {
18280 that.running = false;
18281 that._trigger( "activate", event, eventData );
18282 }
18283
18284 function show() {
18285 that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
18286
18287 if ( toShow.length && that.options.show ) {
18288 that._show( toShow, that.options.show, complete );
18289 } else {
18290 toShow.show();
18291 complete();
18292 }
18293 }
18294
18295 // Start out by hiding, then showing, then completing
18296 if ( toHide.length && this.options.hide ) {
18297 this._hide( toHide, this.options.hide, function() {
18298 that._removeClass( eventData.oldTab.closest( "li" ),
18299 "ui-tabs-active", "ui-state-active" );
18300 show();
18301 } );
18302 } else {
18303 this._removeClass( eventData.oldTab.closest( "li" ),
18304 "ui-tabs-active", "ui-state-active" );
18305 toHide.hide();
18306 show();
18307 }
18308
18309 toHide.attr( "aria-hidden", "true" );
18310 eventData.oldTab.attr( {
18311 "aria-selected": "false",
18312 "aria-expanded": "false"
18313 } );
18314
18315 // If we're switching tabs, remove the old tab from the tab order.
18316 // If we're opening from collapsed state, remove the previous tab from the tab order.
18317 // If we're collapsing, then keep the collapsing tab in the tab order.
18318 if ( toShow.length && toHide.length ) {
18319 eventData.oldTab.attr( "tabIndex", -1 );
18320 } else if ( toShow.length ) {
18321 this.tabs.filter( function() {
18322 return $( this ).attr( "tabIndex" ) === 0;
18323 } )
18324 .attr( "tabIndex", -1 );
18325 }
18326
18327 toShow.attr( "aria-hidden", "false" );
18328 eventData.newTab.attr( {
18329 "aria-selected": "true",
18330 "aria-expanded": "true",
18331 tabIndex: 0
18332 } );
18333 },
18334
18335 _activate: function( index ) {
18336 var anchor,
18337 active = this._findActive( index );
18338
18339 // Trying to activate the already active panel
18340 if ( active[ 0 ] === this.active[ 0 ] ) {
18341 return;
18342 }
18343
18344 // Trying to collapse, simulate a click on the current active header
18345 if ( !active.length ) {
18346 active = this.active;
18347 }
18348
18349 anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
18350 this._eventHandler( {
18351 target: anchor,
18352 currentTarget: anchor,
18353 preventDefault: $.noop
18354 } );
18355 },
18356
18357 _findActive: function( index ) {
18358 return index === false ? $() : this.tabs.eq( index );
18359 },
18360
18361 _getIndex: function( index ) {
18362
18363 // meta-function to give users option to provide a href string instead of a numerical index.
18364 if ( typeof index === "string" ) {
18365 index = this.anchors.index( this.anchors.filter( "[href$='" +
18366 $.escapeSelector( index ) + "']" ) );
18367 }
18368
18369 return index;
18370 },
18371
18372 _destroy: function() {
18373 if ( this.xhr ) {
18374 this.xhr.abort();
18375 }
18376
18377 this.tablist
18378 .removeAttr( "role" )
18379 .off( this.eventNamespace );
18380
18381 this.anchors
18382 .removeAttr( "role tabIndex" )
18383 .removeUniqueId();
18384
18385 this.tabs.add( this.panels ).each( function() {
18386 if ( $.data( this, "ui-tabs-destroy" ) ) {
18387 $( this ).remove();
18388 } else {
18389 $( this ).removeAttr( "role tabIndex " +
18390 "aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" );
18391 }
18392 } );
18393
18394 this.tabs.each( function() {
18395 var li = $( this ),
18396 prev = li.data( "ui-tabs-aria-controls" );
18397 if ( prev ) {
18398 li
18399 .attr( "aria-controls", prev )
18400 .removeData( "ui-tabs-aria-controls" );
18401 } else {
18402 li.removeAttr( "aria-controls" );
18403 }
18404 } );
18405
18406 this.panels.show();
18407
18408 if ( this.options.heightStyle !== "content" ) {
18409 this.panels.css( "height", "" );
18410 }
18411 },
18412
18413 enable: function( index ) {
18414 var disabled = this.options.disabled;
18415 if ( disabled === false ) {
18416 return;
18417 }
18418
18419 if ( index === undefined ) {
18420 disabled = false;
18421 } else {
18422 index = this._getIndex( index );
18423 if ( Array.isArray( disabled ) ) {
18424 disabled = $.map( disabled, function( num ) {
18425 return num !== index ? num : null;
18426 } );
18427 } else {
18428 disabled = $.map( this.tabs, function( li, num ) {
18429 return num !== index ? num : null;
18430 } );
18431 }
18432 }
18433 this._setOptionDisabled( disabled );
18434 },
18435
18436 disable: function( index ) {
18437 var disabled = this.options.disabled;
18438 if ( disabled === true ) {
18439 return;
18440 }
18441
18442 if ( index === undefined ) {
18443 disabled = true;
18444 } else {
18445 index = this._getIndex( index );
18446 if ( $.inArray( index, disabled ) !== -1 ) {
18447 return;
18448 }
18449 if ( Array.isArray( disabled ) ) {
18450 disabled = $.merge( [ index ], disabled ).sort();
18451 } else {
18452 disabled = [ index ];
18453 }
18454 }
18455 this._setOptionDisabled( disabled );
18456 },
18457
18458 load: function( index, event ) {
18459 index = this._getIndex( index );
18460 var that = this,
18461 tab = this.tabs.eq( index ),
18462 anchor = tab.find( ".ui-tabs-anchor" ),
18463 panel = this._getPanelForTab( tab ),
18464 eventData = {
18465 tab: tab,
18466 panel: panel
18467 },
18468 complete = function( jqXHR, status ) {
18469 if ( status === "abort" ) {
18470 that.panels.stop( false, true );
18471 }
18472
18473 that._removeClass( tab, "ui-tabs-loading" );
18474 panel.removeAttr( "aria-busy" );
18475
18476 if ( jqXHR === that.xhr ) {
18477 delete that.xhr;
18478 }
18479 };
18480
18481 // Not remote
18482 if ( this._isLocal( anchor[ 0 ] ) ) {
18483 return;
18484 }
18485
18486 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
18487
18488 // Support: jQuery <1.8
18489 // jQuery <1.8 returns false if the request is canceled in beforeSend,
18490 // but as of 1.8, $.ajax() always returns a jqXHR object.
18491 if ( this.xhr && this.xhr.statusText !== "canceled" ) {
18492 this._addClass( tab, "ui-tabs-loading" );
18493 panel.attr( "aria-busy", "true" );
18494
18495 this.xhr
18496 .done( function( response, status, jqXHR ) {
18497
18498 // support: jQuery <1.8
18499 // http://bugs.jquery.com/ticket/11778
18500 setTimeout( function() {
18501 panel.html( response );
18502 that._trigger( "load", event, eventData );
18503
18504 complete( jqXHR, status );
18505 }, 1 );
18506 } )
18507 .fail( function( jqXHR, status ) {
18508
18509 // support: jQuery <1.8
18510 // http://bugs.jquery.com/ticket/11778
18511 setTimeout( function() {
18512 complete( jqXHR, status );
18513 }, 1 );
18514 } );
18515 }
18516 },
18517
18518 _ajaxSettings: function( anchor, event, eventData ) {
18519 var that = this;
18520 return {
18521
18522 // Support: IE <11 only
18523 // Strip any hash that exists to prevent errors with the Ajax request
18524 url: anchor.attr( "href" ).replace( /#.*$/, "" ),
18525 beforeSend: function( jqXHR, settings ) {
18526 return that._trigger( "beforeLoad", event,
18527 $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
18528 }
18529 };
18530 },
18531
18532 _getPanelForTab: function( tab ) {
18533 var id = $( tab ).attr( "aria-controls" );
18534 return this.element.find( this._sanitizeSelector( "#" + id ) );
18535 }
18536 } );
18537
18538 // DEPRECATED
18539 // TODO: Switch return back to widget declaration at top of file when this is removed
18540 if ( $.uiBackCompat !== false ) {
18541
18542 // Backcompat for ui-tab class (now ui-tabs-tab)
18543 $.widget( "ui.tabs", $.ui.tabs, {
18544 _processTabs: function() {
18545 this._superApply( arguments );
18546 this._addClass( this.tabs, "ui-tab" );
18547 }
18548 } );
18549 }
18550
18551 var widgetsTabs = $.ui.tabs;
18552
18553
18554 /*!
18555 * jQuery UI Tooltip 1.13.2
18556 * http://jqueryui.com
18557 *
18558 * Copyright jQuery Foundation and other contributors
18559 * Released under the MIT license.
18560 * http://jquery.org/license
18561 */
18562
18563 //>>label: Tooltip
18564 //>>group: Widgets
18565 //>>description: Shows additional information for any element on hover or focus.
18566 //>>docs: http://api.jqueryui.com/tooltip/
18567 //>>demos: http://jqueryui.com/tooltip/
18568 //>>css.structure: ../../themes/base/core.css
18569 //>>css.structure: ../../themes/base/tooltip.css
18570 //>>css.theme: ../../themes/base/theme.css
18571
18572
18573 $.widget( "ui.tooltip", {
18574 version: "1.13.2",
18575 options: {
18576 classes: {
18577 "ui-tooltip": "ui-corner-all ui-widget-shadow"
18578 },
18579 content: function() {
18580 var title = $( this ).attr( "title" );
18581
18582 // Escape title, since we're going from an attribute to raw HTML
18583 return $( "<a>" ).text( title ).html();
18584 },
18585 hide: true,
18586
18587 // Disabled elements have inconsistent behavior across browsers (#8661)
18588 items: "[title]:not([disabled])",
18589 position: {
18590 my: "left top+15",
18591 at: "left bottom",
18592 collision: "flipfit flip"
18593 },
18594 show: true,
18595 track: false,
18596
18597 // Callbacks
18598 close: null,
18599 open: null
18600 },
18601
18602 _addDescribedBy: function( elem, id ) {
18603 var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ );
18604 describedby.push( id );
18605 elem
18606 .data( "ui-tooltip-id", id )
18607 .attr( "aria-describedby", String.prototype.trim.call( describedby.join( " " ) ) );
18608 },
18609
18610 _removeDescribedBy: function( elem ) {
18611 var id = elem.data( "ui-tooltip-id" ),
18612 describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ),
18613 index = $.inArray( id, describedby );
18614
18615 if ( index !== -1 ) {
18616 describedby.splice( index, 1 );
18617 }
18618
18619 elem.removeData( "ui-tooltip-id" );
18620 describedby = String.prototype.trim.call( describedby.join( " " ) );
18621 if ( describedby ) {
18622 elem.attr( "aria-describedby", describedby );
18623 } else {
18624 elem.removeAttr( "aria-describedby" );
18625 }
18626 },
18627
18628 _create: function() {
18629 this._on( {
18630 mouseover: "open",
18631 focusin: "open"
18632 } );
18633
18634 // IDs of generated tooltips, needed for destroy
18635 this.tooltips = {};
18636
18637 // IDs of parent tooltips where we removed the title attribute
18638 this.parents = {};
18639
18640 // Append the aria-live region so tooltips announce correctly
18641 this.liveRegion = $( "<div>" )
18642 .attr( {
18643 role: "log",
18644 "aria-live": "assertive",
18645 "aria-relevant": "additions"
18646 } )
18647 .appendTo( this.document[ 0 ].body );
18648 this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
18649
18650 this.disabledTitles = $( [] );
18651 },
18652
18653 _setOption: function( key, value ) {
18654 var that = this;
18655
18656 this._super( key, value );
18657
18658 if ( key === "content" ) {
18659 $.each( this.tooltips, function( id, tooltipData ) {
18660 that._updateContent( tooltipData.element );
18661 } );
18662 }
18663 },
18664
18665 _setOptionDisabled: function( value ) {
18666 this[ value ? "_disable" : "_enable" ]();
18667 },
18668
18669 _disable: function() {
18670 var that = this;
18671
18672 // Close open tooltips
18673 $.each( this.tooltips, function( id, tooltipData ) {
18674 var event = $.Event( "blur" );
18675 event.target = event.currentTarget = tooltipData.element[ 0 ];
18676 that.close( event, true );
18677 } );
18678
18679 // Remove title attributes to prevent native tooltips
18680 this.disabledTitles = this.disabledTitles.add(
18681 this.element.find( this.options.items ).addBack()
18682 .filter( function() {
18683 var element = $( this );
18684 if ( element.is( "[title]" ) ) {
18685 return element
18686 .data( "ui-tooltip-title", element.attr( "title" ) )
18687 .removeAttr( "title" );
18688 }
18689 } )
18690 );
18691 },
18692
18693 _enable: function() {
18694
18695 // restore title attributes
18696 this.disabledTitles.each( function() {
18697 var element = $( this );
18698 if ( element.data( "ui-tooltip-title" ) ) {
18699 element.attr( "title", element.data( "ui-tooltip-title" ) );
18700 }
18701 } );
18702 this.disabledTitles = $( [] );
18703 },
18704
18705 open: function( event ) {
18706 var that = this,
18707 target = $( event ? event.target : this.element )
18708
18709 // we need closest here due to mouseover bubbling,
18710 // but always pointing at the same event target
18711 .closest( this.options.items );
18712
18713 // No element to show a tooltip for or the tooltip is already open
18714 if ( !target.length || target.data( "ui-tooltip-id" ) ) {
18715 return;
18716 }
18717
18718 if ( target.attr( "title" ) ) {
18719 target.data( "ui-tooltip-title", target.attr( "title" ) );
18720 }
18721
18722 target.data( "ui-tooltip-open", true );
18723
18724 // Kill parent tooltips, custom or native, for hover
18725 if ( event && event.type === "mouseover" ) {
18726 target.parents().each( function() {
18727 var parent = $( this ),
18728 blurEvent;
18729 if ( parent.data( "ui-tooltip-open" ) ) {
18730 blurEvent = $.Event( "blur" );
18731 blurEvent.target = blurEvent.currentTarget = this;
18732 that.close( blurEvent, true );
18733 }
18734 if ( parent.attr( "title" ) ) {
18735 parent.uniqueId();
18736 that.parents[ this.id ] = {
18737 element: this,
18738 title: parent.attr( "title" )
18739 };
18740 parent.attr( "title", "" );
18741 }
18742 } );
18743 }
18744
18745 this._registerCloseHandlers( event, target );
18746 this._updateContent( target, event );
18747 },
18748
18749 _updateContent: function( target, event ) {
18750 var content,
18751 contentOption = this.options.content,
18752 that = this,
18753 eventType = event ? event.type : null;
18754
18755 if ( typeof contentOption === "string" || contentOption.nodeType ||
18756 contentOption.jquery ) {
18757 return this._open( event, target, contentOption );
18758 }
18759
18760 content = contentOption.call( target[ 0 ], function( response ) {
18761
18762 // IE may instantly serve a cached response for ajax requests
18763 // delay this call to _open so the other call to _open runs first
18764 that._delay( function() {
18765
18766 // Ignore async response if tooltip was closed already
18767 if ( !target.data( "ui-tooltip-open" ) ) {
18768 return;
18769 }
18770
18771 // JQuery creates a special event for focusin when it doesn't
18772 // exist natively. To improve performance, the native event
18773 // object is reused and the type is changed. Therefore, we can't
18774 // rely on the type being correct after the event finished
18775 // bubbling, so we set it back to the previous value. (#8740)
18776 if ( event ) {
18777 event.type = eventType;
18778 }
18779 this._open( event, target, response );
18780 } );
18781 } );
18782 if ( content ) {
18783 this._open( event, target, content );
18784 }
18785 },
18786
18787 _open: function( event, target, content ) {
18788 var tooltipData, tooltip, delayedShow, a11yContent,
18789 positionOption = $.extend( {}, this.options.position );
18790
18791 if ( !content ) {
18792 return;
18793 }
18794
18795 // Content can be updated multiple times. If the tooltip already
18796 // exists, then just update the content and bail.
18797 tooltipData = this._find( target );
18798 if ( tooltipData ) {
18799 tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
18800 return;
18801 }
18802
18803 // If we have a title, clear it to prevent the native tooltip
18804 // we have to check first to avoid defining a title if none exists
18805 // (we don't want to cause an element to start matching [title])
18806 //
18807 // We use removeAttr only for key events, to allow IE to export the correct
18808 // accessible attributes. For mouse events, set to empty string to avoid
18809 // native tooltip showing up (happens only when removing inside mouseover).
18810 if ( target.is( "[title]" ) ) {
18811 if ( event && event.type === "mouseover" ) {
18812 target.attr( "title", "" );
18813 } else {
18814 target.removeAttr( "title" );
18815 }
18816 }
18817
18818 tooltipData = this._tooltip( target );
18819 tooltip = tooltipData.tooltip;
18820 this._addDescribedBy( target, tooltip.attr( "id" ) );
18821 tooltip.find( ".ui-tooltip-content" ).html( content );
18822
18823 // Support: Voiceover on OS X, JAWS on IE <= 9
18824 // JAWS announces deletions even when aria-relevant="additions"
18825 // Voiceover will sometimes re-read the entire log region's contents from the beginning
18826 this.liveRegion.children().hide();
18827 a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() );
18828 a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" );
18829 a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
18830 a11yContent.appendTo( this.liveRegion );
18831
18832 function position( event ) {
18833 positionOption.of = event;
18834 if ( tooltip.is( ":hidden" ) ) {
18835 return;
18836 }
18837 tooltip.position( positionOption );
18838 }
18839 if ( this.options.track && event && /^mouse/.test( event.type ) ) {
18840 this._on( this.document, {
18841 mousemove: position
18842 } );
18843
18844 // trigger once to override element-relative positioning
18845 position( event );
18846 } else {
18847 tooltip.position( $.extend( {
18848 of: target
18849 }, this.options.position ) );
18850 }
18851
18852 tooltip.hide();
18853
18854 this._show( tooltip, this.options.show );
18855
18856 // Handle tracking tooltips that are shown with a delay (#8644). As soon
18857 // as the tooltip is visible, position the tooltip using the most recent
18858 // event.
18859 // Adds the check to add the timers only when both delay and track options are set (#14682)
18860 if ( this.options.track && this.options.show && this.options.show.delay ) {
18861 delayedShow = this.delayedShow = setInterval( function() {
18862 if ( tooltip.is( ":visible" ) ) {
18863 position( positionOption.of );
18864 clearInterval( delayedShow );
18865 }
18866 }, 13 );
18867 }
18868
18869 this._trigger( "open", event, { tooltip: tooltip } );
18870 },
18871
18872 _registerCloseHandlers: function( event, target ) {
18873 var events = {
18874 keyup: function( event ) {
18875 if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
18876 var fakeEvent = $.Event( event );
18877 fakeEvent.currentTarget = target[ 0 ];
18878 this.close( fakeEvent, true );
18879 }
18880 }
18881 };
18882
18883 // Only bind remove handler for delegated targets. Non-delegated
18884 // tooltips will handle this in destroy.
18885 if ( target[ 0 ] !== this.element[ 0 ] ) {
18886 events.remove = function() {
18887 var targetElement = this._find( target );
18888 if ( targetElement ) {
18889 this._removeTooltip( targetElement.tooltip );
18890 }
18891 };
18892 }
18893
18894 if ( !event || event.type === "mouseover" ) {
18895 events.mouseleave = "close";
18896 }
18897 if ( !event || event.type === "focusin" ) {
18898 events.focusout = "close";
18899 }
18900 this._on( true, target, events );
18901 },
18902
18903 close: function( event ) {
18904 var tooltip,
18905 that = this,
18906 target = $( event ? event.currentTarget : this.element ),
18907 tooltipData = this._find( target );
18908
18909 // The tooltip may already be closed
18910 if ( !tooltipData ) {
18911
18912 // We set ui-tooltip-open immediately upon open (in open()), but only set the
18913 // additional data once there's actually content to show (in _open()). So even if the
18914 // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
18915 // the period between open() and _open().
18916 target.removeData( "ui-tooltip-open" );
18917 return;
18918 }
18919
18920 tooltip = tooltipData.tooltip;
18921
18922 // Disabling closes the tooltip, so we need to track when we're closing
18923 // to avoid an infinite loop in case the tooltip becomes disabled on close
18924 if ( tooltipData.closing ) {
18925 return;
18926 }
18927
18928 // Clear the interval for delayed tracking tooltips
18929 clearInterval( this.delayedShow );
18930
18931 // Only set title if we had one before (see comment in _open())
18932 // If the title attribute has changed since open(), don't restore
18933 if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
18934 target.attr( "title", target.data( "ui-tooltip-title" ) );
18935 }
18936
18937 this._removeDescribedBy( target );
18938
18939 tooltipData.hiding = true;
18940 tooltip.stop( true );
18941 this._hide( tooltip, this.options.hide, function() {
18942 that._removeTooltip( $( this ) );
18943 } );
18944
18945 target.removeData( "ui-tooltip-open" );
18946 this._off( target, "mouseleave focusout keyup" );
18947
18948 // Remove 'remove' binding only on delegated targets
18949 if ( target[ 0 ] !== this.element[ 0 ] ) {
18950 this._off( target, "remove" );
18951 }
18952 this._off( this.document, "mousemove" );
18953
18954 if ( event && event.type === "mouseleave" ) {
18955 $.each( this.parents, function( id, parent ) {
18956 $( parent.element ).attr( "title", parent.title );
18957 delete that.parents[ id ];
18958 } );
18959 }
18960
18961 tooltipData.closing = true;
18962 this._trigger( "close", event, { tooltip: tooltip } );
18963 if ( !tooltipData.hiding ) {
18964 tooltipData.closing = false;
18965 }
18966 },
18967
18968 _tooltip: function( element ) {
18969 var tooltip = $( "<div>" ).attr( "role", "tooltip" ),
18970 content = $( "<div>" ).appendTo( tooltip ),
18971 id = tooltip.uniqueId().attr( "id" );
18972
18973 this._addClass( content, "ui-tooltip-content" );
18974 this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" );
18975
18976 tooltip.appendTo( this._appendTo( element ) );
18977
18978 return this.tooltips[ id ] = {
18979 element: element,
18980 tooltip: tooltip
18981 };
18982 },
18983
18984 _find: function( target ) {
18985 var id = target.data( "ui-tooltip-id" );
18986 return id ? this.tooltips[ id ] : null;
18987 },
18988
18989 _removeTooltip: function( tooltip ) {
18990
18991 // Clear the interval for delayed tracking tooltips
18992 clearInterval( this.delayedShow );
18993
18994 tooltip.remove();
18995 delete this.tooltips[ tooltip.attr( "id" ) ];
18996 },
18997
18998 _appendTo: function( target ) {
18999 var element = target.closest( ".ui-front, dialog" );
19000
19001 if ( !element.length ) {
19002 element = this.document[ 0 ].body;
19003 }
19004
19005 return element;
19006 },
19007
19008 _destroy: function() {
19009 var that = this;
19010
19011 // Close open tooltips
19012 $.each( this.tooltips, function( id, tooltipData ) {
19013
19014 // Delegate to close method to handle common cleanup
19015 var event = $.Event( "blur" ),
19016 element = tooltipData.element;
19017 event.target = event.currentTarget = element[ 0 ];
19018 that.close( event, true );
19019
19020 // Remove immediately; destroying an open tooltip doesn't use the
19021 // hide animation
19022 $( "#" + id ).remove();
19023
19024 // Restore the title
19025 if ( element.data( "ui-tooltip-title" ) ) {
19026
19027 // If the title attribute has changed since open(), don't restore
19028 if ( !element.attr( "title" ) ) {
19029 element.attr( "title", element.data( "ui-tooltip-title" ) );
19030 }
19031 element.removeData( "ui-tooltip-title" );
19032 }
19033 } );
19034 this.liveRegion.remove();
19035 }
19036 } );
19037
19038 // DEPRECATED
19039 // TODO: Switch return back to widget declaration at top of file when this is removed
19040 if ( $.uiBackCompat !== false ) {
19041
19042 // Backcompat for tooltipClass option
19043 $.widget( "ui.tooltip", $.ui.tooltip, {
19044 options: {
19045 tooltipClass: null
19046 },
19047 _tooltip: function() {
19048 var tooltipData = this._superApply( arguments );
19049 if ( this.options.tooltipClass ) {
19050 tooltipData.tooltip.addClass( this.options.tooltipClass );
19051 }
19052 return tooltipData;
19053 }
19054 } );
19055 }
19056
19057 var widgetsTooltip = $.ui.tooltip;
19058
19059
19060
19061
19062 } );

eric ide

mercurial