]> git.mxchange.org Git - mailer.git/blob - js/jquery/jquery-ui.js
Added local files.
[mailer.git] / js / jquery / jquery-ui.js
1 /*! jQuery UI - v1.12.1 - 2017-06-01
2 * http://jqueryui.com
3 * Includes: widget.js, data.js, disable-selection.js, keycode.js, scroll-parent.js, unique-id.js, widgets/draggable.js, widgets/droppable.js, widgets/resizable.js, widgets/selectable.js, widgets/sortable.js, widgets/mouse.js, widgets/progressbar.js, widgets/tabs.js
4 * Copyright jQuery Foundation and other contributors; Licensed MIT */
5
6 (function( factory ) {
7         if ( typeof define === "function" && define.amd ) {
8
9                 // AMD. Register as an anonymous module.
10                 define([ "jquery" ], factory );
11         } else {
12
13                 // Browser globals
14                 factory( jQuery );
15         }
16 }(function( $ ) {
17
18 $.ui = $.ui || {};
19
20 var version = $.ui.version = "1.12.1";
21
22
23 /*!
24  * jQuery UI Widget 1.12.1
25  * http://jqueryui.com
26  *
27  * Copyright jQuery Foundation and other contributors
28  * Released under the MIT license.
29  * http://jquery.org/license
30  */
31
32 //>>label: Widget
33 //>>group: Core
34 //>>description: Provides a factory for creating stateful widgets with a common API.
35 //>>docs: http://api.jqueryui.com/jQuery.widget/
36 //>>demos: http://jqueryui.com/widget/
37
38
39
40 var widgetUuid = 0;
41 var widgetSlice = Array.prototype.slice;
42
43 $.cleanData = ( function( orig ) {
44         return function( elems ) {
45                 var events, elem, i;
46                 for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
47                         try {
48
49                                 // Only trigger remove when necessary to save time
50                                 events = $._data( elem, "events" );
51                                 if ( events && events.remove ) {
52                                         $( elem ).triggerHandler( "remove" );
53                                 }
54
55                         // Http://bugs.jquery.com/ticket/8235
56                         } catch ( e ) {}
57                 }
58                 orig( elems );
59         };
60 } )( $.cleanData );
61
62 $.widget = function( name, base, prototype ) {
63         var existingConstructor, constructor, basePrototype;
64
65         // ProxiedPrototype allows the provided prototype to remain unmodified
66         // so that it can be used as a mixin for multiple widgets (#8876)
67         var proxiedPrototype = {};
68
69         var namespace = name.split( "." )[ 0 ];
70         name = name.split( "." )[ 1 ];
71         var fullName = namespace + "-" + name;
72
73         if ( !prototype ) {
74                 prototype = base;
75                 base = $.Widget;
76         }
77
78         if ( $.isArray( prototype ) ) {
79                 prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
80         }
81
82         // Create selector for plugin
83         $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
84                 return !!$.data( elem, fullName );
85         };
86
87         $[ namespace ] = $[ namespace ] || {};
88         existingConstructor = $[ namespace ][ name ];
89         constructor = $[ namespace ][ name ] = function( options, element ) {
90
91                 // Allow instantiation without "new" keyword
92                 if ( !this._createWidget ) {
93                         return new constructor( options, element );
94                 }
95
96                 // Allow instantiation without initializing for simple inheritance
97                 // must use "new" keyword (the code above always passes args)
98                 if ( arguments.length ) {
99                         this._createWidget( options, element );
100                 }
101         };
102
103         // Extend with the existing constructor to carry over any static properties
104         $.extend( constructor, existingConstructor, {
105                 version: prototype.version,
106
107                 // Copy the object used to create the prototype in case we need to
108                 // redefine the widget later
109                 _proto: $.extend( {}, prototype ),
110
111                 // Track widgets that inherit from this widget in case this widget is
112                 // redefined after a widget inherits from it
113                 _childConstructors: []
114         } );
115
116         basePrototype = new base();
117
118         // We need to make the options hash a property directly on the new instance
119         // otherwise we'll modify the options hash on the prototype that we're
120         // inheriting from
121         basePrototype.options = $.widget.extend( {}, basePrototype.options );
122         $.each( prototype, function( prop, value ) {
123                 if ( !$.isFunction( value ) ) {
124                         proxiedPrototype[ prop ] = value;
125                         return;
126                 }
127                 proxiedPrototype[ prop ] = ( function() {
128                         function _super() {
129                                 return base.prototype[ prop ].apply( this, arguments );
130                         }
131
132                         function _superApply( args ) {
133                                 return base.prototype[ prop ].apply( this, args );
134                         }
135
136                         return function() {
137                                 var __super = this._super;
138                                 var __superApply = this._superApply;
139                                 var returnValue;
140
141                                 this._super = _super;
142                                 this._superApply = _superApply;
143
144                                 returnValue = value.apply( this, arguments );
145
146                                 this._super = __super;
147                                 this._superApply = __superApply;
148
149                                 return returnValue;
150                         };
151                 } )();
152         } );
153         constructor.prototype = $.widget.extend( basePrototype, {
154
155                 // TODO: remove support for widgetEventPrefix
156                 // always use the name + a colon as the prefix, e.g., draggable:start
157                 // don't prefix for widgets that aren't DOM-based
158                 widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
159         }, proxiedPrototype, {
160                 constructor: constructor,
161                 namespace: namespace,
162                 widgetName: name,
163                 widgetFullName: fullName
164         } );
165
166         // If this widget is being redefined then we need to find all widgets that
167         // are inheriting from it and redefine all of them so that they inherit from
168         // the new version of this widget. We're essentially trying to replace one
169         // level in the prototype chain.
170         if ( existingConstructor ) {
171                 $.each( existingConstructor._childConstructors, function( i, child ) {
172                         var childPrototype = child.prototype;
173
174                         // Redefine the child widget using the same prototype that was
175                         // originally used, but inherit from the new version of the base
176                         $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
177                                 child._proto );
178                 } );
179
180                 // Remove the list of existing child constructors from the old constructor
181                 // so the old child constructors can be garbage collected
182                 delete existingConstructor._childConstructors;
183         } else {
184                 base._childConstructors.push( constructor );
185         }
186
187         $.widget.bridge( name, constructor );
188
189         return constructor;
190 };
191
192 $.widget.extend = function( target ) {
193         var input = widgetSlice.call( arguments, 1 );
194         var inputIndex = 0;
195         var inputLength = input.length;
196         var key;
197         var value;
198
199         for ( ; inputIndex < inputLength; inputIndex++ ) {
200                 for ( key in input[ inputIndex ] ) {
201                         value = input[ inputIndex ][ key ];
202                         if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
203
204                                 // Clone objects
205                                 if ( $.isPlainObject( value ) ) {
206                                         target[ key ] = $.isPlainObject( target[ key ] ) ?
207                                                 $.widget.extend( {}, target[ key ], value ) :
208
209                                                 // Don't extend strings, arrays, etc. with objects
210                                                 $.widget.extend( {}, value );
211
212                                 // Copy everything else by reference
213                                 } else {
214                                         target[ key ] = value;
215                                 }
216                         }
217                 }
218         }
219         return target;
220 };
221
222 $.widget.bridge = function( name, object ) {
223         var fullName = object.prototype.widgetFullName || name;
224         $.fn[ name ] = function( options ) {
225                 var isMethodCall = typeof options === "string";
226                 var args = widgetSlice.call( arguments, 1 );
227                 var returnValue = this;
228
229                 if ( isMethodCall ) {
230
231                         // If this is an empty collection, we need to have the instance method
232                         // return undefined instead of the jQuery instance
233                         if ( !this.length && options === "instance" ) {
234                                 returnValue = undefined;
235                         } else {
236                                 this.each( function() {
237                                         var methodValue;
238                                         var instance = $.data( this, fullName );
239
240                                         if ( options === "instance" ) {
241                                                 returnValue = instance;
242                                                 return false;
243                                         }
244
245                                         if ( !instance ) {
246                                                 return $.error( "cannot call methods on " + name +
247                                                         " prior to initialization; " +
248                                                         "attempted to call method '" + options + "'" );
249                                         }
250
251                                         if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
252                                                 return $.error( "no such method '" + options + "' for " + name +
253                                                         " widget instance" );
254                                         }
255
256                                         methodValue = instance[ options ].apply( instance, args );
257
258                                         if ( methodValue !== instance && methodValue !== undefined ) {
259                                                 returnValue = methodValue && methodValue.jquery ?
260                                                         returnValue.pushStack( methodValue.get() ) :
261                                                         methodValue;
262                                                 return false;
263                                         }
264                                 } );
265                         }
266                 } else {
267
268                         // Allow multiple hashes to be passed on init
269                         if ( args.length ) {
270                                 options = $.widget.extend.apply( null, [ options ].concat( args ) );
271                         }
272
273                         this.each( function() {
274                                 var instance = $.data( this, fullName );
275                                 if ( instance ) {
276                                         instance.option( options || {} );
277                                         if ( instance._init ) {
278                                                 instance._init();
279                                         }
280                                 } else {
281                                         $.data( this, fullName, new object( options, this ) );
282                                 }
283                         } );
284                 }
285
286                 return returnValue;
287         };
288 };
289
290 $.Widget = function( /* options, element */ ) {};
291 $.Widget._childConstructors = [];
292
293 $.Widget.prototype = {
294         widgetName: "widget",
295         widgetEventPrefix: "",
296         defaultElement: "<div>",
297
298         options: {
299                 classes: {},
300                 disabled: false,
301
302                 // Callbacks
303                 create: null
304         },
305
306         _createWidget: function( options, element ) {
307                 element = $( element || this.defaultElement || this )[ 0 ];
308                 this.element = $( element );
309                 this.uuid = widgetUuid++;
310                 this.eventNamespace = "." + this.widgetName + this.uuid;
311
312                 this.bindings = $();
313                 this.hoverable = $();
314                 this.focusable = $();
315                 this.classesElementLookup = {};
316
317                 if ( element !== this ) {
318                         $.data( element, this.widgetFullName, this );
319                         this._on( true, this.element, {
320                                 remove: function( event ) {
321                                         if ( event.target === element ) {
322                                                 this.destroy();
323                                         }
324                                 }
325                         } );
326                         this.document = $( element.style ?
327
328                                 // Element within the document
329                                 element.ownerDocument :
330
331                                 // Element is window or document
332                                 element.document || element );
333                         this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
334                 }
335
336                 this.options = $.widget.extend( {},
337                         this.options,
338                         this._getCreateOptions(),
339                         options );
340
341                 this._create();
342
343                 if ( this.options.disabled ) {
344                         this._setOptionDisabled( this.options.disabled );
345                 }
346
347                 this._trigger( "create", null, this._getCreateEventData() );
348                 this._init();
349         },
350
351         _getCreateOptions: function() {
352                 return {};
353         },
354
355         _getCreateEventData: $.noop,
356
357         _create: $.noop,
358
359         _init: $.noop,
360
361         destroy: function() {
362                 var that = this;
363
364                 this._destroy();
365                 $.each( this.classesElementLookup, function( key, value ) {
366                         that._removeClass( value, key );
367                 } );
368
369                 // We can probably remove the unbind calls in 2.0
370                 // all event bindings should go through this._on()
371                 this.element
372                         .off( this.eventNamespace )
373                         .removeData( this.widgetFullName );
374                 this.widget()
375                         .off( this.eventNamespace )
376                         .removeAttr( "aria-disabled" );
377
378                 // Clean up events and states
379                 this.bindings.off( this.eventNamespace );
380         },
381
382         _destroy: $.noop,
383
384         widget: function() {
385                 return this.element;
386         },
387
388         option: function( key, value ) {
389                 var options = key;
390                 var parts;
391                 var curOption;
392                 var i;
393
394                 if ( arguments.length === 0 ) {
395
396                         // Don't return a reference to the internal hash
397                         return $.widget.extend( {}, this.options );
398                 }
399
400                 if ( typeof key === "string" ) {
401
402                         // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
403                         options = {};
404                         parts = key.split( "." );
405                         key = parts.shift();
406                         if ( parts.length ) {
407                                 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
408                                 for ( i = 0; i < parts.length - 1; i++ ) {
409                                         curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
410                                         curOption = curOption[ parts[ i ] ];
411                                 }
412                                 key = parts.pop();
413                                 if ( arguments.length === 1 ) {
414                                         return curOption[ key ] === undefined ? null : curOption[ key ];
415                                 }
416                                 curOption[ key ] = value;
417                         } else {
418                                 if ( arguments.length === 1 ) {
419                                         return this.options[ key ] === undefined ? null : this.options[ key ];
420                                 }
421                                 options[ key ] = value;
422                         }
423                 }
424
425                 this._setOptions( options );
426
427                 return this;
428         },
429
430         _setOptions: function( options ) {
431                 var key;
432
433                 for ( key in options ) {
434                         this._setOption( key, options[ key ] );
435                 }
436
437                 return this;
438         },
439
440         _setOption: function( key, value ) {
441                 if ( key === "classes" ) {
442                         this._setOptionClasses( value );
443                 }
444
445                 this.options[ key ] = value;
446
447                 if ( key === "disabled" ) {
448                         this._setOptionDisabled( value );
449                 }
450
451                 return this;
452         },
453
454         _setOptionClasses: function( value ) {
455                 var classKey, elements, currentElements;
456
457                 for ( classKey in value ) {
458                         currentElements = this.classesElementLookup[ classKey ];
459                         if ( value[ classKey ] === this.options.classes[ classKey ] ||
460                                         !currentElements ||
461                                         !currentElements.length ) {
462                                 continue;
463                         }
464
465                         // We are doing this to create a new jQuery object because the _removeClass() call
466                         // on the next line is going to destroy the reference to the current elements being
467                         // tracked. We need to save a copy of this collection so that we can add the new classes
468                         // below.
469                         elements = $( currentElements.get() );
470                         this._removeClass( currentElements, classKey );
471
472                         // We don't use _addClass() here, because that uses this.options.classes
473                         // for generating the string of classes. We want to use the value passed in from
474                         // _setOption(), this is the new value of the classes option which was passed to
475                         // _setOption(). We pass this value directly to _classes().
476                         elements.addClass( this._classes( {
477                                 element: elements,
478                                 keys: classKey,
479                                 classes: value,
480                                 add: true
481                         } ) );
482                 }
483         },
484
485         _setOptionDisabled: function( value ) {
486                 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
487
488                 // If the widget is becoming disabled, then nothing is interactive
489                 if ( value ) {
490                         this._removeClass( this.hoverable, null, "ui-state-hover" );
491                         this._removeClass( this.focusable, null, "ui-state-focus" );
492                 }
493         },
494
495         enable: function() {
496                 return this._setOptions( { disabled: false } );
497         },
498
499         disable: function() {
500                 return this._setOptions( { disabled: true } );
501         },
502
503         _classes: function( options ) {
504                 var full = [];
505                 var that = this;
506
507                 options = $.extend( {
508                         element: this.element,
509                         classes: this.options.classes || {}
510                 }, options );
511
512                 function processClassString( classes, checkOption ) {
513                         var current, i;
514                         for ( i = 0; i < classes.length; i++ ) {
515                                 current = that.classesElementLookup[ classes[ i ] ] || $();
516                                 if ( options.add ) {
517                                         current = $( $.unique( current.get().concat( options.element.get() ) ) );
518                                 } else {
519                                         current = $( current.not( options.element ).get() );
520                                 }
521                                 that.classesElementLookup[ classes[ i ] ] = current;
522                                 full.push( classes[ i ] );
523                                 if ( checkOption && options.classes[ classes[ i ] ] ) {
524                                         full.push( options.classes[ classes[ i ] ] );
525                                 }
526                         }
527                 }
528
529                 this._on( options.element, {
530                         "remove": "_untrackClassesElement"
531                 } );
532
533                 if ( options.keys ) {
534                         processClassString( options.keys.match( /\S+/g ) || [], true );
535                 }
536                 if ( options.extra ) {
537                         processClassString( options.extra.match( /\S+/g ) || [] );
538                 }
539
540                 return full.join( " " );
541         },
542
543         _untrackClassesElement: function( event ) {
544                 var that = this;
545                 $.each( that.classesElementLookup, function( key, value ) {
546                         if ( $.inArray( event.target, value ) !== -1 ) {
547                                 that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
548                         }
549                 } );
550         },
551
552         _removeClass: function( element, keys, extra ) {
553                 return this._toggleClass( element, keys, extra, false );
554         },
555
556         _addClass: function( element, keys, extra ) {
557                 return this._toggleClass( element, keys, extra, true );
558         },
559
560         _toggleClass: function( element, keys, extra, add ) {
561                 add = ( typeof add === "boolean" ) ? add : extra;
562                 var shift = ( typeof element === "string" || element === null ),
563                         options = {
564                                 extra: shift ? keys : extra,
565                                 keys: shift ? element : keys,
566                                 element: shift ? this.element : element,
567                                 add: add
568                         };
569                 options.element.toggleClass( this._classes( options ), add );
570                 return this;
571         },
572
573         _on: function( suppressDisabledCheck, element, handlers ) {
574                 var delegateElement;
575                 var instance = this;
576
577                 // No suppressDisabledCheck flag, shuffle arguments
578                 if ( typeof suppressDisabledCheck !== "boolean" ) {
579                         handlers = element;
580                         element = suppressDisabledCheck;
581                         suppressDisabledCheck = false;
582                 }
583
584                 // No element argument, shuffle and use this.element
585                 if ( !handlers ) {
586                         handlers = element;
587                         element = this.element;
588                         delegateElement = this.widget();
589                 } else {
590                         element = delegateElement = $( element );
591                         this.bindings = this.bindings.add( element );
592                 }
593
594                 $.each( handlers, function( event, handler ) {
595                         function handlerProxy() {
596
597                                 // Allow widgets to customize the disabled handling
598                                 // - disabled as an array instead of boolean
599                                 // - disabled class as method for disabling individual parts
600                                 if ( !suppressDisabledCheck &&
601                                                 ( instance.options.disabled === true ||
602                                                 $( this ).hasClass( "ui-state-disabled" ) ) ) {
603                                         return;
604                                 }
605                                 return ( typeof handler === "string" ? instance[ handler ] : handler )
606                                         .apply( instance, arguments );
607                         }
608
609                         // Copy the guid so direct unbinding works
610                         if ( typeof handler !== "string" ) {
611                                 handlerProxy.guid = handler.guid =
612                                         handler.guid || handlerProxy.guid || $.guid++;
613                         }
614
615                         var match = event.match( /^([\w:-]*)\s*(.*)$/ );
616                         var eventName = match[ 1 ] + instance.eventNamespace;
617                         var selector = match[ 2 ];
618
619                         if ( selector ) {
620                                 delegateElement.on( eventName, selector, handlerProxy );
621                         } else {
622                                 element.on( eventName, handlerProxy );
623                         }
624                 } );
625         },
626
627         _off: function( element, eventName ) {
628                 eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
629                         this.eventNamespace;
630                 element.off( eventName ).off( eventName );
631
632                 // Clear the stack to avoid memory leaks (#10056)
633                 this.bindings = $( this.bindings.not( element ).get() );
634                 this.focusable = $( this.focusable.not( element ).get() );
635                 this.hoverable = $( this.hoverable.not( element ).get() );
636         },
637
638         _delay: function( handler, delay ) {
639                 function handlerProxy() {
640                         return ( typeof handler === "string" ? instance[ handler ] : handler )
641                                 .apply( instance, arguments );
642                 }
643                 var instance = this;
644                 return setTimeout( handlerProxy, delay || 0 );
645         },
646
647         _hoverable: function( element ) {
648                 this.hoverable = this.hoverable.add( element );
649                 this._on( element, {
650                         mouseenter: function( event ) {
651                                 this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
652                         },
653                         mouseleave: function( event ) {
654                                 this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
655                         }
656                 } );
657         },
658
659         _focusable: function( element ) {
660                 this.focusable = this.focusable.add( element );
661                 this._on( element, {
662                         focusin: function( event ) {
663                                 this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
664                         },
665                         focusout: function( event ) {
666                                 this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
667                         }
668                 } );
669         },
670
671         _trigger: function( type, event, data ) {
672                 var prop, orig;
673                 var callback = this.options[ type ];
674
675                 data = data || {};
676                 event = $.Event( event );
677                 event.type = ( type === this.widgetEventPrefix ?
678                         type :
679                         this.widgetEventPrefix + type ).toLowerCase();
680
681                 // The original event may come from any element
682                 // so we need to reset the target on the new event
683                 event.target = this.element[ 0 ];
684
685                 // Copy original event properties over to the new event
686                 orig = event.originalEvent;
687                 if ( orig ) {
688                         for ( prop in orig ) {
689                                 if ( !( prop in event ) ) {
690                                         event[ prop ] = orig[ prop ];
691                                 }
692                         }
693                 }
694
695                 this.element.trigger( event, data );
696                 return !( $.isFunction( callback ) &&
697                         callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
698                         event.isDefaultPrevented() );
699         }
700 };
701
702 $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
703         $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
704                 if ( typeof options === "string" ) {
705                         options = { effect: options };
706                 }
707
708                 var hasOptions;
709                 var effectName = !options ?
710                         method :
711                         options === true || typeof options === "number" ?
712                                 defaultEffect :
713                                 options.effect || defaultEffect;
714
715                 options = options || {};
716                 if ( typeof options === "number" ) {
717                         options = { duration: options };
718                 }
719
720                 hasOptions = !$.isEmptyObject( options );
721                 options.complete = callback;
722
723                 if ( options.delay ) {
724                         element.delay( options.delay );
725                 }
726
727                 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
728                         element[ method ]( options );
729                 } else if ( effectName !== method && element[ effectName ] ) {
730                         element[ effectName ]( options.duration, options.easing, callback );
731                 } else {
732                         element.queue( function( next ) {
733                                 $( this )[ method ]();
734                                 if ( callback ) {
735                                         callback.call( element[ 0 ] );
736                                 }
737                                 next();
738                         } );
739                 }
740         };
741 } );
742
743 var widget = $.widget;
744
745
746 /*!
747  * jQuery UI :data 1.12.1
748  * http://jqueryui.com
749  *
750  * Copyright jQuery Foundation and other contributors
751  * Released under the MIT license.
752  * http://jquery.org/license
753  */
754
755 //>>label: :data Selector
756 //>>group: Core
757 //>>description: Selects elements which have data stored under the specified key.
758 //>>docs: http://api.jqueryui.com/data-selector/
759
760
761 var data = $.extend( $.expr[ ":" ], {
762         data: $.expr.createPseudo ?
763                 $.expr.createPseudo( function( dataName ) {
764                         return function( elem ) {
765                                 return !!$.data( elem, dataName );
766                         };
767                 } ) :
768
769                 // Support: jQuery <1.8
770                 function( elem, i, match ) {
771                         return !!$.data( elem, match[ 3 ] );
772                 }
773 } );
774
775 /*!
776  * jQuery UI Disable Selection 1.12.1
777  * http://jqueryui.com
778  *
779  * Copyright jQuery Foundation and other contributors
780  * Released under the MIT license.
781  * http://jquery.org/license
782  */
783
784 //>>label: disableSelection
785 //>>group: Core
786 //>>description: Disable selection of text content within the set of matched elements.
787 //>>docs: http://api.jqueryui.com/disableSelection/
788
789 // This file is deprecated
790
791
792 var disableSelection = $.fn.extend( {
793         disableSelection: ( function() {
794                 var eventType = "onselectstart" in document.createElement( "div" ) ?
795                         "selectstart" :
796                         "mousedown";
797
798                 return function() {
799                         return this.on( eventType + ".ui-disableSelection", function( event ) {
800                                 event.preventDefault();
801                         } );
802                 };
803         } )(),
804
805         enableSelection: function() {
806                 return this.off( ".ui-disableSelection" );
807         }
808 } );
809
810
811 /*!
812  * jQuery UI Keycode 1.12.1
813  * http://jqueryui.com
814  *
815  * Copyright jQuery Foundation and other contributors
816  * Released under the MIT license.
817  * http://jquery.org/license
818  */
819
820 //>>label: Keycode
821 //>>group: Core
822 //>>description: Provide keycodes as keynames
823 //>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/
824
825
826 var keycode = $.ui.keyCode = {
827         BACKSPACE: 8,
828         COMMA: 188,
829         DELETE: 46,
830         DOWN: 40,
831         END: 35,
832         ENTER: 13,
833         ESCAPE: 27,
834         HOME: 36,
835         LEFT: 37,
836         PAGE_DOWN: 34,
837         PAGE_UP: 33,
838         PERIOD: 190,
839         RIGHT: 39,
840         SPACE: 32,
841         TAB: 9,
842         UP: 38
843 };
844
845
846 /*!
847  * jQuery UI Scroll Parent 1.12.1
848  * http://jqueryui.com
849  *
850  * Copyright jQuery Foundation and other contributors
851  * Released under the MIT license.
852  * http://jquery.org/license
853  */
854
855 //>>label: scrollParent
856 //>>group: Core
857 //>>description: Get the closest ancestor element that is scrollable.
858 //>>docs: http://api.jqueryui.com/scrollParent/
859
860
861
862 var scrollParent = $.fn.scrollParent = function( includeHidden ) {
863         var position = this.css( "position" ),
864                 excludeStaticParent = position === "absolute",
865                 overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
866                 scrollParent = this.parents().filter( function() {
867                         var parent = $( this );
868                         if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
869                                 return false;
870                         }
871                         return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
872                                 parent.css( "overflow-x" ) );
873                 } ).eq( 0 );
874
875         return position === "fixed" || !scrollParent.length ?
876                 $( this[ 0 ].ownerDocument || document ) :
877                 scrollParent;
878 };
879
880
881 /*!
882  * jQuery UI Unique ID 1.12.1
883  * http://jqueryui.com
884  *
885  * Copyright jQuery Foundation and other contributors
886  * Released under the MIT license.
887  * http://jquery.org/license
888  */
889
890 //>>label: uniqueId
891 //>>group: Core
892 //>>description: Functions to generate and remove uniqueId's
893 //>>docs: http://api.jqueryui.com/uniqueId/
894
895
896
897 var uniqueId = $.fn.extend( {
898         uniqueId: ( function() {
899                 var uuid = 0;
900
901                 return function() {
902                         return this.each( function() {
903                                 if ( !this.id ) {
904                                         this.id = "ui-id-" + ( ++uuid );
905                                 }
906                         } );
907                 };
908         } )(),
909
910         removeUniqueId: function() {
911                 return this.each( function() {
912                         if ( /^ui-id-\d+$/.test( this.id ) ) {
913                                 $( this ).removeAttr( "id" );
914                         }
915                 } );
916         }
917 } );
918
919
920
921
922 // This file is deprecated
923 var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
924
925 /*!
926  * jQuery UI Mouse 1.12.1
927  * http://jqueryui.com
928  *
929  * Copyright jQuery Foundation and other contributors
930  * Released under the MIT license.
931  * http://jquery.org/license
932  */
933
934 //>>label: Mouse
935 //>>group: Widgets
936 //>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
937 //>>docs: http://api.jqueryui.com/mouse/
938
939
940
941 var mouseHandled = false;
942 $( document ).on( "mouseup", function() {
943         mouseHandled = false;
944 } );
945
946 var widgetsMouse = $.widget( "ui.mouse", {
947         version: "1.12.1",
948         options: {
949                 cancel: "input, textarea, button, select, option",
950                 distance: 1,
951                 delay: 0
952         },
953         _mouseInit: function() {
954                 var that = this;
955
956                 this.element
957                         .on( "mousedown." + this.widgetName, function( event ) {
958                                 return that._mouseDown( event );
959                         } )
960                         .on( "click." + this.widgetName, function( event ) {
961                                 if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
962                                         $.removeData( event.target, that.widgetName + ".preventClickEvent" );
963                                         event.stopImmediatePropagation();
964                                         return false;
965                                 }
966                         } );
967
968                 this.started = false;
969         },
970
971         // TODO: make sure destroying one instance of mouse doesn't mess with
972         // other instances of mouse
973         _mouseDestroy: function() {
974                 this.element.off( "." + this.widgetName );
975                 if ( this._mouseMoveDelegate ) {
976                         this.document
977                                 .off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
978                                 .off( "mouseup." + this.widgetName, this._mouseUpDelegate );
979                 }
980         },
981
982         _mouseDown: function( event ) {
983
984                 // don't let more than one widget handle mouseStart
985                 if ( mouseHandled ) {
986                         return;
987                 }
988
989                 this._mouseMoved = false;
990
991                 // We may have missed mouseup (out of window)
992                 ( this._mouseStarted && this._mouseUp( event ) );
993
994                 this._mouseDownEvent = event;
995
996                 var that = this,
997                         btnIsLeft = ( event.which === 1 ),
998
999                         // event.target.nodeName works around a bug in IE 8 with
1000                         // disabled inputs (#7620)
1001                         elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
1002                                 $( event.target ).closest( this.options.cancel ).length : false );
1003                 if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
1004                         return true;
1005                 }
1006
1007                 this.mouseDelayMet = !this.options.delay;
1008                 if ( !this.mouseDelayMet ) {
1009                         this._mouseDelayTimer = setTimeout( function() {
1010                                 that.mouseDelayMet = true;
1011                         }, this.options.delay );
1012                 }
1013
1014                 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
1015                         this._mouseStarted = ( this._mouseStart( event ) !== false );
1016                         if ( !this._mouseStarted ) {
1017                                 event.preventDefault();
1018                                 return true;
1019                         }
1020                 }
1021
1022                 // Click event may never have fired (Gecko & Opera)
1023                 if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
1024                         $.removeData( event.target, this.widgetName + ".preventClickEvent" );
1025                 }
1026
1027                 // These delegates are required to keep context
1028                 this._mouseMoveDelegate = function( event ) {
1029                         return that._mouseMove( event );
1030                 };
1031                 this._mouseUpDelegate = function( event ) {
1032                         return that._mouseUp( event );
1033                 };
1034
1035                 this.document
1036                         .on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
1037                         .on( "mouseup." + this.widgetName, this._mouseUpDelegate );
1038
1039                 event.preventDefault();
1040
1041                 mouseHandled = true;
1042                 return true;
1043         },
1044
1045         _mouseMove: function( event ) {
1046
1047                 // Only check for mouseups outside the document if you've moved inside the document
1048                 // at least once. This prevents the firing of mouseup in the case of IE<9, which will
1049                 // fire a mousemove event if content is placed under the cursor. See #7778
1050                 // Support: IE <9
1051                 if ( this._mouseMoved ) {
1052
1053                         // IE mouseup check - mouseup happened when mouse was out of window
1054                         if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
1055                                         !event.button ) {
1056                                 return this._mouseUp( event );
1057
1058                         // Iframe mouseup check - mouseup occurred in another document
1059                         } else if ( !event.which ) {
1060
1061                                 // Support: Safari <=8 - 9
1062                                 // Safari sets which to 0 if you press any of the following keys
1063                                 // during a drag (#14461)
1064                                 if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
1065                                                 event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
1066                                         this.ignoreMissingWhich = true;
1067                                 } else if ( !this.ignoreMissingWhich ) {
1068                                         return this._mouseUp( event );
1069                                 }
1070                         }
1071                 }
1072
1073                 if ( event.which || event.button ) {
1074                         this._mouseMoved = true;
1075                 }
1076
1077                 if ( this._mouseStarted ) {
1078                         this._mouseDrag( event );
1079                         return event.preventDefault();
1080                 }
1081
1082                 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
1083                         this._mouseStarted =
1084                                 ( this._mouseStart( this._mouseDownEvent, event ) !== false );
1085                         ( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) );
1086                 }
1087
1088                 return !this._mouseStarted;
1089         },
1090
1091         _mouseUp: function( event ) {
1092                 this.document
1093                         .off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
1094                         .off( "mouseup." + this.widgetName, this._mouseUpDelegate );
1095
1096                 if ( this._mouseStarted ) {
1097                         this._mouseStarted = false;
1098
1099                         if ( event.target === this._mouseDownEvent.target ) {
1100                                 $.data( event.target, this.widgetName + ".preventClickEvent", true );
1101                         }
1102
1103                         this._mouseStop( event );
1104                 }
1105
1106                 if ( this._mouseDelayTimer ) {
1107                         clearTimeout( this._mouseDelayTimer );
1108                         delete this._mouseDelayTimer;
1109                 }
1110
1111                 this.ignoreMissingWhich = false;
1112                 mouseHandled = false;
1113                 event.preventDefault();
1114         },
1115
1116         _mouseDistanceMet: function( event ) {
1117                 return ( Math.max(
1118                                 Math.abs( this._mouseDownEvent.pageX - event.pageX ),
1119                                 Math.abs( this._mouseDownEvent.pageY - event.pageY )
1120                         ) >= this.options.distance
1121                 );
1122         },
1123
1124         _mouseDelayMet: function( /* event */ ) {
1125                 return this.mouseDelayMet;
1126         },
1127
1128         // These are placeholder methods, to be overriden by extending plugin
1129         _mouseStart: function( /* event */ ) {},
1130         _mouseDrag: function( /* event */ ) {},
1131         _mouseStop: function( /* event */ ) {},
1132         _mouseCapture: function( /* event */ ) { return true; }
1133 } );
1134
1135
1136
1137
1138 // $.ui.plugin is deprecated. Use $.widget() extensions instead.
1139 var plugin = $.ui.plugin = {
1140         add: function( module, option, set ) {
1141                 var i,
1142                         proto = $.ui[ module ].prototype;
1143                 for ( i in set ) {
1144                         proto.plugins[ i ] = proto.plugins[ i ] || [];
1145                         proto.plugins[ i ].push( [ option, set[ i ] ] );
1146                 }
1147         },
1148         call: function( instance, name, args, allowDisconnected ) {
1149                 var i,
1150                         set = instance.plugins[ name ];
1151
1152                 if ( !set ) {
1153                         return;
1154                 }
1155
1156                 if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
1157                                 instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
1158                         return;
1159                 }
1160
1161                 for ( i = 0; i < set.length; i++ ) {
1162                         if ( instance.options[ set[ i ][ 0 ] ] ) {
1163                                 set[ i ][ 1 ].apply( instance.element, args );
1164                         }
1165                 }
1166         }
1167 };
1168
1169
1170
1171 var safeActiveElement = $.ui.safeActiveElement = function( document ) {
1172         var activeElement;
1173
1174         // Support: IE 9 only
1175         // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
1176         try {
1177                 activeElement = document.activeElement;
1178         } catch ( error ) {
1179                 activeElement = document.body;
1180         }
1181
1182         // Support: IE 9 - 11 only
1183         // IE may return null instead of an element
1184         // Interestingly, this only seems to occur when NOT in an iframe
1185         if ( !activeElement ) {
1186                 activeElement = document.body;
1187         }
1188
1189         // Support: IE 11 only
1190         // IE11 returns a seemingly empty object in some cases when accessing
1191         // document.activeElement from an <iframe>
1192         if ( !activeElement.nodeName ) {
1193                 activeElement = document.body;
1194         }
1195
1196         return activeElement;
1197 };
1198
1199
1200
1201 var safeBlur = $.ui.safeBlur = function( element ) {
1202
1203         // Support: IE9 - 10 only
1204         // If the <body> is blurred, IE will switch windows, see #9420
1205         if ( element && element.nodeName.toLowerCase() !== "body" ) {
1206                 $( element ).trigger( "blur" );
1207         }
1208 };
1209
1210
1211 /*!
1212  * jQuery UI Draggable 1.12.1
1213  * http://jqueryui.com
1214  *
1215  * Copyright jQuery Foundation and other contributors
1216  * Released under the MIT license.
1217  * http://jquery.org/license
1218  */
1219
1220 //>>label: Draggable
1221 //>>group: Interactions
1222 //>>description: Enables dragging functionality for any element.
1223 //>>docs: http://api.jqueryui.com/draggable/
1224 //>>demos: http://jqueryui.com/draggable/
1225 //>>css.structure: ../../themes/base/draggable.css
1226
1227
1228
1229 $.widget( "ui.draggable", $.ui.mouse, {
1230         version: "1.12.1",
1231         widgetEventPrefix: "drag",
1232         options: {
1233                 addClasses: true,
1234                 appendTo: "parent",
1235                 axis: false,
1236                 connectToSortable: false,
1237                 containment: false,
1238                 cursor: "auto",
1239                 cursorAt: false,
1240                 grid: false,
1241                 handle: false,
1242                 helper: "original",
1243                 iframeFix: false,
1244                 opacity: false,
1245                 refreshPositions: false,
1246                 revert: false,
1247                 revertDuration: 500,
1248                 scope: "default",
1249                 scroll: true,
1250                 scrollSensitivity: 20,
1251                 scrollSpeed: 20,
1252                 snap: false,
1253                 snapMode: "both",
1254                 snapTolerance: 20,
1255                 stack: false,
1256                 zIndex: false,
1257
1258                 // Callbacks
1259                 drag: null,
1260                 start: null,
1261                 stop: null
1262         },
1263         _create: function() {
1264
1265                 if ( this.options.helper === "original" ) {
1266                         this._setPositionRelative();
1267                 }
1268                 if ( this.options.addClasses ) {
1269                         this._addClass( "ui-draggable" );
1270                 }
1271                 this._setHandleClassName();
1272
1273                 this._mouseInit();
1274         },
1275
1276         _setOption: function( key, value ) {
1277                 this._super( key, value );
1278                 if ( key === "handle" ) {
1279                         this._removeHandleClassName();
1280                         this._setHandleClassName();
1281                 }
1282         },
1283
1284         _destroy: function() {
1285                 if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
1286                         this.destroyOnClear = true;
1287                         return;
1288                 }
1289                 this._removeHandleClassName();
1290                 this._mouseDestroy();
1291         },
1292
1293         _mouseCapture: function( event ) {
1294                 var o = this.options;
1295
1296                 // Among others, prevent a drag on a resizable-handle
1297                 if ( this.helper || o.disabled ||
1298                                 $( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
1299                         return false;
1300                 }
1301
1302                 //Quit if we're not on a valid handle
1303                 this.handle = this._getHandle( event );
1304                 if ( !this.handle ) {
1305                         return false;
1306                 }
1307
1308                 this._blurActiveElement( event );
1309
1310                 this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
1311
1312                 return true;
1313
1314         },
1315
1316         _blockFrames: function( selector ) {
1317                 this.iframeBlocks = this.document.find( selector ).map( function() {
1318                         var iframe = $( this );
1319
1320                         return $( "<div>" )
1321                                 .css( "position", "absolute" )
1322                                 .appendTo( iframe.parent() )
1323                                 .outerWidth( iframe.outerWidth() )
1324                                 .outerHeight( iframe.outerHeight() )
1325                                 .offset( iframe.offset() )[ 0 ];
1326                 } );
1327         },
1328
1329         _unblockFrames: function() {
1330                 if ( this.iframeBlocks ) {
1331                         this.iframeBlocks.remove();
1332                         delete this.iframeBlocks;
1333                 }
1334         },
1335
1336         _blurActiveElement: function( event ) {
1337                 var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
1338                         target = $( event.target );
1339
1340                 // Don't blur if the event occurred on an element that is within
1341                 // the currently focused element
1342                 // See #10527, #12472
1343                 if ( target.closest( activeElement ).length ) {
1344                         return;
1345                 }
1346
1347                 // Blur any element that currently has focus, see #4261
1348                 $.ui.safeBlur( activeElement );
1349         },
1350
1351         _mouseStart: function( event ) {
1352
1353                 var o = this.options;
1354
1355                 //Create and append the visible helper
1356                 this.helper = this._createHelper( event );
1357
1358                 this._addClass( this.helper, "ui-draggable-dragging" );
1359
1360                 //Cache the helper size
1361                 this._cacheHelperProportions();
1362
1363                 //If ddmanager is used for droppables, set the global draggable
1364                 if ( $.ui.ddmanager ) {
1365                         $.ui.ddmanager.current = this;
1366                 }
1367
1368                 /*
1369                  * - Position generation -
1370                  * This block generates everything position related - it's the core of draggables.
1371                  */
1372
1373                 //Cache the margins of the original element
1374                 this._cacheMargins();
1375
1376                 //Store the helper's css position
1377                 this.cssPosition = this.helper.css( "position" );
1378                 this.scrollParent = this.helper.scrollParent( true );
1379                 this.offsetParent = this.helper.offsetParent();
1380                 this.hasFixedAncestor = this.helper.parents().filter( function() {
1381                                 return $( this ).css( "position" ) === "fixed";
1382                         } ).length > 0;
1383
1384                 //The element's absolute position on the page minus margins
1385                 this.positionAbs = this.element.offset();
1386                 this._refreshOffsets( event );
1387
1388                 //Generate the original position
1389                 this.originalPosition = this.position = this._generatePosition( event, false );
1390                 this.originalPageX = event.pageX;
1391                 this.originalPageY = event.pageY;
1392
1393                 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
1394                 ( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
1395
1396                 //Set a containment if given in the options
1397                 this._setContainment();
1398
1399                 //Trigger event + callbacks
1400                 if ( this._trigger( "start", event ) === false ) {
1401                         this._clear();
1402                         return false;
1403                 }
1404
1405                 //Recache the helper size
1406                 this._cacheHelperProportions();
1407
1408                 //Prepare the droppable offsets
1409                 if ( $.ui.ddmanager && !o.dropBehaviour ) {
1410                         $.ui.ddmanager.prepareOffsets( this, event );
1411                 }
1412
1413                 // Execute the drag once - this causes the helper not to be visible before getting its
1414                 // correct position
1415                 this._mouseDrag( event, true );
1416
1417                 // If the ddmanager is used for droppables, inform the manager that dragging has started
1418                 // (see #5003)
1419                 if ( $.ui.ddmanager ) {
1420                         $.ui.ddmanager.dragStart( this, event );
1421                 }
1422
1423                 return true;
1424         },
1425
1426         _refreshOffsets: function( event ) {
1427                 this.offset = {
1428                         top: this.positionAbs.top - this.margins.top,
1429                         left: this.positionAbs.left - this.margins.left,
1430                         scroll: false,
1431                         parent: this._getParentOffset(),
1432                         relative: this._getRelativeOffset()
1433                 };
1434
1435                 this.offset.click = {
1436                         left: event.pageX - this.offset.left,
1437                         top: event.pageY - this.offset.top
1438                 };
1439         },
1440
1441         _mouseDrag: function( event, noPropagation ) {
1442
1443                 // reset any necessary cached properties (see #5009)
1444                 if ( this.hasFixedAncestor ) {
1445                         this.offset.parent = this._getParentOffset();
1446                 }
1447
1448                 //Compute the helpers position
1449                 this.position = this._generatePosition( event, true );
1450                 this.positionAbs = this._convertPositionTo( "absolute" );
1451
1452                 //Call plugins and callbacks and use the resulting position if something is returned
1453                 if ( !noPropagation ) {
1454                         var ui = this._uiHash();
1455                         if ( this._trigger( "drag", event, ui ) === false ) {
1456                                 this._mouseUp( new $.Event( "mouseup", event ) );
1457                                 return false;
1458                         }
1459                         this.position = ui.position;
1460                 }
1461
1462                 this.helper[ 0 ].style.left = this.position.left + "px";
1463                 this.helper[ 0 ].style.top = this.position.top + "px";
1464
1465                 if ( $.ui.ddmanager ) {
1466                         $.ui.ddmanager.drag( this, event );
1467                 }
1468
1469                 return false;
1470         },
1471
1472         _mouseStop: function( event ) {
1473
1474                 //If we are using droppables, inform the manager about the drop
1475                 var that = this,
1476                         dropped = false;
1477                 if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
1478                         dropped = $.ui.ddmanager.drop( this, event );
1479                 }
1480
1481                 //if a drop comes from outside (a sortable)
1482                 if ( this.dropped ) {
1483                         dropped = this.dropped;
1484                         this.dropped = false;
1485                 }
1486
1487                 if ( ( this.options.revert === "invalid" && !dropped ) ||
1488                                 ( this.options.revert === "valid" && dropped ) ||
1489                                 this.options.revert === true || ( $.isFunction( this.options.revert ) &&
1490                                 this.options.revert.call( this.element, dropped ) )
1491                 ) {
1492                         $( this.helper ).animate(
1493                                 this.originalPosition,
1494                                 parseInt( this.options.revertDuration, 10 ),
1495                                 function() {
1496                                         if ( that._trigger( "stop", event ) !== false ) {
1497                                                 that._clear();
1498                                         }
1499                                 }
1500                         );
1501                 } else {
1502                         if ( this._trigger( "stop", event ) !== false ) {
1503                                 this._clear();
1504                         }
1505                 }
1506
1507                 return false;
1508         },
1509
1510         _mouseUp: function( event ) {
1511                 this._unblockFrames();
1512
1513                 // If the ddmanager is used for droppables, inform the manager that dragging has stopped
1514                 // (see #5003)
1515                 if ( $.ui.ddmanager ) {
1516                         $.ui.ddmanager.dragStop( this, event );
1517                 }
1518
1519                 // Only need to focus if the event occurred on the draggable itself, see #10527
1520                 if ( this.handleElement.is( event.target ) ) {
1521
1522                         // The interaction is over; whether or not the click resulted in a drag,
1523                         // focus the element
1524                         this.element.trigger( "focus" );
1525                 }
1526
1527                 return $.ui.mouse.prototype._mouseUp.call( this, event );
1528         },
1529
1530         cancel: function() {
1531
1532                 if ( this.helper.is( ".ui-draggable-dragging" ) ) {
1533                         this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
1534                 } else {
1535                         this._clear();
1536                 }
1537
1538                 return this;
1539
1540         },
1541
1542         _getHandle: function( event ) {
1543                 return this.options.handle ?
1544                         !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
1545                         true;
1546         },
1547
1548         _setHandleClassName: function() {
1549                 this.handleElement = this.options.handle ?
1550                         this.element.find( this.options.handle ) : this.element;
1551                 this._addClass( this.handleElement, "ui-draggable-handle" );
1552         },
1553
1554         _removeHandleClassName: function() {
1555                 this._removeClass( this.handleElement, "ui-draggable-handle" );
1556         },
1557
1558         _createHelper: function( event ) {
1559
1560                 var o = this.options,
1561                         helperIsFunction = $.isFunction( o.helper ),
1562                         helper = helperIsFunction ?
1563                                 $( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
1564                                 ( o.helper === "clone" ?
1565                                         this.element.clone().removeAttr( "id" ) :
1566                                         this.element );
1567
1568                 if ( !helper.parents( "body" ).length ) {
1569                         helper.appendTo( ( o.appendTo === "parent" ?
1570                                 this.element[ 0 ].parentNode :
1571                                 o.appendTo ) );
1572                 }
1573
1574                 // Http://bugs.jqueryui.com/ticket/9446
1575                 // a helper function can return the original element
1576                 // which wouldn't have been set to relative in _create
1577                 if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
1578                         this._setPositionRelative();
1579                 }
1580
1581                 if ( helper[ 0 ] !== this.element[ 0 ] &&
1582                                 !( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
1583                         helper.css( "position", "absolute" );
1584                 }
1585
1586                 return helper;
1587
1588         },
1589
1590         _setPositionRelative: function() {
1591                 if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
1592                         this.element[ 0 ].style.position = "relative";
1593                 }
1594         },
1595
1596         _adjustOffsetFromHelper: function( obj ) {
1597                 if ( typeof obj === "string" ) {
1598                         obj = obj.split( " " );
1599                 }
1600                 if ( $.isArray( obj ) ) {
1601                         obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
1602                 }
1603                 if ( "left" in obj ) {
1604                         this.offset.click.left = obj.left + this.margins.left;
1605                 }
1606                 if ( "right" in obj ) {
1607                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1608                 }
1609                 if ( "top" in obj ) {
1610                         this.offset.click.top = obj.top + this.margins.top;
1611                 }
1612                 if ( "bottom" in obj ) {
1613                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1614                 }
1615         },
1616
1617         _isRootNode: function( element ) {
1618                 return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
1619         },
1620
1621         _getParentOffset: function() {
1622
1623                 //Get the offsetParent and cache its position
1624                 var po = this.offsetParent.offset(),
1625                         document = this.document[ 0 ];
1626
1627                 // This is a special case where we need to modify a offset calculated on start, since the
1628                 // following happened:
1629                 // 1. The position of the helper is absolute, so it's position is calculated based on the
1630                 // next positioned parent
1631                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
1632                 // the document, which means that the scroll is included in the initial calculation of the
1633                 // offset of the parent, and never recalculated upon drag
1634                 if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
1635                                 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
1636                         po.left += this.scrollParent.scrollLeft();
1637                         po.top += this.scrollParent.scrollTop();
1638                 }
1639
1640                 if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
1641                         po = { top: 0, left: 0 };
1642                 }
1643
1644                 return {
1645                         top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
1646                         left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
1647                 };
1648
1649         },
1650
1651         _getRelativeOffset: function() {
1652                 if ( this.cssPosition !== "relative" ) {
1653                         return { top: 0, left: 0 };
1654                 }
1655
1656                 var p = this.element.position(),
1657                         scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
1658
1659                 return {
1660                         top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
1661                                 ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
1662                         left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
1663                                 ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
1664                 };
1665
1666         },
1667
1668         _cacheMargins: function() {
1669                 this.margins = {
1670                         left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
1671                         top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
1672                         right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
1673                         bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
1674                 };
1675         },
1676
1677         _cacheHelperProportions: function() {
1678                 this.helperProportions = {
1679                         width: this.helper.outerWidth(),
1680                         height: this.helper.outerHeight()
1681                 };
1682         },
1683
1684         _setContainment: function() {
1685
1686                 var isUserScrollable, c, ce,
1687                         o = this.options,
1688                         document = this.document[ 0 ];
1689
1690                 this.relativeContainer = null;
1691
1692                 if ( !o.containment ) {
1693                         this.containment = null;
1694                         return;
1695                 }
1696
1697                 if ( o.containment === "window" ) {
1698                         this.containment = [
1699                                 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1700                                 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1701                                 $( window ).scrollLeft() + $( window ).width() -
1702                                         this.helperProportions.width - this.margins.left,
1703                                 $( window ).scrollTop() +
1704                                         ( $( window ).height() || document.body.parentNode.scrollHeight ) -
1705                                         this.helperProportions.height - this.margins.top
1706                         ];
1707                         return;
1708                 }
1709
1710                 if ( o.containment === "document" ) {
1711                         this.containment = [
1712                                 0,
1713                                 0,
1714                                 $( document ).width() - this.helperProportions.width - this.margins.left,
1715                                 ( $( document ).height() || document.body.parentNode.scrollHeight ) -
1716                                         this.helperProportions.height - this.margins.top
1717                         ];
1718                         return;
1719                 }
1720
1721                 if ( o.containment.constructor === Array ) {
1722                         this.containment = o.containment;
1723                         return;
1724                 }
1725
1726                 if ( o.containment === "parent" ) {
1727                         o.containment = this.helper[ 0 ].parentNode;
1728                 }
1729
1730                 c = $( o.containment );
1731                 ce = c[ 0 ];
1732
1733                 if ( !ce ) {
1734                         return;
1735                 }
1736
1737                 isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
1738
1739                 this.containment = [
1740                         ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
1741                                 ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
1742                         ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
1743                                 ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
1744                         ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
1745                                 ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
1746                                 ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
1747                                 this.helperProportions.width -
1748                                 this.margins.left -
1749                                 this.margins.right,
1750                         ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
1751                                 ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
1752                                 ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
1753                                 this.helperProportions.height -
1754                                 this.margins.top -
1755                                 this.margins.bottom
1756                 ];
1757                 this.relativeContainer = c;
1758         },
1759
1760         _convertPositionTo: function( d, pos ) {
1761
1762                 if ( !pos ) {
1763                         pos = this.position;
1764                 }
1765
1766                 var mod = d === "absolute" ? 1 : -1,
1767                         scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
1768
1769                 return {
1770                         top: (
1771
1772                                 // The absolute mouse position
1773                                 pos.top +
1774
1775                                 // Only for relative positioned nodes: Relative offset from element to offset parent
1776                                 this.offset.relative.top * mod +
1777
1778                                 // The offsetParent's offset without borders (offset + border)
1779                                 this.offset.parent.top * mod -
1780                                 ( ( this.cssPosition === "fixed" ?
1781                                         -this.offset.scroll.top :
1782                                         ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
1783                         ),
1784                         left: (
1785
1786                                 // The absolute mouse position
1787                                 pos.left +
1788
1789                                 // Only for relative positioned nodes: Relative offset from element to offset parent
1790                                 this.offset.relative.left * mod +
1791
1792                                 // The offsetParent's offset without borders (offset + border)
1793                                 this.offset.parent.left * mod   -
1794                                 ( ( this.cssPosition === "fixed" ?
1795                                         -this.offset.scroll.left :
1796                                         ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
1797                         )
1798                 };
1799
1800         },
1801
1802         _generatePosition: function( event, constrainPosition ) {
1803
1804                 var containment, co, top, left,
1805                         o = this.options,
1806                         scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
1807                         pageX = event.pageX,
1808                         pageY = event.pageY;
1809
1810                 // Cache the scroll
1811                 if ( !scrollIsRootNode || !this.offset.scroll ) {
1812                         this.offset.scroll = {
1813                                 top: this.scrollParent.scrollTop(),
1814                                 left: this.scrollParent.scrollLeft()
1815                         };
1816                 }
1817
1818                 /*
1819                  * - Position constraining -
1820                  * Constrain the position to a mix of grid, containment.
1821                  */
1822
1823                 // If we are not dragging yet, we won't check for options
1824                 if ( constrainPosition ) {
1825                         if ( this.containment ) {
1826                                 if ( this.relativeContainer ) {
1827                                         co = this.relativeContainer.offset();
1828                                         containment = [
1829                                                 this.containment[ 0 ] + co.left,
1830                                                 this.containment[ 1 ] + co.top,
1831                                                 this.containment[ 2 ] + co.left,
1832                                                 this.containment[ 3 ] + co.top
1833                                         ];
1834                                 } else {
1835                                         containment = this.containment;
1836                                 }
1837
1838                                 if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
1839                                         pageX = containment[ 0 ] + this.offset.click.left;
1840                                 }
1841                                 if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
1842                                         pageY = containment[ 1 ] + this.offset.click.top;
1843                                 }
1844                                 if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
1845                                         pageX = containment[ 2 ] + this.offset.click.left;
1846                                 }
1847                                 if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
1848                                         pageY = containment[ 3 ] + this.offset.click.top;
1849                                 }
1850                         }
1851
1852                         if ( o.grid ) {
1853
1854                                 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid
1855                                 // argument errors in IE (see ticket #6950)
1856                                 top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
1857                                         this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
1858                                 pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
1859                                         top - this.offset.click.top > containment[ 3 ] ) ?
1860                                                 top :
1861                                                 ( ( top - this.offset.click.top >= containment[ 1 ] ) ?
1862                                                         top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
1863
1864                                 left = o.grid[ 0 ] ? this.originalPageX +
1865                                         Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
1866                                         this.originalPageX;
1867                                 pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
1868                                         left - this.offset.click.left > containment[ 2 ] ) ?
1869                                                 left :
1870                                                 ( ( left - this.offset.click.left >= containment[ 0 ] ) ?
1871                                                         left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
1872                         }
1873
1874                         if ( o.axis === "y" ) {
1875                                 pageX = this.originalPageX;
1876                         }
1877
1878                         if ( o.axis === "x" ) {
1879                                 pageY = this.originalPageY;
1880                         }
1881                 }
1882
1883                 return {
1884                         top: (
1885
1886                                 // The absolute mouse position
1887                                 pageY -
1888
1889                                 // Click offset (relative to the element)
1890                                 this.offset.click.top -
1891
1892                                 // Only for relative positioned nodes: Relative offset from element to offset parent
1893                                 this.offset.relative.top -
1894
1895                                 // The offsetParent's offset without borders (offset + border)
1896                                 this.offset.parent.top +
1897                                 ( this.cssPosition === "fixed" ?
1898                                         -this.offset.scroll.top :
1899                                         ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
1900                         ),
1901                         left: (
1902
1903                                 // The absolute mouse position
1904                                 pageX -
1905
1906                                 // Click offset (relative to the element)
1907                                 this.offset.click.left -
1908
1909                                 // Only for relative positioned nodes: Relative offset from element to offset parent
1910                                 this.offset.relative.left -
1911
1912                                 // The offsetParent's offset without borders (offset + border)
1913                                 this.offset.parent.left +
1914                                 ( this.cssPosition === "fixed" ?
1915                                         -this.offset.scroll.left :
1916                                         ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
1917                         )
1918                 };
1919
1920         },
1921
1922         _clear: function() {
1923                 this._removeClass( this.helper, "ui-draggable-dragging" );
1924                 if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
1925                         this.helper.remove();
1926                 }
1927                 this.helper = null;
1928                 this.cancelHelperRemoval = false;
1929                 if ( this.destroyOnClear ) {
1930                         this.destroy();
1931                 }
1932         },
1933
1934         // From now on bulk stuff - mainly helpers
1935
1936         _trigger: function( type, event, ui ) {
1937                 ui = ui || this._uiHash();
1938                 $.ui.plugin.call( this, type, [ event, ui, this ], true );
1939
1940                 // Absolute position and offset (see #6884 ) have to be recalculated after plugins
1941                 if ( /^(drag|start|stop)/.test( type ) ) {
1942                         this.positionAbs = this._convertPositionTo( "absolute" );
1943                         ui.offset = this.positionAbs;
1944                 }
1945                 return $.Widget.prototype._trigger.call( this, type, event, ui );
1946         },
1947
1948         plugins: {},
1949
1950         _uiHash: function() {
1951                 return {
1952                         helper: this.helper,
1953                         position: this.position,
1954                         originalPosition: this.originalPosition,
1955                         offset: this.positionAbs
1956                 };
1957         }
1958
1959 } );
1960
1961 $.ui.plugin.add( "draggable", "connectToSortable", {
1962         start: function( event, ui, draggable ) {
1963                 var uiSortable = $.extend( {}, ui, {
1964                         item: draggable.element
1965                 } );
1966
1967                 draggable.sortables = [];
1968                 $( draggable.options.connectToSortable ).each( function() {
1969                         var sortable = $( this ).sortable( "instance" );
1970
1971                         if ( sortable && !sortable.options.disabled ) {
1972                                 draggable.sortables.push( sortable );
1973
1974                                 // RefreshPositions is called at drag start to refresh the containerCache
1975                                 // which is used in drag. This ensures it's initialized and synchronized
1976                                 // with any changes that might have happened on the page since initialization.
1977                                 sortable.refreshPositions();
1978                                 sortable._trigger( "activate", event, uiSortable );
1979                         }
1980                 } );
1981         },
1982         stop: function( event, ui, draggable ) {
1983                 var uiSortable = $.extend( {}, ui, {
1984                         item: draggable.element
1985                 } );
1986
1987                 draggable.cancelHelperRemoval = false;
1988
1989                 $.each( draggable.sortables, function() {
1990                         var sortable = this;
1991
1992                         if ( sortable.isOver ) {
1993                                 sortable.isOver = 0;
1994
1995                                 // Allow this sortable to handle removing the helper
1996                                 draggable.cancelHelperRemoval = true;
1997                                 sortable.cancelHelperRemoval = false;
1998
1999                                 // Use _storedCSS To restore properties in the sortable,
2000                                 // as this also handles revert (#9675) since the draggable
2001                                 // may have modified them in unexpected ways (#8809)
2002                                 sortable._storedCSS = {
2003                                         position: sortable.placeholder.css( "position" ),
2004                                         top: sortable.placeholder.css( "top" ),
2005                                         left: sortable.placeholder.css( "left" )
2006                                 };
2007
2008                                 sortable._mouseStop( event );
2009
2010                                 // Once drag has ended, the sortable should return to using
2011                                 // its original helper, not the shared helper from draggable
2012                                 sortable.options.helper = sortable.options._helper;
2013                         } else {
2014
2015                                 // Prevent this Sortable from removing the helper.
2016                                 // However, don't set the draggable to remove the helper
2017                                 // either as another connected Sortable may yet handle the removal.
2018                                 sortable.cancelHelperRemoval = true;
2019
2020                                 sortable._trigger( "deactivate", event, uiSortable );
2021                         }
2022                 } );
2023         },
2024         drag: function( event, ui, draggable ) {
2025                 $.each( draggable.sortables, function() {
2026                         var innermostIntersecting = false,
2027                                 sortable = this;
2028
2029                         // Copy over variables that sortable's _intersectsWith uses
2030                         sortable.positionAbs = draggable.positionAbs;
2031                         sortable.helperProportions = draggable.helperProportions;
2032                         sortable.offset.click = draggable.offset.click;
2033
2034                         if ( sortable._intersectsWith( sortable.containerCache ) ) {
2035                                 innermostIntersecting = true;
2036
2037                                 $.each( draggable.sortables, function() {
2038
2039                                         // Copy over variables that sortable's _intersectsWith uses
2040                                         this.positionAbs = draggable.positionAbs;
2041                                         this.helperProportions = draggable.helperProportions;
2042                                         this.offset.click = draggable.offset.click;
2043
2044                                         if ( this !== sortable &&
2045                                                         this._intersectsWith( this.containerCache ) &&
2046                                                         $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
2047                                                 innermostIntersecting = false;
2048                                         }
2049
2050                                         return innermostIntersecting;
2051                                 } );
2052                         }
2053
2054                         if ( innermostIntersecting ) {
2055
2056                                 // If it intersects, we use a little isOver variable and set it once,
2057                                 // so that the move-in stuff gets fired only once.
2058                                 if ( !sortable.isOver ) {
2059                                         sortable.isOver = 1;
2060
2061                                         // Store draggable's parent in case we need to reappend to it later.
2062                                         draggable._parent = ui.helper.parent();
2063
2064                                         sortable.currentItem = ui.helper
2065                                                 .appendTo( sortable.element )
2066                                                 .data( "ui-sortable-item", true );
2067
2068                                         // Store helper option to later restore it
2069                                         sortable.options._helper = sortable.options.helper;
2070
2071                                         sortable.options.helper = function() {
2072                                                 return ui.helper[ 0 ];
2073                                         };
2074
2075                                         // Fire the start events of the sortable with our passed browser event,
2076                                         // and our own helper (so it doesn't create a new one)
2077                                         event.target = sortable.currentItem[ 0 ];
2078                                         sortable._mouseCapture( event, true );
2079                                         sortable._mouseStart( event, true, true );
2080
2081                                         // Because the browser event is way off the new appended portlet,
2082                                         // modify necessary variables to reflect the changes
2083                                         sortable.offset.click.top = draggable.offset.click.top;
2084                                         sortable.offset.click.left = draggable.offset.click.left;
2085                                         sortable.offset.parent.left -= draggable.offset.parent.left -
2086                                                 sortable.offset.parent.left;
2087                                         sortable.offset.parent.top -= draggable.offset.parent.top -
2088                                                 sortable.offset.parent.top;
2089
2090                                         draggable._trigger( "toSortable", event );
2091
2092                                         // Inform draggable that the helper is in a valid drop zone,
2093                                         // used solely in the revert option to handle "valid/invalid".
2094                                         draggable.dropped = sortable.element;
2095
2096                                         // Need to refreshPositions of all sortables in the case that
2097                                         // adding to one sortable changes the location of the other sortables (#9675)
2098                                         $.each( draggable.sortables, function() {
2099                                                 this.refreshPositions();
2100                                         } );
2101
2102                                         // Hack so receive/update callbacks work (mostly)
2103                                         draggable.currentItem = draggable.element;
2104                                         sortable.fromOutside = draggable;
2105                                 }
2106
2107                                 if ( sortable.currentItem ) {
2108                                         sortable._mouseDrag( event );
2109
2110                                         // Copy the sortable's position because the draggable's can potentially reflect
2111                                         // a relative position, while sortable is always absolute, which the dragged
2112                                         // element has now become. (#8809)
2113                                         ui.position = sortable.position;
2114                                 }
2115                         } else {
2116
2117                                 // If it doesn't intersect with the sortable, and it intersected before,
2118                                 // we fake the drag stop of the sortable, but make sure it doesn't remove
2119                                 // the helper by using cancelHelperRemoval.
2120                                 if ( sortable.isOver ) {
2121
2122                                         sortable.isOver = 0;
2123                                         sortable.cancelHelperRemoval = true;
2124
2125                                         // Calling sortable's mouseStop would trigger a revert,
2126                                         // so revert must be temporarily false until after mouseStop is called.
2127                                         sortable.options._revert = sortable.options.revert;
2128                                         sortable.options.revert = false;
2129
2130                                         sortable._trigger( "out", event, sortable._uiHash( sortable ) );
2131                                         sortable._mouseStop( event, true );
2132
2133                                         // Restore sortable behaviors that were modfied
2134                                         // when the draggable entered the sortable area (#9481)
2135                                         sortable.options.revert = sortable.options._revert;
2136                                         sortable.options.helper = sortable.options._helper;
2137
2138                                         if ( sortable.placeholder ) {
2139                                                 sortable.placeholder.remove();
2140                                         }
2141
2142                                         // Restore and recalculate the draggable's offset considering the sortable
2143                                         // may have modified them in unexpected ways. (#8809, #10669)
2144                                         ui.helper.appendTo( draggable._parent );
2145                                         draggable._refreshOffsets( event );
2146                                         ui.position = draggable._generatePosition( event, true );
2147
2148                                         draggable._trigger( "fromSortable", event );
2149
2150                                         // Inform draggable that the helper is no longer in a valid drop zone
2151                                         draggable.dropped = false;
2152
2153                                         // Need to refreshPositions of all sortables just in case removing
2154                                         // from one sortable changes the location of other sortables (#9675)
2155                                         $.each( draggable.sortables, function() {
2156                                                 this.refreshPositions();
2157                                         } );
2158                                 }
2159                         }
2160                 } );
2161         }
2162 } );
2163
2164 $.ui.plugin.add( "draggable", "cursor", {
2165         start: function( event, ui, instance ) {
2166                 var t = $( "body" ),
2167                         o = instance.options;
2168
2169                 if ( t.css( "cursor" ) ) {
2170                         o._cursor = t.css( "cursor" );
2171                 }
2172                 t.css( "cursor", o.cursor );
2173         },
2174         stop: function( event, ui, instance ) {
2175                 var o = instance.options;
2176                 if ( o._cursor ) {
2177                         $( "body" ).css( "cursor", o._cursor );
2178                 }
2179         }
2180 } );
2181
2182 $.ui.plugin.add( "draggable", "opacity", {
2183         start: function( event, ui, instance ) {
2184                 var t = $( ui.helper ),
2185                         o = instance.options;
2186                 if ( t.css( "opacity" ) ) {
2187                         o._opacity = t.css( "opacity" );
2188                 }
2189                 t.css( "opacity", o.opacity );
2190         },
2191         stop: function( event, ui, instance ) {
2192                 var o = instance.options;
2193                 if ( o._opacity ) {
2194                         $( ui.helper ).css( "opacity", o._opacity );
2195                 }
2196         }
2197 } );
2198
2199 $.ui.plugin.add( "draggable", "scroll", {
2200         start: function( event, ui, i ) {
2201                 if ( !i.scrollParentNotHidden ) {
2202                         i.scrollParentNotHidden = i.helper.scrollParent( false );
2203                 }
2204
2205                 if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
2206                                 i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
2207                         i.overflowOffset = i.scrollParentNotHidden.offset();
2208                 }
2209         },
2210         drag: function( event, ui, i  ) {
2211
2212                 var o = i.options,
2213                         scrolled = false,
2214                         scrollParent = i.scrollParentNotHidden[ 0 ],
2215                         document = i.document[ 0 ];
2216
2217                 if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
2218                         if ( !o.axis || o.axis !== "x" ) {
2219                                 if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
2220                                                 o.scrollSensitivity ) {
2221                                         scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
2222                                 } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
2223                                         scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
2224                                 }
2225                         }
2226
2227                         if ( !o.axis || o.axis !== "y" ) {
2228                                 if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
2229                                                 o.scrollSensitivity ) {
2230                                         scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
2231                                 } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
2232                                         scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
2233                                 }
2234                         }
2235
2236                 } else {
2237
2238                         if ( !o.axis || o.axis !== "x" ) {
2239                                 if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
2240                                         scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
2241                                 } else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
2242                                                 o.scrollSensitivity ) {
2243                                         scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
2244                                 }
2245                         }
2246
2247                         if ( !o.axis || o.axis !== "y" ) {
2248                                 if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
2249                                         scrolled = $( document ).scrollLeft(
2250                                                 $( document ).scrollLeft() - o.scrollSpeed
2251                                         );
2252                                 } else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
2253                                                 o.scrollSensitivity ) {
2254                                         scrolled = $( document ).scrollLeft(
2255                                                 $( document ).scrollLeft() + o.scrollSpeed
2256                                         );
2257                                 }
2258                         }
2259
2260                 }
2261
2262                 if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
2263                         $.ui.ddmanager.prepareOffsets( i, event );
2264                 }
2265
2266         }
2267 } );
2268
2269 $.ui.plugin.add( "draggable", "snap", {
2270         start: function( event, ui, i ) {
2271
2272                 var o = i.options;
2273
2274                 i.snapElements = [];
2275
2276                 $( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
2277                         .each( function() {
2278                                 var $t = $( this ),
2279                                         $o = $t.offset();
2280                                 if ( this !== i.element[ 0 ] ) {
2281                                         i.snapElements.push( {
2282                                                 item: this,
2283                                                 width: $t.outerWidth(), height: $t.outerHeight(),
2284                                                 top: $o.top, left: $o.left
2285                                         } );
2286                                 }
2287                         } );
2288
2289         },
2290         drag: function( event, ui, inst ) {
2291
2292                 var ts, bs, ls, rs, l, r, t, b, i, first,
2293                         o = inst.options,
2294                         d = o.snapTolerance,
2295                         x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
2296                         y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
2297
2298                 for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
2299
2300                         l = inst.snapElements[ i ].left - inst.margins.left;
2301                         r = l + inst.snapElements[ i ].width;
2302                         t = inst.snapElements[ i ].top - inst.margins.top;
2303                         b = t + inst.snapElements[ i ].height;
2304
2305                         if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
2306                                         !$.contains( inst.snapElements[ i ].item.ownerDocument,
2307                                         inst.snapElements[ i ].item ) ) {
2308                                 if ( inst.snapElements[ i ].snapping ) {
2309                                         ( inst.options.snap.release &&
2310                                                 inst.options.snap.release.call(
2311                                                         inst.element,
2312                                                         event,
2313                                                         $.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
2314                                                 ) );
2315                                 }
2316                                 inst.snapElements[ i ].snapping = false;
2317                                 continue;
2318                         }
2319
2320                         if ( o.snapMode !== "inner" ) {
2321                                 ts = Math.abs( t - y2 ) <= d;
2322                                 bs = Math.abs( b - y1 ) <= d;
2323                                 ls = Math.abs( l - x2 ) <= d;
2324                                 rs = Math.abs( r - x1 ) <= d;
2325                                 if ( ts ) {
2326                                         ui.position.top = inst._convertPositionTo( "relative", {
2327                                                 top: t - inst.helperProportions.height,
2328                                                 left: 0
2329                                         } ).top;
2330                                 }
2331                                 if ( bs ) {
2332                                         ui.position.top = inst._convertPositionTo( "relative", {
2333                                                 top: b,
2334                                                 left: 0
2335                                         } ).top;
2336                                 }
2337                                 if ( ls ) {
2338                                         ui.position.left = inst._convertPositionTo( "relative", {
2339                                                 top: 0,
2340                                                 left: l - inst.helperProportions.width
2341                                         } ).left;
2342                                 }
2343                                 if ( rs ) {
2344                                         ui.position.left = inst._convertPositionTo( "relative", {
2345                                                 top: 0,
2346                                                 left: r
2347                                         } ).left;
2348                                 }
2349                         }
2350
2351                         first = ( ts || bs || ls || rs );
2352
2353                         if ( o.snapMode !== "outer" ) {
2354                                 ts = Math.abs( t - y1 ) <= d;
2355                                 bs = Math.abs( b - y2 ) <= d;
2356                                 ls = Math.abs( l - x1 ) <= d;
2357                                 rs = Math.abs( r - x2 ) <= d;
2358                                 if ( ts ) {
2359                                         ui.position.top = inst._convertPositionTo( "relative", {
2360                                                 top: t,
2361                                                 left: 0
2362                                         } ).top;
2363                                 }
2364                                 if ( bs ) {
2365                                         ui.position.top = inst._convertPositionTo( "relative", {
2366                                                 top: b - inst.helperProportions.height,
2367                                                 left: 0
2368                                         } ).top;
2369                                 }
2370                                 if ( ls ) {
2371                                         ui.position.left = inst._convertPositionTo( "relative", {
2372                                                 top: 0,
2373                                                 left: l
2374                                         } ).left;
2375                                 }
2376                                 if ( rs ) {
2377                                         ui.position.left = inst._convertPositionTo( "relative", {
2378                                                 top: 0,
2379                                                 left: r - inst.helperProportions.width
2380                                         } ).left;
2381                                 }
2382                         }
2383
2384                         if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
2385                                 ( inst.options.snap.snap &&
2386                                         inst.options.snap.snap.call(
2387                                                 inst.element,
2388                                                 event,
2389                                                 $.extend( inst._uiHash(), {
2390                                                         snapItem: inst.snapElements[ i ].item
2391                                                 } ) ) );
2392                         }
2393                         inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
2394
2395                 }
2396
2397         }
2398 } );
2399
2400 $.ui.plugin.add( "draggable", "stack", {
2401         start: function( event, ui, instance ) {
2402                 var min,
2403                         o = instance.options,
2404                         group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
2405                                 return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
2406                                         ( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
2407                         } );
2408
2409                 if ( !group.length ) { return; }
2410
2411                 min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
2412                 $( group ).each( function( i ) {
2413                         $( this ).css( "zIndex", min + i );
2414                 } );
2415                 this.css( "zIndex", ( min + group.length ) );
2416         }
2417 } );
2418
2419 $.ui.plugin.add( "draggable", "zIndex", {
2420         start: function( event, ui, instance ) {
2421                 var t = $( ui.helper ),
2422                         o = instance.options;
2423
2424                 if ( t.css( "zIndex" ) ) {
2425                         o._zIndex = t.css( "zIndex" );
2426                 }
2427                 t.css( "zIndex", o.zIndex );
2428         },
2429         stop: function( event, ui, instance ) {
2430                 var o = instance.options;
2431
2432                 if ( o._zIndex ) {
2433                         $( ui.helper ).css( "zIndex", o._zIndex );
2434                 }
2435         }
2436 } );
2437
2438 var widgetsDraggable = $.ui.draggable;
2439
2440
2441 /*!
2442  * jQuery UI Droppable 1.12.1
2443  * http://jqueryui.com
2444  *
2445  * Copyright jQuery Foundation and other contributors
2446  * Released under the MIT license.
2447  * http://jquery.org/license
2448  */
2449
2450 //>>label: Droppable
2451 //>>group: Interactions
2452 //>>description: Enables drop targets for draggable elements.
2453 //>>docs: http://api.jqueryui.com/droppable/
2454 //>>demos: http://jqueryui.com/droppable/
2455
2456
2457
2458 $.widget( "ui.droppable", {
2459         version: "1.12.1",
2460         widgetEventPrefix: "drop",
2461         options: {
2462                 accept: "*",
2463                 addClasses: true,
2464                 greedy: false,
2465                 scope: "default",
2466                 tolerance: "intersect",
2467
2468                 // Callbacks
2469                 activate: null,
2470                 deactivate: null,
2471                 drop: null,
2472                 out: null,
2473                 over: null
2474         },
2475         _create: function() {
2476
2477                 var proportions,
2478                         o = this.options,
2479                         accept = o.accept;
2480
2481                 this.isover = false;
2482                 this.isout = true;
2483
2484                 this.accept = $.isFunction( accept ) ? accept : function( d ) {
2485                         return d.is( accept );
2486                 };
2487
2488                 this.proportions = function( /* valueToWrite */ ) {
2489                         if ( arguments.length ) {
2490
2491                                 // Store the droppable's proportions
2492                                 proportions = arguments[ 0 ];
2493                         } else {
2494
2495                                 // Retrieve or derive the droppable's proportions
2496                                 return proportions ?
2497                                         proportions :
2498                                         proportions = {
2499                                                 width: this.element[ 0 ].offsetWidth,
2500                                                 height: this.element[ 0 ].offsetHeight
2501                                         };
2502                         }
2503                 };
2504
2505                 this._addToManager( o.scope );
2506
2507                 o.addClasses && this._addClass( "ui-droppable" );
2508
2509         },
2510
2511         _addToManager: function( scope ) {
2512
2513                 // Add the reference and positions to the manager
2514                 $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
2515                 $.ui.ddmanager.droppables[ scope ].push( this );
2516         },
2517
2518         _splice: function( drop ) {
2519                 var i = 0;
2520                 for ( ; i < drop.length; i++ ) {
2521                         if ( drop[ i ] === this ) {
2522                                 drop.splice( i, 1 );
2523                         }
2524                 }
2525         },
2526
2527         _destroy: function() {
2528                 var drop = $.ui.ddmanager.droppables[ this.options.scope ];
2529
2530                 this._splice( drop );
2531         },
2532
2533         _setOption: function( key, value ) {
2534
2535                 if ( key === "accept" ) {
2536                         this.accept = $.isFunction( value ) ? value : function( d ) {
2537                                 return d.is( value );
2538                         };
2539                 } else if ( key === "scope" ) {
2540                         var drop = $.ui.ddmanager.droppables[ this.options.scope ];
2541
2542                         this._splice( drop );
2543                         this._addToManager( value );
2544                 }
2545
2546                 this._super( key, value );
2547         },
2548
2549         _activate: function( event ) {
2550                 var draggable = $.ui.ddmanager.current;
2551
2552                 this._addActiveClass();
2553                 if ( draggable ) {
2554                         this._trigger( "activate", event, this.ui( draggable ) );
2555                 }
2556         },
2557
2558         _deactivate: function( event ) {
2559                 var draggable = $.ui.ddmanager.current;
2560
2561                 this._removeActiveClass();
2562                 if ( draggable ) {
2563                         this._trigger( "deactivate", event, this.ui( draggable ) );
2564                 }
2565         },
2566
2567         _over: function( event ) {
2568
2569                 var draggable = $.ui.ddmanager.current;
2570
2571                 // Bail if draggable and droppable are same element
2572                 if ( !draggable || ( draggable.currentItem ||
2573                                 draggable.element )[ 0 ] === this.element[ 0 ] ) {
2574                         return;
2575                 }
2576
2577                 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
2578                                 draggable.element ) ) ) {
2579                         this._addHoverClass();
2580                         this._trigger( "over", event, this.ui( draggable ) );
2581                 }
2582
2583         },
2584
2585         _out: function( event ) {
2586
2587                 var draggable = $.ui.ddmanager.current;
2588
2589                 // Bail if draggable and droppable are same element
2590                 if ( !draggable || ( draggable.currentItem ||
2591                                 draggable.element )[ 0 ] === this.element[ 0 ] ) {
2592                         return;
2593                 }
2594
2595                 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
2596                                 draggable.element ) ) ) {
2597                         this._removeHoverClass();
2598                         this._trigger( "out", event, this.ui( draggable ) );
2599                 }
2600
2601         },
2602
2603         _drop: function( event, custom ) {
2604
2605                 var draggable = custom || $.ui.ddmanager.current,
2606                         childrenIntersection = false;
2607
2608                 // Bail if draggable and droppable are same element
2609                 if ( !draggable || ( draggable.currentItem ||
2610                                 draggable.element )[ 0 ] === this.element[ 0 ] ) {
2611                         return false;
2612                 }
2613
2614                 this.element
2615                         .find( ":data(ui-droppable)" )
2616                         .not( ".ui-draggable-dragging" )
2617                         .each( function() {
2618                                 var inst = $( this ).droppable( "instance" );
2619                                 if (
2620                                         inst.options.greedy &&
2621                                         !inst.options.disabled &&
2622                                         inst.options.scope === draggable.options.scope &&
2623                                         inst.accept.call(
2624                                                 inst.element[ 0 ], ( draggable.currentItem || draggable.element )
2625                                         ) &&
2626                                         intersect(
2627                                                 draggable,
2628                                                 $.extend( inst, { offset: inst.element.offset() } ),
2629                                                 inst.options.tolerance, event
2630                                         )
2631                                 ) {
2632                                         childrenIntersection = true;
2633                                         return false; }
2634                         } );
2635                 if ( childrenIntersection ) {
2636                         return false;
2637                 }
2638
2639                 if ( this.accept.call( this.element[ 0 ],
2640                                 ( draggable.currentItem || draggable.element ) ) ) {
2641                         this._removeActiveClass();
2642                         this._removeHoverClass();
2643
2644                         this._trigger( "drop", event, this.ui( draggable ) );
2645                         return this.element;
2646                 }
2647
2648                 return false;
2649
2650         },
2651
2652         ui: function( c ) {
2653                 return {
2654                         draggable: ( c.currentItem || c.element ),
2655                         helper: c.helper,
2656                         position: c.position,
2657                         offset: c.positionAbs
2658                 };
2659         },
2660
2661         // Extension points just to make backcompat sane and avoid duplicating logic
2662         // TODO: Remove in 1.13 along with call to it below
2663         _addHoverClass: function() {
2664                 this._addClass( "ui-droppable-hover" );
2665         },
2666
2667         _removeHoverClass: function() {
2668                 this._removeClass( "ui-droppable-hover" );
2669         },
2670
2671         _addActiveClass: function() {
2672                 this._addClass( "ui-droppable-active" );
2673         },
2674
2675         _removeActiveClass: function() {
2676                 this._removeClass( "ui-droppable-active" );
2677         }
2678 } );
2679
2680 var intersect = $.ui.intersect = ( function() {
2681         function isOverAxis( x, reference, size ) {
2682                 return ( x >= reference ) && ( x < ( reference + size ) );
2683         }
2684
2685         return function( draggable, droppable, toleranceMode, event ) {
2686
2687                 if ( !droppable.offset ) {
2688                         return false;
2689                 }
2690
2691                 var x1 = ( draggable.positionAbs ||
2692                                 draggable.position.absolute ).left + draggable.margins.left,
2693                         y1 = ( draggable.positionAbs ||
2694                                 draggable.position.absolute ).top + draggable.margins.top,
2695                         x2 = x1 + draggable.helperProportions.width,
2696                         y2 = y1 + draggable.helperProportions.height,
2697                         l = droppable.offset.left,
2698                         t = droppable.offset.top,
2699                         r = l + droppable.proportions().width,
2700                         b = t + droppable.proportions().height;
2701
2702                 switch ( toleranceMode ) {
2703                 case "fit":
2704                         return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
2705                 case "intersect":
2706                         return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
2707                                 x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
2708                                 t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
2709                                 y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
2710                 case "pointer":
2711                         return isOverAxis( event.pageY, t, droppable.proportions().height ) &&
2712                                 isOverAxis( event.pageX, l, droppable.proportions().width );
2713                 case "touch":
2714                         return (
2715                                 ( y1 >= t && y1 <= b ) || // Top edge touching
2716                                 ( y2 >= t && y2 <= b ) || // Bottom edge touching
2717                                 ( y1 < t && y2 > b ) // Surrounded vertically
2718                         ) && (
2719                                 ( x1 >= l && x1 <= r ) || // Left edge touching
2720                                 ( x2 >= l && x2 <= r ) || // Right edge touching
2721                                 ( x1 < l && x2 > r ) // Surrounded horizontally
2722                         );
2723                 default:
2724                         return false;
2725                 }
2726         };
2727 } )();
2728
2729 /*
2730         This manager tracks offsets of draggables and droppables
2731 */
2732 $.ui.ddmanager = {
2733         current: null,
2734         droppables: { "default": [] },
2735         prepareOffsets: function( t, event ) {
2736
2737                 var i, j,
2738                         m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
2739                         type = event ? event.type : null, // workaround for #2317
2740                         list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
2741
2742                 droppablesLoop: for ( i = 0; i < m.length; i++ ) {
2743
2744                         // No disabled and non-accepted
2745                         if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ],
2746                                         ( t.currentItem || t.element ) ) ) ) {
2747                                 continue;
2748                         }
2749
2750                         // Filter out elements in the current dragged item
2751                         for ( j = 0; j < list.length; j++ ) {
2752                                 if ( list[ j ] === m[ i ].element[ 0 ] ) {
2753                                         m[ i ].proportions().height = 0;
2754                                         continue droppablesLoop;
2755                                 }
2756                         }
2757
2758                         m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
2759                         if ( !m[ i ].visible ) {
2760                                 continue;
2761                         }
2762
2763                         // Activate the droppable if used directly from draggables
2764                         if ( type === "mousedown" ) {
2765                                 m[ i ]._activate.call( m[ i ], event );
2766                         }
2767
2768                         m[ i ].offset = m[ i ].element.offset();
2769                         m[ i ].proportions( {
2770                                 width: m[ i ].element[ 0 ].offsetWidth,
2771                                 height: m[ i ].element[ 0 ].offsetHeight
2772                         } );
2773
2774                 }
2775
2776         },
2777         drop: function( draggable, event ) {
2778
2779                 var dropped = false;
2780
2781                 // Create a copy of the droppables in case the list changes during the drop (#9116)
2782                 $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
2783
2784                         if ( !this.options ) {
2785                                 return;
2786                         }
2787                         if ( !this.options.disabled && this.visible &&
2788                                         intersect( draggable, this, this.options.tolerance, event ) ) {
2789                                 dropped = this._drop.call( this, event ) || dropped;
2790                         }
2791
2792                         if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ],
2793                                         ( draggable.currentItem || draggable.element ) ) ) {
2794                                 this.isout = true;
2795                                 this.isover = false;
2796                                 this._deactivate.call( this, event );
2797                         }
2798
2799                 } );
2800                 return dropped;
2801
2802         },
2803         dragStart: function( draggable, event ) {
2804
2805                 // Listen for scrolling so that if the dragging causes scrolling the position of the
2806                 // droppables can be recalculated (see #5003)
2807                 draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() {
2808                         if ( !draggable.options.refreshPositions ) {
2809                                 $.ui.ddmanager.prepareOffsets( draggable, event );
2810                         }
2811                 } );
2812         },
2813         drag: function( draggable, event ) {
2814
2815                 // If you have a highly dynamic page, you might try this option. It renders positions
2816                 // every time you move the mouse.
2817                 if ( draggable.options.refreshPositions ) {
2818                         $.ui.ddmanager.prepareOffsets( draggable, event );
2819                 }
2820
2821                 // Run through all droppables and check their positions based on specific tolerance options
2822                 $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
2823
2824                         if ( this.options.disabled || this.greedyChild || !this.visible ) {
2825                                 return;
2826                         }
2827
2828                         var parentInstance, scope, parent,
2829                                 intersects = intersect( draggable, this, this.options.tolerance, event ),
2830                                 c = !intersects && this.isover ?
2831                                         "isout" :
2832                                         ( intersects && !this.isover ? "isover" : null );
2833                         if ( !c ) {
2834                                 return;
2835                         }
2836
2837                         if ( this.options.greedy ) {
2838
2839                                 // find droppable parents with same scope
2840                                 scope = this.options.scope;
2841                                 parent = this.element.parents( ":data(ui-droppable)" ).filter( function() {
2842                                         return $( this ).droppable( "instance" ).options.scope === scope;
2843                                 } );
2844
2845                                 if ( parent.length ) {
2846                                         parentInstance = $( parent[ 0 ] ).droppable( "instance" );
2847                                         parentInstance.greedyChild = ( c === "isover" );
2848                                 }
2849                         }
2850
2851                         // We just moved into a greedy child
2852                         if ( parentInstance && c === "isover" ) {
2853                                 parentInstance.isover = false;
2854                                 parentInstance.isout = true;
2855                                 parentInstance._out.call( parentInstance, event );
2856                         }
2857
2858                         this[ c ] = true;
2859                         this[ c === "isout" ? "isover" : "isout" ] = false;
2860                         this[ c === "isover" ? "_over" : "_out" ].call( this, event );
2861
2862                         // We just moved out of a greedy child
2863                         if ( parentInstance && c === "isout" ) {
2864                                 parentInstance.isout = false;
2865                                 parentInstance.isover = true;
2866                                 parentInstance._over.call( parentInstance, event );
2867                         }
2868                 } );
2869
2870         },
2871         dragStop: function( draggable, event ) {
2872                 draggable.element.parentsUntil( "body" ).off( "scroll.droppable" );
2873
2874                 // Call prepareOffsets one final time since IE does not fire return scroll events when
2875                 // overflow was caused by drag (see #5003)
2876                 if ( !draggable.options.refreshPositions ) {
2877                         $.ui.ddmanager.prepareOffsets( draggable, event );
2878                 }
2879         }
2880 };
2881
2882 // DEPRECATED
2883 // TODO: switch return back to widget declaration at top of file when this is removed
2884 if ( $.uiBackCompat !== false ) {
2885
2886         // Backcompat for activeClass and hoverClass options
2887         $.widget( "ui.droppable", $.ui.droppable, {
2888                 options: {
2889                         hoverClass: false,
2890                         activeClass: false
2891                 },
2892                 _addActiveClass: function() {
2893                         this._super();
2894                         if ( this.options.activeClass ) {
2895                                 this.element.addClass( this.options.activeClass );
2896                         }
2897                 },
2898                 _removeActiveClass: function() {
2899                         this._super();
2900                         if ( this.options.activeClass ) {
2901                                 this.element.removeClass( this.options.activeClass );
2902                         }
2903                 },
2904                 _addHoverClass: function() {
2905                         this._super();
2906                         if ( this.options.hoverClass ) {
2907                                 this.element.addClass( this.options.hoverClass );
2908                         }
2909                 },
2910                 _removeHoverClass: function() {
2911                         this._super();
2912                         if ( this.options.hoverClass ) {
2913                                 this.element.removeClass( this.options.hoverClass );
2914                         }
2915                 }
2916         } );
2917 }
2918
2919 var widgetsDroppable = $.ui.droppable;
2920
2921
2922 /*!
2923  * jQuery UI Resizable 1.12.1
2924  * http://jqueryui.com
2925  *
2926  * Copyright jQuery Foundation and other contributors
2927  * Released under the MIT license.
2928  * http://jquery.org/license
2929  */
2930
2931 //>>label: Resizable
2932 //>>group: Interactions
2933 //>>description: Enables resize functionality for any element.
2934 //>>docs: http://api.jqueryui.com/resizable/
2935 //>>demos: http://jqueryui.com/resizable/
2936 //>>css.structure: ../../themes/base/core.css
2937 //>>css.structure: ../../themes/base/resizable.css
2938 //>>css.theme: ../../themes/base/theme.css
2939
2940
2941
2942 $.widget( "ui.resizable", $.ui.mouse, {
2943         version: "1.12.1",
2944         widgetEventPrefix: "resize",
2945         options: {
2946                 alsoResize: false,
2947                 animate: false,
2948                 animateDuration: "slow",
2949                 animateEasing: "swing",
2950                 aspectRatio: false,
2951                 autoHide: false,
2952                 classes: {
2953                         "ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se"
2954                 },
2955                 containment: false,
2956                 ghost: false,
2957                 grid: false,
2958                 handles: "e,s,se",
2959                 helper: false,
2960                 maxHeight: null,
2961                 maxWidth: null,
2962                 minHeight: 10,
2963                 minWidth: 10,
2964
2965                 // See #7960
2966                 zIndex: 90,
2967
2968                 // Callbacks
2969                 resize: null,
2970                 start: null,
2971                 stop: null
2972         },
2973
2974         _num: function( value ) {
2975                 return parseFloat( value ) || 0;
2976         },
2977
2978         _isNumber: function( value ) {
2979                 return !isNaN( parseFloat( value ) );
2980         },
2981
2982         _hasScroll: function( el, a ) {
2983
2984                 if ( $( el ).css( "overflow" ) === "hidden" ) {
2985                         return false;
2986                 }
2987
2988                 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
2989                         has = false;
2990
2991                 if ( el[ scroll ] > 0 ) {
2992                         return true;
2993                 }
2994
2995                 // TODO: determine which cases actually cause this to happen
2996                 // if the element doesn't have the scroll set, see if it's possible to
2997                 // set the scroll
2998                 el[ scroll ] = 1;
2999                 has = ( el[ scroll ] > 0 );
3000                 el[ scroll ] = 0;
3001                 return has;
3002         },
3003
3004         _create: function() {
3005
3006                 var margins,
3007                         o = this.options,
3008                         that = this;
3009                 this._addClass( "ui-resizable" );
3010
3011                 $.extend( this, {
3012                         _aspectRatio: !!( o.aspectRatio ),
3013                         aspectRatio: o.aspectRatio,
3014                         originalElement: this.element,
3015                         _proportionallyResizeElements: [],
3016                         _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
3017                 } );
3018
3019                 // Wrap the element if it cannot hold child nodes
3020                 if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) {
3021
3022                         this.element.wrap(
3023                                 $( "<div class='ui-wrapper' style='overflow: hidden;'></div>" ).css( {
3024                                         position: this.element.css( "position" ),
3025                                         width: this.element.outerWidth(),
3026                                         height: this.element.outerHeight(),
3027                                         top: this.element.css( "top" ),
3028                                         left: this.element.css( "left" )
3029                                 } )
3030                         );
3031
3032                         this.element = this.element.parent().data(
3033                                 "ui-resizable", this.element.resizable( "instance" )
3034                         );
3035
3036                         this.elementIsWrapper = true;
3037
3038                         margins = {
3039                                 marginTop: this.originalElement.css( "marginTop" ),
3040                                 marginRight: this.originalElement.css( "marginRight" ),
3041                                 marginBottom: this.originalElement.css( "marginBottom" ),
3042                                 marginLeft: this.originalElement.css( "marginLeft" )
3043                         };
3044
3045                         this.element.css( margins );
3046                         this.originalElement.css( "margin", 0 );
3047
3048                         // support: Safari
3049                         // Prevent Safari textarea resize
3050                         this.originalResizeStyle = this.originalElement.css( "resize" );
3051                         this.originalElement.css( "resize", "none" );
3052
3053                         this._proportionallyResizeElements.push( this.originalElement.css( {
3054                                 position: "static",
3055                                 zoom: 1,
3056                                 display: "block"
3057                         } ) );
3058
3059                         // Support: IE9
3060                         // avoid IE jump (hard set the margin)
3061                         this.originalElement.css( margins );
3062
3063                         this._proportionallyResize();
3064                 }
3065
3066                 this._setupHandles();
3067
3068                 if ( o.autoHide ) {
3069                         $( this.element )
3070                                 .on( "mouseenter", function() {
3071                                         if ( o.disabled ) {
3072                                                 return;
3073                                         }
3074                                         that._removeClass( "ui-resizable-autohide" );
3075                                         that._handles.show();
3076                                 } )
3077                                 .on( "mouseleave", function() {
3078                                         if ( o.disabled ) {
3079                                                 return;
3080                                         }
3081                                         if ( !that.resizing ) {
3082                                                 that._addClass( "ui-resizable-autohide" );
3083                                                 that._handles.hide();
3084                                         }
3085                                 } );
3086                 }
3087
3088                 this._mouseInit();
3089         },
3090
3091         _destroy: function() {
3092
3093                 this._mouseDestroy();
3094
3095                 var wrapper,
3096                         _destroy = function( exp ) {
3097                                 $( exp )
3098                                         .removeData( "resizable" )
3099                                         .removeData( "ui-resizable" )
3100                                         .off( ".resizable" )
3101                                         .find( ".ui-resizable-handle" )
3102                                                 .remove();
3103                         };
3104
3105                 // TODO: Unwrap at same DOM position
3106                 if ( this.elementIsWrapper ) {
3107                         _destroy( this.element );
3108                         wrapper = this.element;
3109                         this.originalElement.css( {
3110                                 position: wrapper.css( "position" ),
3111                                 width: wrapper.outerWidth(),
3112                                 height: wrapper.outerHeight(),
3113                                 top: wrapper.css( "top" ),
3114                                 left: wrapper.css( "left" )
3115                         } ).insertAfter( wrapper );
3116                         wrapper.remove();
3117                 }
3118
3119                 this.originalElement.css( "resize", this.originalResizeStyle );
3120                 _destroy( this.originalElement );
3121
3122                 return this;
3123         },
3124
3125         _setOption: function( key, value ) {
3126                 this._super( key, value );
3127
3128                 switch ( key ) {
3129                 case "handles":
3130                         this._removeHandles();
3131                         this._setupHandles();
3132                         break;
3133                 default:
3134                         break;
3135                 }
3136         },
3137
3138         _setupHandles: function() {
3139                 var o = this.options, handle, i, n, hname, axis, that = this;
3140                 this.handles = o.handles ||
3141                         ( !$( ".ui-resizable-handle", this.element ).length ?
3142                                 "e,s,se" : {
3143                                         n: ".ui-resizable-n",
3144                                         e: ".ui-resizable-e",
3145                                         s: ".ui-resizable-s",
3146                                         w: ".ui-resizable-w",
3147                                         se: ".ui-resizable-se",
3148                                         sw: ".ui-resizable-sw",
3149                                         ne: ".ui-resizable-ne",
3150                                         nw: ".ui-resizable-nw"
3151                                 } );
3152
3153                 this._handles = $();
3154                 if ( this.handles.constructor === String ) {
3155
3156                         if ( this.handles === "all" ) {
3157                                 this.handles = "n,e,s,w,se,sw,ne,nw";
3158                         }
3159
3160                         n = this.handles.split( "," );
3161                         this.handles = {};
3162
3163                         for ( i = 0; i < n.length; i++ ) {
3164
3165                                 handle = $.trim( n[ i ] );
3166                                 hname = "ui-resizable-" + handle;
3167                                 axis = $( "<div>" );
3168                                 this._addClass( axis, "ui-resizable-handle " + hname );
3169
3170                                 axis.css( { zIndex: o.zIndex } );
3171
3172                                 this.handles[ handle ] = ".ui-resizable-" + handle;
3173                                 this.element.append( axis );
3174                         }
3175
3176                 }
3177
3178                 this._renderAxis = function( target ) {
3179
3180                         var i, axis, padPos, padWrapper;
3181
3182                         target = target || this.element;
3183
3184                         for ( i in this.handles ) {
3185
3186                                 if ( this.handles[ i ].constructor === String ) {
3187                                         this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show();
3188                                 } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
3189                                         this.handles[ i ] = $( this.handles[ i ] );
3190                                         this._on( this.handles[ i ], { "mousedown": that._mouseDown } );
3191                                 }
3192
3193                                 if ( this.elementIsWrapper &&
3194                                                 this.originalElement[ 0 ]
3195                                                         .nodeName
3196                                                         .match( /^(textarea|input|select|button)$/i ) ) {
3197                                         axis = $( this.handles[ i ], this.element );
3198
3199                                         padWrapper = /sw|ne|nw|se|n|s/.test( i ) ?
3200                                                 axis.outerHeight() :
3201                                                 axis.outerWidth();
3202
3203                                         padPos = [ "padding",
3204                                                 /ne|nw|n/.test( i ) ? "Top" :
3205                                                 /se|sw|s/.test( i ) ? "Bottom" :
3206                                                 /^e$/.test( i ) ? "Right" : "Left" ].join( "" );
3207
3208                                         target.css( padPos, padWrapper );
3209
3210                                         this._proportionallyResize();
3211                                 }
3212
3213                                 this._handles = this._handles.add( this.handles[ i ] );
3214                         }
3215                 };
3216
3217                 // TODO: make renderAxis a prototype function
3218                 this._renderAxis( this.element );
3219
3220                 this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
3221                 this._handles.disableSelection();
3222
3223                 this._handles.on( "mouseover", function() {
3224                         if ( !that.resizing ) {
3225                                 if ( this.className ) {
3226                                         axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i );
3227                                 }
3228                                 that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se";
3229                         }
3230                 } );
3231
3232                 if ( o.autoHide ) {
3233                         this._handles.hide();
3234                         this._addClass( "ui-resizable-autohide" );
3235                 }
3236         },
3237
3238         _removeHandles: function() {
3239                 this._handles.remove();
3240         },
3241
3242         _mouseCapture: function( event ) {
3243                 var i, handle,
3244                         capture = false;
3245
3246                 for ( i in this.handles ) {
3247                         handle = $( this.handles[ i ] )[ 0 ];
3248                         if ( handle === event.target || $.contains( handle, event.target ) ) {
3249                                 capture = true;
3250                         }
3251                 }
3252
3253                 return !this.options.disabled && capture;
3254         },
3255
3256         _mouseStart: function( event ) {
3257
3258                 var curleft, curtop, cursor,
3259                         o = this.options,
3260                         el = this.element;
3261
3262                 this.resizing = true;
3263
3264                 this._renderProxy();
3265
3266                 curleft = this._num( this.helper.css( "left" ) );
3267                 curtop = this._num( this.helper.css( "top" ) );
3268
3269                 if ( o.containment ) {
3270                         curleft += $( o.containment ).scrollLeft() || 0;
3271                         curtop += $( o.containment ).scrollTop() || 0;
3272                 }
3273
3274                 this.offset = this.helper.offset();
3275                 this.position = { left: curleft, top: curtop };
3276
3277                 this.size = this._helper ? {
3278                                 width: this.helper.width(),
3279                                 height: this.helper.height()
3280                         } : {
3281                                 width: el.width(),
3282                                 height: el.height()
3283                         };
3284
3285                 this.originalSize = this._helper ? {
3286                                 width: el.outerWidth(),
3287                                 height: el.outerHeight()
3288                         } : {
3289                                 width: el.width(),
3290                                 height: el.height()
3291                         };
3292
3293                 this.sizeDiff = {
3294                         width: el.outerWidth() - el.width(),
3295                         height: el.outerHeight() - el.height()
3296                 };
3297
3298                 this.originalPosition = { left: curleft, top: curtop };
3299                 this.originalMousePosition = { left: event.pageX, top: event.pageY };
3300
3301                 this.aspectRatio = ( typeof o.aspectRatio === "number" ) ?
3302                         o.aspectRatio :
3303                         ( ( this.originalSize.width / this.originalSize.height ) || 1 );
3304
3305                 cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" );
3306                 $( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor );
3307
3308                 this._addClass( "ui-resizable-resizing" );
3309                 this._propagate( "start", event );
3310                 return true;
3311         },
3312
3313         _mouseDrag: function( event ) {
3314
3315                 var data, props,
3316                         smp = this.originalMousePosition,
3317                         a = this.axis,
3318                         dx = ( event.pageX - smp.left ) || 0,
3319                         dy = ( event.pageY - smp.top ) || 0,
3320                         trigger = this._change[ a ];
3321
3322                 this._updatePrevProperties();
3323
3324                 if ( !trigger ) {
3325                         return false;
3326                 }
3327
3328                 data = trigger.apply( this, [ event, dx, dy ] );
3329
3330                 this._updateVirtualBoundaries( event.shiftKey );
3331                 if ( this._aspectRatio || event.shiftKey ) {
3332                         data = this._updateRatio( data, event );
3333                 }
3334
3335                 data = this._respectSize( data, event );
3336
3337                 this._updateCache( data );
3338
3339                 this._propagate( "resize", event );
3340
3341                 props = this._applyChanges();
3342
3343                 if ( !this._helper && this._proportionallyResizeElements.length ) {
3344                         this._proportionallyResize();
3345                 }
3346
3347                 if ( !$.isEmptyObject( props ) ) {
3348                         this._updatePrevProperties();
3349                         this._trigger( "resize", event, this.ui() );
3350                         this._applyChanges();
3351                 }
3352
3353                 return false;
3354         },
3355
3356         _mouseStop: function( event ) {
3357
3358                 this.resizing = false;
3359                 var pr, ista, soffseth, soffsetw, s, left, top,
3360                         o = this.options, that = this;
3361
3362                 if ( this._helper ) {
3363
3364                         pr = this._proportionallyResizeElements;
3365                         ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName );
3366                         soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height;
3367                         soffsetw = ista ? 0 : that.sizeDiff.width;
3368
3369                         s = {
3370                                 width: ( that.helper.width()  - soffsetw ),
3371                                 height: ( that.helper.height() - soffseth )
3372                         };
3373                         left = ( parseFloat( that.element.css( "left" ) ) +
3374                                 ( that.position.left - that.originalPosition.left ) ) || null;
3375                         top = ( parseFloat( that.element.css( "top" ) ) +
3376                                 ( that.position.top - that.originalPosition.top ) ) || null;
3377
3378                         if ( !o.animate ) {
3379                                 this.element.css( $.extend( s, { top: top, left: left } ) );
3380                         }
3381
3382                         that.helper.height( that.size.height );
3383                         that.helper.width( that.size.width );
3384
3385                         if ( this._helper && !o.animate ) {
3386                                 this._proportionallyResize();
3387                         }
3388                 }
3389
3390                 $( "body" ).css( "cursor", "auto" );
3391
3392                 this._removeClass( "ui-resizable-resizing" );
3393
3394                 this._propagate( "stop", event );
3395
3396                 if ( this._helper ) {
3397                         this.helper.remove();
3398                 }
3399
3400                 return false;
3401
3402         },
3403
3404         _updatePrevProperties: function() {
3405                 this.prevPosition = {
3406                         top: this.position.top,
3407                         left: this.position.left
3408                 };
3409                 this.prevSize = {
3410                         width: this.size.width,
3411                         height: this.size.height
3412                 };
3413         },
3414
3415         _applyChanges: function() {
3416                 var props = {};
3417
3418                 if ( this.position.top !== this.prevPosition.top ) {
3419                         props.top = this.position.top + "px";
3420                 }
3421                 if ( this.position.left !== this.prevPosition.left ) {
3422                         props.left = this.position.left + "px";
3423                 }
3424                 if ( this.size.width !== this.prevSize.width ) {
3425                         props.width = this.size.width + "px";
3426                 }
3427                 if ( this.size.height !== this.prevSize.height ) {
3428                         props.height = this.size.height + "px";
3429                 }
3430
3431                 this.helper.css( props );
3432
3433                 return props;
3434         },
3435
3436         _updateVirtualBoundaries: function( forceAspectRatio ) {
3437                 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
3438                         o = this.options;
3439
3440                 b = {
3441                         minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0,
3442                         maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity,
3443                         minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0,
3444                         maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity
3445                 };
3446
3447                 if ( this._aspectRatio || forceAspectRatio ) {
3448                         pMinWidth = b.minHeight * this.aspectRatio;
3449                         pMinHeight = b.minWidth / this.aspectRatio;
3450                         pMaxWidth = b.maxHeight * this.aspectRatio;
3451                         pMaxHeight = b.maxWidth / this.aspectRatio;
3452
3453                         if ( pMinWidth > b.minWidth ) {
3454                                 b.minWidth = pMinWidth;
3455                         }
3456                         if ( pMinHeight > b.minHeight ) {
3457                                 b.minHeight = pMinHeight;
3458                         }
3459                         if ( pMaxWidth < b.maxWidth ) {
3460                                 b.maxWidth = pMaxWidth;
3461                         }
3462                         if ( pMaxHeight < b.maxHeight ) {
3463                                 b.maxHeight = pMaxHeight;
3464                         }
3465                 }
3466                 this._vBoundaries = b;
3467         },
3468
3469         _updateCache: function( data ) {
3470                 this.offset = this.helper.offset();
3471                 if ( this._isNumber( data.left ) ) {
3472                         this.position.left = data.left;
3473                 }
3474                 if ( this._isNumber( data.top ) ) {
3475                         this.position.top = data.top;
3476                 }
3477                 if ( this._isNumber( data.height ) ) {
3478                         this.size.height = data.height;
3479                 }
3480                 if ( this._isNumber( data.width ) ) {
3481                         this.size.width = data.width;
3482                 }
3483         },
3484
3485         _updateRatio: function( data ) {
3486
3487                 var cpos = this.position,
3488                         csize = this.size,
3489                         a = this.axis;
3490
3491                 if ( this._isNumber( data.height ) ) {
3492                         data.width = ( data.height * this.aspectRatio );
3493                 } else if ( this._isNumber( data.width ) ) {
3494                         data.height = ( data.width / this.aspectRatio );
3495                 }
3496
3497                 if ( a === "sw" ) {
3498                         data.left = cpos.left + ( csize.width - data.width );
3499                         data.top = null;
3500                 }
3501                 if ( a === "nw" ) {
3502                         data.top = cpos.top + ( csize.height - data.height );
3503                         data.left = cpos.left + ( csize.width - data.width );
3504                 }
3505
3506                 return data;
3507         },
3508
3509         _respectSize: function( data ) {
3510
3511                 var o = this._vBoundaries,
3512                         a = this.axis,
3513                         ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ),
3514                         ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ),
3515                         isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ),
3516                         isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ),
3517                         dw = this.originalPosition.left + this.originalSize.width,
3518                         dh = this.originalPosition.top + this.originalSize.height,
3519                         cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a );
3520                 if ( isminw ) {
3521                         data.width = o.minWidth;
3522                 }
3523                 if ( isminh ) {
3524                         data.height = o.minHeight;
3525                 }
3526                 if ( ismaxw ) {
3527                         data.width = o.maxWidth;
3528                 }
3529                 if ( ismaxh ) {
3530                         data.height = o.maxHeight;
3531                 }
3532
3533                 if ( isminw && cw ) {
3534                         data.left = dw - o.minWidth;
3535                 }
3536                 if ( ismaxw && cw ) {
3537                         data.left = dw - o.maxWidth;
3538                 }
3539                 if ( isminh && ch ) {
3540                         data.top = dh - o.minHeight;
3541                 }
3542                 if ( ismaxh && ch ) {
3543                         data.top = dh - o.maxHeight;
3544                 }
3545
3546                 // Fixing jump error on top/left - bug #2330
3547                 if ( !data.width && !data.height && !data.left && data.top ) {
3548                         data.top = null;
3549                 } else if ( !data.width && !data.height && !data.top && data.left ) {
3550                         data.left = null;
3551                 }
3552
3553                 return data;
3554         },
3555
3556         _getPaddingPlusBorderDimensions: function( element ) {
3557                 var i = 0,
3558                         widths = [],
3559                         borders = [
3560                                 element.css( "borderTopWidth" ),
3561                                 element.css( "borderRightWidth" ),
3562                                 element.css( "borderBottomWidth" ),
3563                                 element.css( "borderLeftWidth" )
3564                         ],
3565                         paddings = [
3566                                 element.css( "paddingTop" ),
3567                                 element.css( "paddingRight" ),
3568                                 element.css( "paddingBottom" ),
3569                                 element.css( "paddingLeft" )
3570                         ];
3571
3572                 for ( ; i < 4; i++ ) {
3573                         widths[ i ] = ( parseFloat( borders[ i ] ) || 0 );
3574                         widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 );
3575                 }
3576
3577                 return {
3578                         height: widths[ 0 ] + widths[ 2 ],
3579                         width: widths[ 1 ] + widths[ 3 ]
3580                 };
3581         },
3582
3583         _proportionallyResize: function() {
3584
3585                 if ( !this._proportionallyResizeElements.length ) {
3586                         return;
3587                 }
3588
3589                 var prel,
3590                         i = 0,
3591                         element = this.helper || this.element;
3592
3593                 for ( ; i < this._proportionallyResizeElements.length; i++ ) {
3594
3595                         prel = this._proportionallyResizeElements[ i ];
3596
3597                         // TODO: Seems like a bug to cache this.outerDimensions
3598                         // considering that we are in a loop.
3599                         if ( !this.outerDimensions ) {
3600                                 this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
3601                         }
3602
3603                         prel.css( {
3604                                 height: ( element.height() - this.outerDimensions.height ) || 0,
3605                                 width: ( element.width() - this.outerDimensions.width ) || 0
3606                         } );
3607
3608                 }
3609
3610         },
3611
3612         _renderProxy: function() {
3613
3614                 var el = this.element, o = this.options;
3615                 this.elementOffset = el.offset();
3616
3617                 if ( this._helper ) {
3618
3619                         this.helper = this.helper || $( "<div style='overflow:hidden;'></div>" );
3620
3621                         this._addClass( this.helper, this._helper );
3622                         this.helper.css( {
3623                                 width: this.element.outerWidth(),
3624                                 height: this.element.outerHeight(),
3625                                 position: "absolute",
3626                                 left: this.elementOffset.left + "px",
3627                                 top: this.elementOffset.top + "px",
3628                                 zIndex: ++o.zIndex //TODO: Don't modify option
3629                         } );
3630
3631                         this.helper
3632                                 .appendTo( "body" )
3633                                 .disableSelection();
3634
3635                 } else {
3636                         this.helper = this.element;
3637                 }
3638
3639         },
3640
3641         _change: {
3642                 e: function( event, dx ) {
3643                         return { width: this.originalSize.width + dx };
3644                 },
3645                 w: function( event, dx ) {
3646                         var cs = this.originalSize, sp = this.originalPosition;
3647                         return { left: sp.left + dx, width: cs.width - dx };
3648                 },
3649                 n: function( event, dx, dy ) {
3650                         var cs = this.originalSize, sp = this.originalPosition;
3651                         return { top: sp.top + dy, height: cs.height - dy };
3652                 },
3653                 s: function( event, dx, dy ) {
3654                         return { height: this.originalSize.height + dy };
3655                 },
3656                 se: function( event, dx, dy ) {
3657                         return $.extend( this._change.s.apply( this, arguments ),
3658                                 this._change.e.apply( this, [ event, dx, dy ] ) );
3659                 },
3660                 sw: function( event, dx, dy ) {
3661                         return $.extend( this._change.s.apply( this, arguments ),
3662                                 this._change.w.apply( this, [ event, dx, dy ] ) );
3663                 },
3664                 ne: function( event, dx, dy ) {
3665                         return $.extend( this._change.n.apply( this, arguments ),
3666                                 this._change.e.apply( this, [ event, dx, dy ] ) );
3667                 },
3668                 nw: function( event, dx, dy ) {
3669                         return $.extend( this._change.n.apply( this, arguments ),
3670                                 this._change.w.apply( this, [ event, dx, dy ] ) );
3671                 }
3672         },
3673
3674         _propagate: function( n, event ) {
3675                 $.ui.plugin.call( this, n, [ event, this.ui() ] );
3676                 ( n !== "resize" && this._trigger( n, event, this.ui() ) );
3677         },
3678
3679         plugins: {},
3680
3681         ui: function() {
3682                 return {
3683                         originalElement: this.originalElement,
3684                         element: this.element,
3685                         helper: this.helper,
3686                         position: this.position,
3687                         size: this.size,
3688                         originalSize: this.originalSize,
3689                         originalPosition: this.originalPosition
3690                 };
3691         }
3692
3693 } );
3694
3695 /*
3696  * Resizable Extensions
3697  */
3698
3699 $.ui.plugin.add( "resizable", "animate", {
3700
3701         stop: function( event ) {
3702                 var that = $( this ).resizable( "instance" ),
3703                         o = that.options,
3704                         pr = that._proportionallyResizeElements,
3705                         ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ),
3706                         soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height,
3707                         soffsetw = ista ? 0 : that.sizeDiff.width,
3708                         style = {
3709                                 width: ( that.size.width - soffsetw ),
3710                                 height: ( that.size.height - soffseth )
3711                         },
3712                         left = ( parseFloat( that.element.css( "left" ) ) +
3713                                 ( that.position.left - that.originalPosition.left ) ) || null,
3714                         top = ( parseFloat( that.element.css( "top" ) ) +
3715                                 ( that.position.top - that.originalPosition.top ) ) || null;
3716
3717                 that.element.animate(
3718                         $.extend( style, top && left ? { top: top, left: left } : {} ), {
3719                                 duration: o.animateDuration,
3720                                 easing: o.animateEasing,
3721                                 step: function() {
3722
3723                                         var data = {
3724                                                 width: parseFloat( that.element.css( "width" ) ),
3725                                                 height: parseFloat( that.element.css( "height" ) ),
3726                                                 top: parseFloat( that.element.css( "top" ) ),
3727                                                 left: parseFloat( that.element.css( "left" ) )
3728                                         };
3729
3730                                         if ( pr && pr.length ) {
3731                                                 $( pr[ 0 ] ).css( { width: data.width, height: data.height } );
3732                                         }
3733
3734                                         // Propagating resize, and updating values for each animation step
3735                                         that._updateCache( data );
3736                                         that._propagate( "resize", event );
3737
3738                                 }
3739                         }
3740                 );
3741         }
3742
3743 } );
3744
3745 $.ui.plugin.add( "resizable", "containment", {
3746
3747         start: function() {
3748                 var element, p, co, ch, cw, width, height,
3749                         that = $( this ).resizable( "instance" ),
3750                         o = that.options,
3751                         el = that.element,
3752                         oc = o.containment,
3753                         ce = ( oc instanceof $ ) ?
3754                                 oc.get( 0 ) :
3755                                 ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
3756
3757                 if ( !ce ) {
3758                         return;
3759                 }
3760
3761                 that.containerElement = $( ce );
3762
3763                 if ( /document/.test( oc ) || oc === document ) {
3764                         that.containerOffset = {
3765                                 left: 0,
3766                                 top: 0
3767                         };
3768                         that.containerPosition = {
3769                                 left: 0,
3770                                 top: 0
3771                         };
3772
3773                         that.parentData = {
3774                                 element: $( document ),
3775                                 left: 0,
3776                                 top: 0,
3777                                 width: $( document ).width(),
3778                                 height: $( document ).height() || document.body.parentNode.scrollHeight
3779                         };
3780                 } else {
3781                         element = $( ce );
3782                         p = [];
3783                         $( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) {
3784                                 p[ i ] = that._num( element.css( "padding" + name ) );
3785                         } );
3786
3787                         that.containerOffset = element.offset();
3788                         that.containerPosition = element.position();
3789                         that.containerSize = {
3790                                 height: ( element.innerHeight() - p[ 3 ] ),
3791                                 width: ( element.innerWidth() - p[ 1 ] )
3792                         };
3793
3794                         co = that.containerOffset;
3795                         ch = that.containerSize.height;
3796                         cw = that.containerSize.width;
3797                         width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
3798                         height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
3799
3800                         that.parentData = {
3801                                 element: ce,
3802                                 left: co.left,
3803                                 top: co.top,
3804                                 width: width,
3805                                 height: height
3806                         };
3807                 }
3808         },
3809
3810         resize: function( event ) {
3811                 var woset, hoset, isParent, isOffsetRelative,
3812                         that = $( this ).resizable( "instance" ),
3813                         o = that.options,
3814                         co = that.containerOffset,
3815                         cp = that.position,
3816                         pRatio = that._aspectRatio || event.shiftKey,
3817                         cop = {
3818                                 top: 0,
3819                                 left: 0
3820                         },
3821                         ce = that.containerElement,
3822                         continueResize = true;
3823
3824                 if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
3825                         cop = co;
3826                 }
3827
3828                 if ( cp.left < ( that._helper ? co.left : 0 ) ) {
3829                         that.size.width = that.size.width +
3830                                 ( that._helper ?
3831                                         ( that.position.left - co.left ) :
3832                                         ( that.position.left - cop.left ) );
3833
3834                         if ( pRatio ) {
3835                                 that.size.height = that.size.width / that.aspectRatio;
3836                                 continueResize = false;
3837                         }
3838                         that.position.left = o.helper ? co.left : 0;
3839                 }
3840
3841                 if ( cp.top < ( that._helper ? co.top : 0 ) ) {
3842                         that.size.height = that.size.height +
3843                                 ( that._helper ?
3844                                         ( that.position.top - co.top ) :
3845                                         that.position.top );
3846
3847                         if ( pRatio ) {
3848                                 that.size.width = that.size.height * that.aspectRatio;
3849                                 continueResize = false;
3850                         }
3851                         that.position.top = that._helper ? co.top : 0;
3852                 }
3853
3854                 isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
3855                 isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
3856
3857                 if ( isParent && isOffsetRelative ) {
3858                         that.offset.left = that.parentData.left + that.position.left;
3859                         that.offset.top = that.parentData.top + that.position.top;
3860                 } else {
3861                         that.offset.left = that.element.offset().left;
3862                         that.offset.top = that.element.offset().top;
3863                 }
3864
3865                 woset = Math.abs( that.sizeDiff.width +
3866                         ( that._helper ?
3867                                 that.offset.left - cop.left :
3868                                 ( that.offset.left - co.left ) ) );
3869
3870                 hoset = Math.abs( that.sizeDiff.height +
3871                         ( that._helper ?
3872                                 that.offset.top - cop.top :
3873                                 ( that.offset.top - co.top ) ) );
3874
3875                 if ( woset + that.size.width >= that.parentData.width ) {
3876                         that.size.width = that.parentData.width - woset;
3877                         if ( pRatio ) {
3878                                 that.size.height = that.size.width / that.aspectRatio;
3879                                 continueResize = false;
3880                         }
3881                 }
3882
3883                 if ( hoset + that.size.height >= that.parentData.height ) {
3884                         that.size.height = that.parentData.height - hoset;
3885                         if ( pRatio ) {
3886                                 that.size.width = that.size.height * that.aspectRatio;
3887                                 continueResize = false;
3888                         }
3889                 }
3890
3891                 if ( !continueResize ) {
3892                         that.position.left = that.prevPosition.left;
3893                         that.position.top = that.prevPosition.top;
3894                         that.size.width = that.prevSize.width;
3895                         that.size.height = that.prevSize.height;
3896                 }
3897         },
3898
3899         stop: function() {
3900                 var that = $( this ).resizable( "instance" ),
3901                         o = that.options,
3902                         co = that.containerOffset,
3903                         cop = that.containerPosition,
3904                         ce = that.containerElement,
3905                         helper = $( that.helper ),
3906                         ho = helper.offset(),
3907                         w = helper.outerWidth() - that.sizeDiff.width,
3908                         h = helper.outerHeight() - that.sizeDiff.height;
3909
3910                 if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
3911                         $( this ).css( {
3912                                 left: ho.left - cop.left - co.left,
3913                                 width: w,
3914                                 height: h
3915                         } );
3916                 }
3917
3918                 if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
3919                         $( this ).css( {
3920                                 left: ho.left - cop.left - co.left,
3921                                 width: w,
3922                                 height: h
3923                         } );
3924                 }
3925         }
3926 } );
3927
3928 $.ui.plugin.add( "resizable", "alsoResize", {
3929
3930         start: function() {
3931                 var that = $( this ).resizable( "instance" ),
3932                         o = that.options;
3933
3934                 $( o.alsoResize ).each( function() {
3935                         var el = $( this );
3936                         el.data( "ui-resizable-alsoresize", {
3937                                 width: parseFloat( el.width() ), height: parseFloat( el.height() ),
3938                                 left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
3939                         } );
3940                 } );
3941         },
3942
3943         resize: function( event, ui ) {
3944                 var that = $( this ).resizable( "instance" ),
3945                         o = that.options,
3946                         os = that.originalSize,
3947                         op = that.originalPosition,
3948                         delta = {
3949                                 height: ( that.size.height - os.height ) || 0,
3950                                 width: ( that.size.width - os.width ) || 0,
3951                                 top: ( that.position.top - op.top ) || 0,
3952                                 left: ( that.position.left - op.left ) || 0
3953                         };
3954
3955                         $( o.alsoResize ).each( function() {
3956                                 var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {},
3957                                         css = el.parents( ui.originalElement[ 0 ] ).length ?
3958                                                         [ "width", "height" ] :
3959                                                         [ "width", "height", "top", "left" ];
3960
3961                                 $.each( css, function( i, prop ) {
3962                                         var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 );
3963                                         if ( sum && sum >= 0 ) {
3964                                                 style[ prop ] = sum || null;
3965                                         }
3966                                 } );
3967
3968                                 el.css( style );
3969                         } );
3970         },
3971
3972         stop: function() {
3973                 $( this ).removeData( "ui-resizable-alsoresize" );
3974         }
3975 } );
3976
3977 $.ui.plugin.add( "resizable", "ghost", {
3978
3979         start: function() {
3980
3981                 var that = $( this ).resizable( "instance" ), cs = that.size;
3982
3983                 that.ghost = that.originalElement.clone();
3984                 that.ghost.css( {
3985                         opacity: 0.25,
3986                         display: "block",
3987                         position: "relative",
3988                         height: cs.height,
3989                         width: cs.width,
3990                         margin: 0,
3991                         left: 0,
3992                         top: 0
3993                 } );
3994
3995                 that._addClass( that.ghost, "ui-resizable-ghost" );
3996
3997                 // DEPRECATED
3998                 // TODO: remove after 1.12
3999                 if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) {
4000
4001                         // Ghost option
4002                         that.ghost.addClass( this.options.ghost );
4003                 }
4004
4005                 that.ghost.appendTo( that.helper );
4006
4007         },
4008
4009         resize: function() {
4010                 var that = $( this ).resizable( "instance" );
4011                 if ( that.ghost ) {
4012                         that.ghost.css( {
4013                                 position: "relative",
4014                                 height: that.size.height,
4015                                 width: that.size.width
4016                         } );
4017                 }
4018         },
4019
4020         stop: function() {
4021                 var that = $( this ).resizable( "instance" );
4022                 if ( that.ghost && that.helper ) {
4023                         that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) );
4024                 }
4025         }
4026
4027 } );
4028
4029 $.ui.plugin.add( "resizable", "grid", {
4030
4031         resize: function() {
4032                 var outerDimensions,
4033                         that = $( this ).resizable( "instance" ),
4034                         o = that.options,
4035                         cs = that.size,
4036                         os = that.originalSize,
4037                         op = that.originalPosition,
4038                         a = that.axis,
4039                         grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
4040                         gridX = ( grid[ 0 ] || 1 ),
4041                         gridY = ( grid[ 1 ] || 1 ),
4042                         ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX,
4043                         oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY,
4044                         newWidth = os.width + ox,
4045                         newHeight = os.height + oy,
4046                         isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ),
4047                         isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ),
4048                         isMinWidth = o.minWidth && ( o.minWidth > newWidth ),
4049                         isMinHeight = o.minHeight && ( o.minHeight > newHeight );
4050
4051                 o.grid = grid;
4052
4053                 if ( isMinWidth ) {
4054                         newWidth += gridX;
4055                 }
4056                 if ( isMinHeight ) {
4057                         newHeight += gridY;
4058                 }
4059                 if ( isMaxWidth ) {
4060                         newWidth -= gridX;
4061                 }
4062                 if ( isMaxHeight ) {
4063                         newHeight -= gridY;
4064                 }
4065
4066                 if ( /^(se|s|e)$/.test( a ) ) {
4067                         that.size.width = newWidth;
4068                         that.size.height = newHeight;
4069                 } else if ( /^(ne)$/.test( a ) ) {
4070                         that.size.width = newWidth;
4071                         that.size.height = newHeight;
4072                         that.position.top = op.top - oy;
4073                 } else if ( /^(sw)$/.test( a ) ) {
4074                         that.size.width = newWidth;
4075                         that.size.height = newHeight;
4076                         that.position.left = op.left - ox;
4077                 } else {
4078                         if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) {
4079                                 outerDimensions = that._getPaddingPlusBorderDimensions( this );
4080                         }
4081
4082                         if ( newHeight - gridY > 0 ) {
4083                                 that.size.height = newHeight;
4084                                 that.position.top = op.top - oy;
4085                         } else {
4086                                 newHeight = gridY - outerDimensions.height;
4087                                 that.size.height = newHeight;
4088                                 that.position.top = op.top + os.height - newHeight;
4089                         }
4090                         if ( newWidth - gridX > 0 ) {
4091                                 that.size.width = newWidth;
4092                                 that.position.left = op.left - ox;
4093                         } else {
4094                                 newWidth = gridX - outerDimensions.width;
4095                                 that.size.width = newWidth;
4096                                 that.position.left = op.left + os.width - newWidth;
4097                         }
4098                 }
4099         }
4100
4101 } );
4102
4103 var widgetsResizable = $.ui.resizable;
4104
4105
4106 /*!
4107  * jQuery UI Selectable 1.12.1
4108  * http://jqueryui.com
4109  *
4110  * Copyright jQuery Foundation and other contributors
4111  * Released under the MIT license.
4112  * http://jquery.org/license
4113  */
4114
4115 //>>label: Selectable
4116 //>>group: Interactions
4117 //>>description: Allows groups of elements to be selected with the mouse.
4118 //>>docs: http://api.jqueryui.com/selectable/
4119 //>>demos: http://jqueryui.com/selectable/
4120 //>>css.structure: ../../themes/base/selectable.css
4121
4122
4123
4124 var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, {
4125         version: "1.12.1",
4126         options: {
4127                 appendTo: "body",
4128                 autoRefresh: true,
4129                 distance: 0,
4130                 filter: "*",
4131                 tolerance: "touch",
4132
4133                 // Callbacks
4134                 selected: null,
4135                 selecting: null,
4136                 start: null,
4137                 stop: null,
4138                 unselected: null,
4139                 unselecting: null
4140         },
4141         _create: function() {
4142                 var that = this;
4143
4144                 this._addClass( "ui-selectable" );
4145
4146                 this.dragged = false;
4147
4148                 // Cache selectee children based on filter
4149                 this.refresh = function() {
4150                         that.elementPos = $( that.element[ 0 ] ).offset();
4151                         that.selectees = $( that.options.filter, that.element[ 0 ] );
4152                         that._addClass( that.selectees, "ui-selectee" );
4153                         that.selectees.each( function() {
4154                                 var $this = $( this ),
4155                                         selecteeOffset = $this.offset(),
4156                                         pos = {
4157                                                 left: selecteeOffset.left - that.elementPos.left,
4158                                                 top: selecteeOffset.top - that.elementPos.top
4159                                         };
4160                                 $.data( this, "selectable-item", {
4161                                         element: this,
4162                                         $element: $this,
4163                                         left: pos.left,
4164                                         top: pos.top,
4165                                         right: pos.left + $this.outerWidth(),
4166                                         bottom: pos.top + $this.outerHeight(),
4167                                         startselected: false,
4168                                         selected: $this.hasClass( "ui-selected" ),
4169                                         selecting: $this.hasClass( "ui-selecting" ),
4170                                         unselecting: $this.hasClass( "ui-unselecting" )
4171                                 } );
4172                         } );
4173                 };
4174                 this.refresh();
4175
4176                 this._mouseInit();
4177
4178                 this.helper = $( "<div>" );
4179                 this._addClass( this.helper, "ui-selectable-helper" );
4180         },
4181
4182         _destroy: function() {
4183                 this.selectees.removeData( "selectable-item" );
4184                 this._mouseDestroy();
4185         },
4186
4187         _mouseStart: function( event ) {
4188                 var that = this,
4189                         options = this.options;
4190
4191                 this.opos = [ event.pageX, event.pageY ];
4192                 this.elementPos = $( this.element[ 0 ] ).offset();
4193
4194                 if ( this.options.disabled ) {
4195                         return;
4196                 }
4197
4198                 this.selectees = $( options.filter, this.element[ 0 ] );
4199
4200                 this._trigger( "start", event );
4201
4202                 $( options.appendTo ).append( this.helper );
4203
4204                 // position helper (lasso)
4205                 this.helper.css( {
4206                         "left": event.pageX,
4207                         "top": event.pageY,
4208                         "width": 0,
4209                         "height": 0
4210                 } );
4211
4212                 if ( options.autoRefresh ) {
4213                         this.refresh();
4214                 }
4215
4216                 this.selectees.filter( ".ui-selected" ).each( function() {
4217                         var selectee = $.data( this, "selectable-item" );
4218                         selectee.startselected = true;
4219                         if ( !event.metaKey && !event.ctrlKey ) {
4220                                 that._removeClass( selectee.$element, "ui-selected" );
4221                                 selectee.selected = false;
4222                                 that._addClass( selectee.$element, "ui-unselecting" );
4223                                 selectee.unselecting = true;
4224
4225                                 // selectable UNSELECTING callback
4226                                 that._trigger( "unselecting", event, {
4227                                         unselecting: selectee.element
4228                                 } );
4229                         }
4230                 } );
4231
4232                 $( event.target ).parents().addBack().each( function() {
4233                         var doSelect,
4234                                 selectee = $.data( this, "selectable-item" );
4235                         if ( selectee ) {
4236                                 doSelect = ( !event.metaKey && !event.ctrlKey ) ||
4237                                         !selectee.$element.hasClass( "ui-selected" );
4238                                 that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
4239                                         ._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
4240                                 selectee.unselecting = !doSelect;
4241                                 selectee.selecting = doSelect;
4242                                 selectee.selected = doSelect;
4243
4244                                 // selectable (UN)SELECTING callback
4245                                 if ( doSelect ) {
4246                                         that._trigger( "selecting", event, {
4247                                                 selecting: selectee.element
4248                                         } );
4249                                 } else {
4250                                         that._trigger( "unselecting", event, {
4251                                                 unselecting: selectee.element
4252                                         } );
4253                                 }
4254                                 return false;
4255                         }
4256                 } );
4257
4258         },
4259
4260         _mouseDrag: function( event ) {
4261
4262                 this.dragged = true;
4263
4264                 if ( this.options.disabled ) {
4265                         return;
4266                 }
4267
4268                 var tmp,
4269                         that = this,
4270                         options = this.options,
4271                         x1 = this.opos[ 0 ],
4272                         y1 = this.opos[ 1 ],
4273                         x2 = event.pageX,
4274                         y2 = event.pageY;
4275
4276                 if ( x1 > x2 ) { tmp = x2; x2 = x1; x1 = tmp; }
4277                 if ( y1 > y2 ) { tmp = y2; y2 = y1; y1 = tmp; }
4278                 this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
4279
4280                 this.selectees.each( function() {
4281                         var selectee = $.data( this, "selectable-item" ),
4282                                 hit = false,
4283                                 offset = {};
4284
4285                         //prevent helper from being selected if appendTo: selectable
4286                         if ( !selectee || selectee.element === that.element[ 0 ] ) {
4287                                 return;
4288                         }
4289
4290                         offset.left   = selectee.left   + that.elementPos.left;
4291                         offset.right  = selectee.right  + that.elementPos.left;
4292                         offset.top    = selectee.top    + that.elementPos.top;
4293                         offset.bottom = selectee.bottom + that.elementPos.top;
4294
4295                         if ( options.tolerance === "touch" ) {
4296                                 hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
4297                     offset.bottom < y1 ) );
4298                         } else if ( options.tolerance === "fit" ) {
4299                                 hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
4300                     offset.bottom < y2 );
4301                         }
4302
4303                         if ( hit ) {
4304
4305                                 // SELECT
4306                                 if ( selectee.selected ) {
4307                                         that._removeClass( selectee.$element, "ui-selected" );
4308                                         selectee.selected = false;
4309                                 }
4310                                 if ( selectee.unselecting ) {
4311                                         that._removeClass( selectee.$element, "ui-unselecting" );
4312                                         selectee.unselecting = false;
4313                                 }
4314                                 if ( !selectee.selecting ) {
4315                                         that._addClass( selectee.$element, "ui-selecting" );
4316                                         selectee.selecting = true;
4317
4318                                         // selectable SELECTING callback
4319                                         that._trigger( "selecting", event, {
4320                                                 selecting: selectee.element
4321                                         } );
4322                                 }
4323                         } else {
4324
4325                                 // UNSELECT
4326                                 if ( selectee.selecting ) {
4327                                         if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
4328                                                 that._removeClass( selectee.$element, "ui-selecting" );
4329                                                 selectee.selecting = false;
4330                                                 that._addClass( selectee.$element, "ui-selected" );
4331                                                 selectee.selected = true;
4332                                         } else {
4333                                                 that._removeClass( selectee.$element, "ui-selecting" );
4334                                                 selectee.selecting = false;
4335                                                 if ( selectee.startselected ) {
4336                                                         that._addClass( selectee.$element, "ui-unselecting" );
4337                                                         selectee.unselecting = true;
4338                                                 }
4339
4340                                                 // selectable UNSELECTING callback
4341                                                 that._trigger( "unselecting", event, {
4342                                                         unselecting: selectee.element
4343                                                 } );
4344                                         }
4345                                 }
4346                                 if ( selectee.selected ) {
4347                                         if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
4348                                                 that._removeClass( selectee.$element, "ui-selected" );
4349                                                 selectee.selected = false;
4350
4351                                                 that._addClass( selectee.$element, "ui-unselecting" );
4352                                                 selectee.unselecting = true;
4353
4354                                                 // selectable UNSELECTING callback
4355                                                 that._trigger( "unselecting", event, {
4356                                                         unselecting: selectee.element
4357                                                 } );
4358                                         }
4359                                 }
4360                         }
4361                 } );
4362
4363                 return false;
4364         },
4365
4366         _mouseStop: function( event ) {
4367                 var that = this;
4368
4369                 this.dragged = false;
4370
4371                 $( ".ui-unselecting", this.element[ 0 ] ).each( function() {
4372                         var selectee = $.data( this, "selectable-item" );
4373                         that._removeClass( selectee.$element, "ui-unselecting" );
4374                         selectee.unselecting = false;
4375                         selectee.startselected = false;
4376                         that._trigger( "unselected", event, {
4377                                 unselected: selectee.element
4378                         } );
4379                 } );
4380                 $( ".ui-selecting", this.element[ 0 ] ).each( function() {
4381                         var selectee = $.data( this, "selectable-item" );
4382                         that._removeClass( selectee.$element, "ui-selecting" )
4383                                 ._addClass( selectee.$element, "ui-selected" );
4384                         selectee.selecting = false;
4385                         selectee.selected = true;
4386                         selectee.startselected = true;
4387                         that._trigger( "selected", event, {
4388                                 selected: selectee.element
4389                         } );
4390                 } );
4391                 this._trigger( "stop", event );
4392
4393                 this.helper.remove();
4394
4395                 return false;
4396         }
4397
4398 } );
4399
4400
4401 /*!
4402  * jQuery UI Sortable 1.12.1
4403  * http://jqueryui.com
4404  *
4405  * Copyright jQuery Foundation and other contributors
4406  * Released under the MIT license.
4407  * http://jquery.org/license
4408  */
4409
4410 //>>label: Sortable
4411 //>>group: Interactions
4412 //>>description: Enables items in a list to be sorted using the mouse.
4413 //>>docs: http://api.jqueryui.com/sortable/
4414 //>>demos: http://jqueryui.com/sortable/
4415 //>>css.structure: ../../themes/base/sortable.css
4416
4417
4418
4419 var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, {
4420         version: "1.12.1",
4421         widgetEventPrefix: "sort",
4422         ready: false,
4423         options: {
4424                 appendTo: "parent",
4425                 axis: false,
4426                 connectWith: false,
4427                 containment: false,
4428                 cursor: "auto",
4429                 cursorAt: false,
4430                 dropOnEmpty: true,
4431                 forcePlaceholderSize: false,
4432                 forceHelperSize: false,
4433                 grid: false,
4434                 handle: false,
4435                 helper: "original",
4436                 items: "> *",
4437                 opacity: false,
4438                 placeholder: false,
4439                 revert: false,
4440                 scroll: true,
4441                 scrollSensitivity: 20,
4442                 scrollSpeed: 20,
4443                 scope: "default",
4444                 tolerance: "intersect",
4445                 zIndex: 1000,
4446
4447                 // Callbacks
4448                 activate: null,
4449                 beforeStop: null,
4450                 change: null,
4451                 deactivate: null,
4452                 out: null,
4453                 over: null,
4454                 receive: null,
4455                 remove: null,
4456                 sort: null,
4457                 start: null,
4458                 stop: null,
4459                 update: null
4460         },
4461
4462         _isOverAxis: function( x, reference, size ) {
4463                 return ( x >= reference ) && ( x < ( reference + size ) );
4464         },
4465
4466         _isFloating: function( item ) {
4467                 return ( /left|right/ ).test( item.css( "float" ) ) ||
4468                         ( /inline|table-cell/ ).test( item.css( "display" ) );
4469         },
4470
4471         _create: function() {
4472                 this.containerCache = {};
4473                 this._addClass( "ui-sortable" );
4474
4475                 //Get the items
4476                 this.refresh();
4477
4478                 //Let's determine the parent's offset
4479                 this.offset = this.element.offset();
4480
4481                 //Initialize mouse events for interaction
4482                 this._mouseInit();
4483
4484                 this._setHandleClassName();
4485
4486                 //We're ready to go
4487                 this.ready = true;
4488
4489         },
4490
4491         _setOption: function( key, value ) {
4492                 this._super( key, value );
4493
4494                 if ( key === "handle" ) {
4495                         this._setHandleClassName();
4496                 }
4497         },
4498
4499         _setHandleClassName: function() {
4500                 var that = this;
4501                 this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" );
4502                 $.each( this.items, function() {
4503                         that._addClass(
4504                                 this.instance.options.handle ?
4505                                         this.item.find( this.instance.options.handle ) :
4506                                         this.item,
4507                                 "ui-sortable-handle"
4508                         );
4509                 } );
4510         },
4511
4512         _destroy: function() {
4513                 this._mouseDestroy();
4514
4515                 for ( var i = this.items.length - 1; i >= 0; i-- ) {
4516                         this.items[ i ].item.removeData( this.widgetName + "-item" );
4517                 }
4518
4519                 return this;
4520         },
4521
4522         _mouseCapture: function( event, overrideHandle ) {
4523                 var currentItem = null,
4524                         validHandle = false,
4525                         that = this;
4526
4527                 if ( this.reverting ) {
4528                         return false;
4529                 }
4530
4531                 if ( this.options.disabled || this.options.type === "static" ) {
4532                         return false;
4533                 }
4534
4535                 //We have to refresh the items data once first
4536                 this._refreshItems( event );
4537
4538                 //Find out if the clicked node (or one of its parents) is a actual item in this.items
4539                 $( event.target ).parents().each( function() {
4540                         if ( $.data( this, that.widgetName + "-item" ) === that ) {
4541                                 currentItem = $( this );
4542                                 return false;
4543                         }
4544                 } );
4545                 if ( $.data( event.target, that.widgetName + "-item" ) === that ) {
4546                         currentItem = $( event.target );
4547                 }
4548
4549                 if ( !currentItem ) {
4550                         return false;
4551                 }
4552                 if ( this.options.handle && !overrideHandle ) {
4553                         $( this.options.handle, currentItem ).find( "*" ).addBack().each( function() {
4554                                 if ( this === event.target ) {
4555                                         validHandle = true;
4556                                 }
4557                         } );
4558                         if ( !validHandle ) {
4559                                 return false;
4560                         }
4561                 }
4562
4563                 this.currentItem = currentItem;
4564                 this._removeCurrentsFromItems();
4565                 return true;
4566
4567         },
4568
4569         _mouseStart: function( event, overrideHandle, noActivation ) {
4570
4571                 var i, body,
4572                         o = this.options;
4573
4574                 this.currentContainer = this;
4575
4576                 //We only need to call refreshPositions, because the refreshItems call has been moved to
4577                 // mouseCapture
4578                 this.refreshPositions();
4579
4580                 //Create and append the visible helper
4581                 this.helper = this._createHelper( event );
4582
4583                 //Cache the helper size
4584                 this._cacheHelperProportions();
4585
4586                 /*
4587                  * - Position generation -
4588                  * This block generates everything position related - it's the core of draggables.
4589                  */
4590
4591                 //Cache the margins of the original element
4592                 this._cacheMargins();
4593
4594                 //Get the next scrolling parent
4595                 this.scrollParent = this.helper.scrollParent();
4596
4597                 //The element's absolute position on the page minus margins
4598                 this.offset = this.currentItem.offset();
4599                 this.offset = {
4600                         top: this.offset.top - this.margins.top,
4601                         left: this.offset.left - this.margins.left
4602                 };
4603
4604                 $.extend( this.offset, {
4605                         click: { //Where the click happened, relative to the element
4606                                 left: event.pageX - this.offset.left,
4607                                 top: event.pageY - this.offset.top
4608                         },
4609                         parent: this._getParentOffset(),
4610
4611                         // This is a relative to absolute position minus the actual position calculation -
4612                         // only used for relative positioned helper
4613                         relative: this._getRelativeOffset()
4614                 } );
4615
4616                 // Only after we got the offset, we can change the helper's position to absolute
4617                 // TODO: Still need to figure out a way to make relative sorting possible
4618                 this.helper.css( "position", "absolute" );
4619                 this.cssPosition = this.helper.css( "position" );
4620
4621                 //Generate the original position
4622                 this.originalPosition = this._generatePosition( event );
4623                 this.originalPageX = event.pageX;
4624                 this.originalPageY = event.pageY;
4625
4626                 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
4627                 ( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
4628
4629                 //Cache the former DOM position
4630                 this.domPosition = {
4631                         prev: this.currentItem.prev()[ 0 ],
4632                         parent: this.currentItem.parent()[ 0 ]
4633                 };
4634
4635                 // If the helper is not the original, hide the original so it's not playing any role during
4636                 // the drag, won't cause anything bad this way
4637                 if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
4638                         this.currentItem.hide();
4639                 }
4640
4641                 //Create the placeholder
4642                 this._createPlaceholder();
4643
4644                 //Set a containment if given in the options
4645                 if ( o.containment ) {
4646                         this._setContainment();
4647                 }
4648
4649                 if ( o.cursor && o.cursor !== "auto" ) { // cursor option
4650                         body = this.document.find( "body" );
4651
4652                         // Support: IE
4653                         this.storedCursor = body.css( "cursor" );
4654                         body.css( "cursor", o.cursor );
4655
4656                         this.storedStylesheet =
4657                                 $( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body );
4658                 }
4659
4660                 if ( o.opacity ) { // opacity option
4661                         if ( this.helper.css( "opacity" ) ) {
4662                                 this._storedOpacity = this.helper.css( "opacity" );
4663                         }
4664                         this.helper.css( "opacity", o.opacity );
4665                 }
4666
4667                 if ( o.zIndex ) { // zIndex option
4668                         if ( this.helper.css( "zIndex" ) ) {
4669                                 this._storedZIndex = this.helper.css( "zIndex" );
4670                         }
4671                         this.helper.css( "zIndex", o.zIndex );
4672                 }
4673
4674                 //Prepare scrolling
4675                 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
4676                                 this.scrollParent[ 0 ].tagName !== "HTML" ) {
4677                         this.overflowOffset = this.scrollParent.offset();
4678                 }
4679
4680                 //Call callbacks
4681                 this._trigger( "start", event, this._uiHash() );
4682
4683                 //Recache the helper size
4684                 if ( !this._preserveHelperProportions ) {
4685                         this._cacheHelperProportions();
4686                 }
4687
4688                 //Post "activate" events to possible containers
4689                 if ( !noActivation ) {
4690                         for ( i = this.containers.length - 1; i >= 0; i-- ) {
4691                                 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
4692                         }
4693                 }
4694
4695                 //Prepare possible droppables
4696                 if ( $.ui.ddmanager ) {
4697                         $.ui.ddmanager.current = this;
4698                 }
4699
4700                 if ( $.ui.ddmanager && !o.dropBehaviour ) {
4701                         $.ui.ddmanager.prepareOffsets( this, event );
4702                 }
4703
4704                 this.dragging = true;
4705
4706                 this._addClass( this.helper, "ui-sortable-helper" );
4707
4708                 // Execute the drag once - this causes the helper not to be visiblebefore getting its
4709                 // correct position
4710                 this._mouseDrag( event );
4711                 return true;
4712
4713         },
4714
4715         _mouseDrag: function( event ) {
4716                 var i, item, itemElement, intersection,
4717                         o = this.options,
4718                         scrolled = false;
4719
4720                 //Compute the helpers position
4721                 this.position = this._generatePosition( event );
4722                 this.positionAbs = this._convertPositionTo( "absolute" );
4723
4724                 if ( !this.lastPositionAbs ) {
4725                         this.lastPositionAbs = this.positionAbs;
4726                 }
4727
4728                 //Do scrolling
4729                 if ( this.options.scroll ) {
4730                         if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
4731                                         this.scrollParent[ 0 ].tagName !== "HTML" ) {
4732
4733                                 if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -
4734                                                 event.pageY < o.scrollSensitivity ) {
4735                                         this.scrollParent[ 0 ].scrollTop =
4736                                                 scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;
4737                                 } else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {
4738                                         this.scrollParent[ 0 ].scrollTop =
4739                                                 scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;
4740                                 }
4741
4742                                 if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -
4743                                                 event.pageX < o.scrollSensitivity ) {
4744                                         this.scrollParent[ 0 ].scrollLeft = scrolled =
4745                                                 this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;
4746                                 } else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {
4747                                         this.scrollParent[ 0 ].scrollLeft = scrolled =
4748                                                 this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;
4749                                 }
4750
4751                         } else {
4752
4753                                 if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {
4754                                         scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );
4755                                 } else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <
4756                                                 o.scrollSensitivity ) {
4757                                         scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );
4758                                 }
4759
4760                                 if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {
4761                                         scrolled = this.document.scrollLeft(
4762                                                 this.document.scrollLeft() - o.scrollSpeed
4763                                         );
4764                                 } else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <
4765                                                 o.scrollSensitivity ) {
4766                                         scrolled = this.document.scrollLeft(
4767                                                 this.document.scrollLeft() + o.scrollSpeed
4768                                         );
4769                                 }
4770
4771                         }
4772
4773                         if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
4774                                 $.ui.ddmanager.prepareOffsets( this, event );
4775                         }
4776                 }
4777
4778                 //Regenerate the absolute position used for position checks
4779                 this.positionAbs = this._convertPositionTo( "absolute" );
4780
4781                 //Set the helper position
4782                 if ( !this.options.axis || this.options.axis !== "y" ) {
4783                         this.helper[ 0 ].style.left = this.position.left + "px";
4784                 }
4785                 if ( !this.options.axis || this.options.axis !== "x" ) {
4786                         this.helper[ 0 ].style.top = this.position.top + "px";
4787                 }
4788
4789                 //Rearrange
4790                 for ( i = this.items.length - 1; i >= 0; i-- ) {
4791
4792                         //Cache variables and intersection, continue if no intersection
4793                         item = this.items[ i ];
4794                         itemElement = item.item[ 0 ];
4795                         intersection = this._intersectsWithPointer( item );
4796                         if ( !intersection ) {
4797                                 continue;
4798                         }
4799
4800                         // Only put the placeholder inside the current Container, skip all
4801                         // items from other containers. This works because when moving
4802                         // an item from one container to another the
4803                         // currentContainer is switched before the placeholder is moved.
4804                         //
4805                         // Without this, moving items in "sub-sortables" can cause
4806                         // the placeholder to jitter between the outer and inner container.
4807                         if ( item.instance !== this.currentContainer ) {
4808                                 continue;
4809                         }
4810
4811                         // Cannot intersect with itself
4812                         // no useless actions that have been done before
4813                         // no action if the item moved is the parent of the item checked
4814                         if ( itemElement !== this.currentItem[ 0 ] &&
4815                                 this.placeholder[ intersection === 1 ? "next" : "prev" ]()[ 0 ] !== itemElement &&
4816                                 !$.contains( this.placeholder[ 0 ], itemElement ) &&
4817                                 ( this.options.type === "semi-dynamic" ?
4818                                         !$.contains( this.element[ 0 ], itemElement ) :
4819                                         true
4820                                 )
4821                         ) {
4822
4823                                 this.direction = intersection === 1 ? "down" : "up";
4824
4825                                 if ( this.options.tolerance === "pointer" || this._intersectsWithSides( item ) ) {
4826                                         this._rearrange( event, item );
4827                                 } else {
4828                                         break;
4829                                 }
4830
4831                                 this._trigger( "change", event, this._uiHash() );
4832                                 break;
4833                         }
4834                 }
4835
4836                 //Post events to containers
4837                 this._contactContainers( event );
4838
4839                 //Interconnect with droppables
4840                 if ( $.ui.ddmanager ) {
4841                         $.ui.ddmanager.drag( this, event );
4842                 }
4843
4844                 //Call callbacks
4845                 this._trigger( "sort", event, this._uiHash() );
4846
4847                 this.lastPositionAbs = this.positionAbs;
4848                 return false;
4849
4850         },
4851
4852         _mouseStop: function( event, noPropagation ) {
4853
4854                 if ( !event ) {
4855                         return;
4856                 }
4857
4858                 //If we are using droppables, inform the manager about the drop
4859                 if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
4860                         $.ui.ddmanager.drop( this, event );
4861                 }
4862
4863                 if ( this.options.revert ) {
4864                         var that = this,
4865                                 cur = this.placeholder.offset(),
4866                                 axis = this.options.axis,
4867                                 animation = {};
4868
4869                         if ( !axis || axis === "x" ) {
4870                                 animation.left = cur.left - this.offset.parent.left - this.margins.left +
4871                                         ( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
4872                                                 0 :
4873                                                 this.offsetParent[ 0 ].scrollLeft
4874                                         );
4875                         }
4876                         if ( !axis || axis === "y" ) {
4877                                 animation.top = cur.top - this.offset.parent.top - this.margins.top +
4878                                         ( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
4879                                                 0 :
4880                                                 this.offsetParent[ 0 ].scrollTop
4881                                         );
4882                         }
4883                         this.reverting = true;
4884                         $( this.helper ).animate(
4885                                 animation,
4886                                 parseInt( this.options.revert, 10 ) || 500,
4887                                 function() {
4888                                         that._clear( event );
4889                                 }
4890                         );
4891                 } else {
4892                         this._clear( event, noPropagation );
4893                 }
4894
4895                 return false;
4896
4897         },
4898
4899         cancel: function() {
4900
4901                 if ( this.dragging ) {
4902
4903                         this._mouseUp( new $.Event( "mouseup", { target: null } ) );
4904
4905                         if ( this.options.helper === "original" ) {
4906                                 this.currentItem.css( this._storedCSS );
4907                                 this._removeClass( this.currentItem, "ui-sortable-helper" );
4908                         } else {
4909                                 this.currentItem.show();
4910                         }
4911
4912                         //Post deactivating events to containers
4913                         for ( var i = this.containers.length - 1; i >= 0; i-- ) {
4914                                 this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) );
4915                                 if ( this.containers[ i ].containerCache.over ) {
4916                                         this.containers[ i ]._trigger( "out", null, this._uiHash( this ) );
4917                                         this.containers[ i ].containerCache.over = 0;
4918                                 }
4919                         }
4920
4921                 }
4922
4923                 if ( this.placeholder ) {
4924
4925                         //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
4926                         // it unbinds ALL events from the original node!
4927                         if ( this.placeholder[ 0 ].parentNode ) {
4928                                 this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
4929                         }
4930                         if ( this.options.helper !== "original" && this.helper &&
4931                                         this.helper[ 0 ].parentNode ) {
4932                                 this.helper.remove();
4933                         }
4934
4935                         $.extend( this, {
4936                                 helper: null,
4937                                 dragging: false,
4938                                 reverting: false,
4939                                 _noFinalSort: null
4940                         } );
4941
4942                         if ( this.domPosition.prev ) {
4943                                 $( this.domPosition.prev ).after( this.currentItem );
4944                         } else {
4945                                 $( this.domPosition.parent ).prepend( this.currentItem );
4946                         }
4947                 }
4948
4949                 return this;
4950
4951         },
4952
4953         serialize: function( o ) {
4954
4955                 var items = this._getItemsAsjQuery( o && o.connected ),
4956                         str = [];
4957                 o = o || {};
4958
4959                 $( items ).each( function() {
4960                         var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" )
4961                                 .match( o.expression || ( /(.+)[\-=_](.+)/ ) );
4962                         if ( res ) {
4963                                 str.push(
4964                                         ( o.key || res[ 1 ] + "[]" ) +
4965                                         "=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );
4966                         }
4967                 } );
4968
4969                 if ( !str.length && o.key ) {
4970                         str.push( o.key + "=" );
4971                 }
4972
4973                 return str.join( "&" );
4974
4975         },
4976
4977         toArray: function( o ) {
4978
4979                 var items = this._getItemsAsjQuery( o && o.connected ),
4980                         ret = [];
4981
4982                 o = o || {};
4983
4984                 items.each( function() {
4985                         ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" );
4986                 } );
4987                 return ret;
4988
4989         },
4990
4991         /* Be careful with the following core functions */
4992         _intersectsWith: function( item ) {
4993
4994                 var x1 = this.positionAbs.left,
4995                         x2 = x1 + this.helperProportions.width,
4996                         y1 = this.positionAbs.top,
4997                         y2 = y1 + this.helperProportions.height,
4998                         l = item.left,
4999                         r = l + item.width,
5000                         t = item.top,
5001                         b = t + item.height,
5002                         dyClick = this.offset.click.top,
5003                         dxClick = this.offset.click.left,
5004                         isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t &&
5005                                 ( y1 + dyClick ) < b ),
5006                         isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l &&
5007                                 ( x1 + dxClick ) < r ),
5008                         isOverElement = isOverElementHeight && isOverElementWidth;
5009
5010                 if ( this.options.tolerance === "pointer" ||
5011                         this.options.forcePointerForContainers ||
5012                         ( this.options.tolerance !== "pointer" &&
5013                                 this.helperProportions[ this.floating ? "width" : "height" ] >
5014                                 item[ this.floating ? "width" : "height" ] )
5015                 ) {
5016                         return isOverElement;
5017                 } else {
5018
5019                         return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half
5020                                 x2 - ( this.helperProportions.width / 2 ) < r && // Left Half
5021                                 t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half
5022                                 y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half
5023
5024                 }
5025         },
5026
5027         _intersectsWithPointer: function( item ) {
5028                 var verticalDirection, horizontalDirection,
5029                         isOverElementHeight = ( this.options.axis === "x" ) ||
5030                                 this._isOverAxis(
5031                                         this.positionAbs.top + this.offset.click.top, item.top, item.height ),
5032                         isOverElementWidth = ( this.options.axis === "y" ) ||
5033                                 this._isOverAxis(
5034                                         this.positionAbs.left + this.offset.click.left, item.left, item.width ),
5035                         isOverElement = isOverElementHeight && isOverElementWidth;
5036
5037                 if ( !isOverElement ) {
5038                         return false;
5039                 }
5040
5041                 verticalDirection = this._getDragVerticalDirection();
5042                 horizontalDirection = this._getDragHorizontalDirection();
5043
5044                 return this.floating ?
5045                         ( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 )
5046                         : ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) );
5047
5048         },
5049
5050         _intersectsWithSides: function( item ) {
5051
5052                 var isOverBottomHalf = this._isOverAxis( this.positionAbs.top +
5053                                 this.offset.click.top, item.top + ( item.height / 2 ), item.height ),
5054                         isOverRightHalf = this._isOverAxis( this.positionAbs.left +
5055                                 this.offset.click.left, item.left + ( item.width / 2 ), item.width ),
5056                         verticalDirection = this._getDragVerticalDirection(),
5057                         horizontalDirection = this._getDragHorizontalDirection();
5058
5059                 if ( this.floating && horizontalDirection ) {
5060                         return ( ( horizontalDirection === "right" && isOverRightHalf ) ||
5061                                 ( horizontalDirection === "left" && !isOverRightHalf ) );
5062                 } else {
5063                         return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) ||
5064                                 ( verticalDirection === "up" && !isOverBottomHalf ) );
5065                 }
5066
5067         },
5068
5069         _getDragVerticalDirection: function() {
5070                 var delta = this.positionAbs.top - this.lastPositionAbs.top;
5071                 return delta !== 0 && ( delta > 0 ? "down" : "up" );
5072         },
5073
5074         _getDragHorizontalDirection: function() {
5075                 var delta = this.positionAbs.left - this.lastPositionAbs.left;
5076                 return delta !== 0 && ( delta > 0 ? "right" : "left" );
5077         },
5078
5079         refresh: function( event ) {
5080                 this._refreshItems( event );
5081                 this._setHandleClassName();
5082                 this.refreshPositions();
5083                 return this;
5084         },
5085
5086         _connectWith: function() {
5087                 var options = this.options;
5088                 return options.connectWith.constructor === String ?
5089                         [ options.connectWith ] :
5090                         options.connectWith;
5091         },
5092
5093         _getItemsAsjQuery: function( connected ) {
5094
5095                 var i, j, cur, inst,
5096                         items = [],
5097                         queries = [],
5098                         connectWith = this._connectWith();
5099
5100                 if ( connectWith && connected ) {
5101                         for ( i = connectWith.length - 1; i >= 0; i-- ) {
5102                                 cur = $( connectWith[ i ], this.document[ 0 ] );
5103                                 for ( j = cur.length - 1; j >= 0; j-- ) {
5104                                         inst = $.data( cur[ j ], this.widgetFullName );
5105                                         if ( inst && inst !== this && !inst.options.disabled ) {
5106                                                 queries.push( [ $.isFunction( inst.options.items ) ?
5107                                                         inst.options.items.call( inst.element ) :
5108                                                         $( inst.options.items, inst.element )
5109                                                                 .not( ".ui-sortable-helper" )
5110                                                                 .not( ".ui-sortable-placeholder" ), inst ] );
5111                                         }
5112                                 }
5113                         }
5114                 }
5115
5116                 queries.push( [ $.isFunction( this.options.items ) ?
5117                         this.options.items
5118                                 .call( this.element, null, { options: this.options, item: this.currentItem } ) :
5119                         $( this.options.items, this.element )
5120                                 .not( ".ui-sortable-helper" )
5121                                 .not( ".ui-sortable-placeholder" ), this ] );
5122
5123                 function addItems() {
5124                         items.push( this );
5125                 }
5126                 for ( i = queries.length - 1; i >= 0; i-- ) {
5127                         queries[ i ][ 0 ].each( addItems );
5128                 }
5129
5130                 return $( items );
5131
5132         },
5133
5134         _removeCurrentsFromItems: function() {
5135
5136                 var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" );
5137
5138                 this.items = $.grep( this.items, function( item ) {
5139                         for ( var j = 0; j < list.length; j++ ) {
5140                                 if ( list[ j ] === item.item[ 0 ] ) {
5141                                         return false;
5142                                 }
5143                         }
5144                         return true;
5145                 } );
5146
5147         },
5148
5149         _refreshItems: function( event ) {
5150
5151                 this.items = [];
5152                 this.containers = [ this ];
5153
5154                 var i, j, cur, inst, targetData, _queries, item, queriesLength,
5155                         items = this.items,
5156                         queries = [ [ $.isFunction( this.options.items ) ?
5157                                 this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :
5158                                 $( this.options.items, this.element ), this ] ],
5159                         connectWith = this._connectWith();
5160
5161                 //Shouldn't be run the first time through due to massive slow-down
5162                 if ( connectWith && this.ready ) {
5163                         for ( i = connectWith.length - 1; i >= 0; i-- ) {
5164                                 cur = $( connectWith[ i ], this.document[ 0 ] );
5165                                 for ( j = cur.length - 1; j >= 0; j-- ) {
5166                                         inst = $.data( cur[ j ], this.widgetFullName );
5167                                         if ( inst && inst !== this && !inst.options.disabled ) {
5168                                                 queries.push( [ $.isFunction( inst.options.items ) ?
5169                                                         inst.options.items
5170                                                                 .call( inst.element[ 0 ], event, { item: this.currentItem } ) :
5171                                                         $( inst.options.items, inst.element ), inst ] );
5172                                                 this.containers.push( inst );
5173                                         }
5174                                 }
5175                         }
5176                 }
5177
5178                 for ( i = queries.length - 1; i >= 0; i-- ) {
5179                         targetData = queries[ i ][ 1 ];
5180                         _queries = queries[ i ][ 0 ];
5181
5182                         for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {
5183                                 item = $( _queries[ j ] );
5184
5185                                 // Data for target checking (mouse manager)
5186                                 item.data( this.widgetName + "-item", targetData );
5187
5188                                 items.push( {
5189                                         item: item,
5190                                         instance: targetData,
5191                                         width: 0, height: 0,
5192                                         left: 0, top: 0
5193                                 } );
5194                         }
5195                 }
5196
5197         },
5198
5199         refreshPositions: function( fast ) {
5200
5201                 // Determine whether items are being displayed horizontally
5202                 this.floating = this.items.length ?
5203                         this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
5204                         false;
5205
5206                 //This has to be redone because due to the item being moved out/into the offsetParent,
5207                 // the offsetParent's position will change
5208                 if ( this.offsetParent && this.helper ) {
5209                         this.offset.parent = this._getParentOffset();
5210                 }
5211
5212                 var i, item, t, p;
5213
5214                 for ( i = this.items.length - 1; i >= 0; i-- ) {
5215                         item = this.items[ i ];
5216
5217                         //We ignore calculating positions of all connected containers when we're not over them
5218                         if ( item.instance !== this.currentContainer && this.currentContainer &&
5219                                         item.item[ 0 ] !== this.currentItem[ 0 ] ) {
5220                                 continue;
5221                         }
5222
5223                         t = this.options.toleranceElement ?
5224                                 $( this.options.toleranceElement, item.item ) :
5225                                 item.item;
5226
5227                         if ( !fast ) {
5228                                 item.width = t.outerWidth();
5229                                 item.height = t.outerHeight();
5230                         }
5231
5232                         p = t.offset();
5233                         item.left = p.left;
5234                         item.top = p.top;
5235                 }
5236
5237                 if ( this.options.custom && this.options.custom.refreshContainers ) {
5238                         this.options.custom.refreshContainers.call( this );
5239                 } else {
5240                         for ( i = this.containers.length - 1; i >= 0; i-- ) {
5241                                 p = this.containers[ i ].element.offset();
5242                                 this.containers[ i ].containerCache.left = p.left;
5243                                 this.containers[ i ].containerCache.top = p.top;
5244                                 this.containers[ i ].containerCache.width =
5245                                         this.containers[ i ].element.outerWidth();
5246                                 this.containers[ i ].containerCache.height =
5247                                         this.containers[ i ].element.outerHeight();
5248                         }
5249                 }
5250
5251                 return this;
5252         },
5253
5254         _createPlaceholder: function( that ) {
5255                 that = that || this;
5256                 var className,
5257                         o = that.options;
5258
5259                 if ( !o.placeholder || o.placeholder.constructor === String ) {
5260                         className = o.placeholder;
5261                         o.placeholder = {
5262                                 element: function() {
5263
5264                                         var nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(),
5265                                                 element = $( "<" + nodeName + ">", that.document[ 0 ] );
5266
5267                                                 that._addClass( element, "ui-sortable-placeholder",
5268                                                                 className || that.currentItem[ 0 ].className )
5269                                                         ._removeClass( element, "ui-sortable-helper" );
5270
5271                                         if ( nodeName === "tbody" ) {
5272                                                 that._createTrPlaceholder(
5273                                                         that.currentItem.find( "tr" ).eq( 0 ),
5274                                                         $( "<tr>", that.document[ 0 ] ).appendTo( element )
5275                                                 );
5276                                         } else if ( nodeName === "tr" ) {
5277                                                 that._createTrPlaceholder( that.currentItem, element );
5278                                         } else if ( nodeName === "img" ) {
5279                                                 element.attr( "src", that.currentItem.attr( "src" ) );
5280                                         }
5281
5282                                         if ( !className ) {
5283                                                 element.css( "visibility", "hidden" );
5284                                         }
5285
5286                                         return element;
5287                                 },
5288                                 update: function( container, p ) {
5289
5290                                         // 1. If a className is set as 'placeholder option, we don't force sizes -
5291                                         // the class is responsible for that
5292                                         // 2. The option 'forcePlaceholderSize can be enabled to force it even if a
5293                                         // class name is specified
5294                                         if ( className && !o.forcePlaceholderSize ) {
5295                                                 return;
5296                                         }
5297
5298                                         //If the element doesn't have a actual height by itself (without styles coming
5299                                         // from a stylesheet), it receives the inline height from the dragged item
5300                                         if ( !p.height() ) {
5301                                                 p.height(
5302                                                         that.currentItem.innerHeight() -
5303                                                         parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) -
5304                                                         parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) );
5305                                         }
5306                                         if ( !p.width() ) {
5307                                                 p.width(
5308                                                         that.currentItem.innerWidth() -
5309                                                         parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) -
5310                                                         parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) );
5311                                         }
5312                                 }
5313                         };
5314                 }
5315
5316                 //Create the placeholder
5317                 that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );
5318
5319                 //Append it after the actual current item
5320                 that.currentItem.after( that.placeholder );
5321
5322                 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
5323                 o.placeholder.update( that, that.placeholder );
5324
5325         },
5326
5327         _createTrPlaceholder: function( sourceTr, targetTr ) {
5328                 var that = this;
5329
5330                 sourceTr.children().each( function() {
5331                         $( "<td>&#160;</td>", that.document[ 0 ] )
5332                                 .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
5333                                 .appendTo( targetTr );
5334                 } );
5335         },
5336
5337         _contactContainers: function( event ) {
5338                 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
5339                         floating, axis,
5340                         innermostContainer = null,
5341                         innermostIndex = null;
5342
5343                 // Get innermost container that intersects with item
5344                 for ( i = this.containers.length - 1; i >= 0; i-- ) {
5345
5346                         // Never consider a container that's located within the item itself
5347                         if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {
5348                                 continue;
5349                         }
5350
5351                         if ( this._intersectsWith( this.containers[ i ].containerCache ) ) {
5352
5353                                 // If we've already found a container and it's more "inner" than this, then continue
5354                                 if ( innermostContainer &&
5355                                                 $.contains(
5356                                                         this.containers[ i ].element[ 0 ],
5357                                                         innermostContainer.element[ 0 ] ) ) {
5358                                         continue;
5359                                 }
5360
5361                                 innermostContainer = this.containers[ i ];
5362                                 innermostIndex = i;
5363
5364                         } else {
5365
5366                                 // container doesn't intersect. trigger "out" event if necessary
5367                                 if ( this.containers[ i ].containerCache.over ) {
5368                                         this.containers[ i ]._trigger( "out", event, this._uiHash( this ) );
5369                                         this.containers[ i ].containerCache.over = 0;
5370                                 }
5371                         }
5372
5373                 }
5374
5375                 // If no intersecting containers found, return
5376                 if ( !innermostContainer ) {
5377                         return;
5378                 }
5379
5380                 // Move the item into the container if it's not there already
5381                 if ( this.containers.length === 1 ) {
5382                         if ( !this.containers[ innermostIndex ].containerCache.over ) {
5383                                 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
5384                                 this.containers[ innermostIndex ].containerCache.over = 1;
5385                         }
5386                 } else {
5387
5388                         // When entering a new container, we will find the item with the least distance and
5389                         // append our item near it
5390                         dist = 10000;
5391                         itemWithLeastDistance = null;
5392                         floating = innermostContainer.floating || this._isFloating( this.currentItem );
5393                         posProperty = floating ? "left" : "top";
5394                         sizeProperty = floating ? "width" : "height";
5395                         axis = floating ? "pageX" : "pageY";
5396
5397                         for ( j = this.items.length - 1; j >= 0; j-- ) {
5398                                 if ( !$.contains(
5399                                                 this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )
5400                                 ) {
5401                                         continue;
5402                                 }
5403                                 if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {
5404                                         continue;
5405                                 }
5406
5407                                 cur = this.items[ j ].item.offset()[ posProperty ];
5408                                 nearBottom = false;
5409                                 if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
5410                                         nearBottom = true;
5411                                 }
5412
5413                                 if ( Math.abs( event[ axis ] - cur ) < dist ) {
5414                                         dist = Math.abs( event[ axis ] - cur );
5415                                         itemWithLeastDistance = this.items[ j ];
5416                                         this.direction = nearBottom ? "up" : "down";
5417                                 }
5418                         }
5419
5420                         //Check if dropOnEmpty is enabled
5421                         if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {
5422                                 return;
5423                         }
5424
5425                         if ( this.currentContainer === this.containers[ innermostIndex ] ) {
5426                                 if ( !this.currentContainer.containerCache.over ) {
5427                                         this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
5428                                         this.currentContainer.containerCache.over = 1;
5429                                 }
5430                                 return;
5431                         }
5432
5433                         itemWithLeastDistance ?
5434                                 this._rearrange( event, itemWithLeastDistance, null, true ) :
5435                                 this._rearrange( event, null, this.containers[ innermostIndex ].element, true );
5436                         this._trigger( "change", event, this._uiHash() );
5437                         this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) );
5438                         this.currentContainer = this.containers[ innermostIndex ];
5439
5440                         //Update the placeholder
5441                         this.options.placeholder.update( this.currentContainer, this.placeholder );
5442
5443                         this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
5444                         this.containers[ innermostIndex ].containerCache.over = 1;
5445                 }
5446
5447         },
5448
5449         _createHelper: function( event ) {
5450
5451                 var o = this.options,
5452                         helper = $.isFunction( o.helper ) ?
5453                                 $( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :
5454                                 ( o.helper === "clone" ? this.currentItem.clone() : this.currentItem );
5455
5456                 //Add the helper to the DOM if that didn't happen already
5457                 if ( !helper.parents( "body" ).length ) {
5458                         $( o.appendTo !== "parent" ?
5459                                 o.appendTo :
5460                                 this.currentItem[ 0 ].parentNode )[ 0 ].appendChild( helper[ 0 ] );
5461                 }
5462
5463                 if ( helper[ 0 ] === this.currentItem[ 0 ] ) {
5464                         this._storedCSS = {
5465                                 width: this.currentItem[ 0 ].style.width,
5466                                 height: this.currentItem[ 0 ].style.height,
5467                                 position: this.currentItem.css( "position" ),
5468                                 top: this.currentItem.css( "top" ),
5469                                 left: this.currentItem.css( "left" )
5470                         };
5471                 }
5472
5473                 if ( !helper[ 0 ].style.width || o.forceHelperSize ) {
5474                         helper.width( this.currentItem.width() );
5475                 }
5476                 if ( !helper[ 0 ].style.height || o.forceHelperSize ) {
5477                         helper.height( this.currentItem.height() );
5478                 }
5479
5480                 return helper;
5481
5482         },
5483
5484         _adjustOffsetFromHelper: function( obj ) {
5485                 if ( typeof obj === "string" ) {
5486                         obj = obj.split( " " );
5487                 }
5488                 if ( $.isArray( obj ) ) {
5489                         obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
5490                 }
5491                 if ( "left" in obj ) {
5492                         this.offset.click.left = obj.left + this.margins.left;
5493                 }
5494                 if ( "right" in obj ) {
5495                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
5496                 }
5497                 if ( "top" in obj ) {
5498                         this.offset.click.top = obj.top + this.margins.top;
5499                 }
5500                 if ( "bottom" in obj ) {
5501                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
5502                 }
5503         },
5504
5505         _getParentOffset: function() {
5506
5507                 //Get the offsetParent and cache its position
5508                 this.offsetParent = this.helper.offsetParent();
5509                 var po = this.offsetParent.offset();
5510
5511                 // This is a special case where we need to modify a offset calculated on start, since the
5512                 // following happened:
5513                 // 1. The position of the helper is absolute, so it's position is calculated based on the
5514                 // next positioned parent
5515                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
5516                 // the document, which means that the scroll is included in the initial calculation of the
5517                 // offset of the parent, and never recalculated upon drag
5518                 if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&
5519                                 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
5520                         po.left += this.scrollParent.scrollLeft();
5521                         po.top += this.scrollParent.scrollTop();
5522                 }
5523
5524                 // This needs to be actually done for all browsers, since pageX/pageY includes this
5525                 // information with an ugly IE fix
5526                 if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ||
5527                                 ( this.offsetParent[ 0 ].tagName &&
5528                                 this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) {
5529                         po = { top: 0, left: 0 };
5530                 }
5531
5532                 return {
5533                         top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
5534                         left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
5535                 };
5536
5537         },
5538
5539         _getRelativeOffset: function() {
5540
5541                 if ( this.cssPosition === "relative" ) {
5542                         var p = this.currentItem.position();
5543                         return {
5544                                 top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
5545                                         this.scrollParent.scrollTop(),
5546                                 left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
5547                                         this.scrollParent.scrollLeft()
5548                         };
5549                 } else {
5550                         return { top: 0, left: 0 };
5551                 }
5552
5553         },
5554
5555         _cacheMargins: function() {
5556                 this.margins = {
5557                         left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ),
5558                         top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 )
5559                 };
5560         },
5561
5562         _cacheHelperProportions: function() {
5563                 this.helperProportions = {
5564                         width: this.helper.outerWidth(),
5565                         height: this.helper.outerHeight()
5566                 };
5567         },
5568
5569         _setContainment: function() {
5570
5571                 var ce, co, over,
5572                         o = this.options;
5573                 if ( o.containment === "parent" ) {
5574                         o.containment = this.helper[ 0 ].parentNode;
5575                 }
5576                 if ( o.containment === "document" || o.containment === "window" ) {
5577                         this.containment = [
5578                                 0 - this.offset.relative.left - this.offset.parent.left,
5579                                 0 - this.offset.relative.top - this.offset.parent.top,
5580                                 o.containment === "document" ?
5581                                         this.document.width() :
5582                                         this.window.width() - this.helperProportions.width - this.margins.left,
5583                                 ( o.containment === "document" ?
5584                                         ( this.document.height() || document.body.parentNode.scrollHeight ) :
5585                                         this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight
5586                                 ) - this.helperProportions.height - this.margins.top
5587                         ];
5588                 }
5589
5590                 if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {
5591                         ce = $( o.containment )[ 0 ];
5592                         co = $( o.containment ).offset();
5593                         over = ( $( ce ).css( "overflow" ) !== "hidden" );
5594
5595                         this.containment = [
5596                                 co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) +
5597                                         ( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left,
5598                                 co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) +
5599                                         ( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top,
5600                                 co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
5601                                         ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) -
5602                                         ( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) -
5603                                         this.helperProportions.width - this.margins.left,
5604                                 co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
5605                                         ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) -
5606                                         ( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) -
5607                                         this.helperProportions.height - this.margins.top
5608                         ];
5609                 }
5610
5611         },
5612
5613         _convertPositionTo: function( d, pos ) {
5614
5615                 if ( !pos ) {
5616                         pos = this.position;
5617                 }
5618                 var mod = d === "absolute" ? 1 : -1,
5619                         scroll = this.cssPosition === "absolute" &&
5620                                 !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
5621                                 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
5622                                         this.offsetParent :
5623                                         this.scrollParent,
5624                         scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
5625
5626                 return {
5627                         top: (
5628
5629                                 // The absolute mouse position
5630                                 pos.top +
5631
5632                                 // Only for relative positioned nodes: Relative offset from element to offset parent
5633                                 this.offset.relative.top * mod +
5634
5635                                 // The offsetParent's offset without borders (offset + border)
5636                                 this.offset.parent.top * mod -
5637                                 ( ( this.cssPosition === "fixed" ?
5638                                         -this.scrollParent.scrollTop() :
5639                                         ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )
5640                         ),
5641                         left: (
5642
5643                                 // The absolute mouse position
5644                                 pos.left +
5645
5646                                 // Only for relative positioned nodes: Relative offset from element to offset parent
5647                                 this.offset.relative.left * mod +
5648
5649                                 // The offsetParent's offset without borders (offset + border)
5650                                 this.offset.parent.left * mod   -
5651                                 ( ( this.cssPosition === "fixed" ?
5652                                         -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
5653                                         scroll.scrollLeft() ) * mod )
5654                         )
5655                 };
5656
5657         },
5658
5659         _generatePosition: function( event ) {
5660
5661                 var top, left,
5662                         o = this.options,
5663                         pageX = event.pageX,
5664                         pageY = event.pageY,
5665                         scroll = this.cssPosition === "absolute" &&
5666                                 !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
5667                                 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
5668                                         this.offsetParent :
5669                                         this.scrollParent,
5670                                 scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
5671
5672                 // This is another very weird special case that only happens for relative elements:
5673                 // 1. If the css position is relative
5674                 // 2. and the scroll parent is the document or similar to the offset parent
5675                 // we have to refresh the relative offset during the scroll so there are no jumps
5676                 if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
5677                                 this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {
5678                         this.offset.relative = this._getRelativeOffset();
5679                 }
5680
5681                 /*
5682                  * - Position constraining -
5683                  * Constrain the position to a mix of grid, containment.
5684                  */
5685
5686                 if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options
5687
5688                         if ( this.containment ) {
5689                                 if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {
5690                                         pageX = this.containment[ 0 ] + this.offset.click.left;
5691                                 }
5692                                 if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {
5693                                         pageY = this.containment[ 1 ] + this.offset.click.top;
5694                                 }
5695                                 if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {
5696                                         pageX = this.containment[ 2 ] + this.offset.click.left;
5697                                 }
5698                                 if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {
5699                                         pageY = this.containment[ 3 ] + this.offset.click.top;
5700                                 }
5701                         }
5702
5703                         if ( o.grid ) {
5704                                 top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /
5705                                         o.grid[ 1 ] ) * o.grid[ 1 ];
5706                                 pageY = this.containment ?
5707                                         ( ( top - this.offset.click.top >= this.containment[ 1 ] &&
5708                                                 top - this.offset.click.top <= this.containment[ 3 ] ) ?
5709                                                         top :
5710                                                         ( ( top - this.offset.click.top >= this.containment[ 1 ] ) ?
5711                                                                 top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) :
5712                                                                 top;
5713
5714                                 left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /
5715                                         o.grid[ 0 ] ) * o.grid[ 0 ];
5716                                 pageX = this.containment ?
5717                                         ( ( left - this.offset.click.left >= this.containment[ 0 ] &&
5718                                                 left - this.offset.click.left <= this.containment[ 2 ] ) ?
5719                                                         left :
5720                                                         ( ( left - this.offset.click.left >= this.containment[ 0 ] ) ?
5721                                                                 left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) :
5722                                                                 left;
5723                         }
5724
5725                 }
5726
5727                 return {
5728                         top: (
5729
5730                                 // The absolute mouse position
5731                                 pageY -
5732
5733                                 // Click offset (relative to the element)
5734                                 this.offset.click.top -
5735
5736                                 // Only for relative positioned nodes: Relative offset from element to offset parent
5737                                 this.offset.relative.top -
5738
5739                                 // The offsetParent's offset without borders (offset + border)
5740                                 this.offset.parent.top +
5741                                 ( ( this.cssPosition === "fixed" ?
5742                                         -this.scrollParent.scrollTop() :
5743                                         ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )
5744                         ),
5745                         left: (
5746
5747                                 // The absolute mouse position
5748                                 pageX -
5749
5750                                 // Click offset (relative to the element)
5751                                 this.offset.click.left -
5752
5753                                 // Only for relative positioned nodes: Relative offset from element to offset parent
5754                                 this.offset.relative.left -
5755
5756                                 // The offsetParent's offset without borders (offset + border)
5757                                 this.offset.parent.left +
5758                                 ( ( this.cssPosition === "fixed" ?
5759                                         -this.scrollParent.scrollLeft() :
5760                                         scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
5761                         )
5762                 };
5763
5764         },
5765
5766         _rearrange: function( event, i, a, hardRefresh ) {
5767
5768                 a ? a[ 0 ].appendChild( this.placeholder[ 0 ] ) :
5769                         i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ],
5770                                 ( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) );
5771
5772                 //Various things done here to improve the performance:
5773                 // 1. we create a setTimeout, that calls refreshPositions
5774                 // 2. on the instance, we have a counter variable, that get's higher after every append
5775                 // 3. on the local scope, we copy the counter variable, and check in the timeout,
5776                 // if it's still the same
5777                 // 4. this lets only the last addition to the timeout stack through
5778                 this.counter = this.counter ? ++this.counter : 1;
5779                 var counter = this.counter;
5780
5781                 this._delay( function() {
5782                         if ( counter === this.counter ) {
5783
5784                                 //Precompute after each DOM insertion, NOT on mousemove
5785                                 this.refreshPositions( !hardRefresh );
5786                         }
5787                 } );
5788
5789         },
5790
5791         _clear: function( event, noPropagation ) {
5792
5793                 this.reverting = false;
5794
5795                 // We delay all events that have to be triggered to after the point where the placeholder
5796                 // has been removed and everything else normalized again
5797                 var i,
5798                         delayedTriggers = [];
5799
5800                 // We first have to update the dom position of the actual currentItem
5801                 // Note: don't do it if the current item is already removed (by a user), or it gets
5802                 // reappended (see #4088)
5803                 if ( !this._noFinalSort && this.currentItem.parent().length ) {
5804                         this.placeholder.before( this.currentItem );
5805                 }
5806                 this._noFinalSort = null;
5807
5808                 if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {
5809                         for ( i in this._storedCSS ) {
5810                                 if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) {
5811                                         this._storedCSS[ i ] = "";
5812                                 }
5813                         }
5814                         this.currentItem.css( this._storedCSS );
5815                         this._removeClass( this.currentItem, "ui-sortable-helper" );
5816                 } else {
5817                         this.currentItem.show();
5818                 }
5819
5820                 if ( this.fromOutside && !noPropagation ) {
5821                         delayedTriggers.push( function( event ) {
5822                                 this._trigger( "receive", event, this._uiHash( this.fromOutside ) );
5823                         } );
5824                 }
5825                 if ( ( this.fromOutside ||
5826                                 this.domPosition.prev !==
5827                                 this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] ||
5828                                 this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {
5829
5830                         // Trigger update callback if the DOM position has changed
5831                         delayedTriggers.push( function( event ) {
5832                                 this._trigger( "update", event, this._uiHash() );
5833                         } );
5834                 }
5835
5836                 // Check if the items Container has Changed and trigger appropriate
5837                 // events.
5838                 if ( this !== this.currentContainer ) {
5839                         if ( !noPropagation ) {
5840                                 delayedTriggers.push( function( event ) {
5841                                         this._trigger( "remove", event, this._uiHash() );
5842                                 } );
5843                                 delayedTriggers.push( ( function( c ) {
5844                                         return function( event ) {
5845                                                 c._trigger( "receive", event, this._uiHash( this ) );
5846                                         };
5847                                 } ).call( this, this.currentContainer ) );
5848                                 delayedTriggers.push( ( function( c ) {
5849                                         return function( event ) {
5850                                                 c._trigger( "update", event, this._uiHash( this ) );
5851                                         };
5852                                 } ).call( this, this.currentContainer ) );
5853                         }
5854                 }
5855
5856                 //Post events to containers
5857                 function delayEvent( type, instance, container ) {
5858                         return function( event ) {
5859                                 container._trigger( type, event, instance._uiHash( instance ) );
5860                         };
5861                 }
5862                 for ( i = this.containers.length - 1; i >= 0; i-- ) {
5863                         if ( !noPropagation ) {
5864                                 delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
5865                         }
5866                         if ( this.containers[ i ].containerCache.over ) {
5867                                 delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
5868                                 this.containers[ i ].containerCache.over = 0;
5869                         }
5870                 }
5871
5872                 //Do what was originally in plugins
5873                 if ( this.storedCursor ) {
5874                         this.document.find( "body" ).css( "cursor", this.storedCursor );
5875                         this.storedStylesheet.remove();
5876                 }
5877                 if ( this._storedOpacity ) {
5878                         this.helper.css( "opacity", this._storedOpacity );
5879                 }
5880                 if ( this._storedZIndex ) {
5881                         this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex );
5882                 }
5883
5884                 this.dragging = false;
5885
5886                 if ( !noPropagation ) {
5887                         this._trigger( "beforeStop", event, this._uiHash() );
5888                 }
5889
5890                 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
5891                 // it unbinds ALL events from the original node!
5892                 this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
5893
5894                 if ( !this.cancelHelperRemoval ) {
5895                         if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
5896                                 this.helper.remove();
5897                         }
5898                         this.helper = null;
5899                 }
5900
5901                 if ( !noPropagation ) {
5902                         for ( i = 0; i < delayedTriggers.length; i++ ) {
5903
5904                                 // Trigger all delayed events
5905                                 delayedTriggers[ i ].call( this, event );
5906                         }
5907                         this._trigger( "stop", event, this._uiHash() );
5908                 }
5909
5910                 this.fromOutside = false;
5911                 return !this.cancelHelperRemoval;
5912
5913         },
5914
5915         _trigger: function() {
5916                 if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {
5917                         this.cancel();
5918                 }
5919         },
5920
5921         _uiHash: function( _inst ) {
5922                 var inst = _inst || this;
5923                 return {
5924                         helper: inst.helper,
5925                         placeholder: inst.placeholder || $( [] ),
5926                         position: inst.position,
5927                         originalPosition: inst.originalPosition,
5928                         offset: inst.positionAbs,
5929                         item: inst.currentItem,
5930                         sender: _inst ? _inst.element : null
5931                 };
5932         }
5933
5934 } );
5935
5936
5937 /*!
5938  * jQuery UI Progressbar 1.12.1
5939  * http://jqueryui.com
5940  *
5941  * Copyright jQuery Foundation and other contributors
5942  * Released under the MIT license.
5943  * http://jquery.org/license
5944  */
5945
5946 //>>label: Progressbar
5947 //>>group: Widgets
5948 // jscs:disable maximumLineLength
5949 //>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators.
5950 // jscs:enable maximumLineLength
5951 //>>docs: http://api.jqueryui.com/progressbar/
5952 //>>demos: http://jqueryui.com/progressbar/
5953 //>>css.structure: ../../themes/base/core.css
5954 //>>css.structure: ../../themes/base/progressbar.css
5955 //>>css.theme: ../../themes/base/theme.css
5956
5957
5958
5959 var widgetsProgressbar = $.widget( "ui.progressbar", {
5960         version: "1.12.1",
5961         options: {
5962                 classes: {
5963                         "ui-progressbar": "ui-corner-all",
5964                         "ui-progressbar-value": "ui-corner-left",
5965                         "ui-progressbar-complete": "ui-corner-right"
5966                 },
5967                 max: 100,
5968                 value: 0,
5969
5970                 change: null,
5971                 complete: null
5972         },
5973
5974         min: 0,
5975
5976         _create: function() {
5977
5978                 // Constrain initial value
5979                 this.oldValue = this.options.value = this._constrainedValue();
5980
5981                 this.element.attr( {
5982
5983                         // Only set static values; aria-valuenow and aria-valuemax are
5984                         // set inside _refreshValue()
5985                         role: "progressbar",
5986                         "aria-valuemin": this.min
5987                 } );
5988                 this._addClass( "ui-progressbar", "ui-widget ui-widget-content" );
5989
5990                 this.valueDiv = $( "<div>" ).appendTo( this.element );
5991                 this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" );
5992                 this._refreshValue();
5993         },
5994
5995         _destroy: function() {
5996                 this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" );
5997
5998                 this.valueDiv.remove();
5999         },
6000
6001         value: function( newValue ) {
6002                 if ( newValue === undefined ) {
6003                         return this.options.value;
6004                 }
6005
6006                 this.options.value = this._constrainedValue( newValue );
6007                 this._refreshValue();
6008         },
6009
6010         _constrainedValue: function( newValue ) {
6011                 if ( newValue === undefined ) {
6012                         newValue = this.options.value;
6013                 }
6014
6015                 this.indeterminate = newValue === false;
6016
6017                 // Sanitize value
6018                 if ( typeof newValue !== "number" ) {
6019                         newValue = 0;
6020                 }
6021
6022                 return this.indeterminate ? false :
6023                         Math.min( this.options.max, Math.max( this.min, newValue ) );
6024         },
6025
6026         _setOptions: function( options ) {
6027
6028                 // Ensure "value" option is set after other values (like max)
6029                 var value = options.value;
6030                 delete options.value;
6031
6032                 this._super( options );
6033
6034                 this.options.value = this._constrainedValue( value );
6035                 this._refreshValue();
6036         },
6037
6038         _setOption: function( key, value ) {
6039                 if ( key === "max" ) {
6040
6041                         // Don't allow a max less than min
6042                         value = Math.max( this.min, value );
6043                 }
6044                 this._super( key, value );
6045         },
6046
6047         _setOptionDisabled: function( value ) {
6048                 this._super( value );
6049
6050                 this.element.attr( "aria-disabled", value );
6051                 this._toggleClass( null, "ui-state-disabled", !!value );
6052         },
6053
6054         _percentage: function() {
6055                 return this.indeterminate ?
6056                         100 :
6057                         100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
6058         },
6059
6060         _refreshValue: function() {
6061                 var value = this.options.value,
6062                         percentage = this._percentage();
6063
6064                 this.valueDiv
6065                         .toggle( this.indeterminate || value > this.min )
6066                         .width( percentage.toFixed( 0 ) + "%" );
6067
6068                 this
6069                         ._toggleClass( this.valueDiv, "ui-progressbar-complete", null,
6070                                 value === this.options.max )
6071                         ._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate );
6072
6073                 if ( this.indeterminate ) {
6074                         this.element.removeAttr( "aria-valuenow" );
6075                         if ( !this.overlayDiv ) {
6076                                 this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv );
6077                                 this._addClass( this.overlayDiv, "ui-progressbar-overlay" );
6078                         }
6079                 } else {
6080                         this.element.attr( {
6081                                 "aria-valuemax": this.options.max,
6082                                 "aria-valuenow": value
6083                         } );
6084                         if ( this.overlayDiv ) {
6085                                 this.overlayDiv.remove();
6086                                 this.overlayDiv = null;
6087                         }
6088                 }
6089
6090                 if ( this.oldValue !== value ) {
6091                         this.oldValue = value;
6092                         this._trigger( "change" );
6093                 }
6094                 if ( value === this.options.max ) {
6095                         this._trigger( "complete" );
6096                 }
6097         }
6098 } );
6099
6100
6101
6102
6103 // Internal use only
6104 var escapeSelector = $.ui.escapeSelector = ( function() {
6105         var selectorEscape = /([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;
6106         return function( selector ) {
6107                 return selector.replace( selectorEscape, "\\$1" );
6108         };
6109 } )();
6110
6111
6112 /*!
6113  * jQuery UI Tabs 1.12.1
6114  * http://jqueryui.com
6115  *
6116  * Copyright jQuery Foundation and other contributors
6117  * Released under the MIT license.
6118  * http://jquery.org/license
6119  */
6120
6121 //>>label: Tabs
6122 //>>group: Widgets
6123 //>>description: Transforms a set of container elements into a tab structure.
6124 //>>docs: http://api.jqueryui.com/tabs/
6125 //>>demos: http://jqueryui.com/tabs/
6126 //>>css.structure: ../../themes/base/core.css
6127 //>>css.structure: ../../themes/base/tabs.css
6128 //>>css.theme: ../../themes/base/theme.css
6129
6130
6131
6132 $.widget( "ui.tabs", {
6133         version: "1.12.1",
6134         delay: 300,
6135         options: {
6136                 active: null,
6137                 classes: {
6138                         "ui-tabs": "ui-corner-all",
6139                         "ui-tabs-nav": "ui-corner-all",
6140                         "ui-tabs-panel": "ui-corner-bottom",
6141                         "ui-tabs-tab": "ui-corner-top"
6142                 },
6143                 collapsible: false,
6144                 event: "click",
6145                 heightStyle: "content",
6146                 hide: null,
6147                 show: null,
6148
6149                 // Callbacks
6150                 activate: null,
6151                 beforeActivate: null,
6152                 beforeLoad: null,
6153                 load: null
6154         },
6155
6156         _isLocal: ( function() {
6157                 var rhash = /#.*$/;
6158
6159                 return function( anchor ) {
6160                         var anchorUrl, locationUrl;
6161
6162                         anchorUrl = anchor.href.replace( rhash, "" );
6163                         locationUrl = location.href.replace( rhash, "" );
6164
6165                         // Decoding may throw an error if the URL isn't UTF-8 (#9518)
6166                         try {
6167                                 anchorUrl = decodeURIComponent( anchorUrl );
6168                         } catch ( error ) {}
6169                         try {
6170                                 locationUrl = decodeURIComponent( locationUrl );
6171                         } catch ( error ) {}
6172
6173                         return anchor.hash.length > 1 && anchorUrl === locationUrl;
6174                 };
6175         } )(),
6176
6177         _create: function() {
6178                 var that = this,
6179                         options = this.options;
6180
6181                 this.running = false;
6182
6183                 this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
6184                 this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
6185
6186                 this._processTabs();
6187                 options.active = this._initialActive();
6188
6189                 // Take disabling tabs via class attribute from HTML
6190                 // into account and update option properly.
6191                 if ( $.isArray( options.disabled ) ) {
6192                         options.disabled = $.unique( options.disabled.concat(
6193                                 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
6194                                         return that.tabs.index( li );
6195                                 } )
6196                         ) ).sort();
6197                 }
6198
6199                 // Check for length avoids error when initializing empty list
6200                 if ( this.options.active !== false && this.anchors.length ) {
6201                         this.active = this._findActive( options.active );
6202                 } else {
6203                         this.active = $();
6204                 }
6205
6206                 this._refresh();
6207
6208                 if ( this.active.length ) {
6209                         this.load( options.active );
6210                 }
6211         },
6212
6213         _initialActive: function() {
6214                 var active = this.options.active,
6215                         collapsible = this.options.collapsible,
6216                         locationHash = location.hash.substring( 1 );
6217
6218                 if ( active === null ) {
6219
6220                         // check the fragment identifier in the URL
6221                         if ( locationHash ) {
6222                                 this.tabs.each( function( i, tab ) {
6223                                         if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
6224                                                 active = i;
6225                                                 return false;
6226                                         }
6227                                 } );
6228                         }
6229
6230                         // Check for a tab marked active via a class
6231                         if ( active === null ) {
6232                                 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
6233                         }
6234
6235                         // No active tab, set to false
6236                         if ( active === null || active === -1 ) {
6237                                 active = this.tabs.length ? 0 : false;
6238                         }
6239                 }
6240
6241                 // Handle numbers: negative, out of range
6242                 if ( active !== false ) {
6243                         active = this.tabs.index( this.tabs.eq( active ) );
6244                         if ( active === -1 ) {
6245                                 active = collapsible ? false : 0;
6246                         }
6247                 }
6248
6249                 // Don't allow collapsible: false and active: false
6250                 if ( !collapsible && active === false && this.anchors.length ) {
6251                         active = 0;
6252                 }
6253
6254                 return active;
6255         },
6256
6257         _getCreateEventData: function() {
6258                 return {
6259                         tab: this.active,
6260                         panel: !this.active.length ? $() : this._getPanelForTab( this.active )
6261                 };
6262         },
6263
6264         _tabKeydown: function( event ) {
6265                 var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ),
6266                         selectedIndex = this.tabs.index( focusedTab ),
6267                         goingForward = true;
6268
6269                 if ( this._handlePageNav( event ) ) {
6270                         return;
6271                 }
6272
6273                 switch ( event.keyCode ) {
6274                 case $.ui.keyCode.RIGHT:
6275                 case $.ui.keyCode.DOWN:
6276                         selectedIndex++;
6277                         break;
6278                 case $.ui.keyCode.UP:
6279                 case $.ui.keyCode.LEFT:
6280                         goingForward = false;
6281                         selectedIndex--;
6282                         break;
6283                 case $.ui.keyCode.END:
6284                         selectedIndex = this.anchors.length - 1;
6285                         break;
6286                 case $.ui.keyCode.HOME:
6287                         selectedIndex = 0;
6288                         break;
6289                 case $.ui.keyCode.SPACE:
6290
6291                         // Activate only, no collapsing
6292                         event.preventDefault();
6293                         clearTimeout( this.activating );
6294                         this._activate( selectedIndex );
6295                         return;
6296                 case $.ui.keyCode.ENTER:
6297
6298                         // Toggle (cancel delayed activation, allow collapsing)
6299                         event.preventDefault();
6300                         clearTimeout( this.activating );
6301
6302                         // Determine if we should collapse or activate
6303                         this._activate( selectedIndex === this.options.active ? false : selectedIndex );
6304                         return;
6305                 default:
6306                         return;
6307                 }
6308
6309                 // Focus the appropriate tab, based on which key was pressed
6310                 event.preventDefault();
6311                 clearTimeout( this.activating );
6312                 selectedIndex = this._focusNextTab( selectedIndex, goingForward );
6313
6314                 // Navigating with control/command key will prevent automatic activation
6315                 if ( !event.ctrlKey && !event.metaKey ) {
6316
6317                         // Update aria-selected immediately so that AT think the tab is already selected.
6318                         // Otherwise AT may confuse the user by stating that they need to activate the tab,
6319                         // but the tab will already be activated by the time the announcement finishes.
6320                         focusedTab.attr( "aria-selected", "false" );
6321                         this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
6322
6323                         this.activating = this._delay( function() {
6324                                 this.option( "active", selectedIndex );
6325                         }, this.delay );
6326                 }
6327         },
6328
6329         _panelKeydown: function( event ) {
6330                 if ( this._handlePageNav( event ) ) {
6331                         return;
6332                 }
6333
6334                 // Ctrl+up moves focus to the current tab
6335                 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
6336                         event.preventDefault();
6337                         this.active.trigger( "focus" );
6338                 }
6339         },
6340
6341         // Alt+page up/down moves focus to the previous/next tab (and activates)
6342         _handlePageNav: function( event ) {
6343                 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
6344                         this._activate( this._focusNextTab( this.options.active - 1, false ) );
6345                         return true;
6346                 }
6347                 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
6348                         this._activate( this._focusNextTab( this.options.active + 1, true ) );
6349                         return true;
6350                 }
6351         },
6352
6353         _findNextTab: function( index, goingForward ) {
6354                 var lastTabIndex = this.tabs.length - 1;
6355
6356                 function constrain() {
6357                         if ( index > lastTabIndex ) {
6358                                 index = 0;
6359                         }
6360                         if ( index < 0 ) {
6361                                 index = lastTabIndex;
6362                         }
6363                         return index;
6364                 }
6365
6366                 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
6367                         index = goingForward ? index + 1 : index - 1;
6368                 }
6369
6370                 return index;
6371         },
6372
6373         _focusNextTab: function( index, goingForward ) {
6374                 index = this._findNextTab( index, goingForward );
6375                 this.tabs.eq( index ).trigger( "focus" );
6376                 return index;
6377         },
6378
6379         _setOption: function( key, value ) {
6380                 if ( key === "active" ) {
6381
6382                         // _activate() will handle invalid values and update this.options
6383                         this._activate( value );
6384                         return;
6385                 }
6386
6387                 this._super( key, value );
6388
6389                 if ( key === "collapsible" ) {
6390                         this._toggleClass( "ui-tabs-collapsible", null, value );
6391
6392                         // Setting collapsible: false while collapsed; open first panel
6393                         if ( !value && this.options.active === false ) {
6394                                 this._activate( 0 );
6395                         }
6396                 }
6397
6398                 if ( key === "event" ) {
6399                         this._setupEvents( value );
6400                 }
6401
6402                 if ( key === "heightStyle" ) {
6403                         this._setupHeightStyle( value );
6404                 }
6405         },
6406
6407         _sanitizeSelector: function( hash ) {
6408                 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
6409         },
6410
6411         refresh: function() {
6412                 var options = this.options,
6413                         lis = this.tablist.children( ":has(a[href])" );
6414
6415                 // Get disabled tabs from class attribute from HTML
6416                 // this will get converted to a boolean if needed in _refresh()
6417                 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
6418                         return lis.index( tab );
6419                 } );
6420
6421                 this._processTabs();
6422
6423                 // Was collapsed or no tabs
6424                 if ( options.active === false || !this.anchors.length ) {
6425                         options.active = false;
6426                         this.active = $();
6427
6428                 // was active, but active tab is gone
6429                 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
6430
6431                         // all remaining tabs are disabled
6432                         if ( this.tabs.length === options.disabled.length ) {
6433                                 options.active = false;
6434                                 this.active = $();
6435
6436                         // activate previous tab
6437                         } else {
6438                                 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
6439                         }
6440
6441                 // was active, active tab still exists
6442                 } else {
6443
6444                         // make sure active index is correct
6445                         options.active = this.tabs.index( this.active );
6446                 }
6447
6448                 this._refresh();
6449         },
6450
6451         _refresh: function() {
6452                 this._setOptionDisabled( this.options.disabled );
6453                 this._setupEvents( this.options.event );
6454                 this._setupHeightStyle( this.options.heightStyle );
6455
6456                 this.tabs.not( this.active ).attr( {
6457                         "aria-selected": "false",
6458                         "aria-expanded": "false",
6459                         tabIndex: -1
6460                 } );
6461                 this.panels.not( this._getPanelForTab( this.active ) )
6462                         .hide()
6463                         .attr( {
6464                                 "aria-hidden": "true"
6465                         } );
6466
6467                 // Make sure one tab is in the tab order
6468                 if ( !this.active.length ) {
6469                         this.tabs.eq( 0 ).attr( "tabIndex", 0 );
6470                 } else {
6471                         this.active
6472                                 .attr( {
6473                                         "aria-selected": "true",
6474                                         "aria-expanded": "true",
6475                                         tabIndex: 0
6476                                 } );
6477                         this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
6478                         this._getPanelForTab( this.active )
6479                                 .show()
6480                                 .attr( {
6481                                         "aria-hidden": "false"
6482                                 } );
6483                 }
6484         },
6485
6486         _processTabs: function() {
6487                 var that = this,
6488                         prevTabs = this.tabs,
6489                         prevAnchors = this.anchors,
6490                         prevPanels = this.panels;
6491
6492                 this.tablist = this._getList().attr( "role", "tablist" );
6493                 this._addClass( this.tablist, "ui-tabs-nav",
6494                         "ui-helper-reset ui-helper-clearfix ui-widget-header" );
6495
6496                 // Prevent users from focusing disabled tabs via click
6497                 this.tablist
6498                         .on( "mousedown" + this.eventNamespace, "> li", function( event ) {
6499                                 if ( $( this ).is( ".ui-state-disabled" ) ) {
6500                                         event.preventDefault();
6501                                 }
6502                         } )
6503
6504                         // Support: IE <9
6505                         // Preventing the default action in mousedown doesn't prevent IE
6506                         // from focusing the element, so if the anchor gets focused, blur.
6507                         // We don't have to worry about focusing the previously focused
6508                         // element since clicking on a non-focusable element should focus
6509                         // the body anyway.
6510                         .on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() {
6511                                 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
6512                                         this.blur();
6513                                 }
6514                         } );
6515
6516                 this.tabs = this.tablist.find( "> li:has(a[href])" )
6517                         .attr( {
6518                                 role: "tab",
6519                                 tabIndex: -1
6520                         } );
6521                 this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" );
6522
6523                 this.anchors = this.tabs.map( function() {
6524                         return $( "a", this )[ 0 ];
6525                 } )
6526                         .attr( {
6527                                 role: "presentation",
6528                                 tabIndex: -1
6529                         } );
6530                 this._addClass( this.anchors, "ui-tabs-anchor" );
6531
6532                 this.panels = $();
6533
6534                 this.anchors.each( function( i, anchor ) {
6535                         var selector, panel, panelId,
6536                                 anchorId = $( anchor ).uniqueId().attr( "id" ),
6537                                 tab = $( anchor ).closest( "li" ),
6538                                 originalAriaControls = tab.attr( "aria-controls" );
6539
6540                         // Inline tab
6541                         if ( that._isLocal( anchor ) ) {
6542                                 selector = anchor.hash;
6543                                 panelId = selector.substring( 1 );
6544                                 panel = that.element.find( that._sanitizeSelector( selector ) );
6545
6546                         // remote tab
6547                         } else {
6548
6549                                 // If the tab doesn't already have aria-controls,
6550                                 // generate an id by using a throw-away element
6551                                 panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
6552                                 selector = "#" + panelId;
6553                                 panel = that.element.find( selector );
6554                                 if ( !panel.length ) {
6555                                         panel = that._createPanel( panelId );
6556                                         panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
6557                                 }
6558                                 panel.attr( "aria-live", "polite" );
6559                         }
6560
6561                         if ( panel.length ) {
6562                                 that.panels = that.panels.add( panel );
6563                         }
6564                         if ( originalAriaControls ) {
6565                                 tab.data( "ui-tabs-aria-controls", originalAriaControls );
6566                         }
6567                         tab.attr( {
6568                                 "aria-controls": panelId,
6569                                 "aria-labelledby": anchorId
6570                         } );
6571                         panel.attr( "aria-labelledby", anchorId );
6572                 } );
6573
6574                 this.panels.attr( "role", "tabpanel" );
6575                 this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
6576
6577                 // Avoid memory leaks (#10056)
6578                 if ( prevTabs ) {
6579                         this._off( prevTabs.not( this.tabs ) );
6580                         this._off( prevAnchors.not( this.anchors ) );
6581                         this._off( prevPanels.not( this.panels ) );
6582                 }
6583         },
6584
6585         // Allow overriding how to find the list for rare usage scenarios (#7715)
6586         _getList: function() {
6587                 return this.tablist || this.element.find( "ol, ul" ).eq( 0 );
6588         },
6589
6590         _createPanel: function( id ) {
6591                 return $( "<div>" )
6592                         .attr( "id", id )
6593                         .data( "ui-tabs-destroy", true );
6594         },
6595
6596         _setOptionDisabled: function( disabled ) {
6597                 var currentItem, li, i;
6598
6599                 if ( $.isArray( disabled ) ) {
6600                         if ( !disabled.length ) {
6601                                 disabled = false;
6602                         } else if ( disabled.length === this.anchors.length ) {
6603                                 disabled = true;
6604                         }
6605                 }
6606
6607                 // Disable tabs
6608                 for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
6609                         currentItem = $( li );
6610                         if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
6611                                 currentItem.attr( "aria-disabled", "true" );
6612                                 this._addClass( currentItem, null, "ui-state-disabled" );
6613                         } else {
6614                                 currentItem.removeAttr( "aria-disabled" );
6615                                 this._removeClass( currentItem, null, "ui-state-disabled" );
6616                         }
6617                 }
6618
6619                 this.options.disabled = disabled;
6620
6621                 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null,
6622                         disabled === true );
6623         },
6624
6625         _setupEvents: function( event ) {
6626                 var events = {};
6627                 if ( event ) {
6628                         $.each( event.split( " " ), function( index, eventName ) {
6629                                 events[ eventName ] = "_eventHandler";
6630                         } );
6631                 }
6632
6633                 this._off( this.anchors.add( this.tabs ).add( this.panels ) );
6634
6635                 // Always prevent the default action, even when disabled
6636                 this._on( true, this.anchors, {
6637                         click: function( event ) {
6638                                 event.preventDefault();
6639                         }
6640                 } );
6641                 this._on( this.anchors, events );
6642                 this._on( this.tabs, { keydown: "_tabKeydown" } );
6643                 this._on( this.panels, { keydown: "_panelKeydown" } );
6644
6645                 this._focusable( this.tabs );
6646                 this._hoverable( this.tabs );
6647         },
6648
6649         _setupHeightStyle: function( heightStyle ) {
6650                 var maxHeight,
6651                         parent = this.element.parent();
6652
6653                 if ( heightStyle === "fill" ) {
6654                         maxHeight = parent.height();
6655                         maxHeight -= this.element.outerHeight() - this.element.height();
6656
6657                         this.element.siblings( ":visible" ).each( function() {
6658                                 var elem = $( this ),
6659                                         position = elem.css( "position" );
6660
6661                                 if ( position === "absolute" || position === "fixed" ) {
6662                                         return;
6663                                 }
6664                                 maxHeight -= elem.outerHeight( true );
6665                         } );
6666
6667                         this.element.children().not( this.panels ).each( function() {
6668                                 maxHeight -= $( this ).outerHeight( true );
6669                         } );
6670
6671                         this.panels.each( function() {
6672                                 $( this ).height( Math.max( 0, maxHeight -
6673                                         $( this ).innerHeight() + $( this ).height() ) );
6674                         } )
6675                                 .css( "overflow", "auto" );
6676                 } else if ( heightStyle === "auto" ) {
6677                         maxHeight = 0;
6678                         this.panels.each( function() {
6679                                 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
6680                         } ).height( maxHeight );
6681                 }
6682         },
6683
6684         _eventHandler: function( event ) {
6685                 var options = this.options,
6686                         active = this.active,
6687                         anchor = $( event.currentTarget ),
6688                         tab = anchor.closest( "li" ),
6689                         clickedIsActive = tab[ 0 ] === active[ 0 ],
6690                         collapsing = clickedIsActive && options.collapsible,
6691                         toShow = collapsing ? $() : this._getPanelForTab( tab ),
6692                         toHide = !active.length ? $() : this._getPanelForTab( active ),
6693                         eventData = {
6694                                 oldTab: active,
6695                                 oldPanel: toHide,
6696                                 newTab: collapsing ? $() : tab,
6697                                 newPanel: toShow
6698                         };
6699
6700                 event.preventDefault();
6701
6702                 if ( tab.hasClass( "ui-state-disabled" ) ||
6703
6704                                 // tab is already loading
6705                                 tab.hasClass( "ui-tabs-loading" ) ||
6706
6707                                 // can't switch durning an animation
6708                                 this.running ||
6709
6710                                 // click on active header, but not collapsible
6711                                 ( clickedIsActive && !options.collapsible ) ||
6712
6713                                 // allow canceling activation
6714                                 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
6715                         return;
6716                 }
6717
6718                 options.active = collapsing ? false : this.tabs.index( tab );
6719
6720                 this.active = clickedIsActive ? $() : tab;
6721                 if ( this.xhr ) {
6722                         this.xhr.abort();
6723                 }
6724
6725                 if ( !toHide.length && !toShow.length ) {
6726                         $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
6727                 }
6728
6729                 if ( toShow.length ) {
6730                         this.load( this.tabs.index( tab ), event );
6731                 }
6732                 this._toggle( event, eventData );
6733         },
6734
6735         // Handles show/hide for selecting tabs
6736         _toggle: function( event, eventData ) {
6737                 var that = this,
6738                         toShow = eventData.newPanel,
6739                         toHide = eventData.oldPanel;
6740
6741                 this.running = true;
6742
6743                 function complete() {
6744                         that.running = false;
6745                         that._trigger( "activate", event, eventData );
6746                 }
6747
6748                 function show() {
6749                         that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
6750
6751                         if ( toShow.length && that.options.show ) {
6752                                 that._show( toShow, that.options.show, complete );
6753                         } else {
6754                                 toShow.show();
6755                                 complete();
6756                         }
6757                 }
6758
6759                 // Start out by hiding, then showing, then completing
6760                 if ( toHide.length && this.options.hide ) {
6761                         this._hide( toHide, this.options.hide, function() {
6762                                 that._removeClass( eventData.oldTab.closest( "li" ),
6763                                         "ui-tabs-active", "ui-state-active" );
6764                                 show();
6765                         } );
6766                 } else {
6767                         this._removeClass( eventData.oldTab.closest( "li" ),
6768                                 "ui-tabs-active", "ui-state-active" );
6769                         toHide.hide();
6770                         show();
6771                 }
6772
6773                 toHide.attr( "aria-hidden", "true" );
6774                 eventData.oldTab.attr( {
6775                         "aria-selected": "false",
6776                         "aria-expanded": "false"
6777                 } );
6778
6779                 // If we're switching tabs, remove the old tab from the tab order.
6780                 // If we're opening from collapsed state, remove the previous tab from the tab order.
6781                 // If we're collapsing, then keep the collapsing tab in the tab order.
6782                 if ( toShow.length && toHide.length ) {
6783                         eventData.oldTab.attr( "tabIndex", -1 );
6784                 } else if ( toShow.length ) {
6785                         this.tabs.filter( function() {
6786                                 return $( this ).attr( "tabIndex" ) === 0;
6787                         } )
6788                                 .attr( "tabIndex", -1 );
6789                 }
6790
6791                 toShow.attr( "aria-hidden", "false" );
6792                 eventData.newTab.attr( {
6793                         "aria-selected": "true",
6794                         "aria-expanded": "true",
6795                         tabIndex: 0
6796                 } );
6797         },
6798
6799         _activate: function( index ) {
6800                 var anchor,
6801                         active = this._findActive( index );
6802
6803                 // Trying to activate the already active panel
6804                 if ( active[ 0 ] === this.active[ 0 ] ) {
6805                         return;
6806                 }
6807
6808                 // Trying to collapse, simulate a click on the current active header
6809                 if ( !active.length ) {
6810                         active = this.active;
6811                 }
6812
6813                 anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
6814                 this._eventHandler( {
6815                         target: anchor,
6816                         currentTarget: anchor,
6817                         preventDefault: $.noop
6818                 } );
6819         },
6820
6821         _findActive: function( index ) {
6822                 return index === false ? $() : this.tabs.eq( index );
6823         },
6824
6825         _getIndex: function( index ) {
6826
6827                 // meta-function to give users option to provide a href string instead of a numerical index.
6828                 if ( typeof index === "string" ) {
6829                         index = this.anchors.index( this.anchors.filter( "[href$='" +
6830                                 $.ui.escapeSelector( index ) + "']" ) );
6831                 }
6832
6833                 return index;
6834         },
6835
6836         _destroy: function() {
6837                 if ( this.xhr ) {
6838                         this.xhr.abort();
6839                 }
6840
6841                 this.tablist
6842                         .removeAttr( "role" )
6843                         .off( this.eventNamespace );
6844
6845                 this.anchors
6846                         .removeAttr( "role tabIndex" )
6847                         .removeUniqueId();
6848
6849                 this.tabs.add( this.panels ).each( function() {
6850                         if ( $.data( this, "ui-tabs-destroy" ) ) {
6851                                 $( this ).remove();
6852                         } else {
6853                                 $( this ).removeAttr( "role tabIndex " +
6854                                         "aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" );
6855                         }
6856                 } );
6857
6858                 this.tabs.each( function() {
6859                         var li = $( this ),
6860                                 prev = li.data( "ui-tabs-aria-controls" );
6861                         if ( prev ) {
6862                                 li
6863                                         .attr( "aria-controls", prev )
6864                                         .removeData( "ui-tabs-aria-controls" );
6865                         } else {
6866                                 li.removeAttr( "aria-controls" );
6867                         }
6868                 } );
6869
6870                 this.panels.show();
6871
6872                 if ( this.options.heightStyle !== "content" ) {
6873                         this.panels.css( "height", "" );
6874                 }
6875         },
6876
6877         enable: function( index ) {
6878                 var disabled = this.options.disabled;
6879                 if ( disabled === false ) {
6880                         return;
6881                 }
6882
6883                 if ( index === undefined ) {
6884                         disabled = false;
6885                 } else {
6886                         index = this._getIndex( index );
6887                         if ( $.isArray( disabled ) ) {
6888                                 disabled = $.map( disabled, function( num ) {
6889                                         return num !== index ? num : null;
6890                                 } );
6891                         } else {
6892                                 disabled = $.map( this.tabs, function( li, num ) {
6893                                         return num !== index ? num : null;
6894                                 } );
6895                         }
6896                 }
6897                 this._setOptionDisabled( disabled );
6898         },
6899
6900         disable: function( index ) {
6901                 var disabled = this.options.disabled;
6902                 if ( disabled === true ) {
6903                         return;
6904                 }
6905
6906                 if ( index === undefined ) {
6907                         disabled = true;
6908                 } else {
6909                         index = this._getIndex( index );
6910                         if ( $.inArray( index, disabled ) !== -1 ) {
6911                                 return;
6912                         }
6913                         if ( $.isArray( disabled ) ) {
6914                                 disabled = $.merge( [ index ], disabled ).sort();
6915                         } else {
6916                                 disabled = [ index ];
6917                         }
6918                 }
6919                 this._setOptionDisabled( disabled );
6920         },
6921
6922         load: function( index, event ) {
6923                 index = this._getIndex( index );
6924                 var that = this,
6925                         tab = this.tabs.eq( index ),
6926                         anchor = tab.find( ".ui-tabs-anchor" ),
6927                         panel = this._getPanelForTab( tab ),
6928                         eventData = {
6929                                 tab: tab,
6930                                 panel: panel
6931                         },
6932                         complete = function( jqXHR, status ) {
6933                                 if ( status === "abort" ) {
6934                                         that.panels.stop( false, true );
6935                                 }
6936
6937                                 that._removeClass( tab, "ui-tabs-loading" );
6938                                 panel.removeAttr( "aria-busy" );
6939
6940                                 if ( jqXHR === that.xhr ) {
6941                                         delete that.xhr;
6942                                 }
6943                         };
6944
6945                 // Not remote
6946                 if ( this._isLocal( anchor[ 0 ] ) ) {
6947                         return;
6948                 }
6949
6950                 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
6951
6952                 // Support: jQuery <1.8
6953                 // jQuery <1.8 returns false if the request is canceled in beforeSend,
6954                 // but as of 1.8, $.ajax() always returns a jqXHR object.
6955                 if ( this.xhr && this.xhr.statusText !== "canceled" ) {
6956                         this._addClass( tab, "ui-tabs-loading" );
6957                         panel.attr( "aria-busy", "true" );
6958
6959                         this.xhr
6960                                 .done( function( response, status, jqXHR ) {
6961
6962                                         // support: jQuery <1.8
6963                                         // http://bugs.jquery.com/ticket/11778
6964                                         setTimeout( function() {
6965                                                 panel.html( response );
6966                                                 that._trigger( "load", event, eventData );
6967
6968                                                 complete( jqXHR, status );
6969                                         }, 1 );
6970                                 } )
6971                                 .fail( function( jqXHR, status ) {
6972
6973                                         // support: jQuery <1.8
6974                                         // http://bugs.jquery.com/ticket/11778
6975                                         setTimeout( function() {
6976                                                 complete( jqXHR, status );
6977                                         }, 1 );
6978                                 } );
6979                 }
6980         },
6981
6982         _ajaxSettings: function( anchor, event, eventData ) {
6983                 var that = this;
6984                 return {
6985
6986                         // Support: IE <11 only
6987                         // Strip any hash that exists to prevent errors with the Ajax request
6988                         url: anchor.attr( "href" ).replace( /#.*$/, "" ),
6989                         beforeSend: function( jqXHR, settings ) {
6990                                 return that._trigger( "beforeLoad", event,
6991                                         $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
6992                         }
6993                 };
6994         },
6995
6996         _getPanelForTab: function( tab ) {
6997                 var id = $( tab ).attr( "aria-controls" );
6998                 return this.element.find( this._sanitizeSelector( "#" + id ) );
6999         }
7000 } );
7001
7002 // DEPRECATED
7003 // TODO: Switch return back to widget declaration at top of file when this is removed
7004 if ( $.uiBackCompat !== false ) {
7005
7006         // Backcompat for ui-tab class (now ui-tabs-tab)
7007         $.widget( "ui.tabs", $.ui.tabs, {
7008                 _processTabs: function() {
7009                         this._superApply( arguments );
7010                         this._addClass( this.tabs, "ui-tab" );
7011                 }
7012         } );
7013 }
7014
7015 var widgetsTabs = $.ui.tabs;
7016
7017
7018
7019
7020 }));