PageSourceSearch

https://www.office-planet.ru/assets/ui/js/libs/jquery.ui.1734003214.js

js office-planet.ru collected 2026-09-28 09:27:00 UTC 183,393 bytes, 6,662 lines download raw bytes

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

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