source: pro-violet-viettel/docs/template/assets/js/uncompressed/jquery-ui-1.10.3.custom.js @ 840

Last change on this file since 840 was 400, checked in by dungnv, 11 years ago
  • Property svn:mime-type set to text/plain
File size: 159.1 KB
Line 
1/*! jQuery UI - v1.10.3 - 2013-07-07
2* http://jqueryui.com
3* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.slider.js
4* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */
5
6(function( $, undefined ) {
7
8var 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.3",
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
123function 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
144function 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
175if ( !$( "<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
222if ( !$.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)
231if ( $( "<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
318var 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
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 ( value === undefined ) {
624                                        return curOption[ key ] === undefined ? null : curOption[ key ];
625                                }
626                                curOption[ key ] = value;
627                        } else {
628                                if ( value === undefined ) {
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
829var mouseHandled = false;
830$( document ).mouseup( function() {
831        mouseHandled = false;
832});
833
834$.widget("ui.mouse", {
835        version: "1.10.3",
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$.widget("ui.draggable", $.ui.mouse, {
986        version: "1.10.3",
987        widgetEventPrefix: "drag",
988        options: {
989                addClasses: true,
990                appendTo: "parent",
991                axis: false,
992                connectToSortable: false,
993                containment: false,
994                cursor: "auto",
995                cursorAt: false,
996                grid: false,
997                handle: false,
998                helper: "original",
999                iframeFix: false,
1000                opacity: false,
1001                refreshPositions: false,
1002                revert: false,
1003                revertDuration: 500,
1004                scope: "default",
1005                scroll: true,
1006                scrollSensitivity: 20,
1007                scrollSpeed: 20,
1008                snap: false,
1009                snapMode: "both",
1010                snapTolerance: 20,
1011                stack: false,
1012                zIndex: false,
1013
1014                // callbacks
1015                drag: null,
1016                start: null,
1017                stop: null
1018        },
1019        _create: function() {
1020
1021                if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) {
1022                        this.element[0].style.position = "relative";
1023                }
1024                if (this.options.addClasses){
1025                        this.element.addClass("ui-draggable");
1026                }
1027                if (this.options.disabled){
1028                        this.element.addClass("ui-draggable-disabled");
1029                }
1030
1031                this._mouseInit();
1032
1033        },
1034
1035        _destroy: function() {
1036                this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1037                this._mouseDestroy();
1038        },
1039
1040        _mouseCapture: function(event) {
1041
1042                var o = this.options;
1043
1044                // among others, prevent a drag on a resizable-handle
1045                if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
1046                        return false;
1047                }
1048
1049                //Quit if we're not on a valid handle
1050                this.handle = this._getHandle(event);
1051                if (!this.handle) {
1052                        return false;
1053                }
1054
1055                $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1056                        $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>")
1057                        .css({
1058                                width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1059                                position: "absolute", opacity: "0.001", zIndex: 1000
1060                        })
1061                        .css($(this).offset())
1062                        .appendTo("body");
1063                });
1064
1065                return true;
1066
1067        },
1068
1069        _mouseStart: function(event) {
1070
1071                var o = this.options;
1072
1073                //Create and append the visible helper
1074                this.helper = this._createHelper(event);
1075
1076                this.helper.addClass("ui-draggable-dragging");
1077
1078                //Cache the helper size
1079                this._cacheHelperProportions();
1080
1081                //If ddmanager is used for droppables, set the global draggable
1082                if($.ui.ddmanager) {
1083                        $.ui.ddmanager.current = this;
1084                }
1085
1086                /*
1087                 * - Position generation -
1088                 * This block generates everything position related - it's the core of draggables.
1089                 */
1090
1091                //Cache the margins of the original element
1092                this._cacheMargins();
1093
1094                //Store the helper's css position
1095                this.cssPosition = this.helper.css( "position" );
1096                this.scrollParent = this.helper.scrollParent();
1097                this.offsetParent = this.helper.offsetParent();
1098                this.offsetParentCssPosition = this.offsetParent.css( "position" );
1099
1100                //The element's absolute position on the page minus margins
1101                this.offset = this.positionAbs = this.element.offset();
1102                this.offset = {
1103                        top: this.offset.top - this.margins.top,
1104                        left: this.offset.left - this.margins.left
1105                };
1106
1107                //Reset scroll cache
1108                this.offset.scroll = false;
1109
1110                $.extend(this.offset, {
1111                        click: { //Where the click happened, relative to the element
1112                                left: event.pageX - this.offset.left,
1113                                top: event.pageY - this.offset.top
1114                        },
1115                        parent: this._getParentOffset(),
1116                        relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1117                });
1118
1119                //Generate the original position
1120                this.originalPosition = this.position = this._generatePosition(event);
1121                this.originalPageX = event.pageX;
1122                this.originalPageY = event.pageY;
1123
1124                //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
1125                (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1126
1127                //Set a containment if given in the options
1128                this._setContainment();
1129
1130                //Trigger event + callbacks
1131                if(this._trigger("start", event) === false) {
1132                        this._clear();
1133                        return false;
1134                }
1135
1136                //Recache the helper size
1137                this._cacheHelperProportions();
1138
1139                //Prepare the droppable offsets
1140                if ($.ui.ddmanager && !o.dropBehaviour) {
1141                        $.ui.ddmanager.prepareOffsets(this, event);
1142                }
1143
1144
1145                this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1146
1147                //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1148                if ( $.ui.ddmanager ) {
1149                        $.ui.ddmanager.dragStart(this, event);
1150                }
1151
1152                return true;
1153        },
1154
1155        _mouseDrag: function(event, noPropagation) {
1156                // reset any necessary cached properties (see #5009)
1157                if ( this.offsetParentCssPosition === "fixed" ) {
1158                        this.offset.parent = this._getParentOffset();
1159                }
1160
1161                //Compute the helpers position
1162                this.position = this._generatePosition(event);
1163                this.positionAbs = this._convertPositionTo("absolute");
1164
1165                //Call plugins and callbacks and use the resulting position if something is returned
1166                if (!noPropagation) {
1167                        var ui = this._uiHash();
1168                        if(this._trigger("drag", event, ui) === false) {
1169                                this._mouseUp({});
1170                                return false;
1171                        }
1172                        this.position = ui.position;
1173                }
1174
1175                if(!this.options.axis || this.options.axis !== "y") {
1176                        this.helper[0].style.left = this.position.left+"px";
1177                }
1178                if(!this.options.axis || this.options.axis !== "x") {
1179                        this.helper[0].style.top = this.position.top+"px";
1180                }
1181                if($.ui.ddmanager) {
1182                        $.ui.ddmanager.drag(this, event);
1183                }
1184
1185                return false;
1186        },
1187
1188        _mouseStop: function(event) {
1189
1190                //If we are using droppables, inform the manager about the drop
1191                var that = this,
1192                        dropped = false;
1193                if ($.ui.ddmanager && !this.options.dropBehaviour) {
1194                        dropped = $.ui.ddmanager.drop(this, event);
1195                }
1196
1197                //if a drop comes from outside (a sortable)
1198                if(this.dropped) {
1199                        dropped = this.dropped;
1200                        this.dropped = false;
1201                }
1202
1203                //if the original element is no longer in the DOM don't bother to continue (see #8269)
1204                if ( this.options.helper === "original" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) {
1205                        return false;
1206                }
1207
1208                if((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
1209                        $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1210                                if(that._trigger("stop", event) !== false) {
1211                                        that._clear();
1212                                }
1213                        });
1214                } else {
1215                        if(this._trigger("stop", event) !== false) {
1216                                this._clear();
1217                        }
1218                }
1219
1220                return false;
1221        },
1222
1223        _mouseUp: function(event) {
1224                //Remove frame helpers
1225                $("div.ui-draggable-iframeFix").each(function() {
1226                        this.parentNode.removeChild(this);
1227                });
1228
1229                //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1230                if( $.ui.ddmanager ) {
1231                        $.ui.ddmanager.dragStop(this, event);
1232                }
1233
1234                return $.ui.mouse.prototype._mouseUp.call(this, event);
1235        },
1236
1237        cancel: function() {
1238
1239                if(this.helper.is(".ui-draggable-dragging")) {
1240                        this._mouseUp({});
1241                } else {
1242                        this._clear();
1243                }
1244
1245                return this;
1246
1247        },
1248
1249        _getHandle: function(event) {
1250                return this.options.handle ?
1251                        !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
1252                        true;
1253        },
1254
1255        _createHelper: function(event) {
1256
1257                var o = this.options,
1258                        helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element);
1259
1260                if(!helper.parents("body").length) {
1261                        helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
1262                }
1263
1264                if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
1265                        helper.css("position", "absolute");
1266                }
1267
1268                return helper;
1269
1270        },
1271
1272        _adjustOffsetFromHelper: function(obj) {
1273                if (typeof obj === "string") {
1274                        obj = obj.split(" ");
1275                }
1276                if ($.isArray(obj)) {
1277                        obj = {left: +obj[0], top: +obj[1] || 0};
1278                }
1279                if ("left" in obj) {
1280                        this.offset.click.left = obj.left + this.margins.left;
1281                }
1282                if ("right" in obj) {
1283                        this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1284                }
1285                if ("top" in obj) {
1286                        this.offset.click.top = obj.top + this.margins.top;
1287                }
1288                if ("bottom" in obj) {
1289                        this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1290                }
1291        },
1292
1293        _getParentOffset: function() {
1294
1295                //Get the offsetParent and cache its position
1296                var po = this.offsetParent.offset();
1297
1298                // This is a special case where we need to modify a offset calculated on start, since the following happened:
1299                // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1300                // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1301                //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1302                if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1303                        po.left += this.scrollParent.scrollLeft();
1304                        po.top += this.scrollParent.scrollTop();
1305                }
1306
1307                //This needs to be actually done for all browsers, since pageX/pageY includes this information
1308                //Ugly IE fix
1309                if((this.offsetParent[0] === document.body) ||
1310                        (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
1311                        po = { top: 0, left: 0 };
1312                }
1313
1314                return {
1315                        top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1316                        left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1317                };
1318
1319        },
1320
1321        _getRelativeOffset: function() {
1322
1323                if(this.cssPosition === "relative") {
1324                        var p = this.element.position();
1325                        return {
1326                                top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1327                                left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1328                        };
1329                } else {
1330                        return { top: 0, left: 0 };
1331                }
1332
1333        },
1334
1335        _cacheMargins: function() {
1336                this.margins = {
1337                        left: (parseInt(this.element.css("marginLeft"),10) || 0),
1338                        top: (parseInt(this.element.css("marginTop"),10) || 0),
1339                        right: (parseInt(this.element.css("marginRight"),10) || 0),
1340                        bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1341                };
1342        },
1343
1344        _cacheHelperProportions: function() {
1345                this.helperProportions = {
1346                        width: this.helper.outerWidth(),
1347                        height: this.helper.outerHeight()
1348                };
1349        },
1350
1351        _setContainment: function() {
1352
1353                var over, c, ce,
1354                        o = this.options;
1355
1356                if ( !o.containment ) {
1357                        this.containment = null;
1358                        return;
1359                }
1360
1361                if ( o.containment === "window" ) {
1362                        this.containment = [
1363                                $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1364                                $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1365                                $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
1366                                $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
1367                        ];
1368                        return;
1369                }
1370
1371                if ( o.containment === "document") {
1372                        this.containment = [
1373                                0,
1374                                0,
1375                                $( document ).width() - this.helperProportions.width - this.margins.left,
1376                                ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
1377                        ];
1378                        return;
1379                }
1380
1381                if ( o.containment.constructor === Array ) {
1382                        this.containment = o.containment;
1383                        return;
1384                }
1385
1386                if ( o.containment === "parent" ) {
1387                        o.containment = this.helper[ 0 ].parentNode;
1388                }
1389
1390                c = $( o.containment );
1391                ce = c[ 0 ];
1392
1393                if( !ce ) {
1394                        return;
1395                }
1396
1397                over = c.css( "overflow" ) !== "hidden";
1398
1399                this.containment = [
1400                        ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
1401                        ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ) ,
1402                        ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - this.helperProportions.width - this.margins.left - this.margins.right,
1403                        ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - this.helperProportions.height - this.margins.top  - this.margins.bottom
1404                ];
1405                this.relative_container = c;
1406        },
1407
1408        _convertPositionTo: function(d, pos) {
1409
1410                if(!pos) {
1411                        pos = this.position;
1412                }
1413
1414                var mod = d === "absolute" ? 1 : -1,
1415                        scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent;
1416
1417                //Cache the scroll
1418                if (!this.offset.scroll) {
1419                        this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
1420                }
1421
1422                return {
1423                        top: (
1424                                pos.top +                                                                                                                               // The absolute mouse position
1425                                this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
1426                                this.offset.parent.top * mod -                                                                          // The offsetParent's offset without borders (offset + border)
1427                                ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) * mod )
1428                        ),
1429                        left: (
1430                                pos.left +                                                                                                                              // The absolute mouse position
1431                                this.offset.relative.left * mod +                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
1432                                this.offset.parent.left * mod   -                                                                               // The offsetParent's offset without borders (offset + border)
1433                                ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) * mod )
1434                        )
1435                };
1436
1437        },
1438
1439        _generatePosition: function(event) {
1440
1441                var containment, co, top, left,
1442                        o = this.options,
1443                        scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent,
1444                        pageX = event.pageX,
1445                        pageY = event.pageY;
1446
1447                //Cache the scroll
1448                if (!this.offset.scroll) {
1449                        this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
1450                }
1451
1452                /*
1453                 * - Position constraining -
1454                 * Constrain the position to a mix of grid, containment.
1455                 */
1456
1457                // If we are not dragging yet, we won't check for options
1458                if ( this.originalPosition ) {
1459                        if ( this.containment ) {
1460                                if ( this.relative_container ){
1461                                        co = this.relative_container.offset();
1462                                        containment = [
1463                                                this.containment[ 0 ] + co.left,
1464                                                this.containment[ 1 ] + co.top,
1465                                                this.containment[ 2 ] + co.left,
1466                                                this.containment[ 3 ] + co.top
1467                                        ];
1468                                }
1469                                else {
1470                                        containment = this.containment;
1471                                }
1472
1473                                if(event.pageX - this.offset.click.left < containment[0]) {
1474                                        pageX = containment[0] + this.offset.click.left;
1475                                }
1476                                if(event.pageY - this.offset.click.top < containment[1]) {
1477                                        pageY = containment[1] + this.offset.click.top;
1478                                }
1479                                if(event.pageX - this.offset.click.left > containment[2]) {
1480                                        pageX = containment[2] + this.offset.click.left;
1481                                }
1482                                if(event.pageY - this.offset.click.top > containment[3]) {
1483                                        pageY = containment[3] + this.offset.click.top;
1484                                }
1485                        }
1486
1487                        if(o.grid) {
1488                                //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1489                                top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
1490                                pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
1491
1492                                left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1493                                pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
1494                        }
1495
1496                }
1497
1498                return {
1499                        top: (
1500                                pageY -                                                                                                                                 // The absolute mouse position
1501                                this.offset.click.top   -                                                                                               // Click offset (relative to the element)
1502                                this.offset.relative.top -                                                                                              // Only for relative positioned nodes: Relative offset from element to offset parent
1503                                this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
1504                                ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top )
1505                        ),
1506                        left: (
1507                                pageX -                                                                                                                                 // The absolute mouse position
1508                                this.offset.click.left -                                                                                                // Click offset (relative to the element)
1509                                this.offset.relative.left -                                                                                             // Only for relative positioned nodes: Relative offset from element to offset parent
1510                                this.offset.parent.left +                                                                                               // The offsetParent's offset without borders (offset + border)
1511                                ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left )
1512                        )
1513                };
1514
1515        },
1516
1517        _clear: function() {
1518                this.helper.removeClass("ui-draggable-dragging");
1519                if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
1520                        this.helper.remove();
1521                }
1522                this.helper = null;
1523                this.cancelHelperRemoval = false;
1524        },
1525
1526        // From now on bulk stuff - mainly helpers
1527
1528        _trigger: function(type, event, ui) {
1529                ui = ui || this._uiHash();
1530                $.ui.plugin.call(this, type, [event, ui]);
1531                //The absolute position has to be recalculated after plugins
1532                if(type === "drag") {
1533                        this.positionAbs = this._convertPositionTo("absolute");
1534                }
1535                return $.Widget.prototype._trigger.call(this, type, event, ui);
1536        },
1537
1538        plugins: {},
1539
1540        _uiHash: function() {
1541                return {
1542                        helper: this.helper,
1543                        position: this.position,
1544                        originalPosition: this.originalPosition,
1545                        offset: this.positionAbs
1546                };
1547        }
1548
1549});
1550
1551$.ui.plugin.add("draggable", "connectToSortable", {
1552        start: function(event, ui) {
1553
1554                var inst = $(this).data("ui-draggable"), o = inst.options,
1555                        uiSortable = $.extend({}, ui, { item: inst.element });
1556                inst.sortables = [];
1557                $(o.connectToSortable).each(function() {
1558                        var sortable = $.data(this, "ui-sortable");
1559                        if (sortable && !sortable.options.disabled) {
1560                                inst.sortables.push({
1561                                        instance: sortable,
1562                                        shouldRevert: sortable.options.revert
1563                                });
1564                                sortable.refreshPositions();    // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
1565                                sortable._trigger("activate", event, uiSortable);
1566                        }
1567                });
1568
1569        },
1570        stop: function(event, ui) {
1571
1572                //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
1573                var inst = $(this).data("ui-draggable"),
1574                        uiSortable = $.extend({}, ui, { item: inst.element });
1575
1576                $.each(inst.sortables, function() {
1577                        if(this.instance.isOver) {
1578
1579                                this.instance.isOver = 0;
1580
1581                                inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
1582                                this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
1583
1584                                //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid"
1585                                if(this.shouldRevert) {
1586                                        this.instance.options.revert = this.shouldRevert;
1587                                }
1588
1589                                //Trigger the stop of the sortable
1590                                this.instance._mouseStop(event);
1591
1592                                this.instance.options.helper = this.instance.options._helper;
1593
1594                                //If the helper has been the original item, restore properties in the sortable
1595                                if(inst.options.helper === "original") {
1596                                        this.instance.currentItem.css({ top: "auto", left: "auto" });
1597                                }
1598
1599                        } else {
1600                                this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
1601                                this.instance._trigger("deactivate", event, uiSortable);
1602                        }
1603
1604                });
1605
1606        },
1607        drag: function(event, ui) {
1608
1609                var inst = $(this).data("ui-draggable"), that = this;
1610
1611                $.each(inst.sortables, function() {
1612
1613                        var innermostIntersecting = false,
1614                                thisSortable = this;
1615
1616                        //Copy over some variables to allow calling the sortable's native _intersectsWith
1617                        this.instance.positionAbs = inst.positionAbs;
1618                        this.instance.helperProportions = inst.helperProportions;
1619                        this.instance.offset.click = inst.offset.click;
1620
1621                        if(this.instance._intersectsWith(this.instance.containerCache)) {
1622                                innermostIntersecting = true;
1623                                $.each(inst.sortables, function () {
1624                                        this.instance.positionAbs = inst.positionAbs;
1625                                        this.instance.helperProportions = inst.helperProportions;
1626                                        this.instance.offset.click = inst.offset.click;
1627                                        if (this !== thisSortable &&
1628                                                this.instance._intersectsWith(this.instance.containerCache) &&
1629                                                $.contains(thisSortable.instance.element[0], this.instance.element[0])
1630                                        ) {
1631                                                innermostIntersecting = false;
1632                                        }
1633                                        return innermostIntersecting;
1634                                });
1635                        }
1636
1637
1638                        if(innermostIntersecting) {
1639                                //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
1640                                if(!this.instance.isOver) {
1641
1642                                        this.instance.isOver = 1;
1643                                        //Now we fake the start of dragging for the sortable instance,
1644                                        //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
1645                                        //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
1646                                        this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true);
1647                                        this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
1648                                        this.instance.options.helper = function() { return ui.helper[0]; };
1649
1650                                        event.target = this.instance.currentItem[0];
1651                                        this.instance._mouseCapture(event, true);
1652                                        this.instance._mouseStart(event, true, true);
1653
1654                                        //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
1655                                        this.instance.offset.click.top = inst.offset.click.top;
1656                                        this.instance.offset.click.left = inst.offset.click.left;
1657                                        this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
1658                                        this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
1659
1660                                        inst._trigger("toSortable", event);
1661                                        inst.dropped = this.instance.element; //draggable revert needs that
1662                                        //hack so receive/update callbacks work (mostly)
1663                                        inst.currentItem = inst.element;
1664                                        this.instance.fromOutside = inst;
1665
1666                                }
1667
1668                                //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
1669                                if(this.instance.currentItem) {
1670                                        this.instance._mouseDrag(event);
1671                                }
1672
1673                        } else {
1674
1675                                //If it doesn't intersect with the sortable, and it intersected before,
1676                                //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
1677                                if(this.instance.isOver) {
1678
1679                                        this.instance.isOver = 0;
1680                                        this.instance.cancelHelperRemoval = true;
1681
1682                                        //Prevent reverting on this forced stop
1683                                        this.instance.options.revert = false;
1684
1685                                        // The out event needs to be triggered independently
1686                                        this.instance._trigger("out", event, this.instance._uiHash(this.instance));
1687
1688                                        this.instance._mouseStop(event, true);
1689                                        this.instance.options.helper = this.instance.options._helper;
1690
1691                                        //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
1692                                        this.instance.currentItem.remove();
1693                                        if(this.instance.placeholder) {
1694                                                this.instance.placeholder.remove();
1695                                        }
1696
1697                                        inst._trigger("fromSortable", event);
1698                                        inst.dropped = false; //draggable revert needs that
1699                                }
1700
1701                        }
1702
1703                });
1704
1705        }
1706});
1707
1708$.ui.plugin.add("draggable", "cursor", {
1709        start: function() {
1710                var t = $("body"), o = $(this).data("ui-draggable").options;
1711                if (t.css("cursor")) {
1712                        o._cursor = t.css("cursor");
1713                }
1714                t.css("cursor", o.cursor);
1715        },
1716        stop: function() {
1717                var o = $(this).data("ui-draggable").options;
1718                if (o._cursor) {
1719                        $("body").css("cursor", o._cursor);
1720                }
1721        }
1722});
1723
1724$.ui.plugin.add("draggable", "opacity", {
1725        start: function(event, ui) {
1726                var t = $(ui.helper), o = $(this).data("ui-draggable").options;
1727                if(t.css("opacity")) {
1728                        o._opacity = t.css("opacity");
1729                }
1730                t.css("opacity", o.opacity);
1731        },
1732        stop: function(event, ui) {
1733                var o = $(this).data("ui-draggable").options;
1734                if(o._opacity) {
1735                        $(ui.helper).css("opacity", o._opacity);
1736                }
1737        }
1738});
1739
1740$.ui.plugin.add("draggable", "scroll", {
1741        start: function() {
1742                var i = $(this).data("ui-draggable");
1743                if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
1744                        i.overflowOffset = i.scrollParent.offset();
1745                }
1746        },
1747        drag: function( event ) {
1748
1749                var i = $(this).data("ui-draggable"), o = i.options, scrolled = false;
1750
1751                if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
1752
1753                        if(!o.axis || o.axis !== "x") {
1754                                if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
1755                                        i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
1756                                } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) {
1757                                        i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
1758                                }
1759                        }
1760
1761                        if(!o.axis || o.axis !== "y") {
1762                                if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
1763                                        i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
1764                                } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) {
1765                                        i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
1766                                }
1767                        }
1768
1769                } else {
1770
1771                        if(!o.axis || o.axis !== "x") {
1772                                if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
1773                                        scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
1774                                } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
1775                                        scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
1776                                }
1777                        }
1778
1779                        if(!o.axis || o.axis !== "y") {
1780                                if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
1781                                        scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
1782                                } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
1783                                        scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
1784                                }
1785                        }
1786
1787                }
1788
1789                if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
1790                        $.ui.ddmanager.prepareOffsets(i, event);
1791                }
1792
1793        }
1794});
1795
1796$.ui.plugin.add("draggable", "snap", {
1797        start: function() {
1798
1799                var i = $(this).data("ui-draggable"),
1800                        o = i.options;
1801
1802                i.snapElements = [];
1803
1804                $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
1805                        var $t = $(this),
1806                                $o = $t.offset();
1807                        if(this !== i.element[0]) {
1808                                i.snapElements.push({
1809                                        item: this,
1810                                        width: $t.outerWidth(), height: $t.outerHeight(),
1811                                        top: $o.top, left: $o.left
1812                                });
1813                        }
1814                });
1815
1816        },
1817        drag: function(event, ui) {
1818
1819                var ts, bs, ls, rs, l, r, t, b, i, first,
1820                        inst = $(this).data("ui-draggable"),
1821                        o = inst.options,
1822                        d = o.snapTolerance,
1823                        x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
1824                        y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
1825
1826                for (i = inst.snapElements.length - 1; i >= 0; i--){
1827
1828                        l = inst.snapElements[i].left;
1829                        r = l + inst.snapElements[i].width;
1830                        t = inst.snapElements[i].top;
1831                        b = t + inst.snapElements[i].height;
1832
1833                        if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
1834                                if(inst.snapElements[i].snapping) {
1835                                        (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1836                                }
1837                                inst.snapElements[i].snapping = false;
1838                                continue;
1839                        }
1840
1841                        if(o.snapMode !== "inner") {
1842                                ts = Math.abs(t - y2) <= d;
1843                                bs = Math.abs(b - y1) <= d;
1844                                ls = Math.abs(l - x2) <= d;
1845                                rs = Math.abs(r - x1) <= d;
1846                                if(ts) {
1847                                        ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1848                                }
1849                                if(bs) {
1850                                        ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
1851                                }
1852                                if(ls) {
1853                                        ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
1854                                }
1855                                if(rs) {
1856                                        ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
1857                                }
1858                        }
1859
1860                        first = (ts || bs || ls || rs);
1861
1862                        if(o.snapMode !== "outer") {
1863                                ts = Math.abs(t - y1) <= d;
1864                                bs = Math.abs(b - y2) <= d;
1865                                ls = Math.abs(l - x1) <= d;
1866                                rs = Math.abs(r - x2) <= d;
1867                                if(ts) {
1868                                        ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
1869                                }
1870                                if(bs) {
1871                                        ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1872                                }
1873                                if(ls) {
1874                                        ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
1875                                }
1876                                if(rs) {
1877                                        ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
1878                                }
1879                        }
1880
1881                        if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
1882                                (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1883                        }
1884                        inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
1885
1886                }
1887
1888        }
1889});
1890
1891$.ui.plugin.add("draggable", "stack", {
1892        start: function() {
1893                var min,
1894                        o = this.data("ui-draggable").options,
1895                        group = $.makeArray($(o.stack)).sort(function(a,b) {
1896                                return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
1897                        });
1898
1899                if (!group.length) { return; }
1900
1901                min = parseInt($(group[0]).css("zIndex"), 10) || 0;
1902                $(group).each(function(i) {
1903                        $(this).css("zIndex", min + i);
1904                });
1905                this.css("zIndex", (min + group.length));
1906        }
1907});
1908
1909$.ui.plugin.add("draggable", "zIndex", {
1910        start: function(event, ui) {
1911                var t = $(ui.helper), o = $(this).data("ui-draggable").options;
1912                if(t.css("zIndex")) {
1913                        o._zIndex = t.css("zIndex");
1914                }
1915                t.css("zIndex", o.zIndex);
1916        },
1917        stop: function(event, ui) {
1918                var o = $(this).data("ui-draggable").options;
1919                if(o._zIndex) {
1920                        $(ui.helper).css("zIndex", o._zIndex);
1921                }
1922        }
1923});
1924
1925})(jQuery);
1926(function( $, undefined ) {
1927
1928function isOverAxis( x, reference, size ) {
1929        return ( x > reference ) && ( x < ( reference + size ) );
1930}
1931
1932$.widget("ui.droppable", {
1933        version: "1.10.3",
1934        widgetEventPrefix: "drop",
1935        options: {
1936                accept: "*",
1937                activeClass: false,
1938                addClasses: true,
1939                greedy: false,
1940                hoverClass: false,
1941                scope: "default",
1942                tolerance: "intersect",
1943
1944                // callbacks
1945                activate: null,
1946                deactivate: null,
1947                drop: null,
1948                out: null,
1949                over: null
1950        },
1951        _create: function() {
1952
1953                var o = this.options,
1954                        accept = o.accept;
1955
1956                this.isover = false;
1957                this.isout = true;
1958
1959                this.accept = $.isFunction(accept) ? accept : function(d) {
1960                        return d.is(accept);
1961                };
1962
1963                //Store the droppable's proportions
1964                this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
1965
1966                // Add the reference and positions to the manager
1967                $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
1968                $.ui.ddmanager.droppables[o.scope].push(this);
1969
1970                (o.addClasses && this.element.addClass("ui-droppable"));
1971
1972        },
1973
1974        _destroy: function() {
1975                var i = 0,
1976                        drop = $.ui.ddmanager.droppables[this.options.scope];
1977
1978                for ( ; i < drop.length; i++ ) {
1979                        if ( drop[i] === this ) {
1980                                drop.splice(i, 1);
1981                        }
1982                }
1983
1984                this.element.removeClass("ui-droppable ui-droppable-disabled");
1985        },
1986
1987        _setOption: function(key, value) {
1988
1989                if(key === "accept") {
1990                        this.accept = $.isFunction(value) ? value : function(d) {
1991                                return d.is(value);
1992                        };
1993                }
1994                $.Widget.prototype._setOption.apply(this, arguments);
1995        },
1996
1997        _activate: function(event) {
1998                var draggable = $.ui.ddmanager.current;
1999                if(this.options.activeClass) {
2000                        this.element.addClass(this.options.activeClass);
2001                }
2002                if(draggable){
2003                        this._trigger("activate", event, this.ui(draggable));
2004                }
2005        },
2006
2007        _deactivate: function(event) {
2008                var draggable = $.ui.ddmanager.current;
2009                if(this.options.activeClass) {
2010                        this.element.removeClass(this.options.activeClass);
2011                }
2012                if(draggable){
2013                        this._trigger("deactivate", event, this.ui(draggable));
2014                }
2015        },
2016
2017        _over: function(event) {
2018
2019                var draggable = $.ui.ddmanager.current;
2020
2021                // Bail if draggable and droppable are same element
2022                if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2023                        return;
2024                }
2025
2026                if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2027                        if(this.options.hoverClass) {
2028                                this.element.addClass(this.options.hoverClass);
2029                        }
2030                        this._trigger("over", event, this.ui(draggable));
2031                }
2032
2033        },
2034
2035        _out: function(event) {
2036
2037                var draggable = $.ui.ddmanager.current;
2038
2039                // Bail if draggable and droppable are same element
2040                if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2041                        return;
2042                }
2043
2044                if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2045                        if(this.options.hoverClass) {
2046                                this.element.removeClass(this.options.hoverClass);
2047                        }
2048                        this._trigger("out", event, this.ui(draggable));
2049                }
2050
2051        },
2052
2053        _drop: function(event,custom) {
2054
2055                var draggable = custom || $.ui.ddmanager.current,
2056                        childrenIntersection = false;
2057
2058                // Bail if draggable and droppable are same element
2059                if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2060                        return false;
2061                }
2062
2063                this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() {
2064                        var inst = $.data(this, "ui-droppable");
2065                        if(
2066                                inst.options.greedy &&
2067                                !inst.options.disabled &&
2068                                inst.options.scope === draggable.options.scope &&
2069                                inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) &&
2070                                $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
2071                        ) { childrenIntersection = true; return false; }
2072                });
2073                if(childrenIntersection) {
2074                        return false;
2075                }
2076
2077                if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2078                        if(this.options.activeClass) {
2079                                this.element.removeClass(this.options.activeClass);
2080                        }
2081                        if(this.options.hoverClass) {
2082                                this.element.removeClass(this.options.hoverClass);
2083                        }
2084                        this._trigger("drop", event, this.ui(draggable));
2085                        return this.element;
2086                }
2087
2088                return false;
2089
2090        },
2091
2092        ui: function(c) {
2093                return {
2094                        draggable: (c.currentItem || c.element),
2095                        helper: c.helper,
2096                        position: c.position,
2097                        offset: c.positionAbs
2098                };
2099        }
2100
2101});
2102
2103$.ui.intersect = function(draggable, droppable, toleranceMode) {
2104
2105        if (!droppable.offset) {
2106                return false;
2107        }
2108
2109        var draggableLeft, draggableTop,
2110                x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
2111                y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height,
2112                l = droppable.offset.left, r = l + droppable.proportions.width,
2113                t = droppable.offset.top, b = t + droppable.proportions.height;
2114
2115        switch (toleranceMode) {
2116                case "fit":
2117                        return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
2118                case "intersect":
2119                        return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
2120                                x2 - (draggable.helperProportions.width / 2) < r && // Left Half
2121                                t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half
2122                                y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
2123                case "pointer":
2124                        draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);
2125                        draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);
2126                        return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width );
2127                case "touch":
2128                        return (
2129                                (y1 >= t && y1 <= b) || // Top edge touching
2130                                (y2 >= t && y2 <= b) || // Bottom edge touching
2131                                (y1 < t && y2 > b)              // Surrounded vertically
2132                        ) && (
2133                                (x1 >= l && x1 <= r) || // Left edge touching
2134                                (x2 >= l && x2 <= r) || // Right edge touching
2135                                (x1 < l && x2 > r)              // Surrounded horizontally
2136                        );
2137                default:
2138                        return false;
2139                }
2140
2141};
2142
2143/*
2144        This manager tracks offsets of draggables and droppables
2145*/
2146$.ui.ddmanager = {
2147        current: null,
2148        droppables: { "default": [] },
2149        prepareOffsets: function(t, event) {
2150
2151                var i, j,
2152                        m = $.ui.ddmanager.droppables[t.options.scope] || [],
2153                        type = event ? event.type : null, // workaround for #2317
2154                        list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack();
2155
2156                droppablesLoop: for (i = 0; i < m.length; i++) {
2157
2158                        //No disabled and non-accepted
2159                        if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) {
2160                                continue;
2161                        }
2162
2163                        // Filter out elements in the current dragged item
2164                        for (j=0; j < list.length; j++) {
2165                                if(list[j] === m[i].element[0]) {
2166                                        m[i].proportions.height = 0;
2167                                        continue droppablesLoop;
2168                                }
2169                        }
2170
2171                        m[i].visible = m[i].element.css("display") !== "none";
2172                        if(!m[i].visible) {
2173                                continue;
2174                        }
2175
2176                        //Activate the droppable if used directly from draggables
2177                        if(type === "mousedown") {
2178                                m[i]._activate.call(m[i], event);
2179                        }
2180
2181                        m[i].offset = m[i].element.offset();
2182                        m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
2183
2184                }
2185
2186        },
2187        drop: function(draggable, event) {
2188
2189                var dropped = false;
2190                // Create a copy of the droppables in case the list changes during the drop (#9116)
2191                $.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() {
2192
2193                        if(!this.options) {
2194                                return;
2195                        }
2196                        if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) {
2197                                dropped = this._drop.call(this, event) || dropped;
2198                        }
2199
2200                        if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2201                                this.isout = true;
2202                                this.isover = false;
2203                                this._deactivate.call(this, event);
2204                        }
2205
2206                });
2207                return dropped;
2208
2209        },
2210        dragStart: function( draggable, event ) {
2211                //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2212                draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2213                        if( !draggable.options.refreshPositions ) {
2214                                $.ui.ddmanager.prepareOffsets( draggable, event );
2215                        }
2216                });
2217        },
2218        drag: function(draggable, event) {
2219
2220                //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2221                if(draggable.options.refreshPositions) {
2222                        $.ui.ddmanager.prepareOffsets(draggable, event);
2223                }
2224
2225                //Run through all droppables and check their positions based on specific tolerance options
2226                $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2227
2228                        if(this.options.disabled || this.greedyChild || !this.visible) {
2229                                return;
2230                        }
2231
2232                        var parentInstance, scope, parent,
2233                                intersects = $.ui.intersect(draggable, this, this.options.tolerance),
2234                                c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null);
2235                        if(!c) {
2236                                return;
2237                        }
2238
2239                        if (this.options.greedy) {
2240                                // find droppable parents with same scope
2241                                scope = this.options.scope;
2242                                parent = this.element.parents(":data(ui-droppable)").filter(function () {
2243                                        return $.data(this, "ui-droppable").options.scope === scope;
2244                                });
2245
2246                                if (parent.length) {
2247                                        parentInstance = $.data(parent[0], "ui-droppable");
2248                                        parentInstance.greedyChild = (c === "isover");
2249                                }
2250                        }
2251
2252                        // we just moved into a greedy child
2253                        if (parentInstance && c === "isover") {
2254                                parentInstance.isover = false;
2255                                parentInstance.isout = true;
2256                                parentInstance._out.call(parentInstance, event);
2257                        }
2258
2259                        this[c] = true;
2260                        this[c === "isout" ? "isover" : "isout"] = false;
2261                        this[c === "isover" ? "_over" : "_out"].call(this, event);
2262
2263                        // we just moved out of a greedy child
2264                        if (parentInstance && c === "isout") {
2265                                parentInstance.isout = false;
2266                                parentInstance.isover = true;
2267                                parentInstance._over.call(parentInstance, event);
2268                        }
2269                });
2270
2271        },
2272        dragStop: function( draggable, event ) {
2273                draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
2274                //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
2275                if( !draggable.options.refreshPositions ) {
2276                        $.ui.ddmanager.prepareOffsets( draggable, event );
2277                }
2278        }
2279};
2280
2281})(jQuery);
2282(function( $, undefined ) {
2283
2284function num(v) {
2285        return parseInt(v, 10) || 0;
2286}
2287
2288function isNumber(value) {
2289        return !isNaN(parseInt(value, 10));
2290}
2291
2292$.widget("ui.resizable", $.ui.mouse, {
2293        version: "1.10.3",
2294        widgetEventPrefix: "resize",
2295        options: {
2296                alsoResize: false,
2297                animate: false,
2298                animateDuration: "slow",
2299                animateEasing: "swing",
2300                aspectRatio: false,
2301                autoHide: false,
2302                containment: false,
2303                ghost: false,
2304                grid: false,
2305                handles: "e,s,se",
2306                helper: false,
2307                maxHeight: null,
2308                maxWidth: null,
2309                minHeight: 10,
2310                minWidth: 10,
2311                // See #7960
2312                zIndex: 90,
2313
2314                // callbacks
2315                resize: null,
2316                start: null,
2317                stop: null
2318        },
2319        _create: function() {
2320
2321                var n, i, handle, axis, hname,
2322                        that = this,
2323                        o = this.options;
2324                this.element.addClass("ui-resizable");
2325
2326                $.extend(this, {
2327                        _aspectRatio: !!(o.aspectRatio),
2328                        aspectRatio: o.aspectRatio,
2329                        originalElement: this.element,
2330                        _proportionallyResizeElements: [],
2331                        _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
2332                });
2333
2334                //Wrap the element if it cannot hold child nodes
2335                if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
2336
2337                        //Create a wrapper element and set the wrapper to the new current internal element
2338                        this.element.wrap(
2339                                $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
2340                                        position: this.element.css("position"),
2341                                        width: this.element.outerWidth(),
2342                                        height: this.element.outerHeight(),
2343                                        top: this.element.css("top"),
2344                                        left: this.element.css("left")
2345                                })
2346                        );
2347
2348                        //Overwrite the original this.element
2349                        this.element = this.element.parent().data(
2350                                "ui-resizable", this.element.data("ui-resizable")
2351                        );
2352
2353                        this.elementIsWrapper = true;
2354
2355                        //Move margins to the wrapper
2356                        this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
2357                        this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
2358
2359                        //Prevent Safari textarea resize
2360                        this.originalResizeStyle = this.originalElement.css("resize");
2361                        this.originalElement.css("resize", "none");
2362
2363                        //Push the actual element to our proportionallyResize internal array
2364                        this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" }));
2365
2366                        // avoid IE jump (hard set the margin)
2367                        this.originalElement.css({ margin: this.originalElement.css("margin") });
2368
2369                        // fix handlers offset
2370                        this._proportionallyResize();
2371
2372                }
2373
2374                this.handles = o.handles || (!$(".ui-resizable-handle", this.element).length ? "e,s,se" : { n: ".ui-resizable-n", e: ".ui-resizable-e", s: ".ui-resizable-s", w: ".ui-resizable-w", se: ".ui-resizable-se", sw: ".ui-resizable-sw", ne: ".ui-resizable-ne", nw: ".ui-resizable-nw" });
2375                if(this.handles.constructor === String) {
2376
2377                        if ( this.handles === "all") {
2378                                this.handles = "n,e,s,w,se,sw,ne,nw";
2379                        }
2380
2381                        n = this.handles.split(",");
2382                        this.handles = {};
2383
2384                        for(i = 0; i < n.length; i++) {
2385
2386                                handle = $.trim(n[i]);
2387                                hname = "ui-resizable-"+handle;
2388                                axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
2389
2390                                // Apply zIndex to all handles - see #7960
2391                                axis.css({ zIndex: o.zIndex });
2392
2393                                //TODO : What's going on here?
2394                                if ("se" === handle) {
2395                                        axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
2396                                }
2397
2398                                //Insert into internal handles object and append to element
2399                                this.handles[handle] = ".ui-resizable-"+handle;
2400                                this.element.append(axis);
2401                        }
2402
2403                }
2404
2405                this._renderAxis = function(target) {
2406
2407                        var i, axis, padPos, padWrapper;
2408
2409                        target = target || this.element;
2410
2411                        for(i in this.handles) {
2412
2413                                if(this.handles[i].constructor === String) {
2414                                        this.handles[i] = $(this.handles[i], this.element).show();
2415                                }
2416
2417                                //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
2418                                if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
2419
2420                                        axis = $(this.handles[i], this.element);
2421
2422                                        //Checking the correct pad and border
2423                                        padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
2424
2425                                        //The padding type i have to apply...
2426                                        padPos = [ "padding",
2427                                                /ne|nw|n/.test(i) ? "Top" :
2428                                                /se|sw|s/.test(i) ? "Bottom" :
2429                                                /^e$/.test(i) ? "Right" : "Left" ].join("");
2430
2431                                        target.css(padPos, padWrapper);
2432
2433                                        this._proportionallyResize();
2434
2435                                }
2436
2437                                //TODO: What's that good for? There's not anything to be executed left
2438                                if(!$(this.handles[i]).length) {
2439                                        continue;
2440                                }
2441                        }
2442                };
2443
2444                //TODO: make renderAxis a prototype function
2445                this._renderAxis(this.element);
2446
2447                this._handles = $(".ui-resizable-handle", this.element)
2448                        .disableSelection();
2449
2450                //Matching axis name
2451                this._handles.mouseover(function() {
2452                        if (!that.resizing) {
2453                                if (this.className) {
2454                                        axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2455                                }
2456                                //Axis, default = se
2457                                that.axis = axis && axis[1] ? axis[1] : "se";
2458                        }
2459                });
2460
2461                //If we want to auto hide the elements
2462                if (o.autoHide) {
2463                        this._handles.hide();
2464                        $(this.element)
2465                                .addClass("ui-resizable-autohide")
2466                                .mouseenter(function() {
2467                                        if (o.disabled) {
2468                                                return;
2469                                        }
2470                                        $(this).removeClass("ui-resizable-autohide");
2471                                        that._handles.show();
2472                                })
2473                                .mouseleave(function(){
2474                                        if (o.disabled) {
2475                                                return;
2476                                        }
2477                                        if (!that.resizing) {
2478                                                $(this).addClass("ui-resizable-autohide");
2479                                                that._handles.hide();
2480                                        }
2481                                });
2482                }
2483
2484                //Initialize the mouse interaction
2485                this._mouseInit();
2486
2487        },
2488
2489        _destroy: function() {
2490
2491                this._mouseDestroy();
2492
2493                var wrapper,
2494                        _destroy = function(exp) {
2495                                $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2496                                        .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove();
2497                        };
2498
2499                //TODO: Unwrap at same DOM position
2500                if (this.elementIsWrapper) {
2501                        _destroy(this.element);
2502                        wrapper = this.element;
2503                        this.originalElement.css({
2504                                position: wrapper.css("position"),
2505                                width: wrapper.outerWidth(),
2506                                height: wrapper.outerHeight(),
2507                                top: wrapper.css("top"),
2508                                left: wrapper.css("left")
2509                        }).insertAfter( wrapper );
2510                        wrapper.remove();
2511                }
2512
2513                this.originalElement.css("resize", this.originalResizeStyle);
2514                _destroy(this.originalElement);
2515
2516                return this;
2517        },
2518
2519        _mouseCapture: function(event) {
2520                var i, handle,
2521                        capture = false;
2522
2523                for (i in this.handles) {
2524                        handle = $(this.handles[i])[0];
2525                        if (handle === event.target || $.contains(handle, event.target)) {
2526                                capture = true;
2527                        }
2528                }
2529
2530                return !this.options.disabled && capture;
2531        },
2532
2533        _mouseStart: function(event) {
2534
2535                var curleft, curtop, cursor,
2536                        o = this.options,
2537                        iniPos = this.element.position(),
2538                        el = this.element;
2539
2540                this.resizing = true;
2541
2542                // bugfix for http://dev.jquery.com/ticket/1749
2543                if ( (/absolute/).test( el.css("position") ) ) {
2544                        el.css({ position: "absolute", top: el.css("top"), left: el.css("left") });
2545                } else if (el.is(".ui-draggable")) {
2546                        el.css({ position: "absolute", top: iniPos.top, left: iniPos.left });
2547                }
2548
2549                this._renderProxy();
2550
2551                curleft = num(this.helper.css("left"));
2552                curtop = num(this.helper.css("top"));
2553
2554                if (o.containment) {
2555                        curleft += $(o.containment).scrollLeft() || 0;
2556                        curtop += $(o.containment).scrollTop() || 0;
2557                }
2558
2559                //Store needed variables
2560                this.offset = this.helper.offset();
2561                this.position = { left: curleft, top: curtop };
2562                this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2563                this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2564                this.originalPosition = { left: curleft, top: curtop };
2565                this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
2566                this.originalMousePosition = { left: event.pageX, top: event.pageY };
2567
2568                //Aspect Ratio
2569                this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
2570
2571                cursor = $(".ui-resizable-" + this.axis).css("cursor");
2572                $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
2573
2574                el.addClass("ui-resizable-resizing");
2575                this._propagate("start", event);
2576                return true;
2577        },
2578
2579        _mouseDrag: function(event) {
2580
2581                //Increase performance, avoid regex
2582                var data,
2583                        el = this.helper, props = {},
2584                        smp = this.originalMousePosition,
2585                        a = this.axis,
2586                        prevTop = this.position.top,
2587                        prevLeft = this.position.left,
2588                        prevWidth = this.size.width,
2589                        prevHeight = this.size.height,
2590                        dx = (event.pageX-smp.left)||0,
2591                        dy = (event.pageY-smp.top)||0,
2592                        trigger = this._change[a];
2593
2594                if (!trigger) {
2595                        return false;
2596                }
2597
2598                // Calculate the attrs that will be change
2599                data = trigger.apply(this, [event, dx, dy]);
2600
2601                // Put this in the mouseDrag handler since the user can start pressing shift while resizing
2602                this._updateVirtualBoundaries(event.shiftKey);
2603                if (this._aspectRatio || event.shiftKey) {
2604                        data = this._updateRatio(data, event);
2605                }
2606
2607                data = this._respectSize(data, event);
2608
2609                this._updateCache(data);
2610
2611                // plugins callbacks need to be called first
2612                this._propagate("resize", event);
2613
2614                if (this.position.top !== prevTop) {
2615                        props.top = this.position.top + "px";
2616                }
2617                if (this.position.left !== prevLeft) {
2618                        props.left = this.position.left + "px";
2619                }
2620                if (this.size.width !== prevWidth) {
2621                        props.width = this.size.width + "px";
2622                }
2623                if (this.size.height !== prevHeight) {
2624                        props.height = this.size.height + "px";
2625                }
2626                el.css(props);
2627
2628                if (!this._helper && this._proportionallyResizeElements.length) {
2629                        this._proportionallyResize();
2630                }
2631
2632                // Call the user callback if the element was resized
2633                if ( ! $.isEmptyObject(props) ) {
2634                        this._trigger("resize", event, this.ui());
2635                }
2636
2637                return false;
2638        },
2639
2640        _mouseStop: function(event) {
2641
2642                this.resizing = false;
2643                var pr, ista, soffseth, soffsetw, s, left, top,
2644                        o = this.options, that = this;
2645
2646                if(this._helper) {
2647
2648                        pr = this._proportionallyResizeElements;
2649                        ista = pr.length && (/textarea/i).test(pr[0].nodeName);
2650                        soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height;
2651                        soffsetw = ista ? 0 : that.sizeDiff.width;
2652
2653                        s = { width: (that.helper.width()  - soffsetw), height: (that.helper.height() - soffseth) };
2654                        left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null;
2655                        top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
2656
2657                        if (!o.animate) {
2658                                this.element.css($.extend(s, { top: top, left: left }));
2659                        }
2660
2661                        that.helper.height(that.size.height);
2662                        that.helper.width(that.size.width);
2663
2664                        if (this._helper && !o.animate) {
2665                                this._proportionallyResize();
2666                        }
2667                }
2668
2669                $("body").css("cursor", "auto");
2670
2671                this.element.removeClass("ui-resizable-resizing");
2672
2673                this._propagate("stop", event);
2674
2675                if (this._helper) {
2676                        this.helper.remove();
2677                }
2678
2679                return false;
2680
2681        },
2682
2683        _updateVirtualBoundaries: function(forceAspectRatio) {
2684                var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
2685                        o = this.options;
2686
2687                b = {
2688                        minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
2689                        maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
2690                        minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
2691                        maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
2692                };
2693
2694                if(this._aspectRatio || forceAspectRatio) {
2695                        // We want to create an enclosing box whose aspect ration is the requested one
2696                        // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
2697                        pMinWidth = b.minHeight * this.aspectRatio;
2698                        pMinHeight = b.minWidth / this.aspectRatio;
2699                        pMaxWidth = b.maxHeight * this.aspectRatio;
2700                        pMaxHeight = b.maxWidth / this.aspectRatio;
2701
2702                        if(pMinWidth > b.minWidth) {
2703                                b.minWidth = pMinWidth;
2704                        }
2705                        if(pMinHeight > b.minHeight) {
2706                                b.minHeight = pMinHeight;
2707                        }
2708                        if(pMaxWidth < b.maxWidth) {
2709                                b.maxWidth = pMaxWidth;
2710                        }
2711                        if(pMaxHeight < b.maxHeight) {
2712                                b.maxHeight = pMaxHeight;
2713                        }
2714                }
2715                this._vBoundaries = b;
2716        },
2717
2718        _updateCache: function(data) {
2719                this.offset = this.helper.offset();
2720                if (isNumber(data.left)) {
2721                        this.position.left = data.left;
2722                }
2723                if (isNumber(data.top)) {
2724                        this.position.top = data.top;
2725                }
2726                if (isNumber(data.height)) {
2727                        this.size.height = data.height;
2728                }
2729                if (isNumber(data.width)) {
2730                        this.size.width = data.width;
2731                }
2732        },
2733
2734        _updateRatio: function( data ) {
2735
2736                var cpos = this.position,
2737                        csize = this.size,
2738                        a = this.axis;
2739
2740                if (isNumber(data.height)) {
2741                        data.width = (data.height * this.aspectRatio);
2742                } else if (isNumber(data.width)) {
2743                        data.height = (data.width / this.aspectRatio);
2744                }
2745
2746                if (a === "sw") {
2747                        data.left = cpos.left + (csize.width - data.width);
2748                        data.top = null;
2749                }
2750                if (a === "nw") {
2751                        data.top = cpos.top + (csize.height - data.height);
2752                        data.left = cpos.left + (csize.width - data.width);
2753                }
2754
2755                return data;
2756        },
2757
2758        _respectSize: function( data ) {
2759
2760                var o = this._vBoundaries,
2761                        a = this.axis,
2762                        ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
2763                        isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
2764                        dw = this.originalPosition.left + this.originalSize.width,
2765                        dh = this.position.top + this.size.height,
2766                        cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
2767                if (isminw) {
2768                        data.width = o.minWidth;
2769                }
2770                if (isminh) {
2771                        data.height = o.minHeight;
2772                }
2773                if (ismaxw) {
2774                        data.width = o.maxWidth;
2775                }
2776                if (ismaxh) {
2777                        data.height = o.maxHeight;
2778                }
2779
2780                if (isminw && cw) {
2781                        data.left = dw - o.minWidth;
2782                }
2783                if (ismaxw && cw) {
2784                        data.left = dw - o.maxWidth;
2785                }
2786                if (isminh && ch) {
2787                        data.top = dh - o.minHeight;
2788                }
2789                if (ismaxh && ch) {
2790                        data.top = dh - o.maxHeight;
2791                }
2792
2793                // fixing jump error on top/left - bug #2330
2794                if (!data.width && !data.height && !data.left && data.top) {
2795                        data.top = null;
2796                } else if (!data.width && !data.height && !data.top && data.left) {
2797                        data.left = null;
2798                }
2799
2800                return data;
2801        },
2802
2803        _proportionallyResize: function() {
2804
2805                if (!this._proportionallyResizeElements.length) {
2806                        return;
2807                }
2808
2809                var i, j, borders, paddings, prel,
2810                        element = this.helper || this.element;
2811
2812                for ( i=0; i < this._proportionallyResizeElements.length; i++) {
2813
2814                        prel = this._proportionallyResizeElements[i];
2815
2816                        if (!this.borderDif) {
2817                                this.borderDif = [];
2818                                borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")];
2819                                paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")];
2820
2821                                for ( j = 0; j < borders.length; j++ ) {
2822                                        this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 );
2823                                }
2824                        }
2825
2826                        prel.css({
2827                                height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
2828                                width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
2829                        });
2830
2831                }
2832
2833        },
2834
2835        _renderProxy: function() {
2836
2837                var el = this.element, o = this.options;
2838                this.elementOffset = el.offset();
2839
2840                if(this._helper) {
2841
2842                        this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
2843
2844                        this.helper.addClass(this._helper).css({
2845                                width: this.element.outerWidth() - 1,
2846                                height: this.element.outerHeight() - 1,
2847                                position: "absolute",
2848                                left: this.elementOffset.left +"px",
2849                                top: this.elementOffset.top +"px",
2850                                zIndex: ++o.zIndex //TODO: Don't modify option
2851                        });
2852
2853                        this.helper
2854                                .appendTo("body")
2855                                .disableSelection();
2856
2857                } else {
2858                        this.helper = this.element;
2859                }
2860
2861        },
2862
2863        _change: {
2864                e: function(event, dx) {
2865                        return { width: this.originalSize.width + dx };
2866                },
2867                w: function(event, dx) {
2868                        var cs = this.originalSize, sp = this.originalPosition;
2869                        return { left: sp.left + dx, width: cs.width - dx };
2870                },
2871                n: function(event, dx, dy) {
2872                        var cs = this.originalSize, sp = this.originalPosition;
2873                        return { top: sp.top + dy, height: cs.height - dy };
2874                },
2875                s: function(event, dx, dy) {
2876                        return { height: this.originalSize.height + dy };
2877                },
2878                se: function(event, dx, dy) {
2879                        return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2880                },
2881                sw: function(event, dx, dy) {
2882                        return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2883                },
2884                ne: function(event, dx, dy) {
2885                        return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2886                },
2887                nw: function(event, dx, dy) {
2888                        return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2889                }
2890        },
2891
2892        _propagate: function(n, event) {
2893                $.ui.plugin.call(this, n, [event, this.ui()]);
2894                (n !== "resize" && this._trigger(n, event, this.ui()));
2895        },
2896
2897        plugins: {},
2898
2899        ui: function() {
2900                return {
2901                        originalElement: this.originalElement,
2902                        element: this.element,
2903                        helper: this.helper,
2904                        position: this.position,
2905                        size: this.size,
2906                        originalSize: this.originalSize,
2907                        originalPosition: this.originalPosition
2908                };
2909        }
2910
2911});
2912
2913/*
2914 * Resizable Extensions
2915 */
2916
2917$.ui.plugin.add("resizable", "animate", {
2918
2919        stop: function( event ) {
2920                var that = $(this).data("ui-resizable"),
2921                        o = that.options,
2922                        pr = that._proportionallyResizeElements,
2923                        ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2924                        soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height,
2925                        soffsetw = ista ? 0 : that.sizeDiff.width,
2926                        style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
2927                        left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null,
2928                        top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
2929
2930                that.element.animate(
2931                        $.extend(style, top && left ? { top: top, left: left } : {}), {
2932                                duration: o.animateDuration,
2933                                easing: o.animateEasing,
2934                                step: function() {
2935
2936                                        var data = {
2937                                                width: parseInt(that.element.css("width"), 10),
2938                                                height: parseInt(that.element.css("height"), 10),
2939                                                top: parseInt(that.element.css("top"), 10),
2940                                                left: parseInt(that.element.css("left"), 10)
2941                                        };
2942
2943                                        if (pr && pr.length) {
2944                                                $(pr[0]).css({ width: data.width, height: data.height });
2945                                        }
2946
2947                                        // propagating resize, and updating values for each animation step
2948                                        that._updateCache(data);
2949                                        that._propagate("resize", event);
2950
2951                                }
2952                        }
2953                );
2954        }
2955
2956});
2957
2958$.ui.plugin.add("resizable", "containment", {
2959
2960        start: function() {
2961                var element, p, co, ch, cw, width, height,
2962                        that = $(this).data("ui-resizable"),
2963                        o = that.options,
2964                        el = that.element,
2965                        oc = o.containment,
2966                        ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
2967
2968                if (!ce) {
2969                        return;
2970                }
2971
2972                that.containerElement = $(ce);
2973
2974                if (/document/.test(oc) || oc === document) {
2975                        that.containerOffset = { left: 0, top: 0 };
2976                        that.containerPosition = { left: 0, top: 0 };
2977
2978                        that.parentData = {
2979                                element: $(document), left: 0, top: 0,
2980                                width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
2981                        };
2982                }
2983
2984                // i'm a node, so compute top, left, right, bottom
2985                else {
2986                        element = $(ce);
2987                        p = [];
2988                        $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
2989
2990                        that.containerOffset = element.offset();
2991                        that.containerPosition = element.position();
2992                        that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
2993
2994                        co = that.containerOffset;
2995                        ch = that.containerSize.height;
2996                        cw = that.containerSize.width;
2997                        width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw );
2998                        height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
2999
3000                        that.parentData = {
3001                                element: ce, left: co.left, top: co.top, width: width, height: height
3002                        };
3003                }
3004        },
3005
3006        resize: function( event ) {
3007                var woset, hoset, isParent, isOffsetRelative,
3008                        that = $(this).data("ui-resizable"),
3009                        o = that.options,
3010                        co = that.containerOffset, cp = that.position,
3011                        pRatio = that._aspectRatio || event.shiftKey,
3012                        cop = { top:0, left:0 }, ce = that.containerElement;
3013
3014                if (ce[0] !== document && (/static/).test(ce.css("position"))) {
3015                        cop = co;
3016                }
3017
3018                if (cp.left < (that._helper ? co.left : 0)) {
3019                        that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
3020                        if (pRatio) {
3021                                that.size.height = that.size.width / that.aspectRatio;
3022                        }
3023                        that.position.left = o.helper ? co.left : 0;
3024                }
3025
3026                if (cp.top < (that._helper ? co.top : 0)) {
3027                        that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
3028                        if (pRatio) {
3029                                that.size.width = that.size.height * that.aspectRatio;
3030                        }
3031                        that.position.top = that._helper ? co.top : 0;
3032                }
3033
3034                that.offset.left = that.parentData.left+that.position.left;
3035                that.offset.top = that.parentData.top+that.position.top;
3036
3037                woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width );
3038                hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
3039
3040                isParent = that.containerElement.get(0) === that.element.parent().get(0);
3041                isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position"));
3042
3043                if(isParent && isOffsetRelative) {
3044                        woset -= that.parentData.left;
3045                }
3046
3047                if (woset + that.size.width >= that.parentData.width) {
3048                        that.size.width = that.parentData.width - woset;
3049                        if (pRatio) {
3050                                that.size.height = that.size.width / that.aspectRatio;
3051                        }
3052                }
3053
3054                if (hoset + that.size.height >= that.parentData.height) {
3055                        that.size.height = that.parentData.height - hoset;
3056                        if (pRatio) {
3057                                that.size.width = that.size.height * that.aspectRatio;
3058                        }
3059                }
3060        },
3061
3062        stop: function(){
3063                var that = $(this).data("ui-resizable"),
3064                        o = that.options,
3065                        co = that.containerOffset,
3066                        cop = that.containerPosition,
3067                        ce = that.containerElement,
3068                        helper = $(that.helper),
3069                        ho = helper.offset(),
3070                        w = helper.outerWidth() - that.sizeDiff.width,
3071                        h = helper.outerHeight() - that.sizeDiff.height;
3072
3073                if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) {
3074                        $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3075                }
3076
3077                if (that._helper && !o.animate && (/static/).test(ce.css("position"))) {
3078                        $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3079                }
3080
3081        }
3082});
3083
3084$.ui.plugin.add("resizable", "alsoResize", {
3085
3086        start: function () {
3087                var that = $(this).data("ui-resizable"),
3088                        o = that.options,
3089                        _store = function (exp) {
3090                                $(exp).each(function() {
3091                                        var el = $(this);
3092                                        el.data("ui-resizable-alsoresize", {
3093                                                width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
3094                                                left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
3095                                        });
3096                                });
3097                        };
3098
3099                if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) {
3100                        if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
3101                        else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
3102                }else{
3103                        _store(o.alsoResize);
3104                }
3105        },
3106
3107        resize: function (event, ui) {
3108                var that = $(this).data("ui-resizable"),
3109                        o = that.options,
3110                        os = that.originalSize,
3111                        op = that.originalPosition,
3112                        delta = {
3113                                height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
3114                                top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
3115                        },
3116
3117                        _alsoResize = function (exp, c) {
3118                                $(exp).each(function() {
3119                                        var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
3120                                                css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"];
3121
3122                                        $.each(css, function (i, prop) {
3123                                                var sum = (start[prop]||0) + (delta[prop]||0);
3124                                                if (sum && sum >= 0) {
3125                                                        style[prop] = sum || null;
3126                                                }
3127                                        });
3128
3129                                        el.css(style);
3130                                });
3131                        };
3132
3133                if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) {
3134                        $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
3135                }else{
3136                        _alsoResize(o.alsoResize);
3137                }
3138        },
3139
3140        stop: function () {
3141                $(this).removeData("resizable-alsoresize");
3142        }
3143});
3144
3145$.ui.plugin.add("resizable", "ghost", {
3146
3147        start: function() {
3148
3149                var that = $(this).data("ui-resizable"), o = that.options, cs = that.size;
3150
3151                that.ghost = that.originalElement.clone();
3152                that.ghost
3153                        .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
3154                        .addClass("ui-resizable-ghost")
3155                        .addClass(typeof o.ghost === "string" ? o.ghost : "");
3156
3157                that.ghost.appendTo(that.helper);
3158
3159        },
3160
3161        resize: function(){
3162                var that = $(this).data("ui-resizable");
3163                if (that.ghost) {
3164                        that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width });
3165                }
3166        },
3167
3168        stop: function() {
3169                var that = $(this).data("ui-resizable");
3170                if (that.ghost && that.helper) {
3171                        that.helper.get(0).removeChild(that.ghost.get(0));
3172                }
3173        }
3174
3175});
3176
3177$.ui.plugin.add("resizable", "grid", {
3178
3179        resize: function() {
3180                var that = $(this).data("ui-resizable"),
3181                        o = that.options,
3182                        cs = that.size,
3183                        os = that.originalSize,
3184                        op = that.originalPosition,
3185                        a = that.axis,
3186                        grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid,
3187                        gridX = (grid[0]||1),
3188                        gridY = (grid[1]||1),
3189                        ox = Math.round((cs.width - os.width) / gridX) * gridX,
3190                        oy = Math.round((cs.height - os.height) / gridY) * gridY,
3191                        newWidth = os.width + ox,
3192                        newHeight = os.height + oy,
3193                        isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
3194                        isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
3195                        isMinWidth = o.minWidth && (o.minWidth > newWidth),
3196                        isMinHeight = o.minHeight && (o.minHeight > newHeight);
3197
3198                o.grid = grid;
3199
3200                if (isMinWidth) {
3201                        newWidth = newWidth + gridX;
3202                }
3203                if (isMinHeight) {
3204                        newHeight = newHeight + gridY;
3205                }
3206                if (isMaxWidth) {
3207                        newWidth = newWidth - gridX;
3208                }
3209                if (isMaxHeight) {
3210                        newHeight = newHeight - gridY;
3211                }
3212
3213                if (/^(se|s|e)$/.test(a)) {
3214                        that.size.width = newWidth;
3215                        that.size.height = newHeight;
3216                } else if (/^(ne)$/.test(a)) {
3217                        that.size.width = newWidth;
3218                        that.size.height = newHeight;
3219                        that.position.top = op.top - oy;
3220                } else if (/^(sw)$/.test(a)) {
3221                        that.size.width = newWidth;
3222                        that.size.height = newHeight;
3223                        that.position.left = op.left - ox;
3224                } else {
3225                        that.size.width = newWidth;
3226                        that.size.height = newHeight;
3227                        that.position.top = op.top - oy;
3228                        that.position.left = op.left - ox;
3229                }
3230        }
3231
3232});
3233
3234})(jQuery);
3235(function( $, undefined ) {
3236
3237$.widget("ui.selectable", $.ui.mouse, {
3238        version: "1.10.3",
3239        options: {
3240                appendTo: "body",
3241                autoRefresh: true,
3242                distance: 0,
3243                filter: "*",
3244                tolerance: "touch",
3245
3246                // callbacks
3247                selected: null,
3248                selecting: null,
3249                start: null,
3250                stop: null,
3251                unselected: null,
3252                unselecting: null
3253        },
3254        _create: function() {
3255                var selectees,
3256                        that = this;
3257
3258                this.element.addClass("ui-selectable");
3259
3260                this.dragged = false;
3261
3262                // cache selectee children based on filter
3263                this.refresh = function() {
3264                        selectees = $(that.options.filter, that.element[0]);
3265                        selectees.addClass("ui-selectee");
3266                        selectees.each(function() {
3267                                var $this = $(this),
3268                                        pos = $this.offset();
3269                                $.data(this, "selectable-item", {
3270                                        element: this,
3271                                        $element: $this,
3272                                        left: pos.left,
3273                                        top: pos.top,
3274                                        right: pos.left + $this.outerWidth(),
3275                                        bottom: pos.top + $this.outerHeight(),
3276                                        startselected: false,
3277                                        selected: $this.hasClass("ui-selected"),
3278                                        selecting: $this.hasClass("ui-selecting"),
3279                                        unselecting: $this.hasClass("ui-unselecting")
3280                                });
3281                        });
3282                };
3283                this.refresh();
3284
3285                this.selectees = selectees.addClass("ui-selectee");
3286
3287                this._mouseInit();
3288
3289                this.helper = $("<div class='ui-selectable-helper'></div>");
3290        },
3291
3292        _destroy: function() {
3293                this.selectees
3294                        .removeClass("ui-selectee")
3295                        .removeData("selectable-item");
3296                this.element
3297                        .removeClass("ui-selectable ui-selectable-disabled");
3298                this._mouseDestroy();
3299        },
3300
3301        _mouseStart: function(event) {
3302                var that = this,
3303                        options = this.options;
3304
3305                this.opos = [event.pageX, event.pageY];
3306
3307                if (this.options.disabled) {
3308                        return;
3309                }
3310
3311                this.selectees = $(options.filter, this.element[0]);
3312
3313                this._trigger("start", event);
3314
3315                $(options.appendTo).append(this.helper);
3316                // position helper (lasso)
3317                this.helper.css({
3318                        "left": event.pageX,
3319                        "top": event.pageY,
3320                        "width": 0,
3321                        "height": 0
3322                });
3323
3324                if (options.autoRefresh) {
3325                        this.refresh();
3326                }
3327
3328                this.selectees.filter(".ui-selected").each(function() {
3329                        var selectee = $.data(this, "selectable-item");
3330                        selectee.startselected = true;
3331                        if (!event.metaKey && !event.ctrlKey) {
3332                                selectee.$element.removeClass("ui-selected");
3333                                selectee.selected = false;
3334                                selectee.$element.addClass("ui-unselecting");
3335                                selectee.unselecting = true;
3336                                // selectable UNSELECTING callback
3337                                that._trigger("unselecting", event, {
3338                                        unselecting: selectee.element
3339                                });
3340                        }
3341                });
3342
3343                $(event.target).parents().addBack().each(function() {
3344                        var doSelect,
3345                                selectee = $.data(this, "selectable-item");
3346                        if (selectee) {
3347                                doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
3348                                selectee.$element
3349                                        .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
3350                                        .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
3351                                selectee.unselecting = !doSelect;
3352                                selectee.selecting = doSelect;
3353                                selectee.selected = doSelect;
3354                                // selectable (UN)SELECTING callback
3355                                if (doSelect) {
3356                                        that._trigger("selecting", event, {
3357                                                selecting: selectee.element
3358                                        });
3359                                } else {
3360                                        that._trigger("unselecting", event, {
3361                                                unselecting: selectee.element
3362                                        });
3363                                }
3364                                return false;
3365                        }
3366                });
3367
3368        },
3369
3370        _mouseDrag: function(event) {
3371
3372                this.dragged = true;
3373
3374                if (this.options.disabled) {
3375                        return;
3376                }
3377
3378                var tmp,
3379                        that = this,
3380                        options = this.options,
3381                        x1 = this.opos[0],
3382                        y1 = this.opos[1],
3383                        x2 = event.pageX,
3384                        y2 = event.pageY;
3385
3386                if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
3387                if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
3388                this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
3389
3390                this.selectees.each(function() {
3391                        var selectee = $.data(this, "selectable-item"),
3392                                hit = false;
3393
3394                        //prevent helper from being selected if appendTo: selectable
3395                        if (!selectee || selectee.element === that.element[0]) {
3396                                return;
3397                        }
3398
3399                        if (options.tolerance === "touch") {
3400                                hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
3401                        } else if (options.tolerance === "fit") {
3402                                hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
3403                        }
3404
3405                        if (hit) {
3406                                // SELECT
3407                                if (selectee.selected) {
3408                                        selectee.$element.removeClass("ui-selected");
3409                                        selectee.selected = false;
3410                                }
3411                                if (selectee.unselecting) {
3412                                        selectee.$element.removeClass("ui-unselecting");
3413                                        selectee.unselecting = false;
3414                                }
3415                                if (!selectee.selecting) {
3416                                        selectee.$element.addClass("ui-selecting");
3417                                        selectee.selecting = true;
3418                                        // selectable SELECTING callback
3419                                        that._trigger("selecting", event, {
3420                                                selecting: selectee.element
3421                                        });
3422                                }
3423                        } else {
3424                                // UNSELECT
3425                                if (selectee.selecting) {
3426                                        if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
3427                                                selectee.$element.removeClass("ui-selecting");
3428                                                selectee.selecting = false;
3429                                                selectee.$element.addClass("ui-selected");
3430                                                selectee.selected = true;
3431                                        } else {
3432                                                selectee.$element.removeClass("ui-selecting");
3433                                                selectee.selecting = false;
3434                                                if (selectee.startselected) {
3435                                                        selectee.$element.addClass("ui-unselecting");
3436                                                        selectee.unselecting = true;
3437                                                }
3438                                                // selectable UNSELECTING callback
3439                                                that._trigger("unselecting", event, {
3440                                                        unselecting: selectee.element
3441                                                });
3442                                        }
3443                                }
3444                                if (selectee.selected) {
3445                                        if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
3446                                                selectee.$element.removeClass("ui-selected");
3447                                                selectee.selected = false;
3448
3449                                                selectee.$element.addClass("ui-unselecting");
3450                                                selectee.unselecting = true;
3451                                                // selectable UNSELECTING callback
3452                                                that._trigger("unselecting", event, {
3453                                                        unselecting: selectee.element
3454                                                });
3455                                        }
3456                                }
3457                        }
3458                });
3459
3460                return false;
3461        },
3462
3463        _mouseStop: function(event) {
3464                var that = this;
3465
3466                this.dragged = false;
3467
3468                $(".ui-unselecting", this.element[0]).each(function() {
3469                        var selectee = $.data(this, "selectable-item");
3470                        selectee.$element.removeClass("ui-unselecting");
3471                        selectee.unselecting = false;
3472                        selectee.startselected = false;
3473                        that._trigger("unselected", event, {
3474                                unselected: selectee.element
3475                        });
3476                });
3477                $(".ui-selecting", this.element[0]).each(function() {
3478                        var selectee = $.data(this, "selectable-item");
3479                        selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
3480                        selectee.selecting = false;
3481                        selectee.selected = true;
3482                        selectee.startselected = true;
3483                        that._trigger("selected", event, {
3484                                selected: selectee.element
3485                        });
3486                });
3487                this._trigger("stop", event);
3488
3489                this.helper.remove();
3490
3491                return false;
3492        }
3493
3494});
3495
3496})(jQuery);
3497(function( $, undefined ) {
3498
3499/*jshint loopfunc: true */
3500
3501function isOverAxis( x, reference, size ) {
3502        return ( x > reference ) && ( x < ( reference + size ) );
3503}
3504
3505function isFloating(item) {
3506        return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
3507}
3508
3509$.widget("ui.sortable", $.ui.mouse, {
3510        version: "1.10.3",
3511        widgetEventPrefix: "sort",
3512        ready: false,
3513        options: {
3514                appendTo: "parent",
3515                axis: false,
3516                connectWith: false,
3517                containment: false,
3518                cursor: "auto",
3519                cursorAt: false,
3520                dropOnEmpty: true,
3521                forcePlaceholderSize: false,
3522                forceHelperSize: false,
3523                grid: false,
3524                handle: false,
3525                helper: "original",
3526                items: "> *",
3527                opacity: false,
3528                placeholder: false,
3529                revert: false,
3530                scroll: true,
3531                scrollSensitivity: 20,
3532                scrollSpeed: 20,
3533                scope: "default",
3534                tolerance: "intersect",
3535                zIndex: 1000,
3536
3537                // callbacks
3538                activate: null,
3539                beforeStop: null,
3540                change: null,
3541                deactivate: null,
3542                out: null,
3543                over: null,
3544                receive: null,
3545                remove: null,
3546                sort: null,
3547                start: null,
3548                stop: null,
3549                update: null
3550        },
3551        _create: function() {
3552
3553                var o = this.options;
3554                this.containerCache = {};
3555                this.element.addClass("ui-sortable");
3556
3557                //Get the items
3558                this.refresh();
3559
3560                //Let's determine if the items are being displayed horizontally
3561                this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false;
3562
3563                //Let's determine the parent's offset
3564                this.offset = this.element.offset();
3565
3566                //Initialize mouse events for interaction
3567                this._mouseInit();
3568
3569                //We're ready to go
3570                this.ready = true;
3571
3572        },
3573
3574        _destroy: function() {
3575                this.element
3576                        .removeClass("ui-sortable ui-sortable-disabled");
3577                this._mouseDestroy();
3578
3579                for ( var i = this.items.length - 1; i >= 0; i-- ) {
3580                        this.items[i].item.removeData(this.widgetName + "-item");
3581                }
3582
3583                return this;
3584        },
3585
3586        _setOption: function(key, value){
3587                if ( key === "disabled" ) {
3588                        this.options[ key ] = value;
3589
3590                        this.widget().toggleClass( "ui-sortable-disabled", !!value );
3591                } else {
3592                        // Don't call widget base _setOption for disable as it adds ui-state-disabled class
3593                        $.Widget.prototype._setOption.apply(this, arguments);
3594                }
3595        },
3596
3597        _mouseCapture: function(event, overrideHandle) {
3598                var currentItem = null,
3599                        validHandle = false,
3600                        that = this;
3601
3602                if (this.reverting) {
3603                        return false;
3604                }
3605
3606                if(this.options.disabled || this.options.type === "static") {
3607                        return false;
3608                }
3609
3610                //We have to refresh the items data once first
3611                this._refreshItems(event);
3612
3613                //Find out if the clicked node (or one of its parents) is a actual item in this.items
3614                $(event.target).parents().each(function() {
3615                        if($.data(this, that.widgetName + "-item") === that) {
3616                                currentItem = $(this);
3617                                return false;
3618                        }
3619                });
3620                if($.data(event.target, that.widgetName + "-item") === that) {
3621                        currentItem = $(event.target);
3622                }
3623
3624                if(!currentItem) {
3625                        return false;
3626                }
3627                if(this.options.handle && !overrideHandle) {
3628                        $(this.options.handle, currentItem).find("*").addBack().each(function() {
3629                                if(this === event.target) {
3630                                        validHandle = true;
3631                                }
3632                        });
3633                        if(!validHandle) {
3634                                return false;
3635                        }
3636                }
3637
3638                this.currentItem = currentItem;
3639                this._removeCurrentsFromItems();
3640                return true;
3641
3642        },
3643
3644        _mouseStart: function(event, overrideHandle, noActivation) {
3645
3646                var i, body,
3647                        o = this.options;
3648
3649                this.currentContainer = this;
3650
3651                //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
3652                this.refreshPositions();
3653
3654                //Create and append the visible helper
3655                this.helper = this._createHelper(event);
3656
3657                //Cache the helper size
3658                this._cacheHelperProportions();
3659
3660                /*
3661                 * - Position generation -
3662                 * This block generates everything position related - it's the core of draggables.
3663                 */
3664
3665                //Cache the margins of the original element
3666                this._cacheMargins();
3667
3668                //Get the next scrolling parent
3669                this.scrollParent = this.helper.scrollParent();
3670
3671                //The element's absolute position on the page minus margins
3672                this.offset = this.currentItem.offset();
3673                this.offset = {
3674                        top: this.offset.top - this.margins.top,
3675                        left: this.offset.left - this.margins.left
3676                };
3677
3678                $.extend(this.offset, {
3679                        click: { //Where the click happened, relative to the element
3680                                left: event.pageX - this.offset.left,
3681                                top: event.pageY - this.offset.top
3682                        },
3683                        parent: this._getParentOffset(),
3684                        relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
3685                });
3686
3687                // Only after we got the offset, we can change the helper's position to absolute
3688                // TODO: Still need to figure out a way to make relative sorting possible
3689                this.helper.css("position", "absolute");
3690                this.cssPosition = this.helper.css("position");
3691
3692                //Generate the original position
3693                this.originalPosition = this._generatePosition(event);
3694                this.originalPageX = event.pageX;
3695                this.originalPageY = event.pageY;
3696
3697                //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
3698                (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
3699
3700                //Cache the former DOM position
3701                this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
3702
3703                //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
3704                if(this.helper[0] !== this.currentItem[0]) {
3705                        this.currentItem.hide();
3706                }
3707
3708                //Create the placeholder
3709                this._createPlaceholder();
3710
3711                //Set a containment if given in the options
3712                if(o.containment) {
3713                        this._setContainment();
3714                }
3715
3716                if( o.cursor && o.cursor !== "auto" ) { // cursor option
3717                        body = this.document.find( "body" );
3718
3719                        // support: IE
3720                        this.storedCursor = body.css( "cursor" );
3721                        body.css( "cursor", o.cursor );
3722
3723                        this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
3724                }
3725
3726                if(o.opacity) { // opacity option
3727                        if (this.helper.css("opacity")) {
3728                                this._storedOpacity = this.helper.css("opacity");
3729                        }
3730                        this.helper.css("opacity", o.opacity);
3731                }
3732
3733                if(o.zIndex) { // zIndex option
3734                        if (this.helper.css("zIndex")) {
3735                                this._storedZIndex = this.helper.css("zIndex");
3736                        }
3737                        this.helper.css("zIndex", o.zIndex);
3738                }
3739
3740                //Prepare scrolling
3741                if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
3742                        this.overflowOffset = this.scrollParent.offset();
3743                }
3744
3745                //Call callbacks
3746                this._trigger("start", event, this._uiHash());
3747
3748                //Recache the helper size
3749                if(!this._preserveHelperProportions) {
3750                        this._cacheHelperProportions();
3751                }
3752
3753
3754                //Post "activate" events to possible containers
3755                if( !noActivation ) {
3756                        for ( i = this.containers.length - 1; i >= 0; i-- ) {
3757                                this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
3758                        }
3759                }
3760
3761                //Prepare possible droppables
3762                if($.ui.ddmanager) {
3763                        $.ui.ddmanager.current = this;
3764                }
3765
3766                if ($.ui.ddmanager && !o.dropBehaviour) {
3767                        $.ui.ddmanager.prepareOffsets(this, event);
3768                }
3769
3770                this.dragging = true;
3771
3772                this.helper.addClass("ui-sortable-helper");
3773                this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
3774                return true;
3775
3776        },
3777
3778        _mouseDrag: function(event) {
3779                var i, item, itemElement, intersection,
3780                        o = this.options,
3781                        scrolled = false;
3782
3783                //Compute the helpers position
3784                this.position = this._generatePosition(event);
3785                this.positionAbs = this._convertPositionTo("absolute");
3786
3787                if (!this.lastPositionAbs) {
3788                        this.lastPositionAbs = this.positionAbs;
3789                }
3790
3791                //Do scrolling
3792                if(this.options.scroll) {
3793                        if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
3794
3795                                if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
3796                                        this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
3797                                } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
3798                                        this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
3799                                }
3800
3801                                if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
3802                                        this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
3803                                } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
3804                                        this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
3805                                }
3806
3807                        } else {
3808
3809                                if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
3810                                        scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
3811                                } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
3812                                        scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
3813                                }
3814
3815                                if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
3816                                        scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
3817                                } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
3818                                        scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
3819                                }
3820
3821                        }
3822
3823                        if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
3824                                $.ui.ddmanager.prepareOffsets(this, event);
3825                        }
3826                }
3827
3828                //Regenerate the absolute position used for position checks
3829                this.positionAbs = this._convertPositionTo("absolute");
3830
3831                //Set the helper position
3832                if(!this.options.axis || this.options.axis !== "y") {
3833                        this.helper[0].style.left = this.position.left+"px";
3834                }
3835                if(!this.options.axis || this.options.axis !== "x") {
3836                        this.helper[0].style.top = this.position.top+"px";
3837                }
3838
3839                //Rearrange
3840                for (i = this.items.length - 1; i >= 0; i--) {
3841
3842                        //Cache variables and intersection, continue if no intersection
3843                        item = this.items[i];
3844                        itemElement = item.item[0];
3845                        intersection = this._intersectsWithPointer(item);
3846                        if (!intersection) {
3847                                continue;
3848                        }
3849
3850                        // Only put the placeholder inside the current Container, skip all
3851                        // items form other containers. This works because when moving
3852                        // an item from one container to another the
3853                        // currentContainer is switched before the placeholder is moved.
3854                        //
3855                        // Without this moving items in "sub-sortables" can cause the placeholder to jitter
3856                        // beetween the outer and inner container.
3857                        if (item.instance !== this.currentContainer) {
3858                                continue;
3859                        }
3860
3861                        // cannot intersect with itself
3862                        // no useless actions that have been done before
3863                        // no action if the item moved is the parent of the item checked
3864                        if (itemElement !== this.currentItem[0] &&
3865                                this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
3866                                !$.contains(this.placeholder[0], itemElement) &&
3867                                (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
3868                        ) {
3869
3870                                this.direction = intersection === 1 ? "down" : "up";
3871
3872                                if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
3873                                        this._rearrange(event, item);
3874                                } else {
3875                                        break;
3876                                }
3877
3878                                this._trigger("change", event, this._uiHash());
3879                                break;
3880                        }
3881                }
3882
3883                //Post events to containers
3884                this._contactContainers(event);
3885
3886                //Interconnect with droppables
3887                if($.ui.ddmanager) {
3888                        $.ui.ddmanager.drag(this, event);
3889                }
3890
3891                //Call callbacks
3892                this._trigger("sort", event, this._uiHash());
3893
3894                this.lastPositionAbs = this.positionAbs;
3895                return false;
3896
3897        },
3898
3899        _mouseStop: function(event, noPropagation) {
3900
3901                if(!event) {
3902                        return;
3903                }
3904
3905                //If we are using droppables, inform the manager about the drop
3906                if ($.ui.ddmanager && !this.options.dropBehaviour) {
3907                        $.ui.ddmanager.drop(this, event);
3908                }
3909
3910                if(this.options.revert) {
3911                        var that = this,
3912                                cur = this.placeholder.offset(),
3913                                axis = this.options.axis,
3914                                animation = {};
3915
3916                        if ( !axis || axis === "x" ) {
3917                                animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft);
3918                        }
3919                        if ( !axis || axis === "y" ) {
3920                                animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop);
3921                        }
3922                        this.reverting = true;
3923                        $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
3924                                that._clear(event);
3925                        });
3926                } else {
3927                        this._clear(event, noPropagation);
3928                }
3929
3930                return false;
3931
3932        },
3933
3934        cancel: function() {
3935
3936                if(this.dragging) {
3937
3938                        this._mouseUp({ target: null });
3939
3940                        if(this.options.helper === "original") {
3941                                this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3942                        } else {
3943                                this.currentItem.show();
3944                        }
3945
3946                        //Post deactivating events to containers
3947                        for (var i = this.containers.length - 1; i >= 0; i--){
3948                                this.containers[i]._trigger("deactivate", null, this._uiHash(this));
3949                                if(this.containers[i].containerCache.over) {
3950                                        this.containers[i]._trigger("out", null, this._uiHash(this));
3951                                        this.containers[i].containerCache.over = 0;
3952                                }
3953                        }
3954
3955                }
3956
3957                if (this.placeholder) {
3958                        //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
3959                        if(this.placeholder[0].parentNode) {
3960                                this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
3961                        }
3962                        if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
3963                                this.helper.remove();
3964                        }
3965
3966                        $.extend(this, {
3967                                helper: null,
3968                                dragging: false,
3969                                reverting: false,
3970                                _noFinalSort: null
3971                        });
3972
3973                        if(this.domPosition.prev) {
3974                                $(this.domPosition.prev).after(this.currentItem);
3975                        } else {
3976                                $(this.domPosition.parent).prepend(this.currentItem);
3977                        }
3978                }
3979
3980                return this;
3981
3982        },
3983
3984        serialize: function(o) {
3985
3986                var items = this._getItemsAsjQuery(o && o.connected),
3987                        str = [];
3988                o = o || {};
3989
3990                $(items).each(function() {
3991                        var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
3992                        if (res) {
3993                                str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
3994                        }
3995                });
3996
3997                if(!str.length && o.key) {
3998                        str.push(o.key + "=");
3999                }
4000
4001                return str.join("&");
4002
4003        },
4004
4005        toArray: function(o) {
4006
4007                var items = this._getItemsAsjQuery(o && o.connected),
4008                        ret = [];
4009
4010                o = o || {};
4011
4012                items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
4013                return ret;
4014
4015        },
4016
4017        /* Be careful with the following core functions */
4018        _intersectsWith: function(item) {
4019
4020                var x1 = this.positionAbs.left,
4021                        x2 = x1 + this.helperProportions.width,
4022                        y1 = this.positionAbs.top,
4023                        y2 = y1 + this.helperProportions.height,
4024                        l = item.left,
4025                        r = l + item.width,
4026                        t = item.top,
4027                        b = t + item.height,
4028                        dyClick = this.offset.click.top,
4029                        dxClick = this.offset.click.left,
4030                        isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
4031                        isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
4032                        isOverElement = isOverElementHeight && isOverElementWidth;
4033
4034                if ( this.options.tolerance === "pointer" ||
4035                        this.options.forcePointerForContainers ||
4036                        (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
4037                ) {
4038                        return isOverElement;
4039                } else {
4040
4041                        return (l < x1 + (this.helperProportions.width / 2) && // Right Half
4042                                x2 - (this.helperProportions.width / 2) < r && // Left Half
4043                                t < y1 + (this.helperProportions.height / 2) && // Bottom Half
4044                                y2 - (this.helperProportions.height / 2) < b ); // Top Half
4045
4046                }
4047        },
4048
4049        _intersectsWithPointer: function(item) {
4050
4051                var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
4052                        isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
4053                        isOverElement = isOverElementHeight && isOverElementWidth,
4054                        verticalDirection = this._getDragVerticalDirection(),
4055                        horizontalDirection = this._getDragHorizontalDirection();
4056
4057                if (!isOverElement) {
4058                        return false;
4059                }
4060
4061                return this.floating ?
4062                        ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
4063                        : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
4064
4065        },
4066
4067        _intersectsWithSides: function(item) {
4068
4069                var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
4070                        isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
4071                        verticalDirection = this._getDragVerticalDirection(),
4072                        horizontalDirection = this._getDragHorizontalDirection();
4073
4074                if (this.floating && horizontalDirection) {
4075                        return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
4076                } else {
4077                        return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
4078                }
4079
4080        },
4081
4082        _getDragVerticalDirection: function() {
4083                var delta = this.positionAbs.top - this.lastPositionAbs.top;
4084                return delta !== 0 && (delta > 0 ? "down" : "up");
4085        },
4086
4087        _getDragHorizontalDirection: function() {
4088                var delta = this.positionAbs.left - this.lastPositionAbs.left;
4089                return delta !== 0 && (delta > 0 ? "right" : "left");
4090        },
4091
4092        refresh: function(event) {
4093                this._refreshItems(event);
4094                this.refreshPositions();
4095                return this;
4096        },
4097
4098        _connectWith: function() {
4099                var options = this.options;
4100                return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
4101        },
4102
4103        _getItemsAsjQuery: function(connected) {
4104
4105                var i, j, cur, inst,
4106                        items = [],
4107                        queries = [],
4108                        connectWith = this._connectWith();
4109
4110                if(connectWith && connected) {
4111                        for (i = connectWith.length - 1; i >= 0; i--){
4112                                cur = $(connectWith[i]);
4113                                for ( j = cur.length - 1; j >= 0; j--){
4114                                        inst = $.data(cur[j], this.widgetFullName);
4115                                        if(inst && inst !== this && !inst.options.disabled) {
4116                                                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]);
4117                                        }
4118                                }
4119                        }
4120                }
4121
4122                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]);
4123
4124                for (i = queries.length - 1; i >= 0; i--){
4125                        queries[i][0].each(function() {
4126                                items.push(this);
4127                        });
4128                }
4129
4130                return $(items);
4131
4132        },
4133
4134        _removeCurrentsFromItems: function() {
4135
4136                var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
4137
4138                this.items = $.grep(this.items, function (item) {
4139                        for (var j=0; j < list.length; j++) {
4140                                if(list[j] === item.item[0]) {
4141                                        return false;
4142                                }
4143                        }
4144                        return true;
4145                });
4146
4147        },
4148
4149        _refreshItems: function(event) {
4150
4151                this.items = [];
4152                this.containers = [this];
4153
4154                var i, j, cur, inst, targetData, _queries, item, queriesLength,
4155                        items = this.items,
4156                        queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
4157                        connectWith = this._connectWith();
4158
4159                if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
4160                        for (i = connectWith.length - 1; i >= 0; i--){
4161                                cur = $(connectWith[i]);
4162                                for (j = cur.length - 1; j >= 0; j--){
4163                                        inst = $.data(cur[j], this.widgetFullName);
4164                                        if(inst && inst !== this && !inst.options.disabled) {
4165                                                queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
4166                                                this.containers.push(inst);
4167                                        }
4168                                }
4169                        }
4170                }
4171
4172                for (i = queries.length - 1; i >= 0; i--) {
4173                        targetData = queries[i][1];
4174                        _queries = queries[i][0];
4175
4176                        for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
4177                                item = $(_queries[j]);
4178
4179                                item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
4180
4181                                items.push({
4182                                        item: item,
4183                                        instance: targetData,
4184                                        width: 0, height: 0,
4185                                        left: 0, top: 0
4186                                });
4187                        }
4188                }
4189
4190        },
4191
4192        refreshPositions: function(fast) {
4193
4194                //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
4195                if(this.offsetParent && this.helper) {
4196                        this.offset.parent = this._getParentOffset();
4197                }
4198
4199                var i, item, t, p;
4200
4201                for (i = this.items.length - 1; i >= 0; i--){
4202                        item = this.items[i];
4203
4204                        //We ignore calculating positions of all connected containers when we're not over them
4205                        if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
4206                                continue;
4207                        }
4208
4209                        t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
4210
4211                        if (!fast) {
4212                                item.width = t.outerWidth();
4213                                item.height = t.outerHeight();
4214                        }
4215
4216                        p = t.offset();
4217                        item.left = p.left;
4218                        item.top = p.top;
4219                }
4220
4221                if(this.options.custom && this.options.custom.refreshContainers) {
4222                        this.options.custom.refreshContainers.call(this);
4223                } else {
4224                        for (i = this.containers.length - 1; i >= 0; i--){
4225                                p = this.containers[i].element.offset();
4226                                this.containers[i].containerCache.left = p.left;
4227                                this.containers[i].containerCache.top = p.top;
4228                                this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
4229                                this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
4230                        }
4231                }
4232
4233                return this;
4234        },
4235
4236        _createPlaceholder: function(that) {
4237                that = that || this;
4238                var className,
4239                        o = that.options;
4240
4241                if(!o.placeholder || o.placeholder.constructor === String) {
4242                        className = o.placeholder;
4243                        o.placeholder = {
4244                                element: function() {
4245
4246                                        var nodeName = that.currentItem[0].nodeName.toLowerCase(),
4247                                                element = $( "<" + nodeName + ">", that.document[0] )
4248                                                        .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
4249                                                        .removeClass("ui-sortable-helper");
4250
4251                                        if ( nodeName === "tr" ) {
4252                                                that.currentItem.children().each(function() {
4253                                                        $( "<td>&#160;</td>", that.document[0] )
4254                                                                .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
4255                                                                .appendTo( element );
4256                                                });
4257                                        } else if ( nodeName === "img" ) {
4258                                                element.attr( "src", that.currentItem.attr( "src" ) );
4259                                        }
4260
4261                                        if ( !className ) {
4262                                                element.css( "visibility", "hidden" );
4263                                        }
4264
4265                                        return element;
4266                                },
4267                                update: function(container, p) {
4268
4269                                        // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
4270                                        // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
4271                                        if(className && !o.forcePlaceholderSize) {
4272                                                return;
4273                                        }
4274
4275                                        //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
4276                                        if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
4277                                        if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
4278                                }
4279                        };
4280                }
4281
4282                //Create the placeholder
4283                that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
4284
4285                //Append it after the actual current item
4286                that.currentItem.after(that.placeholder);
4287
4288                //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
4289                o.placeholder.update(that, that.placeholder);
4290
4291        },
4292
4293        _contactContainers: function(event) {
4294                var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating,
4295                        innermostContainer = null,
4296                        innermostIndex = null;
4297
4298                // get innermost container that intersects with item
4299                for (i = this.containers.length - 1; i >= 0; i--) {
4300
4301                        // never consider a container that's located within the item itself
4302                        if($.contains(this.currentItem[0], this.containers[i].element[0])) {
4303                                continue;
4304                        }
4305
4306                        if(this._intersectsWith(this.containers[i].containerCache)) {
4307
4308                                // if we've already found a container and it's more "inner" than this, then continue
4309                                if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
4310                                        continue;
4311                                }
4312
4313                                innermostContainer = this.containers[i];
4314                                innermostIndex = i;
4315
4316                        } else {
4317                                // container doesn't intersect. trigger "out" event if necessary
4318                                if(this.containers[i].containerCache.over) {
4319                                        this.containers[i]._trigger("out", event, this._uiHash(this));
4320                                        this.containers[i].containerCache.over = 0;
4321                                }
4322                        }
4323
4324                }
4325
4326                // if no intersecting containers found, return
4327                if(!innermostContainer) {
4328                        return;
4329                }
4330
4331                // move the item into the container if it's not there already
4332                if(this.containers.length === 1) {
4333                        if (!this.containers[innermostIndex].containerCache.over) {
4334                                this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4335                                this.containers[innermostIndex].containerCache.over = 1;
4336                        }
4337                } else {
4338
4339                        //When entering a new container, we will find the item with the least distance and append our item near it
4340                        dist = 10000;
4341                        itemWithLeastDistance = null;
4342                        floating = innermostContainer.floating || isFloating(this.currentItem);
4343                        posProperty = floating ? "left" : "top";
4344                        sizeProperty = floating ? "width" : "height";
4345                        base = this.positionAbs[posProperty] + this.offset.click[posProperty];
4346                        for (j = this.items.length - 1; j >= 0; j--) {
4347                                if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
4348                                        continue;
4349                                }
4350                                if(this.items[j].item[0] === this.currentItem[0]) {
4351                                        continue;
4352                                }
4353                                if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) {
4354                                        continue;
4355                                }
4356                                cur = this.items[j].item.offset()[posProperty];
4357                                nearBottom = false;
4358                                if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
4359                                        nearBottom = true;
4360                                        cur += this.items[j][sizeProperty];
4361                                }
4362
4363                                if(Math.abs(cur - base) < dist) {
4364                                        dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
4365                                        this.direction = nearBottom ? "up": "down";
4366                                }
4367                        }
4368
4369                        //Check if dropOnEmpty is enabled
4370                        if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
4371                                return;
4372                        }
4373
4374                        if(this.currentContainer === this.containers[innermostIndex]) {
4375                                return;
4376                        }
4377
4378                        itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
4379                        this._trigger("change", event, this._uiHash());
4380                        this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
4381                        this.currentContainer = this.containers[innermostIndex];
4382
4383                        //Update the placeholder
4384                        this.options.placeholder.update(this.currentContainer, this.placeholder);
4385
4386                        this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4387                        this.containers[innermostIndex].containerCache.over = 1;
4388                }
4389
4390
4391        },
4392
4393        _createHelper: function(event) {
4394
4395                var o = this.options,
4396                        helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
4397
4398                //Add the helper to the DOM if that didn't happen already
4399                if(!helper.parents("body").length) {
4400                        $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
4401                }
4402
4403                if(helper[0] === this.currentItem[0]) {
4404                        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") };
4405                }
4406
4407                if(!helper[0].style.width || o.forceHelperSize) {
4408                        helper.width(this.currentItem.width());
4409                }
4410                if(!helper[0].style.height || o.forceHelperSize) {
4411                        helper.height(this.currentItem.height());
4412                }
4413
4414                return helper;
4415
4416        },
4417
4418        _adjustOffsetFromHelper: function(obj) {
4419                if (typeof obj === "string") {
4420                        obj = obj.split(" ");
4421                }
4422                if ($.isArray(obj)) {
4423                        obj = {left: +obj[0], top: +obj[1] || 0};
4424                }
4425                if ("left" in obj) {
4426                        this.offset.click.left = obj.left + this.margins.left;
4427                }
4428                if ("right" in obj) {
4429                        this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
4430                }
4431                if ("top" in obj) {
4432                        this.offset.click.top = obj.top + this.margins.top;
4433                }
4434                if ("bottom" in obj) {
4435                        this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
4436                }
4437        },
4438
4439        _getParentOffset: function() {
4440
4441
4442                //Get the offsetParent and cache its position
4443                this.offsetParent = this.helper.offsetParent();
4444                var po = this.offsetParent.offset();
4445
4446                // This is a special case where we need to modify a offset calculated on start, since the following happened:
4447                // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
4448                // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
4449                //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
4450                if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
4451                        po.left += this.scrollParent.scrollLeft();
4452                        po.top += this.scrollParent.scrollTop();
4453                }
4454
4455                // This needs to be actually done for all browsers, since pageX/pageY includes this information
4456                // with an ugly IE fix
4457                if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
4458                        po = { top: 0, left: 0 };
4459                }
4460
4461                return {
4462                        top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
4463                        left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
4464                };
4465
4466        },
4467
4468        _getRelativeOffset: function() {
4469
4470                if(this.cssPosition === "relative") {
4471                        var p = this.currentItem.position();
4472                        return {
4473                                top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
4474                                left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
4475                        };
4476                } else {
4477                        return { top: 0, left: 0 };
4478                }
4479
4480        },
4481
4482        _cacheMargins: function() {
4483                this.margins = {
4484                        left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
4485                        top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
4486                };
4487        },
4488
4489        _cacheHelperProportions: function() {
4490                this.helperProportions = {
4491                        width: this.helper.outerWidth(),
4492                        height: this.helper.outerHeight()
4493                };
4494        },
4495
4496        _setContainment: function() {
4497
4498                var ce, co, over,
4499                        o = this.options;
4500                if(o.containment === "parent") {
4501                        o.containment = this.helper[0].parentNode;
4502                }
4503                if(o.containment === "document" || o.containment === "window") {
4504                        this.containment = [
4505                                0 - this.offset.relative.left - this.offset.parent.left,
4506                                0 - this.offset.relative.top - this.offset.parent.top,
4507                                $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
4508                                ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
4509                        ];
4510                }
4511
4512                if(!(/^(document|window|parent)$/).test(o.containment)) {
4513                        ce = $(o.containment)[0];
4514                        co = $(o.containment).offset();
4515                        over = ($(ce).css("overflow") !== "hidden");
4516
4517                        this.containment = [
4518                                co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
4519                                co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
4520                                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,
4521                                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
4522                        ];
4523                }
4524
4525        },
4526
4527        _convertPositionTo: function(d, pos) {
4528
4529                if(!pos) {
4530                        pos = this.position;
4531                }
4532                var mod = d === "absolute" ? 1 : -1,
4533                        scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
4534                        scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
4535
4536                return {
4537                        top: (
4538                                pos.top +                                                                                                                               // The absolute mouse position
4539                                this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
4540                                this.offset.parent.top * mod -                                                                                  // The offsetParent's offset without borders (offset + border)
4541                                ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
4542                        ),
4543                        left: (
4544                                pos.left +                                                                                                                              // The absolute mouse position
4545                                this.offset.relative.left * mod +                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
4546                                this.offset.parent.left * mod   -                                                                               // The offsetParent's offset without borders (offset + border)
4547                                ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
4548                        )
4549                };
4550
4551        },
4552
4553        _generatePosition: function(event) {
4554
4555                var top, left,
4556                        o = this.options,
4557                        pageX = event.pageX,
4558                        pageY = event.pageY,
4559                        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);
4560
4561                // This is another very weird special case that only happens for relative elements:
4562                // 1. If the css position is relative
4563                // 2. and the scroll parent is the document or similar to the offset parent
4564                // we have to refresh the relative offset during the scroll so there are no jumps
4565                if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
4566                        this.offset.relative = this._getRelativeOffset();
4567                }
4568
4569                /*
4570                 * - Position constraining -
4571                 * Constrain the position to a mix of grid, containment.
4572                 */
4573
4574                if(this.originalPosition) { //If we are not dragging yet, we won't check for options
4575
4576                        if(this.containment) {
4577                                if(event.pageX - this.offset.click.left < this.containment[0]) {
4578                                        pageX = this.containment[0] + this.offset.click.left;
4579                                }
4580                                if(event.pageY - this.offset.click.top < this.containment[1]) {
4581                                        pageY = this.containment[1] + this.offset.click.top;
4582                                }
4583                                if(event.pageX - this.offset.click.left > this.containment[2]) {
4584                                        pageX = this.containment[2] + this.offset.click.left;
4585                                }
4586                                if(event.pageY - this.offset.click.top > this.containment[3]) {
4587                                        pageY = this.containment[3] + this.offset.click.top;
4588                                }
4589                        }
4590
4591                        if(o.grid) {
4592                                top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
4593                                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;
4594
4595                                left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
4596                                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;
4597                        }
4598
4599                }
4600
4601                return {
4602                        top: (
4603                                pageY -                                                                                                                         // The absolute mouse position
4604                                this.offset.click.top -                                                                                                 // Click offset (relative to the element)
4605                                this.offset.relative.top        -                                                                                       // Only for relative positioned nodes: Relative offset from element to offset parent
4606                                this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
4607                                ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
4608                        ),
4609                        left: (
4610                                pageX -                                                                                                                         // The absolute mouse position
4611                                this.offset.click.left -                                                                                                // Click offset (relative to the element)
4612                                this.offset.relative.left       -                                                                                       // Only for relative positioned nodes: Relative offset from element to offset parent
4613                                this.offset.parent.left +                                                                                               // The offsetParent's offset without borders (offset + border)
4614                                ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
4615                        )
4616                };
4617
4618        },
4619
4620        _rearrange: function(event, i, a, hardRefresh) {
4621
4622                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));
4623
4624                //Various things done here to improve the performance:
4625                // 1. we create a setTimeout, that calls refreshPositions
4626                // 2. on the instance, we have a counter variable, that get's higher after every append
4627                // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
4628                // 4. this lets only the last addition to the timeout stack through
4629                this.counter = this.counter ? ++this.counter : 1;
4630                var counter = this.counter;
4631
4632                this._delay(function() {
4633                        if(counter === this.counter) {
4634                                this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
4635                        }
4636                });
4637
4638        },
4639
4640        _clear: function(event, noPropagation) {
4641
4642                this.reverting = false;
4643                // We delay all events that have to be triggered to after the point where the placeholder has been removed and
4644                // everything else normalized again
4645                var i,
4646                        delayedTriggers = [];
4647
4648                // We first have to update the dom position of the actual currentItem
4649                // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
4650                if(!this._noFinalSort && this.currentItem.parent().length) {
4651                        this.placeholder.before(this.currentItem);
4652                }
4653                this._noFinalSort = null;
4654
4655                if(this.helper[0] === this.currentItem[0]) {
4656                        for(i in this._storedCSS) {
4657                                if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
4658                                        this._storedCSS[i] = "";
4659                                }
4660                        }
4661                        this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4662                } else {
4663                        this.currentItem.show();
4664                }
4665
4666                if(this.fromOutside && !noPropagation) {
4667                        delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
4668                }
4669                if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
4670                        delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
4671                }
4672
4673                // Check if the items Container has Changed and trigger appropriate
4674                // events.
4675                if (this !== this.currentContainer) {
4676                        if(!noPropagation) {
4677                                delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
4678                                delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
4679                                delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
4680                        }
4681                }
4682
4683
4684                //Post events to containers
4685                for (i = this.containers.length - 1; i >= 0; i--){
4686                        if(!noPropagation) {
4687                                delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4688                        }
4689                        if(this.containers[i].containerCache.over) {
4690                                delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4691                                this.containers[i].containerCache.over = 0;
4692                        }
4693                }
4694
4695                //Do what was originally in plugins
4696                if ( this.storedCursor ) {
4697                        this.document.find( "body" ).css( "cursor", this.storedCursor );
4698                        this.storedStylesheet.remove();
4699                }
4700                if(this._storedOpacity) {
4701                        this.helper.css("opacity", this._storedOpacity);
4702                }
4703                if(this._storedZIndex) {
4704                        this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
4705                }
4706
4707                this.dragging = false;
4708                if(this.cancelHelperRemoval) {
4709                        if(!noPropagation) {
4710                                this._trigger("beforeStop", event, this._uiHash());
4711                                for (i=0; i < delayedTriggers.length; i++) {
4712                                        delayedTriggers[i].call(this, event);
4713                                } //Trigger all delayed events
4714                                this._trigger("stop", event, this._uiHash());
4715                        }
4716
4717                        this.fromOutside = false;
4718                        return false;
4719                }
4720
4721                if(!noPropagation) {
4722                        this._trigger("beforeStop", event, this._uiHash());
4723                }
4724
4725                //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4726                this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4727
4728                if(this.helper[0] !== this.currentItem[0]) {
4729                        this.helper.remove();
4730                }
4731                this.helper = null;
4732
4733                if(!noPropagation) {
4734                        for (i=0; i < delayedTriggers.length; i++) {
4735                                delayedTriggers[i].call(this, event);
4736                        } //Trigger all delayed events
4737                        this._trigger("stop", event, this._uiHash());
4738                }
4739
4740                this.fromOutside = false;
4741                return true;
4742
4743        },
4744
4745        _trigger: function() {
4746                if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
4747                        this.cancel();
4748                }
4749        },
4750
4751        _uiHash: function(_inst) {
4752                var inst = _inst || this;
4753                return {
4754                        helper: inst.helper,
4755                        placeholder: inst.placeholder || $([]),
4756                        position: inst.position,
4757                        originalPosition: inst.originalPosition,
4758                        offset: inst.positionAbs,
4759                        item: inst.currentItem,
4760                        sender: _inst ? _inst.element : null
4761                };
4762        }
4763
4764});
4765
4766})(jQuery);
4767(function( $, undefined ) {
4768
4769// number of pages in a slider
4770// (how many times can you page up/down to go through the whole range)
4771var numPages = 5;
4772
4773$.widget( "ui.slider", $.ui.mouse, {
4774        version: "1.10.3",
4775        widgetEventPrefix: "slide",
4776
4777        options: {
4778                animate: false,
4779                distance: 0,
4780                max: 100,
4781                min: 0,
4782                orientation: "horizontal",
4783                range: false,
4784                step: 1,
4785                value: 0,
4786                values: null,
4787
4788                // callbacks
4789                change: null,
4790                slide: null,
4791                start: null,
4792                stop: null
4793        },
4794
4795        _create: function() {
4796                this._keySliding = false;
4797                this._mouseSliding = false;
4798                this._animateOff = true;
4799                this._handleIndex = null;
4800                this._detectOrientation();
4801                this._mouseInit();
4802
4803                this.element
4804                        .addClass( "ui-slider" +
4805                                " ui-slider-" + this.orientation +
4806                                " ui-widget" +
4807                                " ui-widget-content" +
4808                                " ui-corner-all");
4809
4810                this._refresh();
4811                this._setOption( "disabled", this.options.disabled );
4812
4813                this._animateOff = false;
4814        },
4815
4816        _refresh: function() {
4817                this._createRange();
4818                this._createHandles();
4819                this._setupEvents();
4820                this._refreshValue();
4821        },
4822
4823        _createHandles: function() {
4824                var i, handleCount,
4825                        options = this.options,
4826                        existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
4827                        handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
4828                        handles = [];
4829
4830                handleCount = ( options.values && options.values.length ) || 1;
4831
4832                if ( existingHandles.length > handleCount ) {
4833                        existingHandles.slice( handleCount ).remove();
4834                        existingHandles = existingHandles.slice( 0, handleCount );
4835                }
4836
4837                for ( i = existingHandles.length; i < handleCount; i++ ) {
4838                        handles.push( handle );
4839                }
4840
4841                this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
4842
4843                this.handle = this.handles.eq( 0 );
4844
4845                this.handles.each(function( i ) {
4846                        $( this ).data( "ui-slider-handle-index", i );
4847                });
4848        },
4849
4850        _createRange: function() {
4851                var options = this.options,
4852                        classes = "";
4853
4854                if ( options.range ) {
4855                        if ( options.range === true ) {
4856                                if ( !options.values ) {
4857                                        options.values = [ this._valueMin(), this._valueMin() ];
4858                                } else if ( options.values.length && options.values.length !== 2 ) {
4859                                        options.values = [ options.values[0], options.values[0] ];
4860                                } else if ( $.isArray( options.values ) ) {
4861                                        options.values = options.values.slice(0);
4862                                }
4863                        }
4864
4865                        if ( !this.range || !this.range.length ) {
4866                                this.range = $( "<div></div>" )
4867                                        .appendTo( this.element );
4868
4869                                classes = "ui-slider-range" +
4870                                // note: this isn't the most fittingly semantic framework class for this element,
4871                                // but worked best visually with a variety of themes
4872                                " ui-widget-header ui-corner-all";
4873                        } else {
4874                                this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
4875                                        // Handle range switching from true to min/max
4876                                        .css({
4877                                                "left": "",
4878                                                "bottom": ""
4879                                        });
4880                        }
4881
4882                        this.range.addClass( classes +
4883                                ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
4884                } else {
4885                        this.range = $([]);
4886                }
4887        },
4888
4889        _setupEvents: function() {
4890                var elements = this.handles.add( this.range ).filter( "a" );
4891                this._off( elements );
4892                this._on( elements, this._handleEvents );
4893                this._hoverable( elements );
4894                this._focusable( elements );
4895        },
4896
4897        _destroy: function() {
4898                this.handles.remove();
4899                this.range.remove();
4900
4901                this.element
4902                        .removeClass( "ui-slider" +
4903                                " ui-slider-horizontal" +
4904                                " ui-slider-vertical" +
4905                                " ui-widget" +
4906                                " ui-widget-content" +
4907                                " ui-corner-all" );
4908
4909                this._mouseDestroy();
4910        },
4911
4912        _mouseCapture: function( event ) {
4913                var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
4914                        that = this,
4915                        o = this.options;
4916
4917                if ( o.disabled ) {
4918                        return false;
4919                }
4920
4921                this.elementSize = {
4922                        width: this.element.outerWidth(),
4923                        height: this.element.outerHeight()
4924                };
4925                this.elementOffset = this.element.offset();
4926
4927                position = { x: event.pageX, y: event.pageY };
4928                normValue = this._normValueFromMouse( position );
4929                distance = this._valueMax() - this._valueMin() + 1;
4930                this.handles.each(function( i ) {
4931                        var thisDistance = Math.abs( normValue - that.values(i) );
4932                        if (( distance > thisDistance ) ||
4933                                ( distance === thisDistance &&
4934                                        (i === that._lastChangedValue || that.values(i) === o.min ))) {
4935                                distance = thisDistance;
4936                                closestHandle = $( this );
4937                                index = i;
4938                        }
4939                });
4940
4941                allowed = this._start( event, index );
4942                if ( allowed === false ) {
4943                        return false;
4944                }
4945                this._mouseSliding = true;
4946
4947                this._handleIndex = index;
4948
4949                closestHandle
4950                        .addClass( "ui-state-active" )
4951                        .focus();
4952
4953                offset = closestHandle.offset();
4954                mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
4955                this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
4956                        left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
4957                        top: event.pageY - offset.top -
4958                                ( closestHandle.height() / 2 ) -
4959                                ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
4960                                ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
4961                                ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
4962                };
4963
4964                if ( !this.handles.hasClass( "ui-state-hover" ) ) {
4965                        this._slide( event, index, normValue );
4966                }
4967                this._animateOff = true;
4968                return true;
4969        },
4970
4971        _mouseStart: function() {
4972                return true;
4973        },
4974
4975        _mouseDrag: function( event ) {
4976                var position = { x: event.pageX, y: event.pageY },
4977                        normValue = this._normValueFromMouse( position );
4978
4979                this._slide( event, this._handleIndex, normValue );
4980
4981                return false;
4982        },
4983
4984        _mouseStop: function( event ) {
4985                this.handles.removeClass( "ui-state-active" );
4986                this._mouseSliding = false;
4987
4988                this._stop( event, this._handleIndex );
4989                this._change( event, this._handleIndex );
4990
4991                this._handleIndex = null;
4992                this._clickOffset = null;
4993                this._animateOff = false;
4994
4995                return false;
4996        },
4997
4998        _detectOrientation: function() {
4999                this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
5000        },
5001
5002        _normValueFromMouse: function( position ) {
5003                var pixelTotal,
5004                        pixelMouse,
5005                        percentMouse,
5006                        valueTotal,
5007                        valueMouse;
5008
5009                if ( this.orientation === "horizontal" ) {
5010                        pixelTotal = this.elementSize.width;
5011                        pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
5012                } else {
5013                        pixelTotal = this.elementSize.height;
5014                        pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
5015                }
5016
5017                percentMouse = ( pixelMouse / pixelTotal );
5018                if ( percentMouse > 1 ) {
5019                        percentMouse = 1;
5020                }
5021                if ( percentMouse < 0 ) {
5022                        percentMouse = 0;
5023                }
5024                if ( this.orientation === "vertical" ) {
5025                        percentMouse = 1 - percentMouse;
5026                }
5027
5028                valueTotal = this._valueMax() - this._valueMin();
5029                valueMouse = this._valueMin() + percentMouse * valueTotal;
5030
5031                return this._trimAlignValue( valueMouse );
5032        },
5033
5034        _start: function( event, index ) {
5035                var uiHash = {
5036                        handle: this.handles[ index ],
5037                        value: this.value()
5038                };
5039                if ( this.options.values && this.options.values.length ) {
5040                        uiHash.value = this.values( index );
5041                        uiHash.values = this.values();
5042                }
5043                return this._trigger( "start", event, uiHash );
5044        },
5045
5046        _slide: function( event, index, newVal ) {
5047                var otherVal,
5048                        newValues,
5049                        allowed;
5050
5051                if ( this.options.values && this.options.values.length ) {
5052                        otherVal = this.values( index ? 0 : 1 );
5053
5054                        if ( ( this.options.values.length === 2 && this.options.range === true ) &&
5055                                        ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
5056                                ) {
5057                                newVal = otherVal;
5058                        }
5059
5060                        if ( newVal !== this.values( index ) ) {
5061                                newValues = this.values();
5062                                newValues[ index ] = newVal;
5063                                // A slide can be canceled by returning false from the slide callback
5064                                allowed = this._trigger( "slide", event, {
5065                                        handle: this.handles[ index ],
5066                                        value: newVal,
5067                                        values: newValues
5068                                } );
5069                                otherVal = this.values( index ? 0 : 1 );
5070                                if ( allowed !== false ) {
5071                                        this.values( index, newVal, true );
5072                                }
5073                        }
5074                } else {
5075                        if ( newVal !== this.value() ) {
5076                                // A slide can be canceled by returning false from the slide callback
5077                                allowed = this._trigger( "slide", event, {
5078                                        handle: this.handles[ index ],
5079                                        value: newVal
5080                                } );
5081                                if ( allowed !== false ) {
5082                                        this.value( newVal );
5083                                }
5084                        }
5085                }
5086        },
5087
5088        _stop: function( event, index ) {
5089                var uiHash = {
5090                        handle: this.handles[ index ],
5091                        value: this.value()
5092                };
5093                if ( this.options.values && this.options.values.length ) {
5094                        uiHash.value = this.values( index );
5095                        uiHash.values = this.values();
5096                }
5097
5098                this._trigger( "stop", event, uiHash );
5099        },
5100
5101        _change: function( event, index ) {
5102                if ( !this._keySliding && !this._mouseSliding ) {
5103                        var uiHash = {
5104                                handle: this.handles[ index ],
5105                                value: this.value()
5106                        };
5107                        if ( this.options.values && this.options.values.length ) {
5108                                uiHash.value = this.values( index );
5109                                uiHash.values = this.values();
5110                        }
5111
5112                        //store the last changed value index for reference when handles overlap
5113                        this._lastChangedValue = index;
5114
5115                        this._trigger( "change", event, uiHash );
5116                }
5117        },
5118
5119        value: function( newValue ) {
5120                if ( arguments.length ) {
5121                        this.options.value = this._trimAlignValue( newValue );
5122                        this._refreshValue();
5123                        this._change( null, 0 );
5124                        return;
5125                }
5126
5127                return this._value();
5128        },
5129
5130        values: function( index, newValue ) {
5131                var vals,
5132                        newValues,
5133                        i;
5134
5135                if ( arguments.length > 1 ) {
5136                        this.options.values[ index ] = this._trimAlignValue( newValue );
5137                        this._refreshValue();
5138                        this._change( null, index );
5139                        return;
5140                }
5141
5142                if ( arguments.length ) {
5143                        if ( $.isArray( arguments[ 0 ] ) ) {
5144                                vals = this.options.values;
5145                                newValues = arguments[ 0 ];
5146                                for ( i = 0; i < vals.length; i += 1 ) {
5147                                        vals[ i ] = this._trimAlignValue( newValues[ i ] );
5148                                        this._change( null, i );
5149                                }
5150                                this._refreshValue();
5151                        } else {
5152                                if ( this.options.values && this.options.values.length ) {
5153                                        return this._values( index );
5154                                } else {
5155                                        return this.value();
5156                                }
5157                        }
5158                } else {
5159                        return this._values();
5160                }
5161        },
5162
5163        _setOption: function( key, value ) {
5164                var i,
5165                        valsLength = 0;
5166
5167                if ( key === "range" && this.options.range === true ) {
5168                        if ( value === "min" ) {
5169                                this.options.value = this._values( 0 );
5170                                this.options.values = null;
5171                        } else if ( value === "max" ) {
5172                                this.options.value = this._values( this.options.values.length-1 );
5173                                this.options.values = null;
5174                        }
5175                }
5176
5177                if ( $.isArray( this.options.values ) ) {
5178                        valsLength = this.options.values.length;
5179                }
5180
5181                $.Widget.prototype._setOption.apply( this, arguments );
5182
5183                switch ( key ) {
5184                        case "orientation":
5185                                this._detectOrientation();
5186                                this.element
5187                                        .removeClass( "ui-slider-horizontal ui-slider-vertical" )
5188                                        .addClass( "ui-slider-" + this.orientation );
5189                                this._refreshValue();
5190                                break;
5191                        case "value":
5192                                this._animateOff = true;
5193                                this._refreshValue();
5194                                this._change( null, 0 );
5195                                this._animateOff = false;
5196                                break;
5197                        case "values":
5198                                this._animateOff = true;
5199                                this._refreshValue();
5200                                for ( i = 0; i < valsLength; i += 1 ) {
5201                                        this._change( null, i );
5202                                }
5203                                this._animateOff = false;
5204                                break;
5205                        case "min":
5206                        case "max":
5207                                this._animateOff = true;
5208                                this._refreshValue();
5209                                this._animateOff = false;
5210                                break;
5211                        case "range":
5212                                this._animateOff = true;
5213                                this._refresh();
5214                                this._animateOff = false;
5215                                break;
5216                }
5217        },
5218
5219        //internal value getter
5220        // _value() returns value trimmed by min and max, aligned by step
5221        _value: function() {
5222                var val = this.options.value;
5223                val = this._trimAlignValue( val );
5224
5225                return val;
5226        },
5227
5228        //internal values getter
5229        // _values() returns array of values trimmed by min and max, aligned by step
5230        // _values( index ) returns single value trimmed by min and max, aligned by step
5231        _values: function( index ) {
5232                var val,
5233                        vals,
5234                        i;
5235
5236                if ( arguments.length ) {
5237                        val = this.options.values[ index ];
5238                        val = this._trimAlignValue( val );
5239
5240                        return val;
5241                } else if ( this.options.values && this.options.values.length ) {
5242                        // .slice() creates a copy of the array
5243                        // this copy gets trimmed by min and max and then returned
5244                        vals = this.options.values.slice();
5245                        for ( i = 0; i < vals.length; i+= 1) {
5246                                vals[ i ] = this._trimAlignValue( vals[ i ] );
5247                        }
5248
5249                        return vals;
5250                } else {
5251                        return [];
5252                }
5253        },
5254
5255        // returns the step-aligned value that val is closest to, between (inclusive) min and max
5256        _trimAlignValue: function( val ) {
5257                if ( val <= this._valueMin() ) {
5258                        return this._valueMin();
5259                }
5260                if ( val >= this._valueMax() ) {
5261                        return this._valueMax();
5262                }
5263                var step = ( this.options.step > 0 ) ? this.options.step : 1,
5264                        valModStep = (val - this._valueMin()) % step,
5265                        alignValue = val - valModStep;
5266
5267                if ( Math.abs(valModStep) * 2 >= step ) {
5268                        alignValue += ( valModStep > 0 ) ? step : ( -step );
5269                }
5270
5271                // Since JavaScript has problems with large floats, round
5272                // the final value to 5 digits after the decimal point (see #4124)
5273                return parseFloat( alignValue.toFixed(5) );
5274        },
5275
5276        _valueMin: function() {
5277                return this.options.min;
5278        },
5279
5280        _valueMax: function() {
5281                return this.options.max;
5282        },
5283
5284        _refreshValue: function() {
5285                var lastValPercent, valPercent, value, valueMin, valueMax,
5286                        oRange = this.options.range,
5287                        o = this.options,
5288                        that = this,
5289                        animate = ( !this._animateOff ) ? o.animate : false,
5290                        _set = {};
5291
5292                if ( this.options.values && this.options.values.length ) {
5293                        this.handles.each(function( i ) {
5294                                valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
5295                                _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
5296                                $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
5297                                if ( that.options.range === true ) {
5298                                        if ( that.orientation === "horizontal" ) {
5299                                                if ( i === 0 ) {
5300                                                        that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
5301                                                }
5302                                                if ( i === 1 ) {
5303                                                        that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
5304                                                }
5305                                        } else {
5306                                                if ( i === 0 ) {
5307                                                        that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
5308                                                }
5309                                                if ( i === 1 ) {
5310                                                        that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
5311                                                }
5312                                        }
5313                                }
5314                                lastValPercent = valPercent;
5315                        });
5316                } else {
5317                        value = this.value();
5318                        valueMin = this._valueMin();
5319                        valueMax = this._valueMax();
5320                        valPercent = ( valueMax !== valueMin ) ?
5321                                        ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
5322                                        0;
5323                        _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
5324                        this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
5325
5326                        if ( oRange === "min" && this.orientation === "horizontal" ) {
5327                                this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
5328                        }
5329                        if ( oRange === "max" && this.orientation === "horizontal" ) {
5330                                this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
5331                        }
5332                        if ( oRange === "min" && this.orientation === "vertical" ) {
5333                                this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
5334                        }
5335                        if ( oRange === "max" && this.orientation === "vertical" ) {
5336                                this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
5337                        }
5338                }
5339        },
5340
5341        _handleEvents: {
5342                keydown: function( event ) {
5343                        /*jshint maxcomplexity:25*/
5344                        var allowed, curVal, newVal, step,
5345                                index = $( event.target ).data( "ui-slider-handle-index" );
5346
5347                        switch ( event.keyCode ) {
5348                                case $.ui.keyCode.HOME:
5349                                case $.ui.keyCode.END:
5350                                case $.ui.keyCode.PAGE_UP:
5351                                case $.ui.keyCode.PAGE_DOWN:
5352                                case $.ui.keyCode.UP:
5353                                case $.ui.keyCode.RIGHT:
5354                                case $.ui.keyCode.DOWN:
5355                                case $.ui.keyCode.LEFT:
5356                                        event.preventDefault();
5357                                        if ( !this._keySliding ) {
5358                                                this._keySliding = true;
5359                                                $( event.target ).addClass( "ui-state-active" );
5360                                                allowed = this._start( event, index );
5361                                                if ( allowed === false ) {
5362                                                        return;
5363                                                }
5364                                        }
5365                                        break;
5366                        }
5367
5368                        step = this.options.step;
5369                        if ( this.options.values && this.options.values.length ) {
5370                                curVal = newVal = this.values( index );
5371                        } else {
5372                                curVal = newVal = this.value();
5373                        }
5374
5375                        switch ( event.keyCode ) {
5376                                case $.ui.keyCode.HOME:
5377                                        newVal = this._valueMin();
5378                                        break;
5379                                case $.ui.keyCode.END:
5380                                        newVal = this._valueMax();
5381                                        break;
5382                                case $.ui.keyCode.PAGE_UP:
5383                                        newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
5384                                        break;
5385                                case $.ui.keyCode.PAGE_DOWN:
5386                                        newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
5387                                        break;
5388                                case $.ui.keyCode.UP:
5389                                case $.ui.keyCode.RIGHT:
5390                                        if ( curVal === this._valueMax() ) {
5391                                                return;
5392                                        }
5393                                        newVal = this._trimAlignValue( curVal + step );
5394                                        break;
5395                                case $.ui.keyCode.DOWN:
5396                                case $.ui.keyCode.LEFT:
5397                                        if ( curVal === this._valueMin() ) {
5398                                                return;
5399                                        }
5400                                        newVal = this._trimAlignValue( curVal - step );
5401                                        break;
5402                        }
5403
5404                        this._slide( event, index, newVal );
5405                },
5406                click: function( event ) {
5407                        event.preventDefault();
5408                },
5409                keyup: function( event ) {
5410                        var index = $( event.target ).data( "ui-slider-handle-index" );
5411
5412                        if ( this._keySliding ) {
5413                                this._keySliding = false;
5414                                this._stop( event, index );
5415                                this._change( event, index );
5416                                $( event.target ).removeClass( "ui-state-active" );
5417                        }
5418                }
5419        }
5420
5421});
5422
5423}(jQuery));
Note: See TracBrowser for help on using the repository browser.