]> git.0d.be Git - panikweb.git/blob - panikweb_templates/static/js/jquery-ui-1.10.4.custom.js
6ef1b0f27eda497deb8bbff9f89a6c37d2f5474d
[panikweb.git] / panikweb_templates / static / js / jquery-ui-1.10.4.custom.js
1 /*! jQuery UI - v1.10.4 - 2017-01-14
2 * http://jqueryui.com
3 * Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.sortable.js
4 * Copyright jQuery Foundation and other contributors; Licensed MIT */
5
6 (function( $, undefined ) {
7
8 var uuid = 0,
9         runiqueId = /^ui-id-\d+$/;
10
11 // $.ui might exist from components with no dependencies, e.g., $.ui.position
12 $.ui = $.ui || {};
13
14 $.extend( $.ui, {
15         version: "1.10.4",
16
17         keyCode: {
18                 BACKSPACE: 8,
19                 COMMA: 188,
20                 DELETE: 46,
21                 DOWN: 40,
22                 END: 35,
23                 ENTER: 13,
24                 ESCAPE: 27,
25                 HOME: 36,
26                 LEFT: 37,
27                 NUMPAD_ADD: 107,
28                 NUMPAD_DECIMAL: 110,
29                 NUMPAD_DIVIDE: 111,
30                 NUMPAD_ENTER: 108,
31                 NUMPAD_MULTIPLY: 106,
32                 NUMPAD_SUBTRACT: 109,
33                 PAGE_DOWN: 34,
34                 PAGE_UP: 33,
35                 PERIOD: 190,
36                 RIGHT: 39,
37                 SPACE: 32,
38                 TAB: 9,
39                 UP: 38
40         }
41 });
42
43 // plugins
44 $.fn.extend({
45         focus: (function( orig ) {
46                 return function( delay, fn ) {
47                         return typeof delay === "number" ?
48                                 this.each(function() {
49                                         var elem = this;
50                                         setTimeout(function() {
51                                                 $( elem ).focus();
52                                                 if ( fn ) {
53                                                         fn.call( elem );
54                                                 }
55                                         }, delay );
56                                 }) :
57                                 orig.apply( this, arguments );
58                 };
59         })( $.fn.focus ),
60
61         scrollParent: function() {
62                 var scrollParent;
63                 if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
64                         scrollParent = this.parents().filter(function() {
65                                 return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
66                         }).eq(0);
67                 } else {
68                         scrollParent = this.parents().filter(function() {
69                                 return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
70                         }).eq(0);
71                 }
72
73                 return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
74         },
75
76         zIndex: function( zIndex ) {
77                 if ( zIndex !== undefined ) {
78                         return this.css( "zIndex", zIndex );
79                 }
80
81                 if ( this.length ) {
82                         var elem = $( this[ 0 ] ), position, value;
83                         while ( elem.length && elem[ 0 ] !== document ) {
84                                 // Ignore z-index if position is set to a value where z-index is ignored by the browser
85                                 // This makes behavior of this function consistent across browsers
86                                 // WebKit always returns auto if the element is positioned
87                                 position = elem.css( "position" );
88                                 if ( position === "absolute" || position === "relative" || position === "fixed" ) {
89                                         // IE returns 0 when zIndex is not specified
90                                         // other browsers return a string
91                                         // we ignore the case of nested elements with an explicit value of 0
92                                         // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
93                                         value = parseInt( elem.css( "zIndex" ), 10 );
94                                         if ( !isNaN( value ) && value !== 0 ) {
95                                                 return value;
96                                         }
97                                 }
98                                 elem = elem.parent();
99                         }
100                 }
101
102                 return 0;
103         },
104
105         uniqueId: function() {
106                 return this.each(function() {
107                         if ( !this.id ) {
108                                 this.id = "ui-id-" + (++uuid);
109                         }
110                 });
111         },
112
113         removeUniqueId: function() {
114                 return this.each(function() {
115                         if ( runiqueId.test( this.id ) ) {
116                                 $( this ).removeAttr( "id" );
117                         }
118                 });
119         }
120 });
121
122 // selectors
123 function focusable( element, isTabIndexNotNaN ) {
124         var map, mapName, img,
125                 nodeName = element.nodeName.toLowerCase();
126         if ( "area" === nodeName ) {
127                 map = element.parentNode;
128                 mapName = map.name;
129                 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
130                         return false;
131                 }
132                 img = $( "img[usemap=#" + mapName + "]" )[0];
133                 return !!img && visible( img );
134         }
135         return ( /input|select|textarea|button|object/.test( nodeName ) ?
136                 !element.disabled :
137                 "a" === nodeName ?
138                         element.href || isTabIndexNotNaN :
139                         isTabIndexNotNaN) &&
140                 // the element and all of its ancestors must be visible
141                 visible( element );
142 }
143
144 function visible( element ) {
145         return $.expr.filters.visible( element ) &&
146                 !$( element ).parents().addBack().filter(function() {
147                         return $.css( this, "visibility" ) === "hidden";
148                 }).length;
149 }
150
151 $.extend( $.expr[ ":" ], {
152         data: $.expr.createPseudo ?
153                 $.expr.createPseudo(function( dataName ) {
154                         return function( elem ) {
155                                 return !!$.data( elem, dataName );
156                         };
157                 }) :
158                 // support: jQuery <1.8
159                 function( elem, i, match ) {
160                         return !!$.data( elem, match[ 3 ] );
161                 },
162
163         focusable: function( element ) {
164                 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
165         },
166
167         tabbable: function( element ) {
168                 var tabIndex = $.attr( element, "tabindex" ),
169                         isTabIndexNaN = isNaN( tabIndex );
170                 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
171         }
172 });
173
174 // support: jQuery <1.8
175 if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
176         $.each( [ "Width", "Height" ], function( i, name ) {
177                 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
178                         type = name.toLowerCase(),
179                         orig = {
180                                 innerWidth: $.fn.innerWidth,
181                                 innerHeight: $.fn.innerHeight,
182                                 outerWidth: $.fn.outerWidth,
183                                 outerHeight: $.fn.outerHeight
184                         };
185
186                 function reduce( elem, size, border, margin ) {
187                         $.each( side, function() {
188                                 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
189                                 if ( border ) {
190                                         size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
191                                 }
192                                 if ( margin ) {
193                                         size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
194                                 }
195                         });
196                         return size;
197                 }
198
199                 $.fn[ "inner" + name ] = function( size ) {
200                         if ( size === undefined ) {
201                                 return orig[ "inner" + name ].call( this );
202                         }
203
204                         return this.each(function() {
205                                 $( this ).css( type, reduce( this, size ) + "px" );
206                         });
207                 };
208
209                 $.fn[ "outer" + name] = function( size, margin ) {
210                         if ( typeof size !== "number" ) {
211                                 return orig[ "outer" + name ].call( this, size );
212                         }
213
214                         return this.each(function() {
215                                 $( this).css( type, reduce( this, size, true, margin ) + "px" );
216                         });
217                 };
218         });
219 }
220
221 // support: jQuery <1.8
222 if ( !$.fn.addBack ) {
223         $.fn.addBack = function( selector ) {
224                 return this.add( selector == null ?
225                         this.prevObject : this.prevObject.filter( selector )
226                 );
227         };
228 }
229
230 // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
231 if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
232         $.fn.removeData = (function( removeData ) {
233                 return function( key ) {
234                         if ( arguments.length ) {
235                                 return removeData.call( this, $.camelCase( key ) );
236                         } else {
237                                 return removeData.call( this );
238                         }
239                 };
240         })( $.fn.removeData );
241 }
242
243
244
245
246
247 // deprecated
248 $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
249
250 $.support.selectstart = "onselectstart" in document.createElement( "div" );
251 $.fn.extend({
252         disableSelection: function() {
253                 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
254                         ".ui-disableSelection", function( event ) {
255                                 event.preventDefault();
256                         });
257         },
258
259         enableSelection: function() {
260                 return this.unbind( ".ui-disableSelection" );
261         }
262 });
263
264 $.extend( $.ui, {
265         // $.ui.plugin is deprecated. Use $.widget() extensions instead.
266         plugin: {
267                 add: function( module, option, set ) {
268                         var i,
269                                 proto = $.ui[ module ].prototype;
270                         for ( i in set ) {
271                                 proto.plugins[ i ] = proto.plugins[ i ] || [];
272                                 proto.plugins[ i ].push( [ option, set[ i ] ] );
273                         }
274                 },
275                 call: function( instance, name, args ) {
276                         var i,
277                                 set = instance.plugins[ name ];
278                         if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
279                                 return;
280                         }
281
282                         for ( i = 0; i < set.length; i++ ) {
283                                 if ( instance.options[ set[ i ][ 0 ] ] ) {
284                                         set[ i ][ 1 ].apply( instance.element, args );
285                                 }
286                         }
287                 }
288         },
289
290         // only used by resizable
291         hasScroll: function( el, a ) {
292
293                 //If overflow is hidden, the element might have extra content, but the user wants to hide it
294                 if ( $( el ).css( "overflow" ) === "hidden") {
295                         return false;
296                 }
297
298                 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
299                         has = false;
300
301                 if ( el[ scroll ] > 0 ) {
302                         return true;
303                 }
304
305                 // TODO: determine which cases actually cause this to happen
306                 // if the element doesn't have the scroll set, see if it's possible to
307                 // set the scroll
308                 el[ scroll ] = 1;
309                 has = ( el[ scroll ] > 0 );
310                 el[ scroll ] = 0;
311                 return has;
312         }
313 });
314
315 })( jQuery );
316 (function( $, undefined ) {
317
318 var uuid = 0,
319         slice = Array.prototype.slice,
320         _cleanData = $.cleanData;
321 $.cleanData = function( elems ) {
322         for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
323                 try {
324                         $( elem ).triggerHandler( "remove" );
325                 // http://bugs.jquery.com/ticket/8235
326                 } catch( e ) {}
327         }
328         _cleanData( elems );
329 };
330
331 $.widget = function( name, base, prototype ) {
332         var fullName, existingConstructor, constructor, basePrototype,
333                 // proxiedPrototype allows the provided prototype to remain unmodified
334                 // so that it can be used as a mixin for multiple widgets (#8876)
335                 proxiedPrototype = {},
336                 namespace = name.split( "." )[ 0 ];
337
338         name = name.split( "." )[ 1 ];
339         fullName = namespace + "-" + name;
340
341         if ( !prototype ) {
342                 prototype = base;
343                 base = $.Widget;
344         }
345
346         // create selector for plugin
347         $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
348                 return !!$.data( elem, fullName );
349         };
350
351         $[ namespace ] = $[ namespace ] || {};
352         existingConstructor = $[ namespace ][ name ];
353         constructor = $[ namespace ][ name ] = function( options, element ) {
354                 // allow instantiation without "new" keyword
355                 if ( !this._createWidget ) {
356                         return new constructor( options, element );
357                 }
358
359                 // allow instantiation without initializing for simple inheritance
360                 // must use "new" keyword (the code above always passes args)
361                 if ( arguments.length ) {
362                         this._createWidget( options, element );
363                 }
364         };
365         // extend with the existing constructor to carry over any static properties
366         $.extend( constructor, existingConstructor, {
367                 version: prototype.version,
368                 // copy the object used to create the prototype in case we need to
369                 // redefine the widget later
370                 _proto: $.extend( {}, prototype ),
371                 // track widgets that inherit from this widget in case this widget is
372                 // redefined after a widget inherits from it
373                 _childConstructors: []
374         });
375
376         basePrototype = new base();
377         // we need to make the options hash a property directly on the new instance
378         // otherwise we'll modify the options hash on the prototype that we're
379         // inheriting from
380         basePrototype.options = $.widget.extend( {}, basePrototype.options );
381         $.each( prototype, function( prop, value ) {
382                 if ( !$.isFunction( value ) ) {
383                         proxiedPrototype[ prop ] = value;
384                         return;
385                 }
386                 proxiedPrototype[ prop ] = (function() {
387                         var _super = function() {
388                                         return base.prototype[ prop ].apply( this, arguments );
389                                 },
390                                 _superApply = function( args ) {
391                                         return base.prototype[ prop ].apply( this, args );
392                                 };
393                         return function() {
394                                 var __super = this._super,
395                                         __superApply = this._superApply,
396                                         returnValue;
397
398                                 this._super = _super;
399                                 this._superApply = _superApply;
400
401                                 returnValue = value.apply( this, arguments );
402
403                                 this._super = __super;
404                                 this._superApply = __superApply;
405
406                                 return returnValue;
407                         };
408                 })();
409         });
410         constructor.prototype = $.widget.extend( basePrototype, {
411                 // TODO: remove support for widgetEventPrefix
412                 // always use the name + a colon as the prefix, e.g., draggable:start
413                 // don't prefix for widgets that aren't DOM-based
414                 widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
415         }, proxiedPrototype, {
416                 constructor: constructor,
417                 namespace: namespace,
418                 widgetName: name,
419                 widgetFullName: fullName
420         });
421
422         // If this widget is being redefined then we need to find all widgets that
423         // are inheriting from it and redefine all of them so that they inherit from
424         // the new version of this widget. We're essentially trying to replace one
425         // level in the prototype chain.
426         if ( existingConstructor ) {
427                 $.each( existingConstructor._childConstructors, function( i, child ) {
428                         var childPrototype = child.prototype;
429
430                         // redefine the child widget using the same prototype that was
431                         // originally used, but inherit from the new version of the base
432                         $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
433                 });
434                 // remove the list of existing child constructors from the old constructor
435                 // so the old child constructors can be garbage collected
436                 delete existingConstructor._childConstructors;
437         } else {
438                 base._childConstructors.push( constructor );
439         }
440
441         $.widget.bridge( name, constructor );
442 };
443
444 $.widget.extend = function( target ) {
445         var input = slice.call( arguments, 1 ),
446                 inputIndex = 0,
447                 inputLength = input.length,
448                 key,
449                 value;
450         for ( ; inputIndex < inputLength; inputIndex++ ) {
451                 for ( key in input[ inputIndex ] ) {
452                         value = input[ inputIndex ][ key ];
453                         if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
454                                 // Clone objects
455                                 if ( $.isPlainObject( value ) ) {
456                                         target[ key ] = $.isPlainObject( target[ key ] ) ?
457                                                 $.widget.extend( {}, target[ key ], value ) :
458                                                 // Don't extend strings, arrays, etc. with objects
459                                                 $.widget.extend( {}, value );
460                                 // Copy everything else by reference
461                                 } else {
462                                         target[ key ] = value;
463                                 }
464                         }
465                 }
466         }
467         return target;
468 };
469
470 $.widget.bridge = function( name, object ) {
471         var fullName = object.prototype.widgetFullName || name;
472         $.fn[ name ] = function( options ) {
473                 var isMethodCall = typeof options === "string",
474                         args = slice.call( arguments, 1 ),
475                         returnValue = this;
476
477                 // allow multiple hashes to be passed on init
478                 options = !isMethodCall && args.length ?
479                         $.widget.extend.apply( null, [ options ].concat(args) ) :
480                         options;
481
482                 if ( isMethodCall ) {
483                         this.each(function() {
484                                 var methodValue,
485                                         instance = $.data( this, fullName );
486                                 if ( !instance ) {
487                                         return $.error( "cannot call methods on " + name + " prior to initialization; " +
488                                                 "attempted to call method '" + options + "'" );
489                                 }
490                                 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
491                                         return $.error( "no such method '" + options + "' for " + name + " widget instance" );
492                                 }
493                                 methodValue = instance[ options ].apply( instance, args );
494                                 if ( methodValue !== instance && methodValue !== undefined ) {
495                                         returnValue = methodValue && methodValue.jquery ?
496                                                 returnValue.pushStack( methodValue.get() ) :
497                                                 methodValue;
498                                         return false;
499                                 }
500                         });
501                 } else {
502                         this.each(function() {
503                                 var instance = $.data( this, fullName );
504                                 if ( instance ) {
505                                         instance.option( options || {} )._init();
506                                 } else {
507                                         $.data( this, fullName, new object( options, this ) );
508                                 }
509                         });
510                 }
511
512                 return returnValue;
513         };
514 };
515
516 $.Widget = function( /* options, element */ ) {};
517 $.Widget._childConstructors = [];
518
519 $.Widget.prototype = {
520         widgetName: "widget",
521         widgetEventPrefix: "",
522         defaultElement: "<div>",
523         options: {
524                 disabled: false,
525
526                 // callbacks
527                 create: null
528         },
529         _createWidget: function( options, element ) {
530                 element = $( element || this.defaultElement || this )[ 0 ];
531                 this.element = $( element );
532                 this.uuid = uuid++;
533                 this.eventNamespace = "." + this.widgetName + this.uuid;
534                 this.options = $.widget.extend( {},
535                         this.options,
536                         this._getCreateOptions(),
537                         options );
538
539                 this.bindings = $();
540                 this.hoverable = $();
541                 this.focusable = $();
542
543                 if ( element !== this ) {
544                         $.data( element, this.widgetFullName, this );
545                         this._on( true, this.element, {
546                                 remove: function( event ) {
547                                         if ( event.target === element ) {
548                                                 this.destroy();
549                                         }
550                                 }
551                         });
552                         this.document = $( element.style ?
553                                 // element within the document
554                                 element.ownerDocument :
555                                 // element is window or document
556                                 element.document || element );
557                         this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
558                 }
559
560                 this._create();
561                 this._trigger( "create", null, this._getCreateEventData() );
562                 this._init();
563         },
564         _getCreateOptions: $.noop,
565         _getCreateEventData: $.noop,
566         _create: $.noop,
567         _init: $.noop,
568
569         destroy: function() {
570                 this._destroy();
571                 // we can probably remove the unbind calls in 2.0
572                 // all event bindings should go through this._on()
573                 this.element
574                         .unbind( this.eventNamespace )
575                         // 1.9 BC for #7810
576                         // TODO remove dual storage
577                         .removeData( this.widgetName )
578                         .removeData( this.widgetFullName )
579                         // support: jquery <1.6.3
580                         // http://bugs.jquery.com/ticket/9413
581                         .removeData( $.camelCase( this.widgetFullName ) );
582                 this.widget()
583                         .unbind( this.eventNamespace )
584                         .removeAttr( "aria-disabled" )
585                         .removeClass(
586                                 this.widgetFullName + "-disabled " +
587                                 "ui-state-disabled" );
588
589                 // clean up events and states
590                 this.bindings.unbind( this.eventNamespace );
591                 this.hoverable.removeClass( "ui-state-hover" );
592                 this.focusable.removeClass( "ui-state-focus" );
593         },
594         _destroy: $.noop,
595
596         widget: function() {
597                 return this.element;
598         },
599
600         option: function( key, value ) {
601                 var options = key,
602                         parts,
603                         curOption,
604                         i;
605
606                 if ( arguments.length === 0 ) {
607                         // don't return a reference to the internal hash
608                         return $.widget.extend( {}, this.options );
609                 }
610
611                 if ( typeof key === "string" ) {
612                         // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
613                         options = {};
614                         parts = key.split( "." );
615                         key = parts.shift();
616                         if ( parts.length ) {
617                                 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
618                                 for ( i = 0; i < parts.length - 1; i++ ) {
619                                         curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
620                                         curOption = curOption[ parts[ i ] ];
621                                 }
622                                 key = parts.pop();
623                                 if ( arguments.length === 1 ) {
624                                         return curOption[ key ] === undefined ? null : curOption[ key ];
625                                 }
626                                 curOption[ key ] = value;
627                         } else {
628                                 if ( arguments.length === 1 ) {
629                                         return this.options[ key ] === undefined ? null : this.options[ key ];
630                                 }
631                                 options[ key ] = value;
632                         }
633                 }
634
635                 this._setOptions( options );
636
637                 return this;
638         },
639         _setOptions: function( options ) {
640                 var key;
641
642                 for ( key in options ) {
643                         this._setOption( key, options[ key ] );
644                 }
645
646                 return this;
647         },
648         _setOption: function( key, value ) {
649                 this.options[ key ] = value;
650
651                 if ( key === "disabled" ) {
652                         this.widget()
653                                 .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
654                                 .attr( "aria-disabled", value );
655                         this.hoverable.removeClass( "ui-state-hover" );
656                         this.focusable.removeClass( "ui-state-focus" );
657                 }
658
659                 return this;
660         },
661
662         enable: function() {
663                 return this._setOption( "disabled", false );
664         },
665         disable: function() {
666                 return this._setOption( "disabled", true );
667         },
668
669         _on: function( suppressDisabledCheck, element, handlers ) {
670                 var delegateElement,
671                         instance = this;
672
673                 // no suppressDisabledCheck flag, shuffle arguments
674                 if ( typeof suppressDisabledCheck !== "boolean" ) {
675                         handlers = element;
676                         element = suppressDisabledCheck;
677                         suppressDisabledCheck = false;
678                 }
679
680                 // no element argument, shuffle and use this.element
681                 if ( !handlers ) {
682                         handlers = element;
683                         element = this.element;
684                         delegateElement = this.widget();
685                 } else {
686                         // accept selectors, DOM elements
687                         element = delegateElement = $( element );
688                         this.bindings = this.bindings.add( element );
689                 }
690
691                 $.each( handlers, function( event, handler ) {
692                         function handlerProxy() {
693                                 // allow widgets to customize the disabled handling
694                                 // - disabled as an array instead of boolean
695                                 // - disabled class as method for disabling individual parts
696                                 if ( !suppressDisabledCheck &&
697                                                 ( instance.options.disabled === true ||
698                                                         $( this ).hasClass( "ui-state-disabled" ) ) ) {
699                                         return;
700                                 }
701                                 return ( typeof handler === "string" ? instance[ handler ] : handler )
702                                         .apply( instance, arguments );
703                         }
704
705                         // copy the guid so direct unbinding works
706                         if ( typeof handler !== "string" ) {
707                                 handlerProxy.guid = handler.guid =
708                                         handler.guid || handlerProxy.guid || $.guid++;
709                         }
710
711                         var match = event.match( /^(\w+)\s*(.*)$/ ),
712                                 eventName = match[1] + instance.eventNamespace,
713                                 selector = match[2];
714                         if ( selector ) {
715                                 delegateElement.delegate( selector, eventName, handlerProxy );
716                         } else {
717                                 element.bind( eventName, handlerProxy );
718                         }
719                 });
720         },
721
722         _off: function( element, eventName ) {
723                 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
724                 element.unbind( eventName ).undelegate( eventName );
725         },
726
727         _delay: function( handler, delay ) {
728                 function handlerProxy() {
729                         return ( typeof handler === "string" ? instance[ handler ] : handler )
730                                 .apply( instance, arguments );
731                 }
732                 var instance = this;
733                 return setTimeout( handlerProxy, delay || 0 );
734         },
735
736         _hoverable: function( element ) {
737                 this.hoverable = this.hoverable.add( element );
738                 this._on( element, {
739                         mouseenter: function( event ) {
740                                 $( event.currentTarget ).addClass( "ui-state-hover" );
741                         },
742                         mouseleave: function( event ) {
743                                 $( event.currentTarget ).removeClass( "ui-state-hover" );
744                         }
745                 });
746         },
747
748         _focusable: function( element ) {
749                 this.focusable = this.focusable.add( element );
750                 this._on( element, {
751                         focusin: function( event ) {
752                                 $( event.currentTarget ).addClass( "ui-state-focus" );
753                         },
754                         focusout: function( event ) {
755                                 $( event.currentTarget ).removeClass( "ui-state-focus" );
756                         }
757                 });
758         },
759
760         _trigger: function( type, event, data ) {
761                 var prop, orig,
762                         callback = this.options[ type ];
763
764                 data = data || {};
765                 event = $.Event( event );
766                 event.type = ( type === this.widgetEventPrefix ?
767                         type :
768                         this.widgetEventPrefix + type ).toLowerCase();
769                 // the original event may come from any element
770                 // so we need to reset the target on the new event
771                 event.target = this.element[ 0 ];
772
773                 // copy original event properties over to the new event
774                 orig = event.originalEvent;
775                 if ( orig ) {
776                         for ( prop in orig ) {
777                                 if ( !( prop in event ) ) {
778                                         event[ prop ] = orig[ prop ];
779                                 }
780                         }
781                 }
782
783                 this.element.trigger( event, data );
784                 return !( $.isFunction( callback ) &&
785                         callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
786                         event.isDefaultPrevented() );
787         }
788 };
789
790 $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
791         $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
792                 if ( typeof options === "string" ) {
793                         options = { effect: options };
794                 }
795                 var hasOptions,
796                         effectName = !options ?
797                                 method :
798                                 options === true || typeof options === "number" ?
799                                         defaultEffect :
800                                         options.effect || defaultEffect;
801                 options = options || {};
802                 if ( typeof options === "number" ) {
803                         options = { duration: options };
804                 }
805                 hasOptions = !$.isEmptyObject( options );
806                 options.complete = callback;
807                 if ( options.delay ) {
808                         element.delay( options.delay );
809                 }
810                 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
811                         element[ method ]( options );
812                 } else if ( effectName !== method && element[ effectName ] ) {
813                         element[ effectName ]( options.duration, options.easing, callback );
814                 } else {
815                         element.queue(function( next ) {
816                                 $( this )[ method ]();
817                                 if ( callback ) {
818                                         callback.call( element[ 0 ] );
819                                 }
820                                 next();
821                         });
822                 }
823         };
824 });
825
826 })( jQuery );
827 (function( $, undefined ) {
828
829 var mouseHandled = false;
830 $( document ).mouseup( function() {
831         mouseHandled = false;
832 });
833
834 $.widget("ui.mouse", {
835         version: "1.10.4",
836         options: {
837                 cancel: "input,textarea,button,select,option",
838                 distance: 1,
839                 delay: 0
840         },
841         _mouseInit: function() {
842                 var that = this;
843
844                 this.element
845                         .bind("mousedown."+this.widgetName, function(event) {
846                                 return that._mouseDown(event);
847                         })
848                         .bind("click."+this.widgetName, function(event) {
849                                 if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
850                                         $.removeData(event.target, that.widgetName + ".preventClickEvent");
851                                         event.stopImmediatePropagation();
852                                         return false;
853                                 }
854                         });
855
856                 this.started = false;
857         },
858
859         // TODO: make sure destroying one instance of mouse doesn't mess with
860         // other instances of mouse
861         _mouseDestroy: function() {
862                 this.element.unbind("."+this.widgetName);
863                 if ( this._mouseMoveDelegate ) {
864                         $(document)
865                                 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
866                                 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
867                 }
868         },
869
870         _mouseDown: function(event) {
871                 // don't let more than one widget handle mouseStart
872                 if( mouseHandled ) { return; }
873
874                 // we may have missed mouseup (out of window)
875                 (this._mouseStarted && this._mouseUp(event));
876
877                 this._mouseDownEvent = event;
878
879                 var that = this,
880                         btnIsLeft = (event.which === 1),
881                         // event.target.nodeName works around a bug in IE 8 with
882                         // disabled inputs (#7620)
883                         elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
884                 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
885                         return true;
886                 }
887
888                 this.mouseDelayMet = !this.options.delay;
889                 if (!this.mouseDelayMet) {
890                         this._mouseDelayTimer = setTimeout(function() {
891                                 that.mouseDelayMet = true;
892                         }, this.options.delay);
893                 }
894
895                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
896                         this._mouseStarted = (this._mouseStart(event) !== false);
897                         if (!this._mouseStarted) {
898                                 event.preventDefault();
899                                 return true;
900                         }
901                 }
902
903                 // Click event may never have fired (Gecko & Opera)
904                 if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
905                         $.removeData(event.target, this.widgetName + ".preventClickEvent");
906                 }
907
908                 // these delegates are required to keep context
909                 this._mouseMoveDelegate = function(event) {
910                         return that._mouseMove(event);
911                 };
912                 this._mouseUpDelegate = function(event) {
913                         return that._mouseUp(event);
914                 };
915                 $(document)
916                         .bind("mousemove."+this.widgetName, this._mouseMoveDelegate)
917                         .bind("mouseup."+this.widgetName, this._mouseUpDelegate);
918
919                 event.preventDefault();
920
921                 mouseHandled = true;
922                 return true;
923         },
924
925         _mouseMove: function(event) {
926                 // IE mouseup check - mouseup happened when mouse was out of window
927                 if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
928                         return this._mouseUp(event);
929                 }
930
931                 if (this._mouseStarted) {
932                         this._mouseDrag(event);
933                         return event.preventDefault();
934                 }
935
936                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
937                         this._mouseStarted =
938                                 (this._mouseStart(this._mouseDownEvent, event) !== false);
939                         (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
940                 }
941
942                 return !this._mouseStarted;
943         },
944
945         _mouseUp: function(event) {
946                 $(document)
947                         .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
948                         .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
949
950                 if (this._mouseStarted) {
951                         this._mouseStarted = false;
952
953                         if (event.target === this._mouseDownEvent.target) {
954                                 $.data(event.target, this.widgetName + ".preventClickEvent", true);
955                         }
956
957                         this._mouseStop(event);
958                 }
959
960                 return false;
961         },
962
963         _mouseDistanceMet: function(event) {
964                 return (Math.max(
965                                 Math.abs(this._mouseDownEvent.pageX - event.pageX),
966                                 Math.abs(this._mouseDownEvent.pageY - event.pageY)
967                         ) >= this.options.distance
968                 );
969         },
970
971         _mouseDelayMet: function(/* event */) {
972                 return this.mouseDelayMet;
973         },
974
975         // These are placeholder methods, to be overriden by extending plugin
976         _mouseStart: function(/* event */) {},
977         _mouseDrag: function(/* event */) {},
978         _mouseStop: function(/* event */) {},
979         _mouseCapture: function(/* event */) { return true; }
980 });
981
982 })(jQuery);
983 (function( $, undefined ) {
984
985 function isOverAxis( x, reference, size ) {
986         return ( x > reference ) && ( x < ( reference + size ) );
987 }
988
989 function isFloating(item) {
990         return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
991 }
992
993 $.widget("ui.sortable", $.ui.mouse, {
994         version: "1.10.4",
995         widgetEventPrefix: "sort",
996         ready: false,
997         options: {
998                 appendTo: "parent",
999                 axis: false,
1000                 connectWith: false,
1001                 containment: false,
1002                 cursor: "auto",
1003                 cursorAt: false,
1004                 dropOnEmpty: true,
1005                 forcePlaceholderSize: false,
1006                 forceHelperSize: false,
1007                 grid: false,
1008                 handle: false,
1009                 helper: "original",
1010                 items: "> *",
1011                 opacity: false,
1012                 placeholder: false,
1013                 revert: false,
1014                 scroll: true,
1015                 scrollSensitivity: 20,
1016                 scrollSpeed: 20,
1017                 scope: "default",
1018                 tolerance: "intersect",
1019                 zIndex: 1000,
1020
1021                 // callbacks
1022                 activate: null,
1023                 beforeStop: null,
1024                 change: null,
1025                 deactivate: null,
1026                 out: null,
1027                 over: null,
1028                 receive: null,
1029                 remove: null,
1030                 sort: null,
1031                 start: null,
1032                 stop: null,
1033                 update: null
1034         },
1035         _create: function() {
1036
1037                 var o = this.options;
1038                 this.containerCache = {};
1039                 this.element.addClass("ui-sortable");
1040
1041                 //Get the items
1042                 this.refresh();
1043
1044                 //Let's determine if the items are being displayed horizontally
1045                 this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false;
1046
1047                 //Let's determine the parent's offset
1048                 this.offset = this.element.offset();
1049
1050                 //Initialize mouse events for interaction
1051                 this._mouseInit();
1052
1053                 //We're ready to go
1054                 this.ready = true;
1055
1056         },
1057
1058         _destroy: function() {
1059                 this.element
1060                         .removeClass("ui-sortable ui-sortable-disabled");
1061                 this._mouseDestroy();
1062
1063                 for ( var i = this.items.length - 1; i >= 0; i-- ) {
1064                         this.items[i].item.removeData(this.widgetName + "-item");
1065                 }
1066
1067                 return this;
1068         },
1069
1070         _setOption: function(key, value){
1071                 if ( key === "disabled" ) {
1072                         this.options[ key ] = value;
1073
1074                         this.widget().toggleClass( "ui-sortable-disabled", !!value );
1075                 } else {
1076                         // Don't call widget base _setOption for disable as it adds ui-state-disabled class
1077                         $.Widget.prototype._setOption.apply(this, arguments);
1078                 }
1079         },
1080
1081         _mouseCapture: function(event, overrideHandle) {
1082                 var currentItem = null,
1083                         validHandle = false,
1084                         that = this;
1085
1086                 if (this.reverting) {
1087                         return false;
1088                 }
1089
1090                 if(this.options.disabled || this.options.type === "static") {
1091                         return false;
1092                 }
1093
1094                 //We have to refresh the items data once first
1095                 this._refreshItems(event);
1096
1097                 //Find out if the clicked node (or one of its parents) is a actual item in this.items
1098                 $(event.target).parents().each(function() {
1099                         if($.data(this, that.widgetName + "-item") === that) {
1100                                 currentItem = $(this);
1101                                 return false;
1102                         }
1103                 });
1104                 if($.data(event.target, that.widgetName + "-item") === that) {
1105                         currentItem = $(event.target);
1106                 }
1107
1108                 if(!currentItem) {
1109                         return false;
1110                 }
1111                 if(this.options.handle && !overrideHandle) {
1112                         $(this.options.handle, currentItem).find("*").addBack().each(function() {
1113                                 if(this === event.target) {
1114                                         validHandle = true;
1115                                 }
1116                         });
1117                         if(!validHandle) {
1118                                 return false;
1119                         }
1120                 }
1121
1122                 this.currentItem = currentItem;
1123                 this._removeCurrentsFromItems();
1124                 return true;
1125
1126         },
1127
1128         _mouseStart: function(event, overrideHandle, noActivation) {
1129
1130                 var i, body,
1131                         o = this.options;
1132
1133                 this.currentContainer = this;
1134
1135                 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
1136                 this.refreshPositions();
1137
1138                 //Create and append the visible helper
1139                 this.helper = this._createHelper(event);
1140
1141                 //Cache the helper size
1142                 this._cacheHelperProportions();
1143
1144                 /*
1145                  * - Position generation -
1146                  * This block generates everything position related - it's the core of draggables.
1147                  */
1148
1149                 //Cache the margins of the original element
1150                 this._cacheMargins();
1151
1152                 //Get the next scrolling parent
1153                 this.scrollParent = this.helper.scrollParent();
1154
1155                 //The element's absolute position on the page minus margins
1156                 this.offset = this.currentItem.offset();
1157                 this.offset = {
1158                         top: this.offset.top - this.margins.top,
1159                         left: this.offset.left - this.margins.left
1160                 };
1161
1162                 $.extend(this.offset, {
1163                         click: { //Where the click happened, relative to the element
1164                                 left: event.pageX - this.offset.left,
1165                                 top: event.pageY - this.offset.top
1166                         },
1167                         parent: this._getParentOffset(),
1168                         relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1169                 });
1170
1171                 // Only after we got the offset, we can change the helper's position to absolute
1172                 // TODO: Still need to figure out a way to make relative sorting possible
1173                 this.helper.css("position", "absolute");
1174                 this.cssPosition = this.helper.css("position");
1175
1176                 //Generate the original position
1177                 this.originalPosition = this._generatePosition(event);
1178                 this.originalPageX = event.pageX;
1179                 this.originalPageY = event.pageY;
1180
1181                 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
1182                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1183
1184                 //Cache the former DOM position
1185                 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
1186
1187                 //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
1188                 if(this.helper[0] !== this.currentItem[0]) {
1189                         this.currentItem.hide();
1190                 }
1191
1192                 //Create the placeholder
1193                 this._createPlaceholder();
1194
1195                 //Set a containment if given in the options
1196                 if(o.containment) {
1197                         this._setContainment();
1198                 }
1199
1200                 if( o.cursor && o.cursor !== "auto" ) { // cursor option
1201                         body = this.document.find( "body" );
1202
1203                         // support: IE
1204                         this.storedCursor = body.css( "cursor" );
1205                         body.css( "cursor", o.cursor );
1206
1207                         this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
1208                 }
1209
1210                 if(o.opacity) { // opacity option
1211                         if (this.helper.css("opacity")) {
1212                                 this._storedOpacity = this.helper.css("opacity");
1213                         }
1214                         this.helper.css("opacity", o.opacity);
1215                 }
1216
1217                 if(o.zIndex) { // zIndex option
1218                         if (this.helper.css("zIndex")) {
1219                                 this._storedZIndex = this.helper.css("zIndex");
1220                         }
1221                         this.helper.css("zIndex", o.zIndex);
1222                 }
1223
1224                 //Prepare scrolling
1225                 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
1226                         this.overflowOffset = this.scrollParent.offset();
1227                 }
1228
1229                 //Call callbacks
1230                 this._trigger("start", event, this._uiHash());
1231
1232                 //Recache the helper size
1233                 if(!this._preserveHelperProportions) {
1234                         this._cacheHelperProportions();
1235                 }
1236
1237
1238                 //Post "activate" events to possible containers
1239                 if( !noActivation ) {
1240                         for ( i = this.containers.length - 1; i >= 0; i-- ) {
1241                                 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
1242                         }
1243                 }
1244
1245                 //Prepare possible droppables
1246                 if($.ui.ddmanager) {
1247                         $.ui.ddmanager.current = this;
1248                 }
1249
1250                 if ($.ui.ddmanager && !o.dropBehaviour) {
1251                         $.ui.ddmanager.prepareOffsets(this, event);
1252                 }
1253
1254                 this.dragging = true;
1255
1256                 this.helper.addClass("ui-sortable-helper");
1257                 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1258                 return true;
1259
1260         },
1261
1262         _mouseDrag: function(event) {
1263                 var i, item, itemElement, intersection,
1264                         o = this.options,
1265                         scrolled = false;
1266
1267                 //Compute the helpers position
1268                 this.position = this._generatePosition(event);
1269                 this.positionAbs = this._convertPositionTo("absolute");
1270
1271                 if (!this.lastPositionAbs) {
1272                         this.lastPositionAbs = this.positionAbs;
1273                 }
1274
1275                 //Do scrolling
1276                 if(this.options.scroll) {
1277                         if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
1278
1279                                 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
1280                                         this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
1281                                 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
1282                                         this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
1283                                 }
1284
1285                                 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
1286                                         this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
1287                                 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
1288                                         this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
1289                                 }
1290
1291                         } else {
1292
1293                                 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
1294                                         scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
1295                                 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
1296                                         scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
1297                                 }
1298
1299                                 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
1300                                         scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
1301                                 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
1302                                         scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
1303                                 }
1304
1305                         }
1306
1307                         if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
1308                                 $.ui.ddmanager.prepareOffsets(this, event);
1309                         }
1310                 }
1311
1312                 //Regenerate the absolute position used for position checks
1313                 this.positionAbs = this._convertPositionTo("absolute");
1314
1315                 //Set the helper position
1316                 if(!this.options.axis || this.options.axis !== "y") {
1317                         this.helper[0].style.left = this.position.left+"px";
1318                 }
1319                 if(!this.options.axis || this.options.axis !== "x") {
1320                         this.helper[0].style.top = this.position.top+"px";
1321                 }
1322
1323                 //Rearrange
1324                 for (i = this.items.length - 1; i >= 0; i--) {
1325
1326                         //Cache variables and intersection, continue if no intersection
1327                         item = this.items[i];
1328                         itemElement = item.item[0];
1329                         intersection = this._intersectsWithPointer(item);
1330                         if (!intersection) {
1331                                 continue;
1332                         }
1333
1334                         // Only put the placeholder inside the current Container, skip all
1335                         // items from other containers. This works because when moving
1336                         // an item from one container to another the
1337                         // currentContainer is switched before the placeholder is moved.
1338                         //
1339                         // Without this, moving items in "sub-sortables" can cause
1340                         // the placeholder to jitter beetween the outer and inner container.
1341                         if (item.instance !== this.currentContainer) {
1342                                 continue;
1343                         }
1344
1345                         // cannot intersect with itself
1346                         // no useless actions that have been done before
1347                         // no action if the item moved is the parent of the item checked
1348                         if (itemElement !== this.currentItem[0] &&
1349                                 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
1350                                 !$.contains(this.placeholder[0], itemElement) &&
1351                                 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
1352                         ) {
1353
1354                                 this.direction = intersection === 1 ? "down" : "up";
1355
1356                                 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
1357                                         this._rearrange(event, item);
1358                                 } else {
1359                                         break;
1360                                 }
1361
1362                                 this._trigger("change", event, this._uiHash());
1363                                 break;
1364                         }
1365                 }
1366
1367                 //Post events to containers
1368                 this._contactContainers(event);
1369
1370                 //Interconnect with droppables
1371                 if($.ui.ddmanager) {
1372                         $.ui.ddmanager.drag(this, event);
1373                 }
1374
1375                 //Call callbacks
1376                 this._trigger("sort", event, this._uiHash());
1377
1378                 this.lastPositionAbs = this.positionAbs;
1379                 return false;
1380
1381         },
1382
1383         _mouseStop: function(event, noPropagation) {
1384
1385                 if(!event) {
1386                         return;
1387                 }
1388
1389                 //If we are using droppables, inform the manager about the drop
1390                 if ($.ui.ddmanager && !this.options.dropBehaviour) {
1391                         $.ui.ddmanager.drop(this, event);
1392                 }
1393
1394                 if(this.options.revert) {
1395                         var that = this,
1396                                 cur = this.placeholder.offset(),
1397                                 axis = this.options.axis,
1398                                 animation = {};
1399
1400                         if ( !axis || axis === "x" ) {
1401                                 animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft);
1402                         }
1403                         if ( !axis || axis === "y" ) {
1404                                 animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop);
1405                         }
1406                         this.reverting = true;
1407                         $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
1408                                 that._clear(event);
1409                         });
1410                 } else {
1411                         this._clear(event, noPropagation);
1412                 }
1413
1414                 return false;
1415
1416         },
1417
1418         cancel: function() {
1419
1420                 if(this.dragging) {
1421
1422                         this._mouseUp({ target: null });
1423
1424                         if(this.options.helper === "original") {
1425                                 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
1426                         } else {
1427                                 this.currentItem.show();
1428                         }
1429
1430                         //Post deactivating events to containers
1431                         for (var i = this.containers.length - 1; i >= 0; i--){
1432                                 this.containers[i]._trigger("deactivate", null, this._uiHash(this));
1433                                 if(this.containers[i].containerCache.over) {
1434                                         this.containers[i]._trigger("out", null, this._uiHash(this));
1435                                         this.containers[i].containerCache.over = 0;
1436                                 }
1437                         }
1438
1439                 }
1440
1441                 if (this.placeholder) {
1442                         //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
1443                         if(this.placeholder[0].parentNode) {
1444                                 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
1445                         }
1446                         if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
1447                                 this.helper.remove();
1448                         }
1449
1450                         $.extend(this, {
1451                                 helper: null,
1452                                 dragging: false,
1453                                 reverting: false,
1454                                 _noFinalSort: null
1455                         });
1456
1457                         if(this.domPosition.prev) {
1458                                 $(this.domPosition.prev).after(this.currentItem);
1459                         } else {
1460                                 $(this.domPosition.parent).prepend(this.currentItem);
1461                         }
1462                 }
1463
1464                 return this;
1465
1466         },
1467
1468         serialize: function(o) {
1469
1470                 var items = this._getItemsAsjQuery(o && o.connected),
1471                         str = [];
1472                 o = o || {};
1473
1474                 $(items).each(function() {
1475                         var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
1476                         if (res) {
1477                                 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
1478                         }
1479                 });
1480
1481                 if(!str.length && o.key) {
1482                         str.push(o.key + "=");
1483                 }
1484
1485                 return str.join("&");
1486
1487         },
1488
1489         toArray: function(o) {
1490
1491                 var items = this._getItemsAsjQuery(o && o.connected),
1492                         ret = [];
1493
1494                 o = o || {};
1495
1496                 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
1497                 return ret;
1498
1499         },
1500
1501         /* Be careful with the following core functions */
1502         _intersectsWith: function(item) {
1503
1504                 var x1 = this.positionAbs.left,
1505                         x2 = x1 + this.helperProportions.width,
1506                         y1 = this.positionAbs.top,
1507                         y2 = y1 + this.helperProportions.height,
1508                         l = item.left,
1509                         r = l + item.width,
1510                         t = item.top,
1511                         b = t + item.height,
1512                         dyClick = this.offset.click.top,
1513                         dxClick = this.offset.click.left,
1514                         isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
1515                         isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
1516                         isOverElement = isOverElementHeight && isOverElementWidth;
1517
1518                 if ( this.options.tolerance === "pointer" ||
1519                         this.options.forcePointerForContainers ||
1520                         (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
1521                 ) {
1522                         return isOverElement;
1523                 } else {
1524
1525                         return (l < x1 + (this.helperProportions.width / 2) && // Right Half
1526                                 x2 - (this.helperProportions.width / 2) < r && // Left Half
1527                                 t < y1 + (this.helperProportions.height / 2) && // Bottom Half
1528                                 y2 - (this.helperProportions.height / 2) < b ); // Top Half
1529
1530                 }
1531         },
1532
1533         _intersectsWithPointer: function(item) {
1534
1535                 var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
1536                         isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
1537                         isOverElement = isOverElementHeight && isOverElementWidth,
1538                         verticalDirection = this._getDragVerticalDirection(),
1539                         horizontalDirection = this._getDragHorizontalDirection();
1540
1541                 if (!isOverElement) {
1542                         return false;
1543                 }
1544
1545                 return this.floating ?
1546                         ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
1547                         : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
1548
1549         },
1550
1551         _intersectsWithSides: function(item) {
1552
1553                 var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
1554                         isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
1555                         verticalDirection = this._getDragVerticalDirection(),
1556                         horizontalDirection = this._getDragHorizontalDirection();
1557
1558                 if (this.floating && horizontalDirection) {
1559                         return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
1560                 } else {
1561                         return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
1562                 }
1563
1564         },
1565
1566         _getDragVerticalDirection: function() {
1567                 var delta = this.positionAbs.top - this.lastPositionAbs.top;
1568                 return delta !== 0 && (delta > 0 ? "down" : "up");
1569         },
1570
1571         _getDragHorizontalDirection: function() {
1572                 var delta = this.positionAbs.left - this.lastPositionAbs.left;
1573                 return delta !== 0 && (delta > 0 ? "right" : "left");
1574         },
1575
1576         refresh: function(event) {
1577                 this._refreshItems(event);
1578                 this.refreshPositions();
1579                 return this;
1580         },
1581
1582         _connectWith: function() {
1583                 var options = this.options;
1584                 return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
1585         },
1586
1587         _getItemsAsjQuery: function(connected) {
1588
1589                 var i, j, cur, inst,
1590                         items = [],
1591                         queries = [],
1592                         connectWith = this._connectWith();
1593
1594                 if(connectWith && connected) {
1595                         for (i = connectWith.length - 1; i >= 0; i--){
1596                                 cur = $(connectWith[i]);
1597                                 for ( j = cur.length - 1; j >= 0; j--){
1598                                         inst = $.data(cur[j], this.widgetFullName);
1599                                         if(inst && inst !== this && !inst.options.disabled) {
1600                                                 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]);
1601                                         }
1602                                 }
1603                         }
1604                 }
1605
1606                 queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]);
1607
1608                 function addItems() {
1609                         items.push( this );
1610                 }
1611                 for (i = queries.length - 1; i >= 0; i--){
1612                         queries[i][0].each( addItems );
1613                 }
1614
1615                 return $(items);
1616
1617         },
1618
1619         _removeCurrentsFromItems: function() {
1620
1621                 var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
1622
1623                 this.items = $.grep(this.items, function (item) {
1624                         for (var j=0; j < list.length; j++) {
1625                                 if(list[j] === item.item[0]) {
1626                                         return false;
1627                                 }
1628                         }
1629                         return true;
1630                 });
1631
1632         },
1633
1634         _refreshItems: function(event) {
1635
1636                 this.items = [];
1637                 this.containers = [this];
1638
1639                 var i, j, cur, inst, targetData, _queries, item, queriesLength,
1640                         items = this.items,
1641                         queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
1642                         connectWith = this._connectWith();
1643
1644                 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
1645                         for (i = connectWith.length - 1; i >= 0; i--){
1646                                 cur = $(connectWith[i]);
1647                                 for (j = cur.length - 1; j >= 0; j--){
1648                                         inst = $.data(cur[j], this.widgetFullName);
1649                                         if(inst && inst !== this && !inst.options.disabled) {
1650                                                 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
1651                                                 this.containers.push(inst);
1652                                         }
1653                                 }
1654                         }
1655                 }
1656
1657                 for (i = queries.length - 1; i >= 0; i--) {
1658                         targetData = queries[i][1];
1659                         _queries = queries[i][0];
1660
1661                         for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
1662                                 item = $(_queries[j]);
1663
1664                                 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
1665
1666                                 items.push({
1667                                         item: item,
1668                                         instance: targetData,
1669                                         width: 0, height: 0,
1670                                         left: 0, top: 0
1671                                 });
1672                         }
1673                 }
1674
1675         },
1676
1677         refreshPositions: function(fast) {
1678
1679                 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
1680                 if(this.offsetParent && this.helper) {
1681                         this.offset.parent = this._getParentOffset();
1682                 }
1683
1684                 var i, item, t, p;
1685
1686                 for (i = this.items.length - 1; i >= 0; i--){
1687                         item = this.items[i];
1688
1689                         //We ignore calculating positions of all connected containers when we're not over them
1690                         if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
1691                                 continue;
1692                         }
1693
1694                         t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
1695
1696                         if (!fast) {
1697                                 item.width = t.outerWidth();
1698                                 item.height = t.outerHeight();
1699                         }
1700
1701                         p = t.offset();
1702                         item.left = p.left;
1703                         item.top = p.top;
1704                 }
1705
1706                 if(this.options.custom && this.options.custom.refreshContainers) {
1707                         this.options.custom.refreshContainers.call(this);
1708                 } else {
1709                         for (i = this.containers.length - 1; i >= 0; i--){
1710                                 p = this.containers[i].element.offset();
1711                                 this.containers[i].containerCache.left = p.left;
1712                                 this.containers[i].containerCache.top = p.top;
1713                                 this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
1714                                 this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
1715                         }
1716                 }
1717
1718                 return this;
1719         },
1720
1721         _createPlaceholder: function(that) {
1722                 that = that || this;
1723                 var className,
1724                         o = that.options;
1725
1726                 if(!o.placeholder || o.placeholder.constructor === String) {
1727                         className = o.placeholder;
1728                         o.placeholder = {
1729                                 element: function() {
1730
1731                                         var nodeName = that.currentItem[0].nodeName.toLowerCase(),
1732                                                 element = $( "<" + nodeName + ">", that.document[0] )
1733                                                         .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
1734                                                         .removeClass("ui-sortable-helper");
1735
1736                                         if ( nodeName === "tr" ) {
1737                                                 that.currentItem.children().each(function() {
1738                                                         $( "<td>&#160;</td>", that.document[0] )
1739                                                                 .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
1740                                                                 .appendTo( element );
1741                                                 });
1742                                         } else if ( nodeName === "img" ) {
1743                                                 element.attr( "src", that.currentItem.attr( "src" ) );
1744                                         }
1745
1746                                         if ( !className ) {
1747                                                 element.css( "visibility", "hidden" );
1748                                         }
1749
1750                                         return element;
1751                                 },
1752                                 update: function(container, p) {
1753
1754                                         // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
1755                                         // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
1756                                         if(className && !o.forcePlaceholderSize) {
1757                                                 return;
1758                                         }
1759
1760                                         //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
1761                                         if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
1762                                         if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
1763                                 }
1764                         };
1765                 }
1766
1767                 //Create the placeholder
1768                 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
1769
1770                 //Append it after the actual current item
1771                 that.currentItem.after(that.placeholder);
1772
1773                 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
1774                 o.placeholder.update(that, that.placeholder);
1775
1776         },
1777
1778         _contactContainers: function(event) {
1779                 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating,
1780                         innermostContainer = null,
1781                         innermostIndex = null;
1782
1783                 // get innermost container that intersects with item
1784                 for (i = this.containers.length - 1; i >= 0; i--) {
1785
1786                         // never consider a container that's located within the item itself
1787                         if($.contains(this.currentItem[0], this.containers[i].element[0])) {
1788                                 continue;
1789                         }
1790
1791                         if(this._intersectsWith(this.containers[i].containerCache)) {
1792
1793                                 // if we've already found a container and it's more "inner" than this, then continue
1794                                 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
1795                                         continue;
1796                                 }
1797
1798                                 innermostContainer = this.containers[i];
1799                                 innermostIndex = i;
1800
1801                         } else {
1802                                 // container doesn't intersect. trigger "out" event if necessary
1803                                 if(this.containers[i].containerCache.over) {
1804                                         this.containers[i]._trigger("out", event, this._uiHash(this));
1805                                         this.containers[i].containerCache.over = 0;
1806                                 }
1807                         }
1808
1809                 }
1810
1811                 // if no intersecting containers found, return
1812                 if(!innermostContainer) {
1813                         return;
1814                 }
1815
1816                 // move the item into the container if it's not there already
1817                 if(this.containers.length === 1) {
1818                         if (!this.containers[innermostIndex].containerCache.over) {
1819                                 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
1820                                 this.containers[innermostIndex].containerCache.over = 1;
1821                         }
1822                 } else {
1823
1824                         //When entering a new container, we will find the item with the least distance and append our item near it
1825                         dist = 10000;
1826                         itemWithLeastDistance = null;
1827                         floating = innermostContainer.floating || isFloating(this.currentItem);
1828                         posProperty = floating ? "left" : "top";
1829                         sizeProperty = floating ? "width" : "height";
1830                         base = this.positionAbs[posProperty] + this.offset.click[posProperty];
1831                         for (j = this.items.length - 1; j >= 0; j--) {
1832                                 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
1833                                         continue;
1834                                 }
1835                                 if(this.items[j].item[0] === this.currentItem[0]) {
1836                                         continue;
1837                                 }
1838                                 if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) {
1839                                         continue;
1840                                 }
1841                                 cur = this.items[j].item.offset()[posProperty];
1842                                 nearBottom = false;
1843                                 if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
1844                                         nearBottom = true;
1845                                         cur += this.items[j][sizeProperty];
1846                                 }
1847
1848                                 if(Math.abs(cur - base) < dist) {
1849                                         dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
1850                                         this.direction = nearBottom ? "up": "down";
1851                                 }
1852                         }
1853
1854                         //Check if dropOnEmpty is enabled
1855                         if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
1856                                 return;
1857                         }
1858
1859                         if(this.currentContainer === this.containers[innermostIndex]) {
1860                                 return;
1861                         }
1862
1863                         itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
1864                         this._trigger("change", event, this._uiHash());
1865                         this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
1866                         this.currentContainer = this.containers[innermostIndex];
1867
1868                         //Update the placeholder
1869                         this.options.placeholder.update(this.currentContainer, this.placeholder);
1870
1871                         this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
1872                         this.containers[innermostIndex].containerCache.over = 1;
1873                 }
1874
1875
1876         },
1877
1878         _createHelper: function(event) {
1879
1880                 var o = this.options,
1881                         helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
1882
1883                 //Add the helper to the DOM if that didn't happen already
1884                 if(!helper.parents("body").length) {
1885                         $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
1886                 }
1887
1888                 if(helper[0] === this.currentItem[0]) {
1889                         this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
1890                 }
1891
1892                 if(!helper[0].style.width || o.forceHelperSize) {
1893                         helper.width(this.currentItem.width());
1894                 }
1895                 if(!helper[0].style.height || o.forceHelperSize) {
1896                         helper.height(this.currentItem.height());
1897                 }
1898
1899                 return helper;
1900
1901         },
1902
1903         _adjustOffsetFromHelper: function(obj) {
1904                 if (typeof obj === "string") {
1905                         obj = obj.split(" ");
1906                 }
1907                 if ($.isArray(obj)) {
1908                         obj = {left: +obj[0], top: +obj[1] || 0};
1909                 }
1910                 if ("left" in obj) {
1911                         this.offset.click.left = obj.left + this.margins.left;
1912                 }
1913                 if ("right" in obj) {
1914                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1915                 }
1916                 if ("top" in obj) {
1917                         this.offset.click.top = obj.top + this.margins.top;
1918                 }
1919                 if ("bottom" in obj) {
1920                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1921                 }
1922         },
1923
1924         _getParentOffset: function() {
1925
1926
1927                 //Get the offsetParent and cache its position
1928                 this.offsetParent = this.helper.offsetParent();
1929                 var po = this.offsetParent.offset();
1930
1931                 // This is a special case where we need to modify a offset calculated on start, since the following happened:
1932                 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1933                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1934                 //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1935                 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1936                         po.left += this.scrollParent.scrollLeft();
1937                         po.top += this.scrollParent.scrollTop();
1938                 }
1939
1940                 // This needs to be actually done for all browsers, since pageX/pageY includes this information
1941                 // with an ugly IE fix
1942                 if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
1943                         po = { top: 0, left: 0 };
1944                 }
1945
1946                 return {
1947                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1948                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1949                 };
1950
1951         },
1952
1953         _getRelativeOffset: function() {
1954
1955                 if(this.cssPosition === "relative") {
1956                         var p = this.currentItem.position();
1957                         return {
1958                                 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1959                                 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1960                         };
1961                 } else {
1962                         return { top: 0, left: 0 };
1963                 }
1964
1965         },
1966
1967         _cacheMargins: function() {
1968                 this.margins = {
1969                         left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
1970                         top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
1971                 };
1972         },
1973
1974         _cacheHelperProportions: function() {
1975                 this.helperProportions = {
1976                         width: this.helper.outerWidth(),
1977                         height: this.helper.outerHeight()
1978                 };
1979         },
1980
1981         _setContainment: function() {
1982
1983                 var ce, co, over,
1984                         o = this.options;
1985                 if(o.containment === "parent") {
1986                         o.containment = this.helper[0].parentNode;
1987                 }
1988                 if(o.containment === "document" || o.containment === "window") {
1989                         this.containment = [
1990                                 0 - this.offset.relative.left - this.offset.parent.left,
1991                                 0 - this.offset.relative.top - this.offset.parent.top,
1992                                 $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
1993                                 ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
1994                         ];
1995                 }
1996
1997                 if(!(/^(document|window|parent)$/).test(o.containment)) {
1998                         ce = $(o.containment)[0];
1999                         co = $(o.containment).offset();
2000                         over = ($(ce).css("overflow") !== "hidden");
2001
2002                         this.containment = [
2003                                 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
2004                                 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
2005                                 co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
2006                                 co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
2007                         ];
2008                 }
2009
2010         },
2011
2012         _convertPositionTo: function(d, pos) {
2013
2014                 if(!pos) {
2015                         pos = this.position;
2016                 }
2017                 var mod = d === "absolute" ? 1 : -1,
2018                         scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
2019                         scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
2020
2021                 return {
2022                         top: (
2023                                 pos.top +                                                                                                                               // The absolute mouse position
2024                                 this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
2025                                 this.offset.parent.top * mod -                                                                                  // The offsetParent's offset without borders (offset + border)
2026                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
2027                         ),
2028                         left: (
2029                                 pos.left +                                                                                                                              // The absolute mouse position
2030                                 this.offset.relative.left * mod +                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
2031                                 this.offset.parent.left * mod   -                                                                               // The offsetParent's offset without borders (offset + border)
2032                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
2033                         )
2034                 };
2035
2036         },
2037
2038         _generatePosition: function(event) {
2039
2040                 var top, left,
2041                         o = this.options,
2042                         pageX = event.pageX,
2043                         pageY = event.pageY,
2044                         scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
2045
2046                 // This is another very weird special case that only happens for relative elements:
2047                 // 1. If the css position is relative
2048                 // 2. and the scroll parent is the document or similar to the offset parent
2049                 // we have to refresh the relative offset during the scroll so there are no jumps
2050                 if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
2051                         this.offset.relative = this._getRelativeOffset();
2052                 }
2053
2054                 /*
2055                  * - Position constraining -
2056                  * Constrain the position to a mix of grid, containment.
2057                  */
2058
2059                 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
2060
2061                         if(this.containment) {
2062                                 if(event.pageX - this.offset.click.left < this.containment[0]) {
2063                                         pageX = this.containment[0] + this.offset.click.left;
2064                                 }
2065                                 if(event.pageY - this.offset.click.top < this.containment[1]) {
2066                                         pageY = this.containment[1] + this.offset.click.top;
2067                                 }
2068                                 if(event.pageX - this.offset.click.left > this.containment[2]) {
2069                                         pageX = this.containment[2] + this.offset.click.left;
2070                                 }
2071                                 if(event.pageY - this.offset.click.top > this.containment[3]) {
2072                                         pageY = this.containment[3] + this.offset.click.top;
2073                                 }
2074                         }
2075
2076                         if(o.grid) {
2077                                 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
2078                                 pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
2079
2080                                 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
2081                                 pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
2082                         }
2083
2084                 }
2085
2086                 return {
2087                         top: (
2088                                 pageY -                                                                                                                         // The absolute mouse position
2089                                 this.offset.click.top -                                                                                                 // Click offset (relative to the element)
2090                                 this.offset.relative.top        -                                                                                       // Only for relative positioned nodes: Relative offset from element to offset parent
2091                                 this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
2092                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
2093                         ),
2094                         left: (
2095                                 pageX -                                                                                                                         // The absolute mouse position
2096                                 this.offset.click.left -                                                                                                // Click offset (relative to the element)
2097                                 this.offset.relative.left       -                                                                                       // Only for relative positioned nodes: Relative offset from element to offset parent
2098                                 this.offset.parent.left +                                                                                               // The offsetParent's offset without borders (offset + border)
2099                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
2100                         )
2101                 };
2102
2103         },
2104
2105         _rearrange: function(event, i, a, hardRefresh) {
2106
2107                 a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling));
2108
2109                 //Various things done here to improve the performance:
2110                 // 1. we create a setTimeout, that calls refreshPositions
2111                 // 2. on the instance, we have a counter variable, that get's higher after every append
2112                 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
2113                 // 4. this lets only the last addition to the timeout stack through
2114                 this.counter = this.counter ? ++this.counter : 1;
2115                 var counter = this.counter;
2116
2117                 this._delay(function() {
2118                         if(counter === this.counter) {
2119                                 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
2120                         }
2121                 });
2122
2123         },
2124
2125         _clear: function(event, noPropagation) {
2126
2127                 this.reverting = false;
2128                 // We delay all events that have to be triggered to after the point where the placeholder has been removed and
2129                 // everything else normalized again
2130                 var i,
2131                         delayedTriggers = [];
2132
2133                 // We first have to update the dom position of the actual currentItem
2134                 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
2135                 if(!this._noFinalSort && this.currentItem.parent().length) {
2136                         this.placeholder.before(this.currentItem);
2137                 }
2138                 this._noFinalSort = null;
2139
2140                 if(this.helper[0] === this.currentItem[0]) {
2141                         for(i in this._storedCSS) {
2142                                 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
2143                                         this._storedCSS[i] = "";
2144                                 }
2145                         }
2146                         this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
2147                 } else {
2148                         this.currentItem.show();
2149                 }
2150
2151                 if(this.fromOutside && !noPropagation) {
2152                         delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
2153                 }
2154                 if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
2155                         delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
2156                 }
2157
2158                 // Check if the items Container has Changed and trigger appropriate
2159                 // events.
2160                 if (this !== this.currentContainer) {
2161                         if(!noPropagation) {
2162                                 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
2163                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
2164                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
2165                         }
2166                 }
2167
2168
2169                 //Post events to containers
2170                 function delayEvent( type, instance, container ) {
2171                         return function( event ) {
2172                                 container._trigger( type, event, instance._uiHash( instance ) );
2173                         };
2174                 }
2175                 for (i = this.containers.length - 1; i >= 0; i--){
2176                         if (!noPropagation) {
2177                                 delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
2178                         }
2179                         if(this.containers[i].containerCache.over) {
2180                                 delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
2181                                 this.containers[i].containerCache.over = 0;
2182                         }
2183                 }
2184
2185                 //Do what was originally in plugins
2186                 if ( this.storedCursor ) {
2187                         this.document.find( "body" ).css( "cursor", this.storedCursor );
2188                         this.storedStylesheet.remove();
2189                 }
2190                 if(this._storedOpacity) {
2191                         this.helper.css("opacity", this._storedOpacity);
2192                 }
2193                 if(this._storedZIndex) {
2194                         this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
2195                 }
2196
2197                 this.dragging = false;
2198                 if(this.cancelHelperRemoval) {
2199                         if(!noPropagation) {
2200                                 this._trigger("beforeStop", event, this._uiHash());
2201                                 for (i=0; i < delayedTriggers.length; i++) {
2202                                         delayedTriggers[i].call(this, event);
2203                                 } //Trigger all delayed events
2204                                 this._trigger("stop", event, this._uiHash());
2205                         }
2206
2207                         this.fromOutside = false;
2208                         return false;
2209                 }
2210
2211                 if(!noPropagation) {
2212                         this._trigger("beforeStop", event, this._uiHash());
2213                 }
2214
2215                 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
2216                 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
2217
2218                 if(this.helper[0] !== this.currentItem[0]) {
2219                         this.helper.remove();
2220                 }
2221                 this.helper = null;
2222
2223                 if(!noPropagation) {
2224                         for (i=0; i < delayedTriggers.length; i++) {
2225                                 delayedTriggers[i].call(this, event);
2226                         } //Trigger all delayed events
2227                         this._trigger("stop", event, this._uiHash());
2228                 }
2229
2230                 this.fromOutside = false;
2231                 return true;
2232
2233         },
2234
2235         _trigger: function() {
2236                 if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
2237                         this.cancel();
2238                 }
2239         },
2240
2241         _uiHash: function(_inst) {
2242                 var inst = _inst || this;
2243                 return {
2244                         helper: inst.helper,
2245                         placeholder: inst.placeholder || $([]),
2246                         position: inst.position,
2247                         originalPosition: inst.originalPosition,
2248                         offset: inst.positionAbs,
2249                         item: inst.currentItem,
2250                         sender: _inst ? _inst.element : null
2251                 };
2252         }
2253
2254 });
2255
2256 })(jQuery);