a b/docs/site_libs/jqueryui-1.11.4/jquery-ui.js
1
/*! jQuery UI - v1.11.4 - 2016-01-05
2
* http://jqueryui.com
3
* Includes: core.js, widget.js, mouse.js, position.js, draggable.js, droppable.js, resizable.js, selectable.js, sortable.js, accordion.js, autocomplete.js, button.js, dialog.js, menu.js, progressbar.js, selectmenu.js, slider.js, spinner.js, tabs.js, tooltip.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js
4
* Copyright jQuery Foundation and other contributors; Licensed MIT */
5
6
(function( factory ) {
7
    if ( typeof define === "function" && define.amd ) {
8
9
        // AMD. Register as an anonymous module.
10
        define([ "jquery" ], factory );
11
    } else {
12
13
        // Browser globals
14
        factory( jQuery );
15
    }
16
}(function( $ ) {
17
/*!
18
 * jQuery UI Core 1.11.4
19
 * http://jqueryui.com
20
 *
21
 * Copyright jQuery Foundation and other contributors
22
 * Released under the MIT license.
23
 * http://jquery.org/license
24
 *
25
 * http://api.jqueryui.com/category/ui-core/
26
 */
27
28
29
// $.ui might exist from components with no dependencies, e.g., $.ui.position
30
$.ui = $.ui || {};
31
32
$.extend( $.ui, {
33
    version: "1.11.4",
34
35
    keyCode: {
36
        BACKSPACE: 8,
37
        COMMA: 188,
38
        DELETE: 46,
39
        DOWN: 40,
40
        END: 35,
41
        ENTER: 13,
42
        ESCAPE: 27,
43
        HOME: 36,
44
        LEFT: 37,
45
        PAGE_DOWN: 34,
46
        PAGE_UP: 33,
47
        PERIOD: 190,
48
        RIGHT: 39,
49
        SPACE: 32,
50
        TAB: 9,
51
        UP: 38
52
    }
53
});
54
55
// plugins
56
$.fn.extend({
57
    scrollParent: function( includeHidden ) {
58
        var position = this.css( "position" ),
59
            excludeStaticParent = position === "absolute",
60
            overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
61
            scrollParent = this.parents().filter( function() {
62
                var parent = $( this );
63
                if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
64
                    return false;
65
                }
66
                return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) );
67
            }).eq( 0 );
68
69
        return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent;
70
    },
71
72
    uniqueId: (function() {
73
        var uuid = 0;
74
75
        return function() {
76
            return this.each(function() {
77
                if ( !this.id ) {
78
                    this.id = "ui-id-" + ( ++uuid );
79
                }
80
            });
81
        };
82
    })(),
83
84
    removeUniqueId: function() {
85
        return this.each(function() {
86
            if ( /^ui-id-\d+$/.test( this.id ) ) {
87
                $( this ).removeAttr( "id" );
88
            }
89
        });
90
    }
91
});
92
93
// selectors
94
function focusable( element, isTabIndexNotNaN ) {
95
    var map, mapName, img,
96
        nodeName = element.nodeName.toLowerCase();
97
    if ( "area" === nodeName ) {
98
        map = element.parentNode;
99
        mapName = map.name;
100
        if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
101
            return false;
102
        }
103
        img = $( "img[usemap='#" + mapName + "']" )[ 0 ];
104
        return !!img && visible( img );
105
    }
106
    return ( /^(input|select|textarea|button|object)$/.test( nodeName ) ?
107
        !element.disabled :
108
        "a" === nodeName ?
109
            element.href || isTabIndexNotNaN :
110
            isTabIndexNotNaN) &&
111
        // the element and all of its ancestors must be visible
112
        visible( element );
113
}
114
115
function visible( element ) {
116
    return $.expr.filters.visible( element ) &&
117
        !$( element ).parents().addBack().filter(function() {
118
            return $.css( this, "visibility" ) === "hidden";
119
        }).length;
120
}
121
122
$.extend( $.expr[ ":" ], {
123
    data: $.expr.createPseudo ?
124
        $.expr.createPseudo(function( dataName ) {
125
            return function( elem ) {
126
                return !!$.data( elem, dataName );
127
            };
128
        }) :
129
        // support: jQuery <1.8
130
        function( elem, i, match ) {
131
            return !!$.data( elem, match[ 3 ] );
132
        },
133
134
    focusable: function( element ) {
135
        return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
136
    },
137
138
    tabbable: function( element ) {
139
        var tabIndex = $.attr( element, "tabindex" ),
140
            isTabIndexNaN = isNaN( tabIndex );
141
        return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
142
    }
143
});
144
145
// support: jQuery <1.8
146
if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
147
    $.each( [ "Width", "Height" ], function( i, name ) {
148
        var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
149
            type = name.toLowerCase(),
150
            orig = {
151
                innerWidth: $.fn.innerWidth,
152
                innerHeight: $.fn.innerHeight,
153
                outerWidth: $.fn.outerWidth,
154
                outerHeight: $.fn.outerHeight
155
            };
156
157
        function reduce( elem, size, border, margin ) {
158
            $.each( side, function() {
159
                size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
160
                if ( border ) {
161
                    size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
162
                }
163
                if ( margin ) {
164
                    size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
165
                }
166
            });
167
            return size;
168
        }
169
170
        $.fn[ "inner" + name ] = function( size ) {
171
            if ( size === undefined ) {
172
                return orig[ "inner" + name ].call( this );
173
            }
174
175
            return this.each(function() {
176
                $( this ).css( type, reduce( this, size ) + "px" );
177
            });
178
        };
179
180
        $.fn[ "outer" + name] = function( size, margin ) {
181
            if ( typeof size !== "number" ) {
182
                return orig[ "outer" + name ].call( this, size );
183
            }
184
185
            return this.each(function() {
186
                $( this).css( type, reduce( this, size, true, margin ) + "px" );
187
            });
188
        };
189
    });
190
}
191
192
// support: jQuery <1.8
193
if ( !$.fn.addBack ) {
194
    $.fn.addBack = function( selector ) {
195
        return this.add( selector == null ?
196
            this.prevObject : this.prevObject.filter( selector )
197
        );
198
    };
199
}
200
201
// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
202
if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
203
    $.fn.removeData = (function( removeData ) {
204
        return function( key ) {
205
            if ( arguments.length ) {
206
                return removeData.call( this, $.camelCase( key ) );
207
            } else {
208
                return removeData.call( this );
209
            }
210
        };
211
    })( $.fn.removeData );
212
}
213
214
// deprecated
215
$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
216
217
$.fn.extend({
218
    focus: (function( orig ) {
219
        return function( delay, fn ) {
220
            return typeof delay === "number" ?
221
                this.each(function() {
222
                    var elem = this;
223
                    setTimeout(function() {
224
                        $( elem ).focus();
225
                        if ( fn ) {
226
                            fn.call( elem );
227
                        }
228
                    }, delay );
229
                }) :
230
                orig.apply( this, arguments );
231
        };
232
    })( $.fn.focus ),
233
234
    disableSelection: (function() {
235
        var eventType = "onselectstart" in document.createElement( "div" ) ?
236
            "selectstart" :
237
            "mousedown";
238
239
        return function() {
240
            return this.bind( eventType + ".ui-disableSelection", function( event ) {
241
                event.preventDefault();
242
            });
243
        };
244
    })(),
245
246
    enableSelection: function() {
247
        return this.unbind( ".ui-disableSelection" );
248
    },
249
250
    zIndex: function( zIndex ) {
251
        if ( zIndex !== undefined ) {
252
            return this.css( "zIndex", zIndex );
253
        }
254
255
        if ( this.length ) {
256
            var elem = $( this[ 0 ] ), position, value;
257
            while ( elem.length && elem[ 0 ] !== document ) {
258
                // Ignore z-index if position is set to a value where z-index is ignored by the browser
259
                // This makes behavior of this function consistent across browsers
260
                // WebKit always returns auto if the element is positioned
261
                position = elem.css( "position" );
262
                if ( position === "absolute" || position === "relative" || position === "fixed" ) {
263
                    // IE returns 0 when zIndex is not specified
264
                    // other browsers return a string
265
                    // we ignore the case of nested elements with an explicit value of 0
266
                    // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
267
                    value = parseInt( elem.css( "zIndex" ), 10 );
268
                    if ( !isNaN( value ) && value !== 0 ) {
269
                        return value;
270
                    }
271
                }
272
                elem = elem.parent();
273
            }
274
        }
275
276
        return 0;
277
    }
278
});
279
280
// $.ui.plugin is deprecated. Use $.widget() extensions instead.
281
$.ui.plugin = {
282
    add: function( module, option, set ) {
283
        var i,
284
            proto = $.ui[ module ].prototype;
285
        for ( i in set ) {
286
            proto.plugins[ i ] = proto.plugins[ i ] || [];
287
            proto.plugins[ i ].push( [ option, set[ i ] ] );
288
        }
289
    },
290
    call: function( instance, name, args, allowDisconnected ) {
291
        var i,
292
            set = instance.plugins[ name ];
293
294
        if ( !set ) {
295
            return;
296
        }
297
298
        if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
299
            return;
300
        }
301
302
        for ( i = 0; i < set.length; i++ ) {
303
            if ( instance.options[ set[ i ][ 0 ] ] ) {
304
                set[ i ][ 1 ].apply( instance.element, args );
305
            }
306
        }
307
    }
308
};
309
310
311
/*!
312
 * jQuery UI Widget 1.11.4
313
 * http://jqueryui.com
314
 *
315
 * Copyright jQuery Foundation and other contributors
316
 * Released under the MIT license.
317
 * http://jquery.org/license
318
 *
319
 * http://api.jqueryui.com/jQuery.widget/
320
 */
321
322
323
var widget_uuid = 0,
324
    widget_slice = Array.prototype.slice;
325
326
$.cleanData = (function( orig ) {
327
    return function( elems ) {
328
        var events, elem, i;
329
        for ( i = 0; (elem = elems[i]) != null; i++ ) {
330
            try {
331
332
                // Only trigger remove when necessary to save time
333
                events = $._data( elem, "events" );
334
                if ( events && events.remove ) {
335
                    $( elem ).triggerHandler( "remove" );
336
                }
337
338
            // http://bugs.jquery.com/ticket/8235
339
            } catch ( e ) {}
340
        }
341
        orig( elems );
342
    };
343
})( $.cleanData );
344
345
$.widget = function( name, base, prototype ) {
346
    var fullName, existingConstructor, constructor, basePrototype,
347
        // proxiedPrototype allows the provided prototype to remain unmodified
348
        // so that it can be used as a mixin for multiple widgets (#8876)
349
        proxiedPrototype = {},
350
        namespace = name.split( "." )[ 0 ];
351
352
    name = name.split( "." )[ 1 ];
353
    fullName = namespace + "-" + name;
354
355
    if ( !prototype ) {
356
        prototype = base;
357
        base = $.Widget;
358
    }
359
360
    // create selector for plugin
361
    $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
362
        return !!$.data( elem, fullName );
363
    };
364
365
    $[ namespace ] = $[ namespace ] || {};
366
    existingConstructor = $[ namespace ][ name ];
367
    constructor = $[ namespace ][ name ] = function( options, element ) {
368
        // allow instantiation without "new" keyword
369
        if ( !this._createWidget ) {
370
            return new constructor( options, element );
371
        }
372
373
        // allow instantiation without initializing for simple inheritance
374
        // must use "new" keyword (the code above always passes args)
375
        if ( arguments.length ) {
376
            this._createWidget( options, element );
377
        }
378
    };
379
    // extend with the existing constructor to carry over any static properties
380
    $.extend( constructor, existingConstructor, {
381
        version: prototype.version,
382
        // copy the object used to create the prototype in case we need to
383
        // redefine the widget later
384
        _proto: $.extend( {}, prototype ),
385
        // track widgets that inherit from this widget in case this widget is
386
        // redefined after a widget inherits from it
387
        _childConstructors: []
388
    });
389
390
    basePrototype = new base();
391
    // we need to make the options hash a property directly on the new instance
392
    // otherwise we'll modify the options hash on the prototype that we're
393
    // inheriting from
394
    basePrototype.options = $.widget.extend( {}, basePrototype.options );
395
    $.each( prototype, function( prop, value ) {
396
        if ( !$.isFunction( value ) ) {
397
            proxiedPrototype[ prop ] = value;
398
            return;
399
        }
400
        proxiedPrototype[ prop ] = (function() {
401
            var _super = function() {
402
                    return base.prototype[ prop ].apply( this, arguments );
403
                },
404
                _superApply = function( args ) {
405
                    return base.prototype[ prop ].apply( this, args );
406
                };
407
            return function() {
408
                var __super = this._super,
409
                    __superApply = this._superApply,
410
                    returnValue;
411
412
                this._super = _super;
413
                this._superApply = _superApply;
414
415
                returnValue = value.apply( this, arguments );
416
417
                this._super = __super;
418
                this._superApply = __superApply;
419
420
                return returnValue;
421
            };
422
        })();
423
    });
424
    constructor.prototype = $.widget.extend( basePrototype, {
425
        // TODO: remove support for widgetEventPrefix
426
        // always use the name + a colon as the prefix, e.g., draggable:start
427
        // don't prefix for widgets that aren't DOM-based
428
        widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
429
    }, proxiedPrototype, {
430
        constructor: constructor,
431
        namespace: namespace,
432
        widgetName: name,
433
        widgetFullName: fullName
434
    });
435
436
    // If this widget is being redefined then we need to find all widgets that
437
    // are inheriting from it and redefine all of them so that they inherit from
438
    // the new version of this widget. We're essentially trying to replace one
439
    // level in the prototype chain.
440
    if ( existingConstructor ) {
441
        $.each( existingConstructor._childConstructors, function( i, child ) {
442
            var childPrototype = child.prototype;
443
444
            // redefine the child widget using the same prototype that was
445
            // originally used, but inherit from the new version of the base
446
            $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
447
        });
448
        // remove the list of existing child constructors from the old constructor
449
        // so the old child constructors can be garbage collected
450
        delete existingConstructor._childConstructors;
451
    } else {
452
        base._childConstructors.push( constructor );
453
    }
454
455
    $.widget.bridge( name, constructor );
456
457
    return constructor;
458
};
459
460
$.widget.extend = function( target ) {
461
    var input = widget_slice.call( arguments, 1 ),
462
        inputIndex = 0,
463
        inputLength = input.length,
464
        key,
465
        value;
466
    for ( ; inputIndex < inputLength; inputIndex++ ) {
467
        for ( key in input[ inputIndex ] ) {
468
            value = input[ inputIndex ][ key ];
469
            if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
470
                // Clone objects
471
                if ( $.isPlainObject( value ) ) {
472
                    target[ key ] = $.isPlainObject( target[ key ] ) ?
473
                        $.widget.extend( {}, target[ key ], value ) :
474
                        // Don't extend strings, arrays, etc. with objects
475
                        $.widget.extend( {}, value );
476
                // Copy everything else by reference
477
                } else {
478
                    target[ key ] = value;
479
                }
480
            }
481
        }
482
    }
483
    return target;
484
};
485
486
$.widget.bridge = function( name, object ) {
487
    var fullName = object.prototype.widgetFullName || name;
488
    $.fn[ name ] = function( options ) {
489
        var isMethodCall = typeof options === "string",
490
            args = widget_slice.call( arguments, 1 ),
491
            returnValue = this;
492
493
        if ( isMethodCall ) {
494
            this.each(function() {
495
                var methodValue,
496
                    instance = $.data( this, fullName );
497
                if ( options === "instance" ) {
498
                    returnValue = instance;
499
                    return false;
500
                }
501
                if ( !instance ) {
502
                    return $.error( "cannot call methods on " + name + " prior to initialization; " +
503
                        "attempted to call method '" + options + "'" );
504
                }
505
                if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
506
                    return $.error( "no such method '" + options + "' for " + name + " widget instance" );
507
                }
508
                methodValue = instance[ options ].apply( instance, args );
509
                if ( methodValue !== instance && methodValue !== undefined ) {
510
                    returnValue = methodValue && methodValue.jquery ?
511
                        returnValue.pushStack( methodValue.get() ) :
512
                        methodValue;
513
                    return false;
514
                }
515
            });
516
        } else {
517
518
            // Allow multiple hashes to be passed on init
519
            if ( args.length ) {
520
                options = $.widget.extend.apply( null, [ options ].concat(args) );
521
            }
522
523
            this.each(function() {
524
                var instance = $.data( this, fullName );
525
                if ( instance ) {
526
                    instance.option( options || {} );
527
                    if ( instance._init ) {
528
                        instance._init();
529
                    }
530
                } else {
531
                    $.data( this, fullName, new object( options, this ) );
532
                }
533
            });
534
        }
535
536
        return returnValue;
537
    };
538
};
539
540
$.Widget = function( /* options, element */ ) {};
541
$.Widget._childConstructors = [];
542
543
$.Widget.prototype = {
544
    widgetName: "widget",
545
    widgetEventPrefix: "",
546
    defaultElement: "<div>",
547
    options: {
548
        disabled: false,
549
550
        // callbacks
551
        create: null
552
    },
553
    _createWidget: function( options, element ) {
554
        element = $( element || this.defaultElement || this )[ 0 ];
555
        this.element = $( element );
556
        this.uuid = widget_uuid++;
557
        this.eventNamespace = "." + this.widgetName + this.uuid;
558
559
        this.bindings = $();
560
        this.hoverable = $();
561
        this.focusable = $();
562
563
        if ( element !== this ) {
564
            $.data( element, this.widgetFullName, this );
565
            this._on( true, this.element, {
566
                remove: function( event ) {
567
                    if ( event.target === element ) {
568
                        this.destroy();
569
                    }
570
                }
571
            });
572
            this.document = $( element.style ?
573
                // element within the document
574
                element.ownerDocument :
575
                // element is window or document
576
                element.document || element );
577
            this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
578
        }
579
580
        this.options = $.widget.extend( {},
581
            this.options,
582
            this._getCreateOptions(),
583
            options );
584
585
        this._create();
586
        this._trigger( "create", null, this._getCreateEventData() );
587
        this._init();
588
    },
589
    _getCreateOptions: $.noop,
590
    _getCreateEventData: $.noop,
591
    _create: $.noop,
592
    _init: $.noop,
593
594
    destroy: function() {
595
        this._destroy();
596
        // we can probably remove the unbind calls in 2.0
597
        // all event bindings should go through this._on()
598
        this.element
599
            .unbind( this.eventNamespace )
600
            .removeData( this.widgetFullName )
601
            // support: jquery <1.6.3
602
            // http://bugs.jquery.com/ticket/9413
603
            .removeData( $.camelCase( this.widgetFullName ) );
604
        this.widget()
605
            .unbind( this.eventNamespace )
606
            .removeAttr( "aria-disabled" )
607
            .removeClass(
608
                this.widgetFullName + "-disabled " +
609
                "ui-state-disabled" );
610
611
        // clean up events and states
612
        this.bindings.unbind( this.eventNamespace );
613
        this.hoverable.removeClass( "ui-state-hover" );
614
        this.focusable.removeClass( "ui-state-focus" );
615
    },
616
    _destroy: $.noop,
617
618
    widget: function() {
619
        return this.element;
620
    },
621
622
    option: function( key, value ) {
623
        var options = key,
624
            parts,
625
            curOption,
626
            i;
627
628
        if ( arguments.length === 0 ) {
629
            // don't return a reference to the internal hash
630
            return $.widget.extend( {}, this.options );
631
        }
632
633
        if ( typeof key === "string" ) {
634
            // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
635
            options = {};
636
            parts = key.split( "." );
637
            key = parts.shift();
638
            if ( parts.length ) {
639
                curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
640
                for ( i = 0; i < parts.length - 1; i++ ) {
641
                    curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
642
                    curOption = curOption[ parts[ i ] ];
643
                }
644
                key = parts.pop();
645
                if ( arguments.length === 1 ) {
646
                    return curOption[ key ] === undefined ? null : curOption[ key ];
647
                }
648
                curOption[ key ] = value;
649
            } else {
650
                if ( arguments.length === 1 ) {
651
                    return this.options[ key ] === undefined ? null : this.options[ key ];
652
                }
653
                options[ key ] = value;
654
            }
655
        }
656
657
        this._setOptions( options );
658
659
        return this;
660
    },
661
    _setOptions: function( options ) {
662
        var key;
663
664
        for ( key in options ) {
665
            this._setOption( key, options[ key ] );
666
        }
667
668
        return this;
669
    },
670
    _setOption: function( key, value ) {
671
        this.options[ key ] = value;
672
673
        if ( key === "disabled" ) {
674
            this.widget()
675
                .toggleClass( this.widgetFullName + "-disabled", !!value );
676
677
            // If the widget is becoming disabled, then nothing is interactive
678
            if ( value ) {
679
                this.hoverable.removeClass( "ui-state-hover" );
680
                this.focusable.removeClass( "ui-state-focus" );
681
            }
682
        }
683
684
        return this;
685
    },
686
687
    enable: function() {
688
        return this._setOptions({ disabled: false });
689
    },
690
    disable: function() {
691
        return this._setOptions({ disabled: true });
692
    },
693
694
    _on: function( suppressDisabledCheck, element, handlers ) {
695
        var delegateElement,
696
            instance = this;
697
698
        // no suppressDisabledCheck flag, shuffle arguments
699
        if ( typeof suppressDisabledCheck !== "boolean" ) {
700
            handlers = element;
701
            element = suppressDisabledCheck;
702
            suppressDisabledCheck = false;
703
        }
704
705
        // no element argument, shuffle and use this.element
706
        if ( !handlers ) {
707
            handlers = element;
708
            element = this.element;
709
            delegateElement = this.widget();
710
        } else {
711
            element = delegateElement = $( element );
712
            this.bindings = this.bindings.add( element );
713
        }
714
715
        $.each( handlers, function( event, handler ) {
716
            function handlerProxy() {
717
                // allow widgets to customize the disabled handling
718
                // - disabled as an array instead of boolean
719
                // - disabled class as method for disabling individual parts
720
                if ( !suppressDisabledCheck &&
721
                        ( instance.options.disabled === true ||
722
                            $( this ).hasClass( "ui-state-disabled" ) ) ) {
723
                    return;
724
                }
725
                return ( typeof handler === "string" ? instance[ handler ] : handler )
726
                    .apply( instance, arguments );
727
            }
728
729
            // copy the guid so direct unbinding works
730
            if ( typeof handler !== "string" ) {
731
                handlerProxy.guid = handler.guid =
732
                    handler.guid || handlerProxy.guid || $.guid++;
733
            }
734
735
            var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
736
                eventName = match[1] + instance.eventNamespace,
737
                selector = match[2];
738
            if ( selector ) {
739
                delegateElement.delegate( selector, eventName, handlerProxy );
740
            } else {
741
                element.bind( eventName, handlerProxy );
742
            }
743
        });
744
    },
745
746
    _off: function( element, eventName ) {
747
        eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
748
            this.eventNamespace;
749
        element.unbind( eventName ).undelegate( eventName );
750
751
        // Clear the stack to avoid memory leaks (#10056)
752
        this.bindings = $( this.bindings.not( element ).get() );
753
        this.focusable = $( this.focusable.not( element ).get() );
754
        this.hoverable = $( this.hoverable.not( element ).get() );
755
    },
756
757
    _delay: function( handler, delay ) {
758
        function handlerProxy() {
759
            return ( typeof handler === "string" ? instance[ handler ] : handler )
760
                .apply( instance, arguments );
761
        }
762
        var instance = this;
763
        return setTimeout( handlerProxy, delay || 0 );
764
    },
765
766
    _hoverable: function( element ) {
767
        this.hoverable = this.hoverable.add( element );
768
        this._on( element, {
769
            mouseenter: function( event ) {
770
                $( event.currentTarget ).addClass( "ui-state-hover" );
771
            },
772
            mouseleave: function( event ) {
773
                $( event.currentTarget ).removeClass( "ui-state-hover" );
774
            }
775
        });
776
    },
777
778
    _focusable: function( element ) {
779
        this.focusable = this.focusable.add( element );
780
        this._on( element, {
781
            focusin: function( event ) {
782
                $( event.currentTarget ).addClass( "ui-state-focus" );
783
            },
784
            focusout: function( event ) {
785
                $( event.currentTarget ).removeClass( "ui-state-focus" );
786
            }
787
        });
788
    },
789
790
    _trigger: function( type, event, data ) {
791
        var prop, orig,
792
            callback = this.options[ type ];
793
794
        data = data || {};
795
        event = $.Event( event );
796
        event.type = ( type === this.widgetEventPrefix ?
797
            type :
798
            this.widgetEventPrefix + type ).toLowerCase();
799
        // the original event may come from any element
800
        // so we need to reset the target on the new event
801
        event.target = this.element[ 0 ];
802
803
        // copy original event properties over to the new event
804
        orig = event.originalEvent;
805
        if ( orig ) {
806
            for ( prop in orig ) {
807
                if ( !( prop in event ) ) {
808
                    event[ prop ] = orig[ prop ];
809
                }
810
            }
811
        }
812
813
        this.element.trigger( event, data );
814
        return !( $.isFunction( callback ) &&
815
            callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
816
            event.isDefaultPrevented() );
817
    }
818
};
819
820
$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
821
    $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
822
        if ( typeof options === "string" ) {
823
            options = { effect: options };
824
        }
825
        var hasOptions,
826
            effectName = !options ?
827
                method :
828
                options === true || typeof options === "number" ?
829
                    defaultEffect :
830
                    options.effect || defaultEffect;
831
        options = options || {};
832
        if ( typeof options === "number" ) {
833
            options = { duration: options };
834
        }
835
        hasOptions = !$.isEmptyObject( options );
836
        options.complete = callback;
837
        if ( options.delay ) {
838
            element.delay( options.delay );
839
        }
840
        if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
841
            element[ method ]( options );
842
        } else if ( effectName !== method && element[ effectName ] ) {
843
            element[ effectName ]( options.duration, options.easing, callback );
844
        } else {
845
            element.queue(function( next ) {
846
                $( this )[ method ]();
847
                if ( callback ) {
848
                    callback.call( element[ 0 ] );
849
                }
850
                next();
851
            });
852
        }
853
    };
854
});
855
856
var widget = $.widget;
857
858
859
/*!
860
 * jQuery UI Mouse 1.11.4
861
 * http://jqueryui.com
862
 *
863
 * Copyright jQuery Foundation and other contributors
864
 * Released under the MIT license.
865
 * http://jquery.org/license
866
 *
867
 * http://api.jqueryui.com/mouse/
868
 */
869
870
871
var mouseHandled = false;
872
$( document ).mouseup( function() {
873
    mouseHandled = false;
874
});
875
876
var mouse = $.widget("ui.mouse", {
877
    version: "1.11.4",
878
    options: {
879
        cancel: "input,textarea,button,select,option",
880
        distance: 1,
881
        delay: 0
882
    },
883
    _mouseInit: function() {
884
        var that = this;
885
886
        this.element
887
            .bind("mousedown." + this.widgetName, function(event) {
888
                return that._mouseDown(event);
889
            })
890
            .bind("click." + this.widgetName, function(event) {
891
                if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
892
                    $.removeData(event.target, that.widgetName + ".preventClickEvent");
893
                    event.stopImmediatePropagation();
894
                    return false;
895
                }
896
            });
897
898
        this.started = false;
899
    },
900
901
    // TODO: make sure destroying one instance of mouse doesn't mess with
902
    // other instances of mouse
903
    _mouseDestroy: function() {
904
        this.element.unbind("." + this.widgetName);
905
        if ( this._mouseMoveDelegate ) {
906
            this.document
907
                .unbind("mousemove." + this.widgetName, this._mouseMoveDelegate)
908
                .unbind("mouseup." + this.widgetName, this._mouseUpDelegate);
909
        }
910
    },
911
912
    _mouseDown: function(event) {
913
        // don't let more than one widget handle mouseStart
914
        if ( mouseHandled ) {
915
            return;
916
        }
917
918
        this._mouseMoved = false;
919
920
        // we may have missed mouseup (out of window)
921
        (this._mouseStarted && this._mouseUp(event));
922
923
        this._mouseDownEvent = event;
924
925
        var that = this,
926
            btnIsLeft = (event.which === 1),
927
            // event.target.nodeName works around a bug in IE 8 with
928
            // disabled inputs (#7620)
929
            elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
930
        if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
931
            return true;
932
        }
933
934
        this.mouseDelayMet = !this.options.delay;
935
        if (!this.mouseDelayMet) {
936
            this._mouseDelayTimer = setTimeout(function() {
937
                that.mouseDelayMet = true;
938
            }, this.options.delay);
939
        }
940
941
        if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
942
            this._mouseStarted = (this._mouseStart(event) !== false);
943
            if (!this._mouseStarted) {
944
                event.preventDefault();
945
                return true;
946
            }
947
        }
948
949
        // Click event may never have fired (Gecko & Opera)
950
        if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
951
            $.removeData(event.target, this.widgetName + ".preventClickEvent");
952
        }
953
954
        // these delegates are required to keep context
955
        this._mouseMoveDelegate = function(event) {
956
            return that._mouseMove(event);
957
        };
958
        this._mouseUpDelegate = function(event) {
959
            return that._mouseUp(event);
960
        };
961
962
        this.document
963
            .bind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
964
            .bind( "mouseup." + this.widgetName, this._mouseUpDelegate );
965
966
        event.preventDefault();
967
968
        mouseHandled = true;
969
        return true;
970
    },
971
972
    _mouseMove: function(event) {
973
        // Only check for mouseups outside the document if you've moved inside the document
974
        // at least once. This prevents the firing of mouseup in the case of IE<9, which will
975
        // fire a mousemove event if content is placed under the cursor. See #7778
976
        // Support: IE <9
977
        if ( this._mouseMoved ) {
978
            // IE mouseup check - mouseup happened when mouse was out of window
979
            if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
980
                return this._mouseUp(event);
981
982
            // Iframe mouseup check - mouseup occurred in another document
983
            } else if ( !event.which ) {
984
                return this._mouseUp( event );
985
            }
986
        }
987
988
        if ( event.which || event.button ) {
989
            this._mouseMoved = true;
990
        }
991
992
        if (this._mouseStarted) {
993
            this._mouseDrag(event);
994
            return event.preventDefault();
995
        }
996
997
        if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
998
            this._mouseStarted =
999
                (this._mouseStart(this._mouseDownEvent, event) !== false);
1000
            (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
1001
        }
1002
1003
        return !this._mouseStarted;
1004
    },
1005
1006
    _mouseUp: function(event) {
1007
        this.document
1008
            .unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
1009
            .unbind( "mouseup." + this.widgetName, this._mouseUpDelegate );
1010
1011
        if (this._mouseStarted) {
1012
            this._mouseStarted = false;
1013
1014
            if (event.target === this._mouseDownEvent.target) {
1015
                $.data(event.target, this.widgetName + ".preventClickEvent", true);
1016
            }
1017
1018
            this._mouseStop(event);
1019
        }
1020
1021
        mouseHandled = false;
1022
        return false;
1023
    },
1024
1025
    _mouseDistanceMet: function(event) {
1026
        return (Math.max(
1027
                Math.abs(this._mouseDownEvent.pageX - event.pageX),
1028
                Math.abs(this._mouseDownEvent.pageY - event.pageY)
1029
            ) >= this.options.distance
1030
        );
1031
    },
1032
1033
    _mouseDelayMet: function(/* event */) {
1034
        return this.mouseDelayMet;
1035
    },
1036
1037
    // These are placeholder methods, to be overriden by extending plugin
1038
    _mouseStart: function(/* event */) {},
1039
    _mouseDrag: function(/* event */) {},
1040
    _mouseStop: function(/* event */) {},
1041
    _mouseCapture: function(/* event */) { return true; }
1042
});
1043
1044
1045
/*!
1046
 * jQuery UI Position 1.11.4
1047
 * http://jqueryui.com
1048
 *
1049
 * Copyright jQuery Foundation and other contributors
1050
 * Released under the MIT license.
1051
 * http://jquery.org/license
1052
 *
1053
 * http://api.jqueryui.com/position/
1054
 */
1055
1056
(function() {
1057
1058
$.ui = $.ui || {};
1059
1060
var cachedScrollbarWidth, supportsOffsetFractions,
1061
    max = Math.max,
1062
    abs = Math.abs,
1063
    round = Math.round,
1064
    rhorizontal = /left|center|right/,
1065
    rvertical = /top|center|bottom/,
1066
    roffset = /[\+\-]\d+(\.[\d]+)?%?/,
1067
    rposition = /^\w+/,
1068
    rpercent = /%$/,
1069
    _position = $.fn.position;
1070
1071
function getOffsets( offsets, width, height ) {
1072
    return [
1073
        parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
1074
        parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
1075
    ];
1076
}
1077
1078
function parseCss( element, property ) {
1079
    return parseInt( $.css( element, property ), 10 ) || 0;
1080
}
1081
1082
function getDimensions( elem ) {
1083
    var raw = elem[0];
1084
    if ( raw.nodeType === 9 ) {
1085
        return {
1086
            width: elem.width(),
1087
            height: elem.height(),
1088
            offset: { top: 0, left: 0 }
1089
        };
1090
    }
1091
    if ( $.isWindow( raw ) ) {
1092
        return {
1093
            width: elem.width(),
1094
            height: elem.height(),
1095
            offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
1096
        };
1097
    }
1098
    if ( raw.preventDefault ) {
1099
        return {
1100
            width: 0,
1101
            height: 0,
1102
            offset: { top: raw.pageY, left: raw.pageX }
1103
        };
1104
    }
1105
    return {
1106
        width: elem.outerWidth(),
1107
        height: elem.outerHeight(),
1108
        offset: elem.offset()
1109
    };
1110
}
1111
1112
$.position = {
1113
    scrollbarWidth: function() {
1114
        if ( cachedScrollbarWidth !== undefined ) {
1115
            return cachedScrollbarWidth;
1116
        }
1117
        var w1, w2,
1118
            div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
1119
            innerDiv = div.children()[0];
1120
1121
        $( "body" ).append( div );
1122
        w1 = innerDiv.offsetWidth;
1123
        div.css( "overflow", "scroll" );
1124
1125
        w2 = innerDiv.offsetWidth;
1126
1127
        if ( w1 === w2 ) {
1128
            w2 = div[0].clientWidth;
1129
        }
1130
1131
        div.remove();
1132
1133
        return (cachedScrollbarWidth = w1 - w2);
1134
    },
1135
    getScrollInfo: function( within ) {
1136
        var overflowX = within.isWindow || within.isDocument ? "" :
1137
                within.element.css( "overflow-x" ),
1138
            overflowY = within.isWindow || within.isDocument ? "" :
1139
                within.element.css( "overflow-y" ),
1140
            hasOverflowX = overflowX === "scroll" ||
1141
                ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
1142
            hasOverflowY = overflowY === "scroll" ||
1143
                ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
1144
        return {
1145
            width: hasOverflowY ? $.position.scrollbarWidth() : 0,
1146
            height: hasOverflowX ? $.position.scrollbarWidth() : 0
1147
        };
1148
    },
1149
    getWithinInfo: function( element ) {
1150
        var withinElement = $( element || window ),
1151
            isWindow = $.isWindow( withinElement[0] ),
1152
            isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
1153
        return {
1154
            element: withinElement,
1155
            isWindow: isWindow,
1156
            isDocument: isDocument,
1157
            offset: withinElement.offset() || { left: 0, top: 0 },
1158
            scrollLeft: withinElement.scrollLeft(),
1159
            scrollTop: withinElement.scrollTop(),
1160
1161
            // support: jQuery 1.6.x
1162
            // jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows
1163
            width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(),
1164
            height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight()
1165
        };
1166
    }
1167
};
1168
1169
$.fn.position = function( options ) {
1170
    if ( !options || !options.of ) {
1171
        return _position.apply( this, arguments );
1172
    }
1173
1174
    // make a copy, we don't want to modify arguments
1175
    options = $.extend( {}, options );
1176
1177
    var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
1178
        target = $( options.of ),
1179
        within = $.position.getWithinInfo( options.within ),
1180
        scrollInfo = $.position.getScrollInfo( within ),
1181
        collision = ( options.collision || "flip" ).split( " " ),
1182
        offsets = {};
1183
1184
    dimensions = getDimensions( target );
1185
    if ( target[0].preventDefault ) {
1186
        // force left top to allow flipping
1187
        options.at = "left top";
1188
    }
1189
    targetWidth = dimensions.width;
1190
    targetHeight = dimensions.height;
1191
    targetOffset = dimensions.offset;
1192
    // clone to reuse original targetOffset later
1193
    basePosition = $.extend( {}, targetOffset );
1194
1195
    // force my and at to have valid horizontal and vertical positions
1196
    // if a value is missing or invalid, it will be converted to center
1197
    $.each( [ "my", "at" ], function() {
1198
        var pos = ( options[ this ] || "" ).split( " " ),
1199
            horizontalOffset,
1200
            verticalOffset;
1201
1202
        if ( pos.length === 1) {
1203
            pos = rhorizontal.test( pos[ 0 ] ) ?
1204
                pos.concat( [ "center" ] ) :
1205
                rvertical.test( pos[ 0 ] ) ?
1206
                    [ "center" ].concat( pos ) :
1207
                    [ "center", "center" ];
1208
        }
1209
        pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
1210
        pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
1211
1212
        // calculate offsets
1213
        horizontalOffset = roffset.exec( pos[ 0 ] );
1214
        verticalOffset = roffset.exec( pos[ 1 ] );
1215
        offsets[ this ] = [
1216
            horizontalOffset ? horizontalOffset[ 0 ] : 0,
1217
            verticalOffset ? verticalOffset[ 0 ] : 0
1218
        ];
1219
1220
        // reduce to just the positions without the offsets
1221
        options[ this ] = [
1222
            rposition.exec( pos[ 0 ] )[ 0 ],
1223
            rposition.exec( pos[ 1 ] )[ 0 ]
1224
        ];
1225
    });
1226
1227
    // normalize collision option
1228
    if ( collision.length === 1 ) {
1229
        collision[ 1 ] = collision[ 0 ];
1230
    }
1231
1232
    if ( options.at[ 0 ] === "right" ) {
1233
        basePosition.left += targetWidth;
1234
    } else if ( options.at[ 0 ] === "center" ) {
1235
        basePosition.left += targetWidth / 2;
1236
    }
1237
1238
    if ( options.at[ 1 ] === "bottom" ) {
1239
        basePosition.top += targetHeight;
1240
    } else if ( options.at[ 1 ] === "center" ) {
1241
        basePosition.top += targetHeight / 2;
1242
    }
1243
1244
    atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
1245
    basePosition.left += atOffset[ 0 ];
1246
    basePosition.top += atOffset[ 1 ];
1247
1248
    return this.each(function() {
1249
        var collisionPosition, using,
1250
            elem = $( this ),
1251
            elemWidth = elem.outerWidth(),
1252
            elemHeight = elem.outerHeight(),
1253
            marginLeft = parseCss( this, "marginLeft" ),
1254
            marginTop = parseCss( this, "marginTop" ),
1255
            collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
1256
            collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
1257
            position = $.extend( {}, basePosition ),
1258
            myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1259
1260
        if ( options.my[ 0 ] === "right" ) {
1261
            position.left -= elemWidth;
1262
        } else if ( options.my[ 0 ] === "center" ) {
1263
            position.left -= elemWidth / 2;
1264
        }
1265
1266
        if ( options.my[ 1 ] === "bottom" ) {
1267
            position.top -= elemHeight;
1268
        } else if ( options.my[ 1 ] === "center" ) {
1269
            position.top -= elemHeight / 2;
1270
        }
1271
1272
        position.left += myOffset[ 0 ];
1273
        position.top += myOffset[ 1 ];
1274
1275
        // if the browser doesn't support fractions, then round for consistent results
1276
        if ( !supportsOffsetFractions ) {
1277
            position.left = round( position.left );
1278
            position.top = round( position.top );
1279
        }
1280
1281
        collisionPosition = {
1282
            marginLeft: marginLeft,
1283
            marginTop: marginTop
1284
        };
1285
1286
        $.each( [ "left", "top" ], function( i, dir ) {
1287
            if ( $.ui.position[ collision[ i ] ] ) {
1288
                $.ui.position[ collision[ i ] ][ dir ]( position, {
1289
                    targetWidth: targetWidth,
1290
                    targetHeight: targetHeight,
1291
                    elemWidth: elemWidth,
1292
                    elemHeight: elemHeight,
1293
                    collisionPosition: collisionPosition,
1294
                    collisionWidth: collisionWidth,
1295
                    collisionHeight: collisionHeight,
1296
                    offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1297
                    my: options.my,
1298
                    at: options.at,
1299
                    within: within,
1300
                    elem: elem
1301
                });
1302
            }
1303
        });
1304
1305
        if ( options.using ) {
1306
            // adds feedback as second argument to using callback, if present
1307
            using = function( props ) {
1308
                var left = targetOffset.left - position.left,
1309
                    right = left + targetWidth - elemWidth,
1310
                    top = targetOffset.top - position.top,
1311
                    bottom = top + targetHeight - elemHeight,
1312
                    feedback = {
1313
                        target: {
1314
                            element: target,
1315
                            left: targetOffset.left,
1316
                            top: targetOffset.top,
1317
                            width: targetWidth,
1318
                            height: targetHeight
1319
                        },
1320
                        element: {
1321
                            element: elem,
1322
                            left: position.left,
1323
                            top: position.top,
1324
                            width: elemWidth,
1325
                            height: elemHeight
1326
                        },
1327
                        horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1328
                        vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1329
                    };
1330
                if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1331
                    feedback.horizontal = "center";
1332
                }
1333
                if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1334
                    feedback.vertical = "middle";
1335
                }
1336
                if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1337
                    feedback.important = "horizontal";
1338
                } else {
1339
                    feedback.important = "vertical";
1340
                }
1341
                options.using.call( this, props, feedback );
1342
            };
1343
        }
1344
1345
        elem.offset( $.extend( position, { using: using } ) );
1346
    });
1347
};
1348
1349
$.ui.position = {
1350
    fit: {
1351
        left: function( position, data ) {
1352
            var within = data.within,
1353
                withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1354
                outerWidth = within.width,
1355
                collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1356
                overLeft = withinOffset - collisionPosLeft,
1357
                overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1358
                newOverRight;
1359
1360
            // element is wider than within
1361
            if ( data.collisionWidth > outerWidth ) {
1362
                // element is initially over the left side of within
1363
                if ( overLeft > 0 && overRight <= 0 ) {
1364
                    newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
1365
                    position.left += overLeft - newOverRight;
1366
                // element is initially over right side of within
1367
                } else if ( overRight > 0 && overLeft <= 0 ) {
1368
                    position.left = withinOffset;
1369
                // element is initially over both left and right sides of within
1370
                } else {
1371
                    if ( overLeft > overRight ) {
1372
                        position.left = withinOffset + outerWidth - data.collisionWidth;
1373
                    } else {
1374
                        position.left = withinOffset;
1375
                    }
1376
                }
1377
            // too far left -> align with left edge
1378
            } else if ( overLeft > 0 ) {
1379
                position.left += overLeft;
1380
            // too far right -> align with right edge
1381
            } else if ( overRight > 0 ) {
1382
                position.left -= overRight;
1383
            // adjust based on position and margin
1384
            } else {
1385
                position.left = max( position.left - collisionPosLeft, position.left );
1386
            }
1387
        },
1388
        top: function( position, data ) {
1389
            var within = data.within,
1390
                withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1391
                outerHeight = data.within.height,
1392
                collisionPosTop = position.top - data.collisionPosition.marginTop,
1393
                overTop = withinOffset - collisionPosTop,
1394
                overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1395
                newOverBottom;
1396
1397
            // element is taller than within
1398
            if ( data.collisionHeight > outerHeight ) {
1399
                // element is initially over the top of within
1400
                if ( overTop > 0 && overBottom <= 0 ) {
1401
                    newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
1402
                    position.top += overTop - newOverBottom;
1403
                // element is initially over bottom of within
1404
                } else if ( overBottom > 0 && overTop <= 0 ) {
1405
                    position.top = withinOffset;
1406
                // element is initially over both top and bottom of within
1407
                } else {
1408
                    if ( overTop > overBottom ) {
1409
                        position.top = withinOffset + outerHeight - data.collisionHeight;
1410
                    } else {
1411
                        position.top = withinOffset;
1412
                    }
1413
                }
1414
            // too far up -> align with top
1415
            } else if ( overTop > 0 ) {
1416
                position.top += overTop;
1417
            // too far down -> align with bottom edge
1418
            } else if ( overBottom > 0 ) {
1419
                position.top -= overBottom;
1420
            // adjust based on position and margin
1421
            } else {
1422
                position.top = max( position.top - collisionPosTop, position.top );
1423
            }
1424
        }
1425
    },
1426
    flip: {
1427
        left: function( position, data ) {
1428
            var within = data.within,
1429
                withinOffset = within.offset.left + within.scrollLeft,
1430
                outerWidth = within.width,
1431
                offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1432
                collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1433
                overLeft = collisionPosLeft - offsetLeft,
1434
                overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1435
                myOffset = data.my[ 0 ] === "left" ?
1436
                    -data.elemWidth :
1437
                    data.my[ 0 ] === "right" ?
1438
                        data.elemWidth :
1439
                        0,
1440
                atOffset = data.at[ 0 ] === "left" ?
1441
                    data.targetWidth :
1442
                    data.at[ 0 ] === "right" ?
1443
                        -data.targetWidth :
1444
                        0,
1445
                offset = -2 * data.offset[ 0 ],
1446
                newOverRight,
1447
                newOverLeft;
1448
1449
            if ( overLeft < 0 ) {
1450
                newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
1451
                if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1452
                    position.left += myOffset + atOffset + offset;
1453
                }
1454
            } else if ( overRight > 0 ) {
1455
                newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
1456
                if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1457
                    position.left += myOffset + atOffset + offset;
1458
                }
1459
            }
1460
        },
1461
        top: function( position, data ) {
1462
            var within = data.within,
1463
                withinOffset = within.offset.top + within.scrollTop,
1464
                outerHeight = within.height,
1465
                offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1466
                collisionPosTop = position.top - data.collisionPosition.marginTop,
1467
                overTop = collisionPosTop - offsetTop,
1468
                overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1469
                top = data.my[ 1 ] === "top",
1470
                myOffset = top ?
1471
                    -data.elemHeight :
1472
                    data.my[ 1 ] === "bottom" ?
1473
                        data.elemHeight :
1474
                        0,
1475
                atOffset = data.at[ 1 ] === "top" ?
1476
                    data.targetHeight :
1477
                    data.at[ 1 ] === "bottom" ?
1478
                        -data.targetHeight :
1479
                        0,
1480
                offset = -2 * data.offset[ 1 ],
1481
                newOverTop,
1482
                newOverBottom;
1483
            if ( overTop < 0 ) {
1484
                newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
1485
                if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
1486
                    position.top += myOffset + atOffset + offset;
1487
                }
1488
            } else if ( overBottom > 0 ) {
1489
                newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
1490
                if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
1491
                    position.top += myOffset + atOffset + offset;
1492
                }
1493
            }
1494
        }
1495
    },
1496
    flipfit: {
1497
        left: function() {
1498
            $.ui.position.flip.left.apply( this, arguments );
1499
            $.ui.position.fit.left.apply( this, arguments );
1500
        },
1501
        top: function() {
1502
            $.ui.position.flip.top.apply( this, arguments );
1503
            $.ui.position.fit.top.apply( this, arguments );
1504
        }
1505
    }
1506
};
1507
1508
// fraction support test
1509
(function() {
1510
    var testElement, testElementParent, testElementStyle, offsetLeft, i,
1511
        body = document.getElementsByTagName( "body" )[ 0 ],
1512
        div = document.createElement( "div" );
1513
1514
    //Create a "fake body" for testing based on method used in jQuery.support
1515
    testElement = document.createElement( body ? "div" : "body" );
1516
    testElementStyle = {
1517
        visibility: "hidden",
1518
        width: 0,
1519
        height: 0,
1520
        border: 0,
1521
        margin: 0,
1522
        background: "none"
1523
    };
1524
    if ( body ) {
1525
        $.extend( testElementStyle, {
1526
            position: "absolute",
1527
            left: "-1000px",
1528
            top: "-1000px"
1529
        });
1530
    }
1531
    for ( i in testElementStyle ) {
1532
        testElement.style[ i ] = testElementStyle[ i ];
1533
    }
1534
    testElement.appendChild( div );
1535
    testElementParent = body || document.documentElement;
1536
    testElementParent.insertBefore( testElement, testElementParent.firstChild );
1537
1538
    div.style.cssText = "position: absolute; left: 10.7432222px;";
1539
1540
    offsetLeft = $( div ).offset().left;
1541
    supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11;
1542
1543
    testElement.innerHTML = "";
1544
    testElementParent.removeChild( testElement );
1545
})();
1546
1547
})();
1548
1549
var position = $.ui.position;
1550
1551
1552
/*!
1553
 * jQuery UI Draggable 1.11.4
1554
 * http://jqueryui.com
1555
 *
1556
 * Copyright jQuery Foundation and other contributors
1557
 * Released under the MIT license.
1558
 * http://jquery.org/license
1559
 *
1560
 * http://api.jqueryui.com/draggable/
1561
 */
1562
1563
1564
$.widget("ui.draggable", $.ui.mouse, {
1565
    version: "1.11.4",
1566
    widgetEventPrefix: "drag",
1567
    options: {
1568
        addClasses: true,
1569
        appendTo: "parent",
1570
        axis: false,
1571
        connectToSortable: false,
1572
        containment: false,
1573
        cursor: "auto",
1574
        cursorAt: false,
1575
        grid: false,
1576
        handle: false,
1577
        helper: "original",
1578
        iframeFix: false,
1579
        opacity: false,
1580
        refreshPositions: false,
1581
        revert: false,
1582
        revertDuration: 500,
1583
        scope: "default",
1584
        scroll: true,
1585
        scrollSensitivity: 20,
1586
        scrollSpeed: 20,
1587
        snap: false,
1588
        snapMode: "both",
1589
        snapTolerance: 20,
1590
        stack: false,
1591
        zIndex: false,
1592
1593
        // callbacks
1594
        drag: null,
1595
        start: null,
1596
        stop: null
1597
    },
1598
    _create: function() {
1599
1600
        if ( this.options.helper === "original" ) {
1601
            this._setPositionRelative();
1602
        }
1603
        if (this.options.addClasses){
1604
            this.element.addClass("ui-draggable");
1605
        }
1606
        if (this.options.disabled){
1607
            this.element.addClass("ui-draggable-disabled");
1608
        }
1609
        this._setHandleClassName();
1610
1611
        this._mouseInit();
1612
    },
1613
1614
    _setOption: function( key, value ) {
1615
        this._super( key, value );
1616
        if ( key === "handle" ) {
1617
            this._removeHandleClassName();
1618
            this._setHandleClassName();
1619
        }
1620
    },
1621
1622
    _destroy: function() {
1623
        if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
1624
            this.destroyOnClear = true;
1625
            return;
1626
        }
1627
        this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1628
        this._removeHandleClassName();
1629
        this._mouseDestroy();
1630
    },
1631
1632
    _mouseCapture: function(event) {
1633
        var o = this.options;
1634
1635
        this._blurActiveElement( event );
1636
1637
        // among others, prevent a drag on a resizable-handle
1638
        if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
1639
            return false;
1640
        }
1641
1642
        //Quit if we're not on a valid handle
1643
        this.handle = this._getHandle(event);
1644
        if (!this.handle) {
1645
            return false;
1646
        }
1647
1648
        this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
1649
1650
        return true;
1651
1652
    },
1653
1654
    _blockFrames: function( selector ) {
1655
        this.iframeBlocks = this.document.find( selector ).map(function() {
1656
            var iframe = $( this );
1657
1658
            return $( "<div>" )
1659
                .css( "position", "absolute" )
1660
                .appendTo( iframe.parent() )
1661
                .outerWidth( iframe.outerWidth() )
1662
                .outerHeight( iframe.outerHeight() )
1663
                .offset( iframe.offset() )[ 0 ];
1664
        });
1665
    },
1666
1667
    _unblockFrames: function() {
1668
        if ( this.iframeBlocks ) {
1669
            this.iframeBlocks.remove();
1670
            delete this.iframeBlocks;
1671
        }
1672
    },
1673
1674
    _blurActiveElement: function( event ) {
1675
        var document = this.document[ 0 ];
1676
1677
        // Only need to blur if the event occurred on the draggable itself, see #10527
1678
        if ( !this.handleElement.is( event.target ) ) {
1679
            return;
1680
        }
1681
1682
        // support: IE9
1683
        // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
1684
        try {
1685
1686
            // Support: IE9, IE10
1687
            // If the <body> is blurred, IE will switch windows, see #9520
1688
            if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) {
1689
1690
                // Blur any element that currently has focus, see #4261
1691
                $( document.activeElement ).blur();
1692
            }
1693
        } catch ( error ) {}
1694
    },
1695
1696
    _mouseStart: function(event) {
1697
1698
        var o = this.options;
1699
1700
        //Create and append the visible helper
1701
        this.helper = this._createHelper(event);
1702
1703
        this.helper.addClass("ui-draggable-dragging");
1704
1705
        //Cache the helper size
1706
        this._cacheHelperProportions();
1707
1708
        //If ddmanager is used for droppables, set the global draggable
1709
        if ($.ui.ddmanager) {
1710
            $.ui.ddmanager.current = this;
1711
        }
1712
1713
        /*
1714
         * - Position generation -
1715
         * This block generates everything position related - it's the core of draggables.
1716
         */
1717
1718
        //Cache the margins of the original element
1719
        this._cacheMargins();
1720
1721
        //Store the helper's css position
1722
        this.cssPosition = this.helper.css( "position" );
1723
        this.scrollParent = this.helper.scrollParent( true );
1724
        this.offsetParent = this.helper.offsetParent();
1725
        this.hasFixedAncestor = this.helper.parents().filter(function() {
1726
                return $( this ).css( "position" ) === "fixed";
1727
            }).length > 0;
1728
1729
        //The element's absolute position on the page minus margins
1730
        this.positionAbs = this.element.offset();
1731
        this._refreshOffsets( event );
1732
1733
        //Generate the original position
1734
        this.originalPosition = this.position = this._generatePosition( event, false );
1735
        this.originalPageX = event.pageX;
1736
        this.originalPageY = event.pageY;
1737
1738
        //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
1739
        (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1740
1741
        //Set a containment if given in the options
1742
        this._setContainment();
1743
1744
        //Trigger event + callbacks
1745
        if (this._trigger("start", event) === false) {
1746
            this._clear();
1747
            return false;
1748
        }
1749
1750
        //Recache the helper size
1751
        this._cacheHelperProportions();
1752
1753
        //Prepare the droppable offsets
1754
        if ($.ui.ddmanager && !o.dropBehaviour) {
1755
            $.ui.ddmanager.prepareOffsets(this, event);
1756
        }
1757
1758
        // Reset helper's right/bottom css if they're set and set explicit width/height instead
1759
        // as this prevents resizing of elements with right/bottom set (see #7772)
1760
        this._normalizeRightBottom();
1761
1762
        this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1763
1764
        //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1765
        if ( $.ui.ddmanager ) {
1766
            $.ui.ddmanager.dragStart(this, event);
1767
        }
1768
1769
        return true;
1770
    },
1771
1772
    _refreshOffsets: function( event ) {
1773
        this.offset = {
1774
            top: this.positionAbs.top - this.margins.top,
1775
            left: this.positionAbs.left - this.margins.left,
1776
            scroll: false,
1777
            parent: this._getParentOffset(),
1778
            relative: this._getRelativeOffset()
1779
        };
1780
1781
        this.offset.click = {
1782
            left: event.pageX - this.offset.left,
1783
            top: event.pageY - this.offset.top
1784
        };
1785
    },
1786
1787
    _mouseDrag: function(event, noPropagation) {
1788
        // reset any necessary cached properties (see #5009)
1789
        if ( this.hasFixedAncestor ) {
1790
            this.offset.parent = this._getParentOffset();
1791
        }
1792
1793
        //Compute the helpers position
1794
        this.position = this._generatePosition( event, true );
1795
        this.positionAbs = this._convertPositionTo("absolute");
1796
1797
        //Call plugins and callbacks and use the resulting position if something is returned
1798
        if (!noPropagation) {
1799
            var ui = this._uiHash();
1800
            if (this._trigger("drag", event, ui) === false) {
1801
                this._mouseUp({});
1802
                return false;
1803
            }
1804
            this.position = ui.position;
1805
        }
1806
1807
        this.helper[ 0 ].style.left = this.position.left + "px";
1808
        this.helper[ 0 ].style.top = this.position.top + "px";
1809
1810
        if ($.ui.ddmanager) {
1811
            $.ui.ddmanager.drag(this, event);
1812
        }
1813
1814
        return false;
1815
    },
1816
1817
    _mouseStop: function(event) {
1818
1819
        //If we are using droppables, inform the manager about the drop
1820
        var that = this,
1821
            dropped = false;
1822
        if ($.ui.ddmanager && !this.options.dropBehaviour) {
1823
            dropped = $.ui.ddmanager.drop(this, event);
1824
        }
1825
1826
        //if a drop comes from outside (a sortable)
1827
        if (this.dropped) {
1828
            dropped = this.dropped;
1829
            this.dropped = false;
1830
        }
1831
1832
        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))) {
1833
            $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1834
                if (that._trigger("stop", event) !== false) {
1835
                    that._clear();
1836
                }
1837
            });
1838
        } else {
1839
            if (this._trigger("stop", event) !== false) {
1840
                this._clear();
1841
            }
1842
        }
1843
1844
        return false;
1845
    },
1846
1847
    _mouseUp: function( event ) {
1848
        this._unblockFrames();
1849
1850
        //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1851
        if ( $.ui.ddmanager ) {
1852
            $.ui.ddmanager.dragStop(this, event);
1853
        }
1854
1855
        // Only need to focus if the event occurred on the draggable itself, see #10527
1856
        if ( this.handleElement.is( event.target ) ) {
1857
            // The interaction is over; whether or not the click resulted in a drag, focus the element
1858
            this.element.focus();
1859
        }
1860
1861
        return $.ui.mouse.prototype._mouseUp.call(this, event);
1862
    },
1863
1864
    cancel: function() {
1865
1866
        if (this.helper.is(".ui-draggable-dragging")) {
1867
            this._mouseUp({});
1868
        } else {
1869
            this._clear();
1870
        }
1871
1872
        return this;
1873
1874
    },
1875
1876
    _getHandle: function(event) {
1877
        return this.options.handle ?
1878
            !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
1879
            true;
1880
    },
1881
1882
    _setHandleClassName: function() {
1883
        this.handleElement = this.options.handle ?
1884
            this.element.find( this.options.handle ) : this.element;
1885
        this.handleElement.addClass( "ui-draggable-handle" );
1886
    },
1887
1888
    _removeHandleClassName: function() {
1889
        this.handleElement.removeClass( "ui-draggable-handle" );
1890
    },
1891
1892
    _createHelper: function(event) {
1893
1894
        var o = this.options,
1895
            helperIsFunction = $.isFunction( o.helper ),
1896
            helper = helperIsFunction ?
1897
                $( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
1898
                ( o.helper === "clone" ?
1899
                    this.element.clone().removeAttr( "id" ) :
1900
                    this.element );
1901
1902
        if (!helper.parents("body").length) {
1903
            helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
1904
        }
1905
1906
        // http://bugs.jqueryui.com/ticket/9446
1907
        // a helper function can return the original element
1908
        // which wouldn't have been set to relative in _create
1909
        if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
1910
            this._setPositionRelative();
1911
        }
1912
1913
        if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
1914
            helper.css("position", "absolute");
1915
        }
1916
1917
        return helper;
1918
1919
    },
1920
1921
    _setPositionRelative: function() {
1922
        if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
1923
            this.element[ 0 ].style.position = "relative";
1924
        }
1925
    },
1926
1927
    _adjustOffsetFromHelper: function(obj) {
1928
        if (typeof obj === "string") {
1929
            obj = obj.split(" ");
1930
        }
1931
        if ($.isArray(obj)) {
1932
            obj = { left: +obj[0], top: +obj[1] || 0 };
1933
        }
1934
        if ("left" in obj) {
1935
            this.offset.click.left = obj.left + this.margins.left;
1936
        }
1937
        if ("right" in obj) {
1938
            this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1939
        }
1940
        if ("top" in obj) {
1941
            this.offset.click.top = obj.top + this.margins.top;
1942
        }
1943
        if ("bottom" in obj) {
1944
            this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1945
        }
1946
    },
1947
1948
    _isRootNode: function( element ) {
1949
        return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
1950
    },
1951
1952
    _getParentOffset: function() {
1953
1954
        //Get the offsetParent and cache its position
1955
        var po = this.offsetParent.offset(),
1956
            document = this.document[ 0 ];
1957
1958
        // This is a special case where we need to modify a offset calculated on start, since the following happened:
1959
        // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1960
        // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1961
        //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1962
        if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1963
            po.left += this.scrollParent.scrollLeft();
1964
            po.top += this.scrollParent.scrollTop();
1965
        }
1966
1967
        if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
1968
            po = { top: 0, left: 0 };
1969
        }
1970
1971
        return {
1972
            top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0),
1973
            left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0)
1974
        };
1975
1976
    },
1977
1978
    _getRelativeOffset: function() {
1979
        if ( this.cssPosition !== "relative" ) {
1980
            return { top: 0, left: 0 };
1981
        }
1982
1983
        var p = this.element.position(),
1984
            scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
1985
1986
        return {
1987
            top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
1988
            left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
1989
        };
1990
1991
    },
1992
1993
    _cacheMargins: function() {
1994
        this.margins = {
1995
            left: (parseInt(this.element.css("marginLeft"), 10) || 0),
1996
            top: (parseInt(this.element.css("marginTop"), 10) || 0),
1997
            right: (parseInt(this.element.css("marginRight"), 10) || 0),
1998
            bottom: (parseInt(this.element.css("marginBottom"), 10) || 0)
1999
        };
2000
    },
2001
2002
    _cacheHelperProportions: function() {
2003
        this.helperProportions = {
2004
            width: this.helper.outerWidth(),
2005
            height: this.helper.outerHeight()
2006
        };
2007
    },
2008
2009
    _setContainment: function() {
2010
2011
        var isUserScrollable, c, ce,
2012
            o = this.options,
2013
            document = this.document[ 0 ];
2014
2015
        this.relativeContainer = null;
2016
2017
        if ( !o.containment ) {
2018
            this.containment = null;
2019
            return;
2020
        }
2021
2022
        if ( o.containment === "window" ) {
2023
            this.containment = [
2024
                $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
2025
                $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
2026
                $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
2027
                $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
2028
            ];
2029
            return;
2030
        }
2031
2032
        if ( o.containment === "document") {
2033
            this.containment = [
2034
                0,
2035
                0,
2036
                $( document ).width() - this.helperProportions.width - this.margins.left,
2037
                ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
2038
            ];
2039
            return;
2040
        }
2041
2042
        if ( o.containment.constructor === Array ) {
2043
            this.containment = o.containment;
2044
            return;
2045
        }
2046
2047
        if ( o.containment === "parent" ) {
2048
            o.containment = this.helper[ 0 ].parentNode;
2049
        }
2050
2051
        c = $( o.containment );
2052
        ce = c[ 0 ];
2053
2054
        if ( !ce ) {
2055
            return;
2056
        }
2057
2058
        isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
2059
2060
        this.containment = [
2061
            ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
2062
            ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
2063
            ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
2064
                ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
2065
                ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
2066
                this.helperProportions.width -
2067
                this.margins.left -
2068
                this.margins.right,
2069
            ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
2070
                ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
2071
                ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
2072
                this.helperProportions.height -
2073
                this.margins.top -
2074
                this.margins.bottom
2075
        ];
2076
        this.relativeContainer = c;
2077
    },
2078
2079
    _convertPositionTo: function(d, pos) {
2080
2081
        if (!pos) {
2082
            pos = this.position;
2083
        }
2084
2085
        var mod = d === "absolute" ? 1 : -1,
2086
            scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
2087
2088
        return {
2089
            top: (
2090
                pos.top +                                                               // The absolute mouse position
2091
                this.offset.relative.top * mod +                                        // Only for relative positioned nodes: Relative offset from element to offset parent
2092
                this.offset.parent.top * mod -                                      // The offsetParent's offset without borders (offset + border)
2093
                ( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)
2094
            ),
2095
            left: (
2096
                pos.left +                                                              // The absolute mouse position
2097
                this.offset.relative.left * mod +                                       // Only for relative positioned nodes: Relative offset from element to offset parent
2098
                this.offset.parent.left * mod   -                                       // The offsetParent's offset without borders (offset + border)
2099
                ( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod)
2100
            )
2101
        };
2102
2103
    },
2104
2105
    _generatePosition: function( event, constrainPosition ) {
2106
2107
        var containment, co, top, left,
2108
            o = this.options,
2109
            scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
2110
            pageX = event.pageX,
2111
            pageY = event.pageY;
2112
2113
        // Cache the scroll
2114
        if ( !scrollIsRootNode || !this.offset.scroll ) {
2115
            this.offset.scroll = {
2116
                top: this.scrollParent.scrollTop(),
2117
                left: this.scrollParent.scrollLeft()
2118
            };
2119
        }
2120
2121
        /*
2122
         * - Position constraining -
2123
         * Constrain the position to a mix of grid, containment.
2124
         */
2125
2126
        // If we are not dragging yet, we won't check for options
2127
        if ( constrainPosition ) {
2128
            if ( this.containment ) {
2129
                if ( this.relativeContainer ){
2130
                    co = this.relativeContainer.offset();
2131
                    containment = [
2132
                        this.containment[ 0 ] + co.left,
2133
                        this.containment[ 1 ] + co.top,
2134
                        this.containment[ 2 ] + co.left,
2135
                        this.containment[ 3 ] + co.top
2136
                    ];
2137
                } else {
2138
                    containment = this.containment;
2139
                }
2140
2141
                if (event.pageX - this.offset.click.left < containment[0]) {
2142
                    pageX = containment[0] + this.offset.click.left;
2143
                }
2144
                if (event.pageY - this.offset.click.top < containment[1]) {
2145
                    pageY = containment[1] + this.offset.click.top;
2146
                }
2147
                if (event.pageX - this.offset.click.left > containment[2]) {
2148
                    pageX = containment[2] + this.offset.click.left;
2149
                }
2150
                if (event.pageY - this.offset.click.top > containment[3]) {
2151
                    pageY = containment[3] + this.offset.click.top;
2152
                }
2153
            }
2154
2155
            if (o.grid) {
2156
                //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
2157
                top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
2158
                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;
2159
2160
                left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
2161
                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;
2162
            }
2163
2164
            if ( o.axis === "y" ) {
2165
                pageX = this.originalPageX;
2166
            }
2167
2168
            if ( o.axis === "x" ) {
2169
                pageY = this.originalPageY;
2170
            }
2171
        }
2172
2173
        return {
2174
            top: (
2175
                pageY -                                                                 // The absolute mouse position
2176
                this.offset.click.top   -                                               // Click offset (relative to the element)
2177
                this.offset.relative.top -                                              // Only for relative positioned nodes: Relative offset from element to offset parent
2178
                this.offset.parent.top +                                                // The offsetParent's offset without borders (offset + border)
2179
                ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
2180
            ),
2181
            left: (
2182
                pageX -                                                                 // The absolute mouse position
2183
                this.offset.click.left -                                                // Click offset (relative to the element)
2184
                this.offset.relative.left -                                             // Only for relative positioned nodes: Relative offset from element to offset parent
2185
                this.offset.parent.left +                                               // The offsetParent's offset without borders (offset + border)
2186
                ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
2187
            )
2188
        };
2189
2190
    },
2191
2192
    _clear: function() {
2193
        this.helper.removeClass("ui-draggable-dragging");
2194
        if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
2195
            this.helper.remove();
2196
        }
2197
        this.helper = null;
2198
        this.cancelHelperRemoval = false;
2199
        if ( this.destroyOnClear ) {
2200
            this.destroy();
2201
        }
2202
    },
2203
2204
    _normalizeRightBottom: function() {
2205
        if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) {
2206
            this.helper.width( this.helper.width() );
2207
            this.helper.css( "right", "auto" );
2208
        }
2209
        if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) {
2210
            this.helper.height( this.helper.height() );
2211
            this.helper.css( "bottom", "auto" );
2212
        }
2213
    },
2214
2215
    // From now on bulk stuff - mainly helpers
2216
2217
    _trigger: function( type, event, ui ) {
2218
        ui = ui || this._uiHash();
2219
        $.ui.plugin.call( this, type, [ event, ui, this ], true );
2220
2221
        // Absolute position and offset (see #6884 ) have to be recalculated after plugins
2222
        if ( /^(drag|start|stop)/.test( type ) ) {
2223
            this.positionAbs = this._convertPositionTo( "absolute" );
2224
            ui.offset = this.positionAbs;
2225
        }
2226
        return $.Widget.prototype._trigger.call( this, type, event, ui );
2227
    },
2228
2229
    plugins: {},
2230
2231
    _uiHash: function() {
2232
        return {
2233
            helper: this.helper,
2234
            position: this.position,
2235
            originalPosition: this.originalPosition,
2236
            offset: this.positionAbs
2237
        };
2238
    }
2239
2240
});
2241
2242
$.ui.plugin.add( "draggable", "connectToSortable", {
2243
    start: function( event, ui, draggable ) {
2244
        var uiSortable = $.extend( {}, ui, {
2245
            item: draggable.element
2246
        });
2247
2248
        draggable.sortables = [];
2249
        $( draggable.options.connectToSortable ).each(function() {
2250
            var sortable = $( this ).sortable( "instance" );
2251
2252
            if ( sortable && !sortable.options.disabled ) {
2253
                draggable.sortables.push( sortable );
2254
2255
                // refreshPositions is called at drag start to refresh the containerCache
2256
                // which is used in drag. This ensures it's initialized and synchronized
2257
                // with any changes that might have happened on the page since initialization.
2258
                sortable.refreshPositions();
2259
                sortable._trigger("activate", event, uiSortable);
2260
            }
2261
        });
2262
    },
2263
    stop: function( event, ui, draggable ) {
2264
        var uiSortable = $.extend( {}, ui, {
2265
            item: draggable.element
2266
        });
2267
2268
        draggable.cancelHelperRemoval = false;
2269
2270
        $.each( draggable.sortables, function() {
2271
            var sortable = this;
2272
2273
            if ( sortable.isOver ) {
2274
                sortable.isOver = 0;
2275
2276
                // Allow this sortable to handle removing the helper
2277
                draggable.cancelHelperRemoval = true;
2278
                sortable.cancelHelperRemoval = false;
2279
2280
                // Use _storedCSS To restore properties in the sortable,
2281
                // as this also handles revert (#9675) since the draggable
2282
                // may have modified them in unexpected ways (#8809)
2283
                sortable._storedCSS = {
2284
                    position: sortable.placeholder.css( "position" ),
2285
                    top: sortable.placeholder.css( "top" ),
2286
                    left: sortable.placeholder.css( "left" )
2287
                };
2288
2289
                sortable._mouseStop(event);
2290
2291
                // Once drag has ended, the sortable should return to using
2292
                // its original helper, not the shared helper from draggable
2293
                sortable.options.helper = sortable.options._helper;
2294
            } else {
2295
                // Prevent this Sortable from removing the helper.
2296
                // However, don't set the draggable to remove the helper
2297
                // either as another connected Sortable may yet handle the removal.
2298
                sortable.cancelHelperRemoval = true;
2299
2300
                sortable._trigger( "deactivate", event, uiSortable );
2301
            }
2302
        });
2303
    },
2304
    drag: function( event, ui, draggable ) {
2305
        $.each( draggable.sortables, function() {
2306
            var innermostIntersecting = false,
2307
                sortable = this;
2308
2309
            // Copy over variables that sortable's _intersectsWith uses
2310
            sortable.positionAbs = draggable.positionAbs;
2311
            sortable.helperProportions = draggable.helperProportions;
2312
            sortable.offset.click = draggable.offset.click;
2313
2314
            if ( sortable._intersectsWith( sortable.containerCache ) ) {
2315
                innermostIntersecting = true;
2316
2317
                $.each( draggable.sortables, function() {
2318
                    // Copy over variables that sortable's _intersectsWith uses
2319
                    this.positionAbs = draggable.positionAbs;
2320
                    this.helperProportions = draggable.helperProportions;
2321
                    this.offset.click = draggable.offset.click;
2322
2323
                    if ( this !== sortable &&
2324
                            this._intersectsWith( this.containerCache ) &&
2325
                            $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
2326
                        innermostIntersecting = false;
2327
                    }
2328
2329
                    return innermostIntersecting;
2330
                });
2331
            }
2332
2333
            if ( innermostIntersecting ) {
2334
                // If it intersects, we use a little isOver variable and set it once,
2335
                // so that the move-in stuff gets fired only once.
2336
                if ( !sortable.isOver ) {
2337
                    sortable.isOver = 1;
2338
2339
                    // Store draggable's parent in case we need to reappend to it later.
2340
                    draggable._parent = ui.helper.parent();
2341
2342
                    sortable.currentItem = ui.helper
2343
                        .appendTo( sortable.element )
2344
                        .data( "ui-sortable-item", true );
2345
2346
                    // Store helper option to later restore it
2347
                    sortable.options._helper = sortable.options.helper;
2348
2349
                    sortable.options.helper = function() {
2350
                        return ui.helper[ 0 ];
2351
                    };
2352
2353
                    // Fire the start events of the sortable with our passed browser event,
2354
                    // and our own helper (so it doesn't create a new one)
2355
                    event.target = sortable.currentItem[ 0 ];
2356
                    sortable._mouseCapture( event, true );
2357
                    sortable._mouseStart( event, true, true );
2358
2359
                    // Because the browser event is way off the new appended portlet,
2360
                    // modify necessary variables to reflect the changes
2361
                    sortable.offset.click.top = draggable.offset.click.top;
2362
                    sortable.offset.click.left = draggable.offset.click.left;
2363
                    sortable.offset.parent.left -= draggable.offset.parent.left -
2364
                        sortable.offset.parent.left;
2365
                    sortable.offset.parent.top -= draggable.offset.parent.top -
2366
                        sortable.offset.parent.top;
2367
2368
                    draggable._trigger( "toSortable", event );
2369
2370
                    // Inform draggable that the helper is in a valid drop zone,
2371
                    // used solely in the revert option to handle "valid/invalid".
2372
                    draggable.dropped = sortable.element;
2373
2374
                    // Need to refreshPositions of all sortables in the case that
2375
                    // adding to one sortable changes the location of the other sortables (#9675)
2376
                    $.each( draggable.sortables, function() {
2377
                        this.refreshPositions();
2378
                    });
2379
2380
                    // hack so receive/update callbacks work (mostly)
2381
                    draggable.currentItem = draggable.element;
2382
                    sortable.fromOutside = draggable;
2383
                }
2384
2385
                if ( sortable.currentItem ) {
2386
                    sortable._mouseDrag( event );
2387
                    // Copy the sortable's position because the draggable's can potentially reflect
2388
                    // a relative position, while sortable is always absolute, which the dragged
2389
                    // element has now become. (#8809)
2390
                    ui.position = sortable.position;
2391
                }
2392
            } else {
2393
                // If it doesn't intersect with the sortable, and it intersected before,
2394
                // we fake the drag stop of the sortable, but make sure it doesn't remove
2395
                // the helper by using cancelHelperRemoval.
2396
                if ( sortable.isOver ) {
2397
2398
                    sortable.isOver = 0;
2399
                    sortable.cancelHelperRemoval = true;
2400
2401
                    // Calling sortable's mouseStop would trigger a revert,
2402
                    // so revert must be temporarily false until after mouseStop is called.
2403
                    sortable.options._revert = sortable.options.revert;
2404
                    sortable.options.revert = false;
2405
2406
                    sortable._trigger( "out", event, sortable._uiHash( sortable ) );
2407
                    sortable._mouseStop( event, true );
2408
2409
                    // restore sortable behaviors that were modfied
2410
                    // when the draggable entered the sortable area (#9481)
2411
                    sortable.options.revert = sortable.options._revert;
2412
                    sortable.options.helper = sortable.options._helper;
2413
2414
                    if ( sortable.placeholder ) {
2415
                        sortable.placeholder.remove();
2416
                    }
2417
2418
                    // Restore and recalculate the draggable's offset considering the sortable
2419
                    // may have modified them in unexpected ways. (#8809, #10669)
2420
                    ui.helper.appendTo( draggable._parent );
2421
                    draggable._refreshOffsets( event );
2422
                    ui.position = draggable._generatePosition( event, true );
2423
2424
                    draggable._trigger( "fromSortable", event );
2425
2426
                    // Inform draggable that the helper is no longer in a valid drop zone
2427
                    draggable.dropped = false;
2428
2429
                    // Need to refreshPositions of all sortables just in case removing
2430
                    // from one sortable changes the location of other sortables (#9675)
2431
                    $.each( draggable.sortables, function() {
2432
                        this.refreshPositions();
2433
                    });
2434
                }
2435
            }
2436
        });
2437
    }
2438
});
2439
2440
$.ui.plugin.add("draggable", "cursor", {
2441
    start: function( event, ui, instance ) {
2442
        var t = $( "body" ),
2443
            o = instance.options;
2444
2445
        if (t.css("cursor")) {
2446
            o._cursor = t.css("cursor");
2447
        }
2448
        t.css("cursor", o.cursor);
2449
    },
2450
    stop: function( event, ui, instance ) {
2451
        var o = instance.options;
2452
        if (o._cursor) {
2453
            $("body").css("cursor", o._cursor);
2454
        }
2455
    }
2456
});
2457
2458
$.ui.plugin.add("draggable", "opacity", {
2459
    start: function( event, ui, instance ) {
2460
        var t = $( ui.helper ),
2461
            o = instance.options;
2462
        if (t.css("opacity")) {
2463
            o._opacity = t.css("opacity");
2464
        }
2465
        t.css("opacity", o.opacity);
2466
    },
2467
    stop: function( event, ui, instance ) {
2468
        var o = instance.options;
2469
        if (o._opacity) {
2470
            $(ui.helper).css("opacity", o._opacity);
2471
        }
2472
    }
2473
});
2474
2475
$.ui.plugin.add("draggable", "scroll", {
2476
    start: function( event, ui, i ) {
2477
        if ( !i.scrollParentNotHidden ) {
2478
            i.scrollParentNotHidden = i.helper.scrollParent( false );
2479
        }
2480
2481
        if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
2482
            i.overflowOffset = i.scrollParentNotHidden.offset();
2483
        }
2484
    },
2485
    drag: function( event, ui, i  ) {
2486
2487
        var o = i.options,
2488
            scrolled = false,
2489
            scrollParent = i.scrollParentNotHidden[ 0 ],
2490
            document = i.document[ 0 ];
2491
2492
        if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
2493
            if ( !o.axis || o.axis !== "x" ) {
2494
                if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) {
2495
                    scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
2496
                } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
2497
                    scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
2498
                }
2499
            }
2500
2501
            if ( !o.axis || o.axis !== "y" ) {
2502
                if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) {
2503
                    scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
2504
                } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
2505
                    scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
2506
                }
2507
            }
2508
2509
        } else {
2510
2511
            if (!o.axis || o.axis !== "x") {
2512
                if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
2513
                    scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
2514
                } else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
2515
                    scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
2516
                }
2517
            }
2518
2519
            if (!o.axis || o.axis !== "y") {
2520
                if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
2521
                    scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
2522
                } else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
2523
                    scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
2524
                }
2525
            }
2526
2527
        }
2528
2529
        if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
2530
            $.ui.ddmanager.prepareOffsets(i, event);
2531
        }
2532
2533
    }
2534
});
2535
2536
$.ui.plugin.add("draggable", "snap", {
2537
    start: function( event, ui, i ) {
2538
2539
        var o = i.options;
2540
2541
        i.snapElements = [];
2542
2543
        $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
2544
            var $t = $(this),
2545
                $o = $t.offset();
2546
            if (this !== i.element[0]) {
2547
                i.snapElements.push({
2548
                    item: this,
2549
                    width: $t.outerWidth(), height: $t.outerHeight(),
2550
                    top: $o.top, left: $o.left
2551
                });
2552
            }
2553
        });
2554
2555
    },
2556
    drag: function( event, ui, inst ) {
2557
2558
        var ts, bs, ls, rs, l, r, t, b, i, first,
2559
            o = inst.options,
2560
            d = o.snapTolerance,
2561
            x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
2562
            y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
2563
2564
        for (i = inst.snapElements.length - 1; i >= 0; i--){
2565
2566
            l = inst.snapElements[i].left - inst.margins.left;
2567
            r = l + inst.snapElements[i].width;
2568
            t = inst.snapElements[i].top - inst.margins.top;
2569
            b = t + inst.snapElements[i].height;
2570
2571
            if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
2572
                if (inst.snapElements[i].snapping) {
2573
                    (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2574
                }
2575
                inst.snapElements[i].snapping = false;
2576
                continue;
2577
            }
2578
2579
            if (o.snapMode !== "inner") {
2580
                ts = Math.abs(t - y2) <= d;
2581
                bs = Math.abs(b - y1) <= d;
2582
                ls = Math.abs(l - x2) <= d;
2583
                rs = Math.abs(r - x1) <= d;
2584
                if (ts) {
2585
                    ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top;
2586
                }
2587
                if (bs) {
2588
                    ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top;
2589
                }
2590
                if (ls) {
2591
                    ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left;
2592
                }
2593
                if (rs) {
2594
                    ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left;
2595
                }
2596
            }
2597
2598
            first = (ts || bs || ls || rs);
2599
2600
            if (o.snapMode !== "outer") {
2601
                ts = Math.abs(t - y1) <= d;
2602
                bs = Math.abs(b - y2) <= d;
2603
                ls = Math.abs(l - x1) <= d;
2604
                rs = Math.abs(r - x2) <= d;
2605
                if (ts) {
2606
                    ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top;
2607
                }
2608
                if (bs) {
2609
                    ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top;
2610
                }
2611
                if (ls) {
2612
                    ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left;
2613
                }
2614
                if (rs) {
2615
                    ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left;
2616
                }
2617
            }
2618
2619
            if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
2620
                (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2621
            }
2622
            inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
2623
2624
        }
2625
2626
    }
2627
});
2628
2629
$.ui.plugin.add("draggable", "stack", {
2630
    start: function( event, ui, instance ) {
2631
        var min,
2632
            o = instance.options,
2633
            group = $.makeArray($(o.stack)).sort(function(a, b) {
2634
                return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0);
2635
            });
2636
2637
        if (!group.length) { return; }
2638
2639
        min = parseInt($(group[0]).css("zIndex"), 10) || 0;
2640
        $(group).each(function(i) {
2641
            $(this).css("zIndex", min + i);
2642
        });
2643
        this.css("zIndex", (min + group.length));
2644
    }
2645
});
2646
2647
$.ui.plugin.add("draggable", "zIndex", {
2648
    start: function( event, ui, instance ) {
2649
        var t = $( ui.helper ),
2650
            o = instance.options;
2651
2652
        if (t.css("zIndex")) {
2653
            o._zIndex = t.css("zIndex");
2654
        }
2655
        t.css("zIndex", o.zIndex);
2656
    },
2657
    stop: function( event, ui, instance ) {
2658
        var o = instance.options;
2659
2660
        if (o._zIndex) {
2661
            $(ui.helper).css("zIndex", o._zIndex);
2662
        }
2663
    }
2664
});
2665
2666
var draggable = $.ui.draggable;
2667
2668
2669
/*!
2670
 * jQuery UI Droppable 1.11.4
2671
 * http://jqueryui.com
2672
 *
2673
 * Copyright jQuery Foundation and other contributors
2674
 * Released under the MIT license.
2675
 * http://jquery.org/license
2676
 *
2677
 * http://api.jqueryui.com/droppable/
2678
 */
2679
2680
2681
$.widget( "ui.droppable", {
2682
    version: "1.11.4",
2683
    widgetEventPrefix: "drop",
2684
    options: {
2685
        accept: "*",
2686
        activeClass: false,
2687
        addClasses: true,
2688
        greedy: false,
2689
        hoverClass: false,
2690
        scope: "default",
2691
        tolerance: "intersect",
2692
2693
        // callbacks
2694
        activate: null,
2695
        deactivate: null,
2696
        drop: null,
2697
        out: null,
2698
        over: null
2699
    },
2700
    _create: function() {
2701
2702
        var proportions,
2703
            o = this.options,
2704
            accept = o.accept;
2705
2706
        this.isover = false;
2707
        this.isout = true;
2708
2709
        this.accept = $.isFunction( accept ) ? accept : function( d ) {
2710
            return d.is( accept );
2711
        };
2712
2713
        this.proportions = function( /* valueToWrite */ ) {
2714
            if ( arguments.length ) {
2715
                // Store the droppable's proportions
2716
                proportions = arguments[ 0 ];
2717
            } else {
2718
                // Retrieve or derive the droppable's proportions
2719
                return proportions ?
2720
                    proportions :
2721
                    proportions = {
2722
                        width: this.element[ 0 ].offsetWidth,
2723
                        height: this.element[ 0 ].offsetHeight
2724
                    };
2725
            }
2726
        };
2727
2728
        this._addToManager( o.scope );
2729
2730
        o.addClasses && this.element.addClass( "ui-droppable" );
2731
2732
    },
2733
2734
    _addToManager: function( scope ) {
2735
        // Add the reference and positions to the manager
2736
        $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
2737
        $.ui.ddmanager.droppables[ scope ].push( this );
2738
    },
2739
2740
    _splice: function( drop ) {
2741
        var i = 0;
2742
        for ( ; i < drop.length; i++ ) {
2743
            if ( drop[ i ] === this ) {
2744
                drop.splice( i, 1 );
2745
            }
2746
        }
2747
    },
2748
2749
    _destroy: function() {
2750
        var drop = $.ui.ddmanager.droppables[ this.options.scope ];
2751
2752
        this._splice( drop );
2753
2754
        this.element.removeClass( "ui-droppable ui-droppable-disabled" );
2755
    },
2756
2757
    _setOption: function( key, value ) {
2758
2759
        if ( key === "accept" ) {
2760
            this.accept = $.isFunction( value ) ? value : function( d ) {
2761
                return d.is( value );
2762
            };
2763
        } else if ( key === "scope" ) {
2764
            var drop = $.ui.ddmanager.droppables[ this.options.scope ];
2765
2766
            this._splice( drop );
2767
            this._addToManager( value );
2768
        }
2769
2770
        this._super( key, value );
2771
    },
2772
2773
    _activate: function( event ) {
2774
        var draggable = $.ui.ddmanager.current;
2775
        if ( this.options.activeClass ) {
2776
            this.element.addClass( this.options.activeClass );
2777
        }
2778
        if ( draggable ){
2779
            this._trigger( "activate", event, this.ui( draggable ) );
2780
        }
2781
    },
2782
2783
    _deactivate: function( event ) {
2784
        var draggable = $.ui.ddmanager.current;
2785
        if ( this.options.activeClass ) {
2786
            this.element.removeClass( this.options.activeClass );
2787
        }
2788
        if ( draggable ){
2789
            this._trigger( "deactivate", event, this.ui( draggable ) );
2790
        }
2791
    },
2792
2793
    _over: function( event ) {
2794
2795
        var draggable = $.ui.ddmanager.current;
2796
2797
        // Bail if draggable and droppable are same element
2798
        if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2799
            return;
2800
        }
2801
2802
        if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2803
            if ( this.options.hoverClass ) {
2804
                this.element.addClass( this.options.hoverClass );
2805
            }
2806
            this._trigger( "over", event, this.ui( draggable ) );
2807
        }
2808
2809
    },
2810
2811
    _out: function( event ) {
2812
2813
        var draggable = $.ui.ddmanager.current;
2814
2815
        // Bail if draggable and droppable are same element
2816
        if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2817
            return;
2818
        }
2819
2820
        if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2821
            if ( this.options.hoverClass ) {
2822
                this.element.removeClass( this.options.hoverClass );
2823
            }
2824
            this._trigger( "out", event, this.ui( draggable ) );
2825
        }
2826
2827
    },
2828
2829
    _drop: function( event, custom ) {
2830
2831
        var draggable = custom || $.ui.ddmanager.current,
2832
            childrenIntersection = false;
2833
2834
        // Bail if draggable and droppable are same element
2835
        if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2836
            return false;
2837
        }
2838
2839
        this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() {
2840
            var inst = $( this ).droppable( "instance" );
2841
            if (
2842
                inst.options.greedy &&
2843
                !inst.options.disabled &&
2844
                inst.options.scope === draggable.options.scope &&
2845
                inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) &&
2846
                $.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event )
2847
            ) { childrenIntersection = true; return false; }
2848
        });
2849
        if ( childrenIntersection ) {
2850
            return false;
2851
        }
2852
2853
        if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2854
            if ( this.options.activeClass ) {
2855
                this.element.removeClass( this.options.activeClass );
2856
            }
2857
            if ( this.options.hoverClass ) {
2858
                this.element.removeClass( this.options.hoverClass );
2859
            }
2860
            this._trigger( "drop", event, this.ui( draggable ) );
2861
            return this.element;
2862
        }
2863
2864
        return false;
2865
2866
    },
2867
2868
    ui: function( c ) {
2869
        return {
2870
            draggable: ( c.currentItem || c.element ),
2871
            helper: c.helper,
2872
            position: c.position,
2873
            offset: c.positionAbs
2874
        };
2875
    }
2876
2877
});
2878
2879
$.ui.intersect = (function() {
2880
    function isOverAxis( x, reference, size ) {
2881
        return ( x >= reference ) && ( x < ( reference + size ) );
2882
    }
2883
2884
    return function( draggable, droppable, toleranceMode, event ) {
2885
2886
        if ( !droppable.offset ) {
2887
            return false;
2888
        }
2889
2890
        var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left,
2891
            y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top,
2892
            x2 = x1 + draggable.helperProportions.width,
2893
            y2 = y1 + draggable.helperProportions.height,
2894
            l = droppable.offset.left,
2895
            t = droppable.offset.top,
2896
            r = l + droppable.proportions().width,
2897
            b = t + droppable.proportions().height;
2898
2899
        switch ( toleranceMode ) {
2900
        case "fit":
2901
            return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
2902
        case "intersect":
2903
            return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
2904
                x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
2905
                t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
2906
                y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
2907
        case "pointer":
2908
            return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width );
2909
        case "touch":
2910
            return (
2911
                ( y1 >= t && y1 <= b ) || // Top edge touching
2912
                ( y2 >= t && y2 <= b ) || // Bottom edge touching
2913
                ( y1 < t && y2 > b ) // Surrounded vertically
2914
            ) && (
2915
                ( x1 >= l && x1 <= r ) || // Left edge touching
2916
                ( x2 >= l && x2 <= r ) || // Right edge touching
2917
                ( x1 < l && x2 > r ) // Surrounded horizontally
2918
            );
2919
        default:
2920
            return false;
2921
        }
2922
    };
2923
})();
2924
2925
/*
2926
    This manager tracks offsets of draggables and droppables
2927
*/
2928
$.ui.ddmanager = {
2929
    current: null,
2930
    droppables: { "default": [] },
2931
    prepareOffsets: function( t, event ) {
2932
2933
        var i, j,
2934
            m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
2935
            type = event ? event.type : null, // workaround for #2317
2936
            list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
2937
2938
        droppablesLoop: for ( i = 0; i < m.length; i++ ) {
2939
2940
            // No disabled and non-accepted
2941
            if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) {
2942
                continue;
2943
            }
2944
2945
            // Filter out elements in the current dragged item
2946
            for ( j = 0; j < list.length; j++ ) {
2947
                if ( list[ j ] === m[ i ].element[ 0 ] ) {
2948
                    m[ i ].proportions().height = 0;
2949
                    continue droppablesLoop;
2950
                }
2951
            }
2952
2953
            m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
2954
            if ( !m[ i ].visible ) {
2955
                continue;
2956
            }
2957
2958
            // Activate the droppable if used directly from draggables
2959
            if ( type === "mousedown" ) {
2960
                m[ i ]._activate.call( m[ i ], event );
2961
            }
2962
2963
            m[ i ].offset = m[ i ].element.offset();
2964
            m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
2965
2966
        }
2967
2968
    },
2969
    drop: function( draggable, event ) {
2970
2971
        var dropped = false;
2972
        // Create a copy of the droppables in case the list changes during the drop (#9116)
2973
        $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
2974
2975
            if ( !this.options ) {
2976
                return;
2977
            }
2978
            if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
2979
                dropped = this._drop.call( this, event ) || dropped;
2980
            }
2981
2982
            if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2983
                this.isout = true;
2984
                this.isover = false;
2985
                this._deactivate.call( this, event );
2986
            }
2987
2988
        });
2989
        return dropped;
2990
2991
    },
2992
    dragStart: function( draggable, event ) {
2993
        // Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2994
        draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2995
            if ( !draggable.options.refreshPositions ) {
2996
                $.ui.ddmanager.prepareOffsets( draggable, event );
2997
            }
2998
        });
2999
    },
3000
    drag: function( draggable, event ) {
3001
3002
        // If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
3003
        if ( draggable.options.refreshPositions ) {
3004
            $.ui.ddmanager.prepareOffsets( draggable, event );
3005
        }
3006
3007
        // Run through all droppables and check their positions based on specific tolerance options
3008
        $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
3009
3010
            if ( this.options.disabled || this.greedyChild || !this.visible ) {
3011
                return;
3012
            }
3013
3014
            var parentInstance, scope, parent,
3015
                intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
3016
                c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null );
3017
            if ( !c ) {
3018
                return;
3019
            }
3020
3021
            if ( this.options.greedy ) {
3022
                // find droppable parents with same scope
3023
                scope = this.options.scope;
3024
                parent = this.element.parents( ":data(ui-droppable)" ).filter(function() {
3025
                    return $( this ).droppable( "instance" ).options.scope === scope;
3026
                });
3027
3028
                if ( parent.length ) {
3029
                    parentInstance = $( parent[ 0 ] ).droppable( "instance" );
3030
                    parentInstance.greedyChild = ( c === "isover" );
3031
                }
3032
            }
3033
3034
            // we just moved into a greedy child
3035
            if ( parentInstance && c === "isover" ) {
3036
                parentInstance.isover = false;
3037
                parentInstance.isout = true;
3038
                parentInstance._out.call( parentInstance, event );
3039
            }
3040
3041
            this[ c ] = true;
3042
            this[c === "isout" ? "isover" : "isout"] = false;
3043
            this[c === "isover" ? "_over" : "_out"].call( this, event );
3044
3045
            // we just moved out of a greedy child
3046
            if ( parentInstance && c === "isout" ) {
3047
                parentInstance.isout = false;
3048
                parentInstance.isover = true;
3049
                parentInstance._over.call( parentInstance, event );
3050
            }
3051
        });
3052
3053
    },
3054
    dragStop: function( draggable, event ) {
3055
        draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
3056
        // Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
3057
        if ( !draggable.options.refreshPositions ) {
3058
            $.ui.ddmanager.prepareOffsets( draggable, event );
3059
        }
3060
    }
3061
};
3062
3063
var droppable = $.ui.droppable;
3064
3065
3066
/*!
3067
 * jQuery UI Resizable 1.11.4
3068
 * http://jqueryui.com
3069
 *
3070
 * Copyright jQuery Foundation and other contributors
3071
 * Released under the MIT license.
3072
 * http://jquery.org/license
3073
 *
3074
 * http://api.jqueryui.com/resizable/
3075
 */
3076
3077
3078
$.widget("ui.resizable", $.ui.mouse, {
3079
    version: "1.11.4",
3080
    widgetEventPrefix: "resize",
3081
    options: {
3082
        alsoResize: false,
3083
        animate: false,
3084
        animateDuration: "slow",
3085
        animateEasing: "swing",
3086
        aspectRatio: false,
3087
        autoHide: false,
3088
        containment: false,
3089
        ghost: false,
3090
        grid: false,
3091
        handles: "e,s,se",
3092
        helper: false,
3093
        maxHeight: null,
3094
        maxWidth: null,
3095
        minHeight: 10,
3096
        minWidth: 10,
3097
        // See #7960
3098
        zIndex: 90,
3099
3100
        // callbacks
3101
        resize: null,
3102
        start: null,
3103
        stop: null
3104
    },
3105
3106
    _num: function( value ) {
3107
        return parseInt( value, 10 ) || 0;
3108
    },
3109
3110
    _isNumber: function( value ) {
3111
        return !isNaN( parseInt( value, 10 ) );
3112
    },
3113
3114
    _hasScroll: function( el, a ) {
3115
3116
        if ( $( el ).css( "overflow" ) === "hidden") {
3117
            return false;
3118
        }
3119
3120
        var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
3121
            has = false;
3122
3123
        if ( el[ scroll ] > 0 ) {
3124
            return true;
3125
        }
3126
3127
        // TODO: determine which cases actually cause this to happen
3128
        // if the element doesn't have the scroll set, see if it's possible to
3129
        // set the scroll
3130
        el[ scroll ] = 1;
3131
        has = ( el[ scroll ] > 0 );
3132
        el[ scroll ] = 0;
3133
        return has;
3134
    },
3135
3136
    _create: function() {
3137
3138
        var n, i, handle, axis, hname,
3139
            that = this,
3140
            o = this.options;
3141
        this.element.addClass("ui-resizable");
3142
3143
        $.extend(this, {
3144
            _aspectRatio: !!(o.aspectRatio),
3145
            aspectRatio: o.aspectRatio,
3146
            originalElement: this.element,
3147
            _proportionallyResizeElements: [],
3148
            _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
3149
        });
3150
3151
        // Wrap the element if it cannot hold child nodes
3152
        if (this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)) {
3153
3154
            this.element.wrap(
3155
                $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
3156
                    position: this.element.css("position"),
3157
                    width: this.element.outerWidth(),
3158
                    height: this.element.outerHeight(),
3159
                    top: this.element.css("top"),
3160
                    left: this.element.css("left")
3161
                })
3162
            );
3163
3164
            this.element = this.element.parent().data(
3165
                "ui-resizable", this.element.resizable( "instance" )
3166
            );
3167
3168
            this.elementIsWrapper = true;
3169
3170
            this.element.css({
3171
                marginLeft: this.originalElement.css("marginLeft"),
3172
                marginTop: this.originalElement.css("marginTop"),
3173
                marginRight: this.originalElement.css("marginRight"),
3174
                marginBottom: this.originalElement.css("marginBottom")
3175
            });
3176
            this.originalElement.css({
3177
                marginLeft: 0,
3178
                marginTop: 0,
3179
                marginRight: 0,
3180
                marginBottom: 0
3181
            });
3182
            // support: Safari
3183
            // Prevent Safari textarea resize
3184
            this.originalResizeStyle = this.originalElement.css("resize");
3185
            this.originalElement.css("resize", "none");
3186
3187
            this._proportionallyResizeElements.push( this.originalElement.css({
3188
                position: "static",
3189
                zoom: 1,
3190
                display: "block"
3191
            }) );
3192
3193
            // support: IE9
3194
            // avoid IE jump (hard set the margin)
3195
            this.originalElement.css({ margin: this.originalElement.css("margin") });
3196
3197
            this._proportionallyResize();
3198
        }
3199
3200
        this.handles = o.handles ||
3201
            ( !$(".ui-resizable-handle", this.element).length ?
3202
                "e,s,se" : {
3203
                    n: ".ui-resizable-n",
3204
                    e: ".ui-resizable-e",
3205
                    s: ".ui-resizable-s",
3206
                    w: ".ui-resizable-w",
3207
                    se: ".ui-resizable-se",
3208
                    sw: ".ui-resizable-sw",
3209
                    ne: ".ui-resizable-ne",
3210
                    nw: ".ui-resizable-nw"
3211
                } );
3212
3213
        this._handles = $();
3214
        if ( this.handles.constructor === String ) {
3215
3216
            if ( this.handles === "all") {
3217
                this.handles = "n,e,s,w,se,sw,ne,nw";
3218
            }
3219
3220
            n = this.handles.split(",");
3221
            this.handles = {};
3222
3223
            for (i = 0; i < n.length; i++) {
3224
3225
                handle = $.trim(n[i]);
3226
                hname = "ui-resizable-" + handle;
3227
                axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
3228
3229
                axis.css({ zIndex: o.zIndex });
3230
3231
                // TODO : What's going on here?
3232
                if ("se" === handle) {
3233
                    axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
3234
                }
3235
3236
                this.handles[handle] = ".ui-resizable-" + handle;
3237
                this.element.append(axis);
3238
            }
3239
3240
        }
3241
3242
        this._renderAxis = function(target) {
3243
3244
            var i, axis, padPos, padWrapper;
3245
3246
            target = target || this.element;
3247
3248
            for (i in this.handles) {
3249
3250
                if (this.handles[i].constructor === String) {
3251
                    this.handles[i] = this.element.children( this.handles[ i ] ).first().show();
3252
                } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
3253
                    this.handles[ i ] = $( this.handles[ i ] );
3254
                    this._on( this.handles[ i ], { "mousedown": that._mouseDown });
3255
                }
3256
3257
                if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)) {
3258
3259
                    axis = $(this.handles[i], this.element);
3260
3261
                    padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
3262
3263
                    padPos = [ "padding",
3264
                        /ne|nw|n/.test(i) ? "Top" :
3265
                        /se|sw|s/.test(i) ? "Bottom" :
3266
                        /^e$/.test(i) ? "Right" : "Left" ].join("");
3267
3268
                    target.css(padPos, padWrapper);
3269
3270
                    this._proportionallyResize();
3271
                }
3272
3273
                this._handles = this._handles.add( this.handles[ i ] );
3274
            }
3275
        };
3276
3277
        // TODO: make renderAxis a prototype function
3278
        this._renderAxis(this.element);
3279
3280
        this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
3281
        this._handles.disableSelection();
3282
3283
        this._handles.mouseover(function() {
3284
            if (!that.resizing) {
3285
                if (this.className) {
3286
                    axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
3287
                }
3288
                that.axis = axis && axis[1] ? axis[1] : "se";
3289
            }
3290
        });
3291
3292
        if (o.autoHide) {
3293
            this._handles.hide();
3294
            $(this.element)
3295
                .addClass("ui-resizable-autohide")
3296
                .mouseenter(function() {
3297
                    if (o.disabled) {
3298
                        return;
3299
                    }
3300
                    $(this).removeClass("ui-resizable-autohide");
3301
                    that._handles.show();
3302
                })
3303
                .mouseleave(function() {
3304
                    if (o.disabled) {
3305
                        return;
3306
                    }
3307
                    if (!that.resizing) {
3308
                        $(this).addClass("ui-resizable-autohide");
3309
                        that._handles.hide();
3310
                    }
3311
                });
3312
        }
3313
3314
        this._mouseInit();
3315
    },
3316
3317
    _destroy: function() {
3318
3319
        this._mouseDestroy();
3320
3321
        var wrapper,
3322
            _destroy = function(exp) {
3323
                $(exp)
3324
                    .removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
3325
                    .removeData("resizable")
3326
                    .removeData("ui-resizable")
3327
                    .unbind(".resizable")
3328
                    .find(".ui-resizable-handle")
3329
                        .remove();
3330
            };
3331
3332
        // TODO: Unwrap at same DOM position
3333
        if (this.elementIsWrapper) {
3334
            _destroy(this.element);
3335
            wrapper = this.element;
3336
            this.originalElement.css({
3337
                position: wrapper.css("position"),
3338
                width: wrapper.outerWidth(),
3339
                height: wrapper.outerHeight(),
3340
                top: wrapper.css("top"),
3341
                left: wrapper.css("left")
3342
            }).insertAfter( wrapper );
3343
            wrapper.remove();
3344
        }
3345
3346
        this.originalElement.css("resize", this.originalResizeStyle);
3347
        _destroy(this.originalElement);
3348
3349
        return this;
3350
    },
3351
3352
    _mouseCapture: function(event) {
3353
        var i, handle,
3354
            capture = false;
3355
3356
        for (i in this.handles) {
3357
            handle = $(this.handles[i])[0];
3358
            if (handle === event.target || $.contains(handle, event.target)) {
3359
                capture = true;
3360
            }
3361
        }
3362
3363
        return !this.options.disabled && capture;
3364
    },
3365
3366
    _mouseStart: function(event) {
3367
3368
        var curleft, curtop, cursor,
3369
            o = this.options,
3370
            el = this.element;
3371
3372
        this.resizing = true;
3373
3374
        this._renderProxy();
3375
3376
        curleft = this._num(this.helper.css("left"));
3377
        curtop = this._num(this.helper.css("top"));
3378
3379
        if (o.containment) {
3380
            curleft += $(o.containment).scrollLeft() || 0;
3381
            curtop += $(o.containment).scrollTop() || 0;
3382
        }
3383
3384
        this.offset = this.helper.offset();
3385
        this.position = { left: curleft, top: curtop };
3386
3387
        this.size = this._helper ? {
3388
                width: this.helper.width(),
3389
                height: this.helper.height()
3390
            } : {
3391
                width: el.width(),
3392
                height: el.height()
3393
            };
3394
3395
        this.originalSize = this._helper ? {
3396
                width: el.outerWidth(),
3397
                height: el.outerHeight()
3398
            } : {
3399
                width: el.width(),
3400
                height: el.height()
3401
            };
3402
3403
        this.sizeDiff = {
3404
            width: el.outerWidth() - el.width(),
3405
            height: el.outerHeight() - el.height()
3406
        };
3407
3408
        this.originalPosition = { left: curleft, top: curtop };
3409
        this.originalMousePosition = { left: event.pageX, top: event.pageY };
3410
3411
        this.aspectRatio = (typeof o.aspectRatio === "number") ?
3412
            o.aspectRatio :
3413
            ((this.originalSize.width / this.originalSize.height) || 1);
3414
3415
        cursor = $(".ui-resizable-" + this.axis).css("cursor");
3416
        $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
3417
3418
        el.addClass("ui-resizable-resizing");
3419
        this._propagate("start", event);
3420
        return true;
3421
    },
3422
3423
    _mouseDrag: function(event) {
3424
3425
        var data, props,
3426
            smp = this.originalMousePosition,
3427
            a = this.axis,
3428
            dx = (event.pageX - smp.left) || 0,
3429
            dy = (event.pageY - smp.top) || 0,
3430
            trigger = this._change[a];
3431
3432
        this._updatePrevProperties();
3433
3434
        if (!trigger) {
3435
            return false;
3436
        }
3437
3438
        data = trigger.apply(this, [ event, dx, dy ]);
3439
3440
        this._updateVirtualBoundaries(event.shiftKey);
3441
        if (this._aspectRatio || event.shiftKey) {
3442
            data = this._updateRatio(data, event);
3443
        }
3444
3445
        data = this._respectSize(data, event);
3446
3447
        this._updateCache(data);
3448
3449
        this._propagate("resize", event);
3450
3451
        props = this._applyChanges();
3452
3453
        if ( !this._helper && this._proportionallyResizeElements.length ) {
3454
            this._proportionallyResize();
3455
        }
3456
3457
        if ( !$.isEmptyObject( props ) ) {
3458
            this._updatePrevProperties();
3459
            this._trigger( "resize", event, this.ui() );
3460
            this._applyChanges();
3461
        }
3462
3463
        return false;
3464
    },
3465
3466
    _mouseStop: function(event) {
3467
3468
        this.resizing = false;
3469
        var pr, ista, soffseth, soffsetw, s, left, top,
3470
            o = this.options, that = this;
3471
3472
        if (this._helper) {
3473
3474
            pr = this._proportionallyResizeElements;
3475
            ista = pr.length && (/textarea/i).test(pr[0].nodeName);
3476
            soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height;
3477
            soffsetw = ista ? 0 : that.sizeDiff.width;
3478
3479
            s = {
3480
                width: (that.helper.width()  - soffsetw),
3481
                height: (that.helper.height() - soffseth)
3482
            };
3483
            left = (parseInt(that.element.css("left"), 10) +
3484
                (that.position.left - that.originalPosition.left)) || null;
3485
            top = (parseInt(that.element.css("top"), 10) +
3486
                (that.position.top - that.originalPosition.top)) || null;
3487
3488
            if (!o.animate) {
3489
                this.element.css($.extend(s, { top: top, left: left }));
3490
            }
3491
3492
            that.helper.height(that.size.height);
3493
            that.helper.width(that.size.width);
3494
3495
            if (this._helper && !o.animate) {
3496
                this._proportionallyResize();
3497
            }
3498
        }
3499
3500
        $("body").css("cursor", "auto");
3501
3502
        this.element.removeClass("ui-resizable-resizing");
3503
3504
        this._propagate("stop", event);
3505
3506
        if (this._helper) {
3507
            this.helper.remove();
3508
        }
3509
3510
        return false;
3511
3512
    },
3513
3514
    _updatePrevProperties: function() {
3515
        this.prevPosition = {
3516
            top: this.position.top,
3517
            left: this.position.left
3518
        };
3519
        this.prevSize = {
3520
            width: this.size.width,
3521
            height: this.size.height
3522
        };
3523
    },
3524
3525
    _applyChanges: function() {
3526
        var props = {};
3527
3528
        if ( this.position.top !== this.prevPosition.top ) {
3529
            props.top = this.position.top + "px";
3530
        }
3531
        if ( this.position.left !== this.prevPosition.left ) {
3532
            props.left = this.position.left + "px";
3533
        }
3534
        if ( this.size.width !== this.prevSize.width ) {
3535
            props.width = this.size.width + "px";
3536
        }
3537
        if ( this.size.height !== this.prevSize.height ) {
3538
            props.height = this.size.height + "px";
3539
        }
3540
3541
        this.helper.css( props );
3542
3543
        return props;
3544
    },
3545
3546
    _updateVirtualBoundaries: function(forceAspectRatio) {
3547
        var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
3548
            o = this.options;
3549
3550
        b = {
3551
            minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0,
3552
            maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity,
3553
            minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0,
3554
            maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity
3555
        };
3556
3557
        if (this._aspectRatio || forceAspectRatio) {
3558
            pMinWidth = b.minHeight * this.aspectRatio;
3559
            pMinHeight = b.minWidth / this.aspectRatio;
3560
            pMaxWidth = b.maxHeight * this.aspectRatio;
3561
            pMaxHeight = b.maxWidth / this.aspectRatio;
3562
3563
            if (pMinWidth > b.minWidth) {
3564
                b.minWidth = pMinWidth;
3565
            }
3566
            if (pMinHeight > b.minHeight) {
3567
                b.minHeight = pMinHeight;
3568
            }
3569
            if (pMaxWidth < b.maxWidth) {
3570
                b.maxWidth = pMaxWidth;
3571
            }
3572
            if (pMaxHeight < b.maxHeight) {
3573
                b.maxHeight = pMaxHeight;
3574
            }
3575
        }
3576
        this._vBoundaries = b;
3577
    },
3578
3579
    _updateCache: function(data) {
3580
        this.offset = this.helper.offset();
3581
        if (this._isNumber(data.left)) {
3582
            this.position.left = data.left;
3583
        }
3584
        if (this._isNumber(data.top)) {
3585
            this.position.top = data.top;
3586
        }
3587
        if (this._isNumber(data.height)) {
3588
            this.size.height = data.height;
3589
        }
3590
        if (this._isNumber(data.width)) {
3591
            this.size.width = data.width;
3592
        }
3593
    },
3594
3595
    _updateRatio: function( data ) {
3596
3597
        var cpos = this.position,
3598
            csize = this.size,
3599
            a = this.axis;
3600
3601
        if (this._isNumber(data.height)) {
3602
            data.width = (data.height * this.aspectRatio);
3603
        } else if (this._isNumber(data.width)) {
3604
            data.height = (data.width / this.aspectRatio);
3605
        }
3606
3607
        if (a === "sw") {
3608
            data.left = cpos.left + (csize.width - data.width);
3609
            data.top = null;
3610
        }
3611
        if (a === "nw") {
3612
            data.top = cpos.top + (csize.height - data.height);
3613
            data.left = cpos.left + (csize.width - data.width);
3614
        }
3615
3616
        return data;
3617
    },
3618
3619
    _respectSize: function( data ) {
3620
3621
        var o = this._vBoundaries,
3622
            a = this.axis,
3623
            ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width),
3624
            ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
3625
            isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width),
3626
            isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
3627
            dw = this.originalPosition.left + this.originalSize.width,
3628
            dh = this.position.top + this.size.height,
3629
            cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
3630
        if (isminw) {
3631
            data.width = o.minWidth;
3632
        }
3633
        if (isminh) {
3634
            data.height = o.minHeight;
3635
        }
3636
        if (ismaxw) {
3637
            data.width = o.maxWidth;
3638
        }
3639
        if (ismaxh) {
3640
            data.height = o.maxHeight;
3641
        }
3642
3643
        if (isminw && cw) {
3644
            data.left = dw - o.minWidth;
3645
        }
3646
        if (ismaxw && cw) {
3647
            data.left = dw - o.maxWidth;
3648
        }
3649
        if (isminh && ch) {
3650
            data.top = dh - o.minHeight;
3651
        }
3652
        if (ismaxh && ch) {
3653
            data.top = dh - o.maxHeight;
3654
        }
3655
3656
        // Fixing jump error on top/left - bug #2330
3657
        if (!data.width && !data.height && !data.left && data.top) {
3658
            data.top = null;
3659
        } else if (!data.width && !data.height && !data.top && data.left) {
3660
            data.left = null;
3661
        }
3662
3663
        return data;
3664
    },
3665
3666
    _getPaddingPlusBorderDimensions: function( element ) {
3667
        var i = 0,
3668
            widths = [],
3669
            borders = [
3670
                element.css( "borderTopWidth" ),
3671
                element.css( "borderRightWidth" ),
3672
                element.css( "borderBottomWidth" ),
3673
                element.css( "borderLeftWidth" )
3674
            ],
3675
            paddings = [
3676
                element.css( "paddingTop" ),
3677
                element.css( "paddingRight" ),
3678
                element.css( "paddingBottom" ),
3679
                element.css( "paddingLeft" )
3680
            ];
3681
3682
        for ( ; i < 4; i++ ) {
3683
            widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 );
3684
            widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 );
3685
        }
3686
3687
        return {
3688
            height: widths[ 0 ] + widths[ 2 ],
3689
            width: widths[ 1 ] + widths[ 3 ]
3690
        };
3691
    },
3692
3693
    _proportionallyResize: function() {
3694
3695
        if (!this._proportionallyResizeElements.length) {
3696
            return;
3697
        }
3698
3699
        var prel,
3700
            i = 0,
3701
            element = this.helper || this.element;
3702
3703
        for ( ; i < this._proportionallyResizeElements.length; i++) {
3704
3705
            prel = this._proportionallyResizeElements[i];
3706
3707
            // TODO: Seems like a bug to cache this.outerDimensions
3708
            // considering that we are in a loop.
3709
            if (!this.outerDimensions) {
3710
                this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
3711
            }
3712
3713
            prel.css({
3714
                height: (element.height() - this.outerDimensions.height) || 0,
3715
                width: (element.width() - this.outerDimensions.width) || 0
3716
            });
3717
3718
        }
3719
3720
    },
3721
3722
    _renderProxy: function() {
3723
3724
        var el = this.element, o = this.options;
3725
        this.elementOffset = el.offset();
3726
3727
        if (this._helper) {
3728
3729
            this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
3730
3731
            this.helper.addClass(this._helper).css({
3732
                width: this.element.outerWidth() - 1,
3733
                height: this.element.outerHeight() - 1,
3734
                position: "absolute",
3735
                left: this.elementOffset.left + "px",
3736
                top: this.elementOffset.top + "px",
3737
                zIndex: ++o.zIndex //TODO: Don't modify option
3738
            });
3739
3740
            this.helper
3741
                .appendTo("body")
3742
                .disableSelection();
3743
3744
        } else {
3745
            this.helper = this.element;
3746
        }
3747
3748
    },
3749
3750
    _change: {
3751
        e: function(event, dx) {
3752
            return { width: this.originalSize.width + dx };
3753
        },
3754
        w: function(event, dx) {
3755
            var cs = this.originalSize, sp = this.originalPosition;
3756
            return { left: sp.left + dx, width: cs.width - dx };
3757
        },
3758
        n: function(event, dx, dy) {
3759
            var cs = this.originalSize, sp = this.originalPosition;
3760
            return { top: sp.top + dy, height: cs.height - dy };
3761
        },
3762
        s: function(event, dx, dy) {
3763
            return { height: this.originalSize.height + dy };
3764
        },
3765
        se: function(event, dx, dy) {
3766
            return $.extend(this._change.s.apply(this, arguments),
3767
                this._change.e.apply(this, [ event, dx, dy ]));
3768
        },
3769
        sw: function(event, dx, dy) {
3770
            return $.extend(this._change.s.apply(this, arguments),
3771
                this._change.w.apply(this, [ event, dx, dy ]));
3772
        },
3773
        ne: function(event, dx, dy) {
3774
            return $.extend(this._change.n.apply(this, arguments),
3775
                this._change.e.apply(this, [ event, dx, dy ]));
3776
        },
3777
        nw: function(event, dx, dy) {
3778
            return $.extend(this._change.n.apply(this, arguments),
3779
                this._change.w.apply(this, [ event, dx, dy ]));
3780
        }
3781
    },
3782
3783
    _propagate: function(n, event) {
3784
        $.ui.plugin.call(this, n, [ event, this.ui() ]);
3785
        (n !== "resize" && this._trigger(n, event, this.ui()));
3786
    },
3787
3788
    plugins: {},
3789
3790
    ui: function() {
3791
        return {
3792
            originalElement: this.originalElement,
3793
            element: this.element,
3794
            helper: this.helper,
3795
            position: this.position,
3796
            size: this.size,
3797
            originalSize: this.originalSize,
3798
            originalPosition: this.originalPosition
3799
        };
3800
    }
3801
3802
});
3803
3804
/*
3805
 * Resizable Extensions
3806
 */
3807
3808
$.ui.plugin.add("resizable", "animate", {
3809
3810
    stop: function( event ) {
3811
        var that = $(this).resizable( "instance" ),
3812
            o = that.options,
3813
            pr = that._proportionallyResizeElements,
3814
            ista = pr.length && (/textarea/i).test(pr[0].nodeName),
3815
            soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height,
3816
            soffsetw = ista ? 0 : that.sizeDiff.width,
3817
            style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
3818
            left = (parseInt(that.element.css("left"), 10) +
3819
                (that.position.left - that.originalPosition.left)) || null,
3820
            top = (parseInt(that.element.css("top"), 10) +
3821
                (that.position.top - that.originalPosition.top)) || null;
3822
3823
        that.element.animate(
3824
            $.extend(style, top && left ? { top: top, left: left } : {}), {
3825
                duration: o.animateDuration,
3826
                easing: o.animateEasing,
3827
                step: function() {
3828
3829
                    var data = {
3830
                        width: parseInt(that.element.css("width"), 10),
3831
                        height: parseInt(that.element.css("height"), 10),
3832
                        top: parseInt(that.element.css("top"), 10),
3833
                        left: parseInt(that.element.css("left"), 10)
3834
                    };
3835
3836
                    if (pr && pr.length) {
3837
                        $(pr[0]).css({ width: data.width, height: data.height });
3838
                    }
3839
3840
                    // propagating resize, and updating values for each animation step
3841
                    that._updateCache(data);
3842
                    that._propagate("resize", event);
3843
3844
                }
3845
            }
3846
        );
3847
    }
3848
3849
});
3850
3851
$.ui.plugin.add( "resizable", "containment", {
3852
3853
    start: function() {
3854
        var element, p, co, ch, cw, width, height,
3855
            that = $( this ).resizable( "instance" ),
3856
            o = that.options,
3857
            el = that.element,
3858
            oc = o.containment,
3859
            ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
3860
3861
        if ( !ce ) {
3862
            return;
3863
        }
3864
3865
        that.containerElement = $( ce );
3866
3867
        if ( /document/.test( oc ) || oc === document ) {
3868
            that.containerOffset = {
3869
                left: 0,
3870
                top: 0
3871
            };
3872
            that.containerPosition = {
3873
                left: 0,
3874
                top: 0
3875
            };
3876
3877
            that.parentData = {
3878
                element: $( document ),
3879
                left: 0,
3880
                top: 0,
3881
                width: $( document ).width(),
3882
                height: $( document ).height() || document.body.parentNode.scrollHeight
3883
            };
3884
        } else {
3885
            element = $( ce );
3886
            p = [];
3887
            $([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) {
3888
                p[ i ] = that._num( element.css( "padding" + name ) );
3889
            });
3890
3891
            that.containerOffset = element.offset();
3892
            that.containerPosition = element.position();
3893
            that.containerSize = {
3894
                height: ( element.innerHeight() - p[ 3 ] ),
3895
                width: ( element.innerWidth() - p[ 1 ] )
3896
            };
3897
3898
            co = that.containerOffset;
3899
            ch = that.containerSize.height;
3900
            cw = that.containerSize.width;
3901
            width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
3902
            height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
3903
3904
            that.parentData = {
3905
                element: ce,
3906
                left: co.left,
3907
                top: co.top,
3908
                width: width,
3909
                height: height
3910
            };
3911
        }
3912
    },
3913
3914
    resize: function( event ) {
3915
        var woset, hoset, isParent, isOffsetRelative,
3916
            that = $( this ).resizable( "instance" ),
3917
            o = that.options,
3918
            co = that.containerOffset,
3919
            cp = that.position,
3920
            pRatio = that._aspectRatio || event.shiftKey,
3921
            cop = {
3922
                top: 0,
3923
                left: 0
3924
            },
3925
            ce = that.containerElement,
3926
            continueResize = true;
3927
3928
        if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
3929
            cop = co;
3930
        }
3931
3932
        if ( cp.left < ( that._helper ? co.left : 0 ) ) {
3933
            that.size.width = that.size.width +
3934
                ( that._helper ?
3935
                    ( that.position.left - co.left ) :
3936
                    ( that.position.left - cop.left ) );
3937
3938
            if ( pRatio ) {
3939
                that.size.height = that.size.width / that.aspectRatio;
3940
                continueResize = false;
3941
            }
3942
            that.position.left = o.helper ? co.left : 0;
3943
        }
3944
3945
        if ( cp.top < ( that._helper ? co.top : 0 ) ) {
3946
            that.size.height = that.size.height +
3947
                ( that._helper ?
3948
                    ( that.position.top - co.top ) :
3949
                    that.position.top );
3950
3951
            if ( pRatio ) {
3952
                that.size.width = that.size.height * that.aspectRatio;
3953
                continueResize = false;
3954
            }
3955
            that.position.top = that._helper ? co.top : 0;
3956
        }
3957
3958
        isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
3959
        isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
3960
3961
        if ( isParent && isOffsetRelative ) {
3962
            that.offset.left = that.parentData.left + that.position.left;
3963
            that.offset.top = that.parentData.top + that.position.top;
3964
        } else {
3965
            that.offset.left = that.element.offset().left;
3966
            that.offset.top = that.element.offset().top;
3967
        }
3968
3969
        woset = Math.abs( that.sizeDiff.width +
3970
            (that._helper ?
3971
                that.offset.left - cop.left :
3972
                (that.offset.left - co.left)) );
3973
3974
        hoset = Math.abs( that.sizeDiff.height +
3975
            (that._helper ?
3976
                that.offset.top - cop.top :
3977
                (that.offset.top - co.top)) );
3978
3979
        if ( woset + that.size.width >= that.parentData.width ) {
3980
            that.size.width = that.parentData.width - woset;
3981
            if ( pRatio ) {
3982
                that.size.height = that.size.width / that.aspectRatio;
3983
                continueResize = false;
3984
            }
3985
        }
3986
3987
        if ( hoset + that.size.height >= that.parentData.height ) {
3988
            that.size.height = that.parentData.height - hoset;
3989
            if ( pRatio ) {
3990
                that.size.width = that.size.height * that.aspectRatio;
3991
                continueResize = false;
3992
            }
3993
        }
3994
3995
        if ( !continueResize ) {
3996
            that.position.left = that.prevPosition.left;
3997
            that.position.top = that.prevPosition.top;
3998
            that.size.width = that.prevSize.width;
3999
            that.size.height = that.prevSize.height;
4000
        }
4001
    },
4002
4003
    stop: function() {
4004
        var that = $( this ).resizable( "instance" ),
4005
            o = that.options,
4006
            co = that.containerOffset,
4007
            cop = that.containerPosition,
4008
            ce = that.containerElement,
4009
            helper = $( that.helper ),
4010
            ho = helper.offset(),
4011
            w = helper.outerWidth() - that.sizeDiff.width,
4012
            h = helper.outerHeight() - that.sizeDiff.height;
4013
4014
        if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
4015
            $( this ).css({
4016
                left: ho.left - cop.left - co.left,
4017
                width: w,
4018
                height: h
4019
            });
4020
        }
4021
4022
        if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
4023
            $( this ).css({
4024
                left: ho.left - cop.left - co.left,
4025
                width: w,
4026
                height: h
4027
            });
4028
        }
4029
    }
4030
});
4031
4032
$.ui.plugin.add("resizable", "alsoResize", {
4033
4034
    start: function() {
4035
        var that = $(this).resizable( "instance" ),
4036
            o = that.options;
4037
4038
        $(o.alsoResize).each(function() {
4039
            var el = $(this);
4040
            el.data("ui-resizable-alsoresize", {
4041
                width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
4042
                left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
4043
            });
4044
        });
4045
    },
4046
4047
    resize: function(event, ui) {
4048
        var that = $(this).resizable( "instance" ),
4049
            o = that.options,
4050
            os = that.originalSize,
4051
            op = that.originalPosition,
4052
            delta = {
4053
                height: (that.size.height - os.height) || 0,
4054
                width: (that.size.width - os.width) || 0,
4055
                top: (that.position.top - op.top) || 0,
4056
                left: (that.position.left - op.left) || 0
4057
            };
4058
4059
            $(o.alsoResize).each(function() {
4060
                var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
4061
                    css = el.parents(ui.originalElement[0]).length ?
4062
                            [ "width", "height" ] :
4063
                            [ "width", "height", "top", "left" ];
4064
4065
                $.each(css, function(i, prop) {
4066
                    var sum = (start[prop] || 0) + (delta[prop] || 0);
4067
                    if (sum && sum >= 0) {
4068
                        style[prop] = sum || null;
4069
                    }
4070
                });
4071
4072
                el.css(style);
4073
            });
4074
    },
4075
4076
    stop: function() {
4077
        $(this).removeData("resizable-alsoresize");
4078
    }
4079
});
4080
4081
$.ui.plugin.add("resizable", "ghost", {
4082
4083
    start: function() {
4084
4085
        var that = $(this).resizable( "instance" ), o = that.options, cs = that.size;
4086
4087
        that.ghost = that.originalElement.clone();
4088
        that.ghost
4089
            .css({
4090
                opacity: 0.25,
4091
                display: "block",
4092
                position: "relative",
4093
                height: cs.height,
4094
                width: cs.width,
4095
                margin: 0,
4096
                left: 0,
4097
                top: 0
4098
            })
4099
            .addClass("ui-resizable-ghost")
4100
            .addClass(typeof o.ghost === "string" ? o.ghost : "");
4101
4102
        that.ghost.appendTo(that.helper);
4103
4104
    },
4105
4106
    resize: function() {
4107
        var that = $(this).resizable( "instance" );
4108
        if (that.ghost) {
4109
            that.ghost.css({
4110
                position: "relative",
4111
                height: that.size.height,
4112
                width: that.size.width
4113
            });
4114
        }
4115
    },
4116
4117
    stop: function() {
4118
        var that = $(this).resizable( "instance" );
4119
        if (that.ghost && that.helper) {
4120
            that.helper.get(0).removeChild(that.ghost.get(0));
4121
        }
4122
    }
4123
4124
});
4125
4126
$.ui.plugin.add("resizable", "grid", {
4127
4128
    resize: function() {
4129
        var outerDimensions,
4130
            that = $(this).resizable( "instance" ),
4131
            o = that.options,
4132
            cs = that.size,
4133
            os = that.originalSize,
4134
            op = that.originalPosition,
4135
            a = that.axis,
4136
            grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
4137
            gridX = (grid[0] || 1),
4138
            gridY = (grid[1] || 1),
4139
            ox = Math.round((cs.width - os.width) / gridX) * gridX,
4140
            oy = Math.round((cs.height - os.height) / gridY) * gridY,
4141
            newWidth = os.width + ox,
4142
            newHeight = os.height + oy,
4143
            isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
4144
            isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
4145
            isMinWidth = o.minWidth && (o.minWidth > newWidth),
4146
            isMinHeight = o.minHeight && (o.minHeight > newHeight);
4147
4148
        o.grid = grid;
4149
4150
        if (isMinWidth) {
4151
            newWidth += gridX;
4152
        }
4153
        if (isMinHeight) {
4154
            newHeight += gridY;
4155
        }
4156
        if (isMaxWidth) {
4157
            newWidth -= gridX;
4158
        }
4159
        if (isMaxHeight) {
4160
            newHeight -= gridY;
4161
        }
4162
4163
        if (/^(se|s|e)$/.test(a)) {
4164
            that.size.width = newWidth;
4165
            that.size.height = newHeight;
4166
        } else if (/^(ne)$/.test(a)) {
4167
            that.size.width = newWidth;
4168
            that.size.height = newHeight;
4169
            that.position.top = op.top - oy;
4170
        } else if (/^(sw)$/.test(a)) {
4171
            that.size.width = newWidth;
4172
            that.size.height = newHeight;
4173
            that.position.left = op.left - ox;
4174
        } else {
4175
            if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) {
4176
                outerDimensions = that._getPaddingPlusBorderDimensions( this );
4177
            }
4178
4179
            if ( newHeight - gridY > 0 ) {
4180
                that.size.height = newHeight;
4181
                that.position.top = op.top - oy;
4182
            } else {
4183
                newHeight = gridY - outerDimensions.height;
4184
                that.size.height = newHeight;
4185
                that.position.top = op.top + os.height - newHeight;
4186
            }
4187
            if ( newWidth - gridX > 0 ) {
4188
                that.size.width = newWidth;
4189
                that.position.left = op.left - ox;
4190
            } else {
4191
                newWidth = gridX - outerDimensions.width;
4192
                that.size.width = newWidth;
4193
                that.position.left = op.left + os.width - newWidth;
4194
            }
4195
        }
4196
    }
4197
4198
});
4199
4200
var resizable = $.ui.resizable;
4201
4202
4203
/*!
4204
 * jQuery UI Selectable 1.11.4
4205
 * http://jqueryui.com
4206
 *
4207
 * Copyright jQuery Foundation and other contributors
4208
 * Released under the MIT license.
4209
 * http://jquery.org/license
4210
 *
4211
 * http://api.jqueryui.com/selectable/
4212
 */
4213
4214
4215
var selectable = $.widget("ui.selectable", $.ui.mouse, {
4216
    version: "1.11.4",
4217
    options: {
4218
        appendTo: "body",
4219
        autoRefresh: true,
4220
        distance: 0,
4221
        filter: "*",
4222
        tolerance: "touch",
4223
4224
        // callbacks
4225
        selected: null,
4226
        selecting: null,
4227
        start: null,
4228
        stop: null,
4229
        unselected: null,
4230
        unselecting: null
4231
    },
4232
    _create: function() {
4233
        var selectees,
4234
            that = this;
4235
4236
        this.element.addClass("ui-selectable");
4237
4238
        this.dragged = false;
4239
4240
        // cache selectee children based on filter
4241
        this.refresh = function() {
4242
            selectees = $(that.options.filter, that.element[0]);
4243
            selectees.addClass("ui-selectee");
4244
            selectees.each(function() {
4245
                var $this = $(this),
4246
                    pos = $this.offset();
4247
                $.data(this, "selectable-item", {
4248
                    element: this,
4249
                    $element: $this,
4250
                    left: pos.left,
4251
                    top: pos.top,
4252
                    right: pos.left + $this.outerWidth(),
4253
                    bottom: pos.top + $this.outerHeight(),
4254
                    startselected: false,
4255
                    selected: $this.hasClass("ui-selected"),
4256
                    selecting: $this.hasClass("ui-selecting"),
4257
                    unselecting: $this.hasClass("ui-unselecting")
4258
                });
4259
            });
4260
        };
4261
        this.refresh();
4262
4263
        this.selectees = selectees.addClass("ui-selectee");
4264
4265
        this._mouseInit();
4266
4267
        this.helper = $("<div class='ui-selectable-helper'></div>");
4268
    },
4269
4270
    _destroy: function() {
4271
        this.selectees
4272
            .removeClass("ui-selectee")
4273
            .removeData("selectable-item");
4274
        this.element
4275
            .removeClass("ui-selectable ui-selectable-disabled");
4276
        this._mouseDestroy();
4277
    },
4278
4279
    _mouseStart: function(event) {
4280
        var that = this,
4281
            options = this.options;
4282
4283
        this.opos = [ event.pageX, event.pageY ];
4284
4285
        if (this.options.disabled) {
4286
            return;
4287
        }
4288
4289
        this.selectees = $(options.filter, this.element[0]);
4290
4291
        this._trigger("start", event);
4292
4293
        $(options.appendTo).append(this.helper);
4294
        // position helper (lasso)
4295
        this.helper.css({
4296
            "left": event.pageX,
4297
            "top": event.pageY,
4298
            "width": 0,
4299
            "height": 0
4300
        });
4301
4302
        if (options.autoRefresh) {
4303
            this.refresh();
4304
        }
4305
4306
        this.selectees.filter(".ui-selected").each(function() {
4307
            var selectee = $.data(this, "selectable-item");
4308
            selectee.startselected = true;
4309
            if (!event.metaKey && !event.ctrlKey) {
4310
                selectee.$element.removeClass("ui-selected");
4311
                selectee.selected = false;
4312
                selectee.$element.addClass("ui-unselecting");
4313
                selectee.unselecting = true;
4314
                // selectable UNSELECTING callback
4315
                that._trigger("unselecting", event, {
4316
                    unselecting: selectee.element
4317
                });
4318
            }
4319
        });
4320
4321
        $(event.target).parents().addBack().each(function() {
4322
            var doSelect,
4323
                selectee = $.data(this, "selectable-item");
4324
            if (selectee) {
4325
                doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
4326
                selectee.$element
4327
                    .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
4328
                    .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
4329
                selectee.unselecting = !doSelect;
4330
                selectee.selecting = doSelect;
4331
                selectee.selected = doSelect;
4332
                // selectable (UN)SELECTING callback
4333
                if (doSelect) {
4334
                    that._trigger("selecting", event, {
4335
                        selecting: selectee.element
4336
                    });
4337
                } else {
4338
                    that._trigger("unselecting", event, {
4339
                        unselecting: selectee.element
4340
                    });
4341
                }
4342
                return false;
4343
            }
4344
        });
4345
4346
    },
4347
4348
    _mouseDrag: function(event) {
4349
4350
        this.dragged = true;
4351
4352
        if (this.options.disabled) {
4353
            return;
4354
        }
4355
4356
        var tmp,
4357
            that = this,
4358
            options = this.options,
4359
            x1 = this.opos[0],
4360
            y1 = this.opos[1],
4361
            x2 = event.pageX,
4362
            y2 = event.pageY;
4363
4364
        if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
4365
        if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
4366
        this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 });
4367
4368
        this.selectees.each(function() {
4369
            var selectee = $.data(this, "selectable-item"),
4370
                hit = false;
4371
4372
            //prevent helper from being selected if appendTo: selectable
4373
            if (!selectee || selectee.element === that.element[0]) {
4374
                return;
4375
            }
4376
4377
            if (options.tolerance === "touch") {
4378
                hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
4379
            } else if (options.tolerance === "fit") {
4380
                hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
4381
            }
4382
4383
            if (hit) {
4384
                // SELECT
4385
                if (selectee.selected) {
4386
                    selectee.$element.removeClass("ui-selected");
4387
                    selectee.selected = false;
4388
                }
4389
                if (selectee.unselecting) {
4390
                    selectee.$element.removeClass("ui-unselecting");
4391
                    selectee.unselecting = false;
4392
                }
4393
                if (!selectee.selecting) {
4394
                    selectee.$element.addClass("ui-selecting");
4395
                    selectee.selecting = true;
4396
                    // selectable SELECTING callback
4397
                    that._trigger("selecting", event, {
4398
                        selecting: selectee.element
4399
                    });
4400
                }
4401
            } else {
4402
                // UNSELECT
4403
                if (selectee.selecting) {
4404
                    if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
4405
                        selectee.$element.removeClass("ui-selecting");
4406
                        selectee.selecting = false;
4407
                        selectee.$element.addClass("ui-selected");
4408
                        selectee.selected = true;
4409
                    } else {
4410
                        selectee.$element.removeClass("ui-selecting");
4411
                        selectee.selecting = false;
4412
                        if (selectee.startselected) {
4413
                            selectee.$element.addClass("ui-unselecting");
4414
                            selectee.unselecting = true;
4415
                        }
4416
                        // selectable UNSELECTING callback
4417
                        that._trigger("unselecting", event, {
4418
                            unselecting: selectee.element
4419
                        });
4420
                    }
4421
                }
4422
                if (selectee.selected) {
4423
                    if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
4424
                        selectee.$element.removeClass("ui-selected");
4425
                        selectee.selected = false;
4426
4427
                        selectee.$element.addClass("ui-unselecting");
4428
                        selectee.unselecting = true;
4429
                        // selectable UNSELECTING callback
4430
                        that._trigger("unselecting", event, {
4431
                            unselecting: selectee.element
4432
                        });
4433
                    }
4434
                }
4435
            }
4436
        });
4437
4438
        return false;
4439
    },
4440
4441
    _mouseStop: function(event) {
4442
        var that = this;
4443
4444
        this.dragged = false;
4445
4446
        $(".ui-unselecting", this.element[0]).each(function() {
4447
            var selectee = $.data(this, "selectable-item");
4448
            selectee.$element.removeClass("ui-unselecting");
4449
            selectee.unselecting = false;
4450
            selectee.startselected = false;
4451
            that._trigger("unselected", event, {
4452
                unselected: selectee.element
4453
            });
4454
        });
4455
        $(".ui-selecting", this.element[0]).each(function() {
4456
            var selectee = $.data(this, "selectable-item");
4457
            selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
4458
            selectee.selecting = false;
4459
            selectee.selected = true;
4460
            selectee.startselected = true;
4461
            that._trigger("selected", event, {
4462
                selected: selectee.element
4463
            });
4464
        });
4465
        this._trigger("stop", event);
4466
4467
        this.helper.remove();
4468
4469
        return false;
4470
    }
4471
4472
});
4473
4474
4475
/*!
4476
 * jQuery UI Sortable 1.11.4
4477
 * http://jqueryui.com
4478
 *
4479
 * Copyright jQuery Foundation and other contributors
4480
 * Released under the MIT license.
4481
 * http://jquery.org/license
4482
 *
4483
 * http://api.jqueryui.com/sortable/
4484
 */
4485
4486
4487
var sortable = $.widget("ui.sortable", $.ui.mouse, {
4488
    version: "1.11.4",
4489
    widgetEventPrefix: "sort",
4490
    ready: false,
4491
    options: {
4492
        appendTo: "parent",
4493
        axis: false,
4494
        connectWith: false,
4495
        containment: false,
4496
        cursor: "auto",
4497
        cursorAt: false,
4498
        dropOnEmpty: true,
4499
        forcePlaceholderSize: false,
4500
        forceHelperSize: false,
4501
        grid: false,
4502
        handle: false,
4503
        helper: "original",
4504
        items: "> *",
4505
        opacity: false,
4506
        placeholder: false,
4507
        revert: false,
4508
        scroll: true,
4509
        scrollSensitivity: 20,
4510
        scrollSpeed: 20,
4511
        scope: "default",
4512
        tolerance: "intersect",
4513
        zIndex: 1000,
4514
4515
        // callbacks
4516
        activate: null,
4517
        beforeStop: null,
4518
        change: null,
4519
        deactivate: null,
4520
        out: null,
4521
        over: null,
4522
        receive: null,
4523
        remove: null,
4524
        sort: null,
4525
        start: null,
4526
        stop: null,
4527
        update: null
4528
    },
4529
4530
    _isOverAxis: function( x, reference, size ) {
4531
        return ( x >= reference ) && ( x < ( reference + size ) );
4532
    },
4533
4534
    _isFloating: function( item ) {
4535
        return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
4536
    },
4537
4538
    _create: function() {
4539
        this.containerCache = {};
4540
        this.element.addClass("ui-sortable");
4541
4542
        //Get the items
4543
        this.refresh();
4544
4545
        //Let's determine the parent's offset
4546
        this.offset = this.element.offset();
4547
4548
        //Initialize mouse events for interaction
4549
        this._mouseInit();
4550
4551
        this._setHandleClassName();
4552
4553
        //We're ready to go
4554
        this.ready = true;
4555
4556
    },
4557
4558
    _setOption: function( key, value ) {
4559
        this._super( key, value );
4560
4561
        if ( key === "handle" ) {
4562
            this._setHandleClassName();
4563
        }
4564
    },
4565
4566
    _setHandleClassName: function() {
4567
        this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" );
4568
        $.each( this.items, function() {
4569
            ( this.instance.options.handle ?
4570
                this.item.find( this.instance.options.handle ) : this.item )
4571
                .addClass( "ui-sortable-handle" );
4572
        });
4573
    },
4574
4575
    _destroy: function() {
4576
        this.element
4577
            .removeClass( "ui-sortable ui-sortable-disabled" )
4578
            .find( ".ui-sortable-handle" )
4579
                .removeClass( "ui-sortable-handle" );
4580
        this._mouseDestroy();
4581
4582
        for ( var i = this.items.length - 1; i >= 0; i-- ) {
4583
            this.items[i].item.removeData(this.widgetName + "-item");
4584
        }
4585
4586
        return this;
4587
    },
4588
4589
    _mouseCapture: function(event, overrideHandle) {
4590
        var currentItem = null,
4591
            validHandle = false,
4592
            that = this;
4593
4594
        if (this.reverting) {
4595
            return false;
4596
        }
4597
4598
        if(this.options.disabled || this.options.type === "static") {
4599
            return false;
4600
        }
4601
4602
        //We have to refresh the items data once first
4603
        this._refreshItems(event);
4604
4605
        //Find out if the clicked node (or one of its parents) is a actual item in this.items
4606
        $(event.target).parents().each(function() {
4607
            if($.data(this, that.widgetName + "-item") === that) {
4608
                currentItem = $(this);
4609
                return false;
4610
            }
4611
        });
4612
        if($.data(event.target, that.widgetName + "-item") === that) {
4613
            currentItem = $(event.target);
4614
        }
4615
4616
        if(!currentItem) {
4617
            return false;
4618
        }
4619
        if(this.options.handle && !overrideHandle) {
4620
            $(this.options.handle, currentItem).find("*").addBack().each(function() {
4621
                if(this === event.target) {
4622
                    validHandle = true;
4623
                }
4624
            });
4625
            if(!validHandle) {
4626
                return false;
4627
            }
4628
        }
4629
4630
        this.currentItem = currentItem;
4631
        this._removeCurrentsFromItems();
4632
        return true;
4633
4634
    },
4635
4636
    _mouseStart: function(event, overrideHandle, noActivation) {
4637
4638
        var i, body,
4639
            o = this.options;
4640
4641
        this.currentContainer = this;
4642
4643
        //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
4644
        this.refreshPositions();
4645
4646
        //Create and append the visible helper
4647
        this.helper = this._createHelper(event);
4648
4649
        //Cache the helper size
4650
        this._cacheHelperProportions();
4651
4652
        /*
4653
         * - Position generation -
4654
         * This block generates everything position related - it's the core of draggables.
4655
         */
4656
4657
        //Cache the margins of the original element
4658
        this._cacheMargins();
4659
4660
        //Get the next scrolling parent
4661
        this.scrollParent = this.helper.scrollParent();
4662
4663
        //The element's absolute position on the page minus margins
4664
        this.offset = this.currentItem.offset();
4665
        this.offset = {
4666
            top: this.offset.top - this.margins.top,
4667
            left: this.offset.left - this.margins.left
4668
        };
4669
4670
        $.extend(this.offset, {
4671
            click: { //Where the click happened, relative to the element
4672
                left: event.pageX - this.offset.left,
4673
                top: event.pageY - this.offset.top
4674
            },
4675
            parent: this._getParentOffset(),
4676
            relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
4677
        });
4678
4679
        // Only after we got the offset, we can change the helper's position to absolute
4680
        // TODO: Still need to figure out a way to make relative sorting possible
4681
        this.helper.css("position", "absolute");
4682
        this.cssPosition = this.helper.css("position");
4683
4684
        //Generate the original position
4685
        this.originalPosition = this._generatePosition(event);
4686
        this.originalPageX = event.pageX;
4687
        this.originalPageY = event.pageY;
4688
4689
        //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
4690
        (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
4691
4692
        //Cache the former DOM position
4693
        this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
4694
4695
        //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
4696
        if(this.helper[0] !== this.currentItem[0]) {
4697
            this.currentItem.hide();
4698
        }
4699
4700
        //Create the placeholder
4701
        this._createPlaceholder();
4702
4703
        //Set a containment if given in the options
4704
        if(o.containment) {
4705
            this._setContainment();
4706
        }
4707
4708
        if( o.cursor && o.cursor !== "auto" ) { // cursor option
4709
            body = this.document.find( "body" );
4710
4711
            // support: IE
4712
            this.storedCursor = body.css( "cursor" );
4713
            body.css( "cursor", o.cursor );
4714
4715
            this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
4716
        }
4717
4718
        if(o.opacity) { // opacity option
4719
            if (this.helper.css("opacity")) {
4720
                this._storedOpacity = this.helper.css("opacity");
4721
            }
4722
            this.helper.css("opacity", o.opacity);
4723
        }
4724
4725
        if(o.zIndex) { // zIndex option
4726
            if (this.helper.css("zIndex")) {
4727
                this._storedZIndex = this.helper.css("zIndex");
4728
            }
4729
            this.helper.css("zIndex", o.zIndex);
4730
        }
4731
4732
        //Prepare scrolling
4733
        if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
4734
            this.overflowOffset = this.scrollParent.offset();
4735
        }
4736
4737
        //Call callbacks
4738
        this._trigger("start", event, this._uiHash());
4739
4740
        //Recache the helper size
4741
        if(!this._preserveHelperProportions) {
4742
            this._cacheHelperProportions();
4743
        }
4744
4745
4746
        //Post "activate" events to possible containers
4747
        if( !noActivation ) {
4748
            for ( i = this.containers.length - 1; i >= 0; i-- ) {
4749
                this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
4750
            }
4751
        }
4752
4753
        //Prepare possible droppables
4754
        if($.ui.ddmanager) {
4755
            $.ui.ddmanager.current = this;
4756
        }
4757
4758
        if ($.ui.ddmanager && !o.dropBehaviour) {
4759
            $.ui.ddmanager.prepareOffsets(this, event);
4760
        }
4761
4762
        this.dragging = true;
4763
4764
        this.helper.addClass("ui-sortable-helper");
4765
        this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
4766
        return true;
4767
4768
    },
4769
4770
    _mouseDrag: function(event) {
4771
        var i, item, itemElement, intersection,
4772
            o = this.options,
4773
            scrolled = false;
4774
4775
        //Compute the helpers position
4776
        this.position = this._generatePosition(event);
4777
        this.positionAbs = this._convertPositionTo("absolute");
4778
4779
        if (!this.lastPositionAbs) {
4780
            this.lastPositionAbs = this.positionAbs;
4781
        }
4782
4783
        //Do scrolling
4784
        if(this.options.scroll) {
4785
            if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
4786
4787
                if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
4788
                    this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
4789
                } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
4790
                    this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
4791
                }
4792
4793
                if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
4794
                    this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
4795
                } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
4796
                    this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
4797
                }
4798
4799
            } else {
4800
4801
                if(event.pageY - this.document.scrollTop() < o.scrollSensitivity) {
4802
                    scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed);
4803
                } else if(this.window.height() - (event.pageY - this.document.scrollTop()) < o.scrollSensitivity) {
4804
                    scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed);
4805
                }
4806
4807
                if(event.pageX - this.document.scrollLeft() < o.scrollSensitivity) {
4808
                    scrolled = this.document.scrollLeft(this.document.scrollLeft() - o.scrollSpeed);
4809
                } else if(this.window.width() - (event.pageX - this.document.scrollLeft()) < o.scrollSensitivity) {
4810
                    scrolled = this.document.scrollLeft(this.document.scrollLeft() + o.scrollSpeed);
4811
                }
4812
4813
            }
4814
4815
            if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
4816
                $.ui.ddmanager.prepareOffsets(this, event);
4817
            }
4818
        }
4819
4820
        //Regenerate the absolute position used for position checks
4821
        this.positionAbs = this._convertPositionTo("absolute");
4822
4823
        //Set the helper position
4824
        if(!this.options.axis || this.options.axis !== "y") {
4825
            this.helper[0].style.left = this.position.left+"px";
4826
        }
4827
        if(!this.options.axis || this.options.axis !== "x") {
4828
            this.helper[0].style.top = this.position.top+"px";
4829
        }
4830
4831
        //Rearrange
4832
        for (i = this.items.length - 1; i >= 0; i--) {
4833
4834
            //Cache variables and intersection, continue if no intersection
4835
            item = this.items[i];
4836
            itemElement = item.item[0];
4837
            intersection = this._intersectsWithPointer(item);
4838
            if (!intersection) {
4839
                continue;
4840
            }
4841
4842
            // Only put the placeholder inside the current Container, skip all
4843
            // items from other containers. This works because when moving
4844
            // an item from one container to another the
4845
            // currentContainer is switched before the placeholder is moved.
4846
            //
4847
            // Without this, moving items in "sub-sortables" can cause
4848
            // the placeholder to jitter between the outer and inner container.
4849
            if (item.instance !== this.currentContainer) {
4850
                continue;
4851
            }
4852
4853
            // cannot intersect with itself
4854
            // no useless actions that have been done before
4855
            // no action if the item moved is the parent of the item checked
4856
            if (itemElement !== this.currentItem[0] &&
4857
                this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
4858
                !$.contains(this.placeholder[0], itemElement) &&
4859
                (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
4860
            ) {
4861
4862
                this.direction = intersection === 1 ? "down" : "up";
4863
4864
                if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
4865
                    this._rearrange(event, item);
4866
                } else {
4867
                    break;
4868
                }
4869
4870
                this._trigger("change", event, this._uiHash());
4871
                break;
4872
            }
4873
        }
4874
4875
        //Post events to containers
4876
        this._contactContainers(event);
4877
4878
        //Interconnect with droppables
4879
        if($.ui.ddmanager) {
4880
            $.ui.ddmanager.drag(this, event);
4881
        }
4882
4883
        //Call callbacks
4884
        this._trigger("sort", event, this._uiHash());
4885
4886
        this.lastPositionAbs = this.positionAbs;
4887
        return false;
4888
4889
    },
4890
4891
    _mouseStop: function(event, noPropagation) {
4892
4893
        if(!event) {
4894
            return;
4895
        }
4896
4897
        //If we are using droppables, inform the manager about the drop
4898
        if ($.ui.ddmanager && !this.options.dropBehaviour) {
4899
            $.ui.ddmanager.drop(this, event);
4900
        }
4901
4902
        if(this.options.revert) {
4903
            var that = this,
4904
                cur = this.placeholder.offset(),
4905
                axis = this.options.axis,
4906
                animation = {};
4907
4908
            if ( !axis || axis === "x" ) {
4909
                animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollLeft);
4910
            }
4911
            if ( !axis || axis === "y" ) {
4912
                animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollTop);
4913
            }
4914
            this.reverting = true;
4915
            $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
4916
                that._clear(event);
4917
            });
4918
        } else {
4919
            this._clear(event, noPropagation);
4920
        }
4921
4922
        return false;
4923
4924
    },
4925
4926
    cancel: function() {
4927
4928
        if(this.dragging) {
4929
4930
            this._mouseUp({ target: null });
4931
4932
            if(this.options.helper === "original") {
4933
                this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4934
            } else {
4935
                this.currentItem.show();
4936
            }
4937
4938
            //Post deactivating events to containers
4939
            for (var i = this.containers.length - 1; i >= 0; i--){
4940
                this.containers[i]._trigger("deactivate", null, this._uiHash(this));
4941
                if(this.containers[i].containerCache.over) {
4942
                    this.containers[i]._trigger("out", null, this._uiHash(this));
4943
                    this.containers[i].containerCache.over = 0;
4944
                }
4945
            }
4946
4947
        }
4948
4949
        if (this.placeholder) {
4950
            //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4951
            if(this.placeholder[0].parentNode) {
4952
                this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4953
            }
4954
            if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
4955
                this.helper.remove();
4956
            }
4957
4958
            $.extend(this, {
4959
                helper: null,
4960
                dragging: false,
4961
                reverting: false,
4962
                _noFinalSort: null
4963
            });
4964
4965
            if(this.domPosition.prev) {
4966
                $(this.domPosition.prev).after(this.currentItem);
4967
            } else {
4968
                $(this.domPosition.parent).prepend(this.currentItem);
4969
            }
4970
        }
4971
4972
        return this;
4973
4974
    },
4975
4976
    serialize: function(o) {
4977
4978
        var items = this._getItemsAsjQuery(o && o.connected),
4979
            str = [];
4980
        o = o || {};
4981
4982
        $(items).each(function() {
4983
            var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
4984
            if (res) {
4985
                str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
4986
            }
4987
        });
4988
4989
        if(!str.length && o.key) {
4990
            str.push(o.key + "=");
4991
        }
4992
4993
        return str.join("&");
4994
4995
    },
4996
4997
    toArray: function(o) {
4998
4999
        var items = this._getItemsAsjQuery(o && o.connected),
5000
            ret = [];
5001
5002
        o = o || {};
5003
5004
        items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
5005
        return ret;
5006
5007
    },
5008
5009
    /* Be careful with the following core functions */
5010
    _intersectsWith: function(item) {
5011
5012
        var x1 = this.positionAbs.left,
5013
            x2 = x1 + this.helperProportions.width,
5014
            y1 = this.positionAbs.top,
5015
            y2 = y1 + this.helperProportions.height,
5016
            l = item.left,
5017
            r = l + item.width,
5018
            t = item.top,
5019
            b = t + item.height,
5020
            dyClick = this.offset.click.top,
5021
            dxClick = this.offset.click.left,
5022
            isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
5023
            isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
5024
            isOverElement = isOverElementHeight && isOverElementWidth;
5025
5026
        if ( this.options.tolerance === "pointer" ||
5027
            this.options.forcePointerForContainers ||
5028
            (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
5029
        ) {
5030
            return isOverElement;
5031
        } else {
5032
5033
            return (l < x1 + (this.helperProportions.width / 2) && // Right Half
5034
                x2 - (this.helperProportions.width / 2) < r && // Left Half
5035
                t < y1 + (this.helperProportions.height / 2) && // Bottom Half
5036
                y2 - (this.helperProportions.height / 2) < b ); // Top Half
5037
5038
        }
5039
    },
5040
5041
    _intersectsWithPointer: function(item) {
5042
5043
        var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
5044
            isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
5045
            isOverElement = isOverElementHeight && isOverElementWidth,
5046
            verticalDirection = this._getDragVerticalDirection(),
5047
            horizontalDirection = this._getDragHorizontalDirection();
5048
5049
        if (!isOverElement) {
5050
            return false;
5051
        }
5052
5053
        return this.floating ?
5054
            ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
5055
            : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
5056
5057
    },
5058
5059
    _intersectsWithSides: function(item) {
5060
5061
        var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
5062
            isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
5063
            verticalDirection = this._getDragVerticalDirection(),
5064
            horizontalDirection = this._getDragHorizontalDirection();
5065
5066
        if (this.floating && horizontalDirection) {
5067
            return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
5068
        } else {
5069
            return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
5070
        }
5071
5072
    },
5073
5074
    _getDragVerticalDirection: function() {
5075
        var delta = this.positionAbs.top - this.lastPositionAbs.top;
5076
        return delta !== 0 && (delta > 0 ? "down" : "up");
5077
    },
5078
5079
    _getDragHorizontalDirection: function() {
5080
        var delta = this.positionAbs.left - this.lastPositionAbs.left;
5081
        return delta !== 0 && (delta > 0 ? "right" : "left");
5082
    },
5083
5084
    refresh: function(event) {
5085
        this._refreshItems(event);
5086
        this._setHandleClassName();
5087
        this.refreshPositions();
5088
        return this;
5089
    },
5090
5091
    _connectWith: function() {
5092
        var options = this.options;
5093
        return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
5094
    },
5095
5096
    _getItemsAsjQuery: function(connected) {
5097
5098
        var i, j, cur, inst,
5099
            items = [],
5100
            queries = [],
5101
            connectWith = this._connectWith();
5102
5103
        if(connectWith && connected) {
5104
            for (i = connectWith.length - 1; i >= 0; i--){
5105
                cur = $(connectWith[i], this.document[0]);
5106
                for ( j = cur.length - 1; j >= 0; j--){
5107
                    inst = $.data(cur[j], this.widgetFullName);
5108
                    if(inst && inst !== this && !inst.options.disabled) {
5109
                        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]);
5110
                    }
5111
                }
5112
            }
5113
        }
5114
5115
        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]);
5116
5117
        function addItems() {
5118
            items.push( this );
5119
        }
5120
        for (i = queries.length - 1; i >= 0; i--){
5121
            queries[i][0].each( addItems );
5122
        }
5123
5124
        return $(items);
5125
5126
    },
5127
5128
    _removeCurrentsFromItems: function() {
5129
5130
        var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
5131
5132
        this.items = $.grep(this.items, function (item) {
5133
            for (var j=0; j < list.length; j++) {
5134
                if(list[j] === item.item[0]) {
5135
                    return false;
5136
                }
5137
            }
5138
            return true;
5139
        });
5140
5141
    },
5142
5143
    _refreshItems: function(event) {
5144
5145
        this.items = [];
5146
        this.containers = [this];
5147
5148
        var i, j, cur, inst, targetData, _queries, item, queriesLength,
5149
            items = this.items,
5150
            queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
5151
            connectWith = this._connectWith();
5152
5153
        if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
5154
            for (i = connectWith.length - 1; i >= 0; i--){
5155
                cur = $(connectWith[i], this.document[0]);
5156
                for (j = cur.length - 1; j >= 0; j--){
5157
                    inst = $.data(cur[j], this.widgetFullName);
5158
                    if(inst && inst !== this && !inst.options.disabled) {
5159
                        queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
5160
                        this.containers.push(inst);
5161
                    }
5162
                }
5163
            }
5164
        }
5165
5166
        for (i = queries.length - 1; i >= 0; i--) {
5167
            targetData = queries[i][1];
5168
            _queries = queries[i][0];
5169
5170
            for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
5171
                item = $(_queries[j]);
5172
5173
                item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
5174
5175
                items.push({
5176
                    item: item,
5177
                    instance: targetData,
5178
                    width: 0, height: 0,
5179
                    left: 0, top: 0
5180
                });
5181
            }
5182
        }
5183
5184
    },
5185
5186
    refreshPositions: function(fast) {
5187
5188
        // Determine whether items are being displayed horizontally
5189
        this.floating = this.items.length ?
5190
            this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
5191
            false;
5192
5193
        //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
5194
        if(this.offsetParent && this.helper) {
5195
            this.offset.parent = this._getParentOffset();
5196
        }
5197
5198
        var i, item, t, p;
5199
5200
        for (i = this.items.length - 1; i >= 0; i--){
5201
            item = this.items[i];
5202
5203
            //We ignore calculating positions of all connected containers when we're not over them
5204
            if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
5205
                continue;
5206
            }
5207
5208
            t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
5209
5210
            if (!fast) {
5211
                item.width = t.outerWidth();
5212
                item.height = t.outerHeight();
5213
            }
5214
5215
            p = t.offset();
5216
            item.left = p.left;
5217
            item.top = p.top;
5218
        }
5219
5220
        if(this.options.custom && this.options.custom.refreshContainers) {
5221
            this.options.custom.refreshContainers.call(this);
5222
        } else {
5223
            for (i = this.containers.length - 1; i >= 0; i--){
5224
                p = this.containers[i].element.offset();
5225
                this.containers[i].containerCache.left = p.left;
5226
                this.containers[i].containerCache.top = p.top;
5227
                this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
5228
                this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
5229
            }
5230
        }
5231
5232
        return this;
5233
    },
5234
5235
    _createPlaceholder: function(that) {
5236
        that = that || this;
5237
        var className,
5238
            o = that.options;
5239
5240
        if(!o.placeholder || o.placeholder.constructor === String) {
5241
            className = o.placeholder;
5242
            o.placeholder = {
5243
                element: function() {
5244
5245
                    var nodeName = that.currentItem[0].nodeName.toLowerCase(),
5246
                        element = $( "<" + nodeName + ">", that.document[0] )
5247
                            .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
5248
                            .removeClass("ui-sortable-helper");
5249
5250
                    if ( nodeName === "tbody" ) {
5251
                        that._createTrPlaceholder(
5252
                            that.currentItem.find( "tr" ).eq( 0 ),
5253
                            $( "<tr>", that.document[ 0 ] ).appendTo( element )
5254
                        );
5255
                    } else if ( nodeName === "tr" ) {
5256
                        that._createTrPlaceholder( that.currentItem, element );
5257
                    } else if ( nodeName === "img" ) {
5258
                        element.attr( "src", that.currentItem.attr( "src" ) );
5259
                    }
5260
5261
                    if ( !className ) {
5262
                        element.css( "visibility", "hidden" );
5263
                    }
5264
5265
                    return element;
5266
                },
5267
                update: function(container, p) {
5268
5269
                    // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
5270
                    // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
5271
                    if(className && !o.forcePlaceholderSize) {
5272
                        return;
5273
                    }
5274
5275
                    //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
5276
                    if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
5277
                    if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
5278
                }
5279
            };
5280
        }
5281
5282
        //Create the placeholder
5283
        that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
5284
5285
        //Append it after the actual current item
5286
        that.currentItem.after(that.placeholder);
5287
5288
        //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
5289
        o.placeholder.update(that, that.placeholder);
5290
5291
    },
5292
5293
    _createTrPlaceholder: function( sourceTr, targetTr ) {
5294
        var that = this;
5295
5296
        sourceTr.children().each(function() {
5297
            $( "<td>&#160;</td>", that.document[ 0 ] )
5298
                .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
5299
                .appendTo( targetTr );
5300
        });
5301
    },
5302
5303
    _contactContainers: function(event) {
5304
        var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis,
5305
            innermostContainer = null,
5306
            innermostIndex = null;
5307
5308
        // get innermost container that intersects with item
5309
        for (i = this.containers.length - 1; i >= 0; i--) {
5310
5311
            // never consider a container that's located within the item itself
5312
            if($.contains(this.currentItem[0], this.containers[i].element[0])) {
5313
                continue;
5314
            }
5315
5316
            if(this._intersectsWith(this.containers[i].containerCache)) {
5317
5318
                // if we've already found a container and it's more "inner" than this, then continue
5319
                if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
5320
                    continue;
5321
                }
5322
5323
                innermostContainer = this.containers[i];
5324
                innermostIndex = i;
5325
5326
            } else {
5327
                // container doesn't intersect. trigger "out" event if necessary
5328
                if(this.containers[i].containerCache.over) {
5329
                    this.containers[i]._trigger("out", event, this._uiHash(this));
5330
                    this.containers[i].containerCache.over = 0;
5331
                }
5332
            }
5333
5334
        }
5335
5336
        // if no intersecting containers found, return
5337
        if(!innermostContainer) {
5338
            return;
5339
        }
5340
5341
        // move the item into the container if it's not there already
5342
        if(this.containers.length === 1) {
5343
            if (!this.containers[innermostIndex].containerCache.over) {
5344
                this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
5345
                this.containers[innermostIndex].containerCache.over = 1;
5346
            }
5347
        } else {
5348
5349
            //When entering a new container, we will find the item with the least distance and append our item near it
5350
            dist = 10000;
5351
            itemWithLeastDistance = null;
5352
            floating = innermostContainer.floating || this._isFloating(this.currentItem);
5353
            posProperty = floating ? "left" : "top";
5354
            sizeProperty = floating ? "width" : "height";
5355
            axis = floating ? "clientX" : "clientY";
5356
5357
            for (j = this.items.length - 1; j >= 0; j--) {
5358
                if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
5359
                    continue;
5360
                }
5361
                if(this.items[j].item[0] === this.currentItem[0]) {
5362
                    continue;
5363
                }
5364
5365
                cur = this.items[j].item.offset()[posProperty];
5366
                nearBottom = false;
5367
                if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
5368
                    nearBottom = true;
5369
                }
5370
5371
                if ( Math.abs( event[ axis ] - cur ) < dist ) {
5372
                    dist = Math.abs( event[ axis ] - cur );
5373
                    itemWithLeastDistance = this.items[ j ];
5374
                    this.direction = nearBottom ? "up": "down";
5375
                }
5376
            }
5377
5378
            //Check if dropOnEmpty is enabled
5379
            if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
5380
                return;
5381
            }
5382
5383
            if(this.currentContainer === this.containers[innermostIndex]) {
5384
                if ( !this.currentContainer.containerCache.over ) {
5385
                    this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
5386
                    this.currentContainer.containerCache.over = 1;
5387
                }
5388
                return;
5389
            }
5390
5391
            itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
5392
            this._trigger("change", event, this._uiHash());
5393
            this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
5394
            this.currentContainer = this.containers[innermostIndex];
5395
5396
            //Update the placeholder
5397
            this.options.placeholder.update(this.currentContainer, this.placeholder);
5398
5399
            this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
5400
            this.containers[innermostIndex].containerCache.over = 1;
5401
        }
5402
5403
5404
    },
5405
5406
    _createHelper: function(event) {
5407
5408
        var o = this.options,
5409
            helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
5410
5411
        //Add the helper to the DOM if that didn't happen already
5412
        if(!helper.parents("body").length) {
5413
            $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
5414
        }
5415
5416
        if(helper[0] === this.currentItem[0]) {
5417
            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") };
5418
        }
5419
5420
        if(!helper[0].style.width || o.forceHelperSize) {
5421
            helper.width(this.currentItem.width());
5422
        }
5423
        if(!helper[0].style.height || o.forceHelperSize) {
5424
            helper.height(this.currentItem.height());
5425
        }
5426
5427
        return helper;
5428
5429
    },
5430
5431
    _adjustOffsetFromHelper: function(obj) {
5432
        if (typeof obj === "string") {
5433
            obj = obj.split(" ");
5434
        }
5435
        if ($.isArray(obj)) {
5436
            obj = {left: +obj[0], top: +obj[1] || 0};
5437
        }
5438
        if ("left" in obj) {
5439
            this.offset.click.left = obj.left + this.margins.left;
5440
        }
5441
        if ("right" in obj) {
5442
            this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
5443
        }
5444
        if ("top" in obj) {
5445
            this.offset.click.top = obj.top + this.margins.top;
5446
        }
5447
        if ("bottom" in obj) {
5448
            this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
5449
        }
5450
    },
5451
5452
    _getParentOffset: function() {
5453
5454
5455
        //Get the offsetParent and cache its position
5456
        this.offsetParent = this.helper.offsetParent();
5457
        var po = this.offsetParent.offset();
5458
5459
        // This is a special case where we need to modify a offset calculated on start, since the following happened:
5460
        // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
5461
        // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
5462
        //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
5463
        if(this.cssPosition === "absolute" && this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) {
5464
            po.left += this.scrollParent.scrollLeft();
5465
            po.top += this.scrollParent.scrollTop();
5466
        }
5467
5468
        // This needs to be actually done for all browsers, since pageX/pageY includes this information
5469
        // with an ugly IE fix
5470
        if( this.offsetParent[0] === this.document[0].body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
5471
            po = { top: 0, left: 0 };
5472
        }
5473
5474
        return {
5475
            top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
5476
            left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
5477
        };
5478
5479
    },
5480
5481
    _getRelativeOffset: function() {
5482
5483
        if(this.cssPosition === "relative") {
5484
            var p = this.currentItem.position();
5485
            return {
5486
                top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
5487
                left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
5488
            };
5489
        } else {
5490
            return { top: 0, left: 0 };
5491
        }
5492
5493
    },
5494
5495
    _cacheMargins: function() {
5496
        this.margins = {
5497
            left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
5498
            top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
5499
        };
5500
    },
5501
5502
    _cacheHelperProportions: function() {
5503
        this.helperProportions = {
5504
            width: this.helper.outerWidth(),
5505
            height: this.helper.outerHeight()
5506
        };
5507
    },
5508
5509
    _setContainment: function() {
5510
5511
        var ce, co, over,
5512
            o = this.options;
5513
        if(o.containment === "parent") {
5514
            o.containment = this.helper[0].parentNode;
5515
        }
5516
        if(o.containment === "document" || o.containment === "window") {
5517
            this.containment = [
5518
                0 - this.offset.relative.left - this.offset.parent.left,
5519
                0 - this.offset.relative.top - this.offset.parent.top,
5520
                o.containment === "document" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left,
5521
                (o.containment === "document" ? this.document.width() : this.window.height() || this.document[0].body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
5522
            ];
5523
        }
5524
5525
        if(!(/^(document|window|parent)$/).test(o.containment)) {
5526
            ce = $(o.containment)[0];
5527
            co = $(o.containment).offset();
5528
            over = ($(ce).css("overflow") !== "hidden");
5529
5530
            this.containment = [
5531
                co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
5532
                co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
5533
                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,
5534
                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
5535
            ];
5536
        }
5537
5538
    },
5539
5540
    _convertPositionTo: function(d, pos) {
5541
5542
        if(!pos) {
5543
            pos = this.position;
5544
        }
5545
        var mod = d === "absolute" ? 1 : -1,
5546
            scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
5547
            scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
5548
5549
        return {
5550
            top: (
5551
                pos.top +                                                               // The absolute mouse position
5552
                this.offset.relative.top * mod +                                        // Only for relative positioned nodes: Relative offset from element to offset parent
5553
                this.offset.parent.top * mod -                                          // The offsetParent's offset without borders (offset + border)
5554
                ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
5555
            ),
5556
            left: (
5557
                pos.left +                                                              // The absolute mouse position
5558
                this.offset.relative.left * mod +                                       // Only for relative positioned nodes: Relative offset from element to offset parent
5559
                this.offset.parent.left * mod   -                                       // The offsetParent's offset without borders (offset + border)
5560
                ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
5561
            )
5562
        };
5563
5564
    },
5565
5566
    _generatePosition: function(event) {
5567
5568
        var top, left,
5569
            o = this.options,
5570
            pageX = event.pageX,
5571
            pageY = event.pageY,
5572
            scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
5573
5574
        // This is another very weird special case that only happens for relative elements:
5575
        // 1. If the css position is relative
5576
        // 2. and the scroll parent is the document or similar to the offset parent
5577
        // we have to refresh the relative offset during the scroll so there are no jumps
5578
        if(this.cssPosition === "relative" && !(this.scrollParent[0] !== this.document[0] && this.scrollParent[0] !== this.offsetParent[0])) {
5579
            this.offset.relative = this._getRelativeOffset();
5580
        }
5581
5582
        /*
5583
         * - Position constraining -
5584
         * Constrain the position to a mix of grid, containment.
5585
         */
5586
5587
        if(this.originalPosition) { //If we are not dragging yet, we won't check for options
5588
5589
            if(this.containment) {
5590
                if(event.pageX - this.offset.click.left < this.containment[0]) {
5591
                    pageX = this.containment[0] + this.offset.click.left;
5592
                }
5593
                if(event.pageY - this.offset.click.top < this.containment[1]) {
5594
                    pageY = this.containment[1] + this.offset.click.top;
5595
                }
5596
                if(event.pageX - this.offset.click.left > this.containment[2]) {
5597
                    pageX = this.containment[2] + this.offset.click.left;
5598
                }
5599
                if(event.pageY - this.offset.click.top > this.containment[3]) {
5600
                    pageY = this.containment[3] + this.offset.click.top;
5601
                }
5602
            }
5603
5604
            if(o.grid) {
5605
                top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
5606
                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;
5607
5608
                left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
5609
                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;
5610
            }
5611
5612
        }
5613
5614
        return {
5615
            top: (
5616
                pageY -                                                             // The absolute mouse position
5617
                this.offset.click.top -                                                 // Click offset (relative to the element)
5618
                this.offset.relative.top    -                                           // Only for relative positioned nodes: Relative offset from element to offset parent
5619
                this.offset.parent.top +                                                // The offsetParent's offset without borders (offset + border)
5620
                ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
5621
            ),
5622
            left: (
5623
                pageX -                                                             // The absolute mouse position
5624
                this.offset.click.left -                                                // Click offset (relative to the element)
5625
                this.offset.relative.left   -                                           // Only for relative positioned nodes: Relative offset from element to offset parent
5626
                this.offset.parent.left +                                               // The offsetParent's offset without borders (offset + border)
5627
                ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
5628
            )
5629
        };
5630
5631
    },
5632
5633
    _rearrange: function(event, i, a, hardRefresh) {
5634
5635
        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));
5636
5637
        //Various things done here to improve the performance:
5638
        // 1. we create a setTimeout, that calls refreshPositions
5639
        // 2. on the instance, we have a counter variable, that get's higher after every append
5640
        // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
5641
        // 4. this lets only the last addition to the timeout stack through
5642
        this.counter = this.counter ? ++this.counter : 1;
5643
        var counter = this.counter;
5644
5645
        this._delay(function() {
5646
            if(counter === this.counter) {
5647
                this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
5648
            }
5649
        });
5650
5651
    },
5652
5653
    _clear: function(event, noPropagation) {
5654
5655
        this.reverting = false;
5656
        // We delay all events that have to be triggered to after the point where the placeholder has been removed and
5657
        // everything else normalized again
5658
        var i,
5659
            delayedTriggers = [];
5660
5661
        // We first have to update the dom position of the actual currentItem
5662
        // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
5663
        if(!this._noFinalSort && this.currentItem.parent().length) {
5664
            this.placeholder.before(this.currentItem);
5665
        }
5666
        this._noFinalSort = null;
5667
5668
        if(this.helper[0] === this.currentItem[0]) {
5669
            for(i in this._storedCSS) {
5670
                if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
5671
                    this._storedCSS[i] = "";
5672
                }
5673
            }
5674
            this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
5675
        } else {
5676
            this.currentItem.show();
5677
        }
5678
5679
        if(this.fromOutside && !noPropagation) {
5680
            delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
5681
        }
5682
        if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
5683
            delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
5684
        }
5685
5686
        // Check if the items Container has Changed and trigger appropriate
5687
        // events.
5688
        if (this !== this.currentContainer) {
5689
            if(!noPropagation) {
5690
                delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
5691
                delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
5692
                delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
5693
            }
5694
        }
5695
5696
5697
        //Post events to containers
5698
        function delayEvent( type, instance, container ) {
5699
            return function( event ) {
5700
                container._trigger( type, event, instance._uiHash( instance ) );
5701
            };
5702
        }
5703
        for (i = this.containers.length - 1; i >= 0; i--){
5704
            if (!noPropagation) {
5705
                delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
5706
            }
5707
            if(this.containers[i].containerCache.over) {
5708
                delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
5709
                this.containers[i].containerCache.over = 0;
5710
            }
5711
        }
5712
5713
        //Do what was originally in plugins
5714
        if ( this.storedCursor ) {
5715
            this.document.find( "body" ).css( "cursor", this.storedCursor );
5716
            this.storedStylesheet.remove();
5717
        }
5718
        if(this._storedOpacity) {
5719
            this.helper.css("opacity", this._storedOpacity);
5720
        }
5721
        if(this._storedZIndex) {
5722
            this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
5723
        }
5724
5725
        this.dragging = false;
5726
5727
        if(!noPropagation) {
5728
            this._trigger("beforeStop", event, this._uiHash());
5729
        }
5730
5731
        //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
5732
        this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
5733
5734
        if ( !this.cancelHelperRemoval ) {
5735
            if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
5736
                this.helper.remove();
5737
            }
5738
            this.helper = null;
5739
        }
5740
5741
        if(!noPropagation) {
5742
            for (i=0; i < delayedTriggers.length; i++) {
5743
                delayedTriggers[i].call(this, event);
5744
            } //Trigger all delayed events
5745
            this._trigger("stop", event, this._uiHash());
5746
        }
5747
5748
        this.fromOutside = false;
5749
        return !this.cancelHelperRemoval;
5750
5751
    },
5752
5753
    _trigger: function() {
5754
        if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
5755
            this.cancel();
5756
        }
5757
    },
5758
5759
    _uiHash: function(_inst) {
5760
        var inst = _inst || this;
5761
        return {
5762
            helper: inst.helper,
5763
            placeholder: inst.placeholder || $([]),
5764
            position: inst.position,
5765
            originalPosition: inst.originalPosition,
5766
            offset: inst.positionAbs,
5767
            item: inst.currentItem,
5768
            sender: _inst ? _inst.element : null
5769
        };
5770
    }
5771
5772
});
5773
5774
5775
/*!
5776
 * jQuery UI Accordion 1.11.4
5777
 * http://jqueryui.com
5778
 *
5779
 * Copyright jQuery Foundation and other contributors
5780
 * Released under the MIT license.
5781
 * http://jquery.org/license
5782
 *
5783
 * http://api.jqueryui.com/accordion/
5784
 */
5785
5786
5787
var accordion = $.widget( "ui.accordion", {
5788
    version: "1.11.4",
5789
    options: {
5790
        active: 0,
5791
        animate: {},
5792
        collapsible: false,
5793
        event: "click",
5794
        header: "> li > :first-child,> :not(li):even",
5795
        heightStyle: "auto",
5796
        icons: {
5797
            activeHeader: "ui-icon-triangle-1-s",
5798
            header: "ui-icon-triangle-1-e"
5799
        },
5800
5801
        // callbacks
5802
        activate: null,
5803
        beforeActivate: null
5804
    },
5805
5806
    hideProps: {
5807
        borderTopWidth: "hide",
5808
        borderBottomWidth: "hide",
5809
        paddingTop: "hide",
5810
        paddingBottom: "hide",
5811
        height: "hide"
5812
    },
5813
5814
    showProps: {
5815
        borderTopWidth: "show",
5816
        borderBottomWidth: "show",
5817
        paddingTop: "show",
5818
        paddingBottom: "show",
5819
        height: "show"
5820
    },
5821
5822
    _create: function() {
5823
        var options = this.options;
5824
        this.prevShow = this.prevHide = $();
5825
        this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
5826
            // ARIA
5827
            .attr( "role", "tablist" );
5828
5829
        // don't allow collapsible: false and active: false / null
5830
        if ( !options.collapsible && (options.active === false || options.active == null) ) {
5831
            options.active = 0;
5832
        }
5833
5834
        this._processPanels();
5835
        // handle negative values
5836
        if ( options.active < 0 ) {
5837
            options.active += this.headers.length;
5838
        }
5839
        this._refresh();
5840
    },
5841
5842
    _getCreateEventData: function() {
5843
        return {
5844
            header: this.active,
5845
            panel: !this.active.length ? $() : this.active.next()
5846
        };
5847
    },
5848
5849
    _createIcons: function() {
5850
        var icons = this.options.icons;
5851
        if ( icons ) {
5852
            $( "<span>" )
5853
                .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
5854
                .prependTo( this.headers );
5855
            this.active.children( ".ui-accordion-header-icon" )
5856
                .removeClass( icons.header )
5857
                .addClass( icons.activeHeader );
5858
            this.headers.addClass( "ui-accordion-icons" );
5859
        }
5860
    },
5861
5862
    _destroyIcons: function() {
5863
        this.headers
5864
            .removeClass( "ui-accordion-icons" )
5865
            .children( ".ui-accordion-header-icon" )
5866
                .remove();
5867
    },
5868
5869
    _destroy: function() {
5870
        var contents;
5871
5872
        // clean up main element
5873
        this.element
5874
            .removeClass( "ui-accordion ui-widget ui-helper-reset" )
5875
            .removeAttr( "role" );
5876
5877
        // clean up headers
5878
        this.headers
5879
            .removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " +
5880
                "ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
5881
            .removeAttr( "role" )
5882
            .removeAttr( "aria-expanded" )
5883
            .removeAttr( "aria-selected" )
5884
            .removeAttr( "aria-controls" )
5885
            .removeAttr( "tabIndex" )
5886
            .removeUniqueId();
5887
5888
        this._destroyIcons();
5889
5890
        // clean up content panels
5891
        contents = this.headers.next()
5892
            .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " +
5893
                "ui-accordion-content ui-accordion-content-active ui-state-disabled" )
5894
            .css( "display", "" )
5895
            .removeAttr( "role" )
5896
            .removeAttr( "aria-hidden" )
5897
            .removeAttr( "aria-labelledby" )
5898
            .removeUniqueId();
5899
5900
        if ( this.options.heightStyle !== "content" ) {
5901
            contents.css( "height", "" );
5902
        }
5903
    },
5904
5905
    _setOption: function( key, value ) {
5906
        if ( key === "active" ) {
5907
            // _activate() will handle invalid values and update this.options
5908
            this._activate( value );
5909
            return;
5910
        }
5911
5912
        if ( key === "event" ) {
5913
            if ( this.options.event ) {
5914
                this._off( this.headers, this.options.event );
5915
            }
5916
            this._setupEvents( value );
5917
        }
5918
5919
        this._super( key, value );
5920
5921
        // setting collapsible: false while collapsed; open first panel
5922
        if ( key === "collapsible" && !value && this.options.active === false ) {
5923
            this._activate( 0 );
5924
        }
5925
5926
        if ( key === "icons" ) {
5927
            this._destroyIcons();
5928
            if ( value ) {
5929
                this._createIcons();
5930
            }
5931
        }
5932
5933
        // #5332 - opacity doesn't cascade to positioned elements in IE
5934
        // so we need to add the disabled class to the headers and panels
5935
        if ( key === "disabled" ) {
5936
            this.element
5937
                .toggleClass( "ui-state-disabled", !!value )
5938
                .attr( "aria-disabled", value );
5939
            this.headers.add( this.headers.next() )
5940
                .toggleClass( "ui-state-disabled", !!value );
5941
        }
5942
    },
5943
5944
    _keydown: function( event ) {
5945
        if ( event.altKey || event.ctrlKey ) {
5946
            return;
5947
        }
5948
5949
        var keyCode = $.ui.keyCode,
5950
            length = this.headers.length,
5951
            currentIndex = this.headers.index( event.target ),
5952
            toFocus = false;
5953
5954
        switch ( event.keyCode ) {
5955
            case keyCode.RIGHT:
5956
            case keyCode.DOWN:
5957
                toFocus = this.headers[ ( currentIndex + 1 ) % length ];
5958
                break;
5959
            case keyCode.LEFT:
5960
            case keyCode.UP:
5961
                toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
5962
                break;
5963
            case keyCode.SPACE:
5964
            case keyCode.ENTER:
5965
                this._eventHandler( event );
5966
                break;
5967
            case keyCode.HOME:
5968
                toFocus = this.headers[ 0 ];
5969
                break;
5970
            case keyCode.END:
5971
                toFocus = this.headers[ length - 1 ];
5972
                break;
5973
        }
5974
5975
        if ( toFocus ) {
5976
            $( event.target ).attr( "tabIndex", -1 );
5977
            $( toFocus ).attr( "tabIndex", 0 );
5978
            toFocus.focus();
5979
            event.preventDefault();
5980
        }
5981
    },
5982
5983
    _panelKeyDown: function( event ) {
5984
        if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
5985
            $( event.currentTarget ).prev().focus();
5986
        }
5987
    },
5988
5989
    refresh: function() {
5990
        var options = this.options;
5991
        this._processPanels();
5992
5993
        // was collapsed or no panel
5994
        if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
5995
            options.active = false;
5996
            this.active = $();
5997
        // active false only when collapsible is true
5998
        } else if ( options.active === false ) {
5999
            this._activate( 0 );
6000
        // was active, but active panel is gone
6001
        } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
6002
            // all remaining panel are disabled
6003
            if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
6004
                options.active = false;
6005
                this.active = $();
6006
            // activate previous panel
6007
            } else {
6008
                this._activate( Math.max( 0, options.active - 1 ) );
6009
            }
6010
        // was active, active panel still exists
6011
        } else {
6012
            // make sure active index is correct
6013
            options.active = this.headers.index( this.active );
6014
        }
6015
6016
        this._destroyIcons();
6017
6018
        this._refresh();
6019
    },
6020
6021
    _processPanels: function() {
6022
        var prevHeaders = this.headers,
6023
            prevPanels = this.panels;
6024
6025
        this.headers = this.element.find( this.options.header )
6026
            .addClass( "ui-accordion-header ui-state-default ui-corner-all" );
6027
6028
        this.panels = this.headers.next()
6029
            .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
6030
            .filter( ":not(.ui-accordion-content-active)" )
6031
            .hide();
6032
6033
        // Avoid memory leaks (#10056)
6034
        if ( prevPanels ) {
6035
            this._off( prevHeaders.not( this.headers ) );
6036
            this._off( prevPanels.not( this.panels ) );
6037
        }
6038
    },
6039
6040
    _refresh: function() {
6041
        var maxHeight,
6042
            options = this.options,
6043
            heightStyle = options.heightStyle,
6044
            parent = this.element.parent();
6045
6046
        this.active = this._findActive( options.active )
6047
            .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
6048
            .removeClass( "ui-corner-all" );
6049
        this.active.next()
6050
            .addClass( "ui-accordion-content-active" )
6051
            .show();
6052
6053
        this.headers
6054
            .attr( "role", "tab" )
6055
            .each(function() {
6056
                var header = $( this ),
6057
                    headerId = header.uniqueId().attr( "id" ),
6058
                    panel = header.next(),
6059
                    panelId = panel.uniqueId().attr( "id" );
6060
                header.attr( "aria-controls", panelId );
6061
                panel.attr( "aria-labelledby", headerId );
6062
            })
6063
            .next()
6064
                .attr( "role", "tabpanel" );
6065
6066
        this.headers
6067
            .not( this.active )
6068
            .attr({
6069
                "aria-selected": "false",
6070
                "aria-expanded": "false",
6071
                tabIndex: -1
6072
            })
6073
            .next()
6074
                .attr({
6075
                    "aria-hidden": "true"
6076
                })
6077
                .hide();
6078
6079
        // make sure at least one header is in the tab order
6080
        if ( !this.active.length ) {
6081
            this.headers.eq( 0 ).attr( "tabIndex", 0 );
6082
        } else {
6083
            this.active.attr({
6084
                "aria-selected": "true",
6085
                "aria-expanded": "true",
6086
                tabIndex: 0
6087
            })
6088
            .next()
6089
                .attr({
6090
                    "aria-hidden": "false"
6091
                });
6092
        }
6093
6094
        this._createIcons();
6095
6096
        this._setupEvents( options.event );
6097
6098
        if ( heightStyle === "fill" ) {
6099
            maxHeight = parent.height();
6100
            this.element.siblings( ":visible" ).each(function() {
6101
                var elem = $( this ),
6102
                    position = elem.css( "position" );
6103
6104
                if ( position === "absolute" || position === "fixed" ) {
6105
                    return;
6106
                }
6107
                maxHeight -= elem.outerHeight( true );
6108
            });
6109
6110
            this.headers.each(function() {
6111
                maxHeight -= $( this ).outerHeight( true );
6112
            });
6113
6114
            this.headers.next()
6115
                .each(function() {
6116
                    $( this ).height( Math.max( 0, maxHeight -
6117
                        $( this ).innerHeight() + $( this ).height() ) );
6118
                })
6119
                .css( "overflow", "auto" );
6120
        } else if ( heightStyle === "auto" ) {
6121
            maxHeight = 0;
6122
            this.headers.next()
6123
                .each(function() {
6124
                    maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
6125
                })
6126
                .height( maxHeight );
6127
        }
6128
    },
6129
6130
    _activate: function( index ) {
6131
        var active = this._findActive( index )[ 0 ];
6132
6133
        // trying to activate the already active panel
6134
        if ( active === this.active[ 0 ] ) {
6135
            return;
6136
        }
6137
6138
        // trying to collapse, simulate a click on the currently active header
6139
        active = active || this.active[ 0 ];
6140
6141
        this._eventHandler({
6142
            target: active,
6143
            currentTarget: active,
6144
            preventDefault: $.noop
6145
        });
6146
    },
6147
6148
    _findActive: function( selector ) {
6149
        return typeof selector === "number" ? this.headers.eq( selector ) : $();
6150
    },
6151
6152
    _setupEvents: function( event ) {
6153
        var events = {
6154
            keydown: "_keydown"
6155
        };
6156
        if ( event ) {
6157
            $.each( event.split( " " ), function( index, eventName ) {
6158
                events[ eventName ] = "_eventHandler";
6159
            });
6160
        }
6161
6162
        this._off( this.headers.add( this.headers.next() ) );
6163
        this._on( this.headers, events );
6164
        this._on( this.headers.next(), { keydown: "_panelKeyDown" });
6165
        this._hoverable( this.headers );
6166
        this._focusable( this.headers );
6167
    },
6168
6169
    _eventHandler: function( event ) {
6170
        var options = this.options,
6171
            active = this.active,
6172
            clicked = $( event.currentTarget ),
6173
            clickedIsActive = clicked[ 0 ] === active[ 0 ],
6174
            collapsing = clickedIsActive && options.collapsible,
6175
            toShow = collapsing ? $() : clicked.next(),
6176
            toHide = active.next(),
6177
            eventData = {
6178
                oldHeader: active,
6179
                oldPanel: toHide,
6180
                newHeader: collapsing ? $() : clicked,
6181
                newPanel: toShow
6182
            };
6183
6184
        event.preventDefault();
6185
6186
        if (
6187
                // click on active header, but not collapsible
6188
                ( clickedIsActive && !options.collapsible ) ||
6189
                // allow canceling activation
6190
                ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
6191
            return;
6192
        }
6193
6194
        options.active = collapsing ? false : this.headers.index( clicked );
6195
6196
        // when the call to ._toggle() comes after the class changes
6197
        // it causes a very odd bug in IE 8 (see #6720)
6198
        this.active = clickedIsActive ? $() : clicked;
6199
        this._toggle( eventData );
6200
6201
        // switch classes
6202
        // corner classes on the previously active header stay after the animation
6203
        active.removeClass( "ui-accordion-header-active ui-state-active" );
6204
        if ( options.icons ) {
6205
            active.children( ".ui-accordion-header-icon" )
6206
                .removeClass( options.icons.activeHeader )
6207
                .addClass( options.icons.header );
6208
        }
6209
6210
        if ( !clickedIsActive ) {
6211
            clicked
6212
                .removeClass( "ui-corner-all" )
6213
                .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
6214
            if ( options.icons ) {
6215
                clicked.children( ".ui-accordion-header-icon" )
6216
                    .removeClass( options.icons.header )
6217
                    .addClass( options.icons.activeHeader );
6218
            }
6219
6220
            clicked
6221
                .next()
6222
                .addClass( "ui-accordion-content-active" );
6223
        }
6224
    },
6225
6226
    _toggle: function( data ) {
6227
        var toShow = data.newPanel,
6228
            toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
6229
6230
        // handle activating a panel during the animation for another activation
6231
        this.prevShow.add( this.prevHide ).stop( true, true );
6232
        this.prevShow = toShow;
6233
        this.prevHide = toHide;
6234
6235
        if ( this.options.animate ) {
6236
            this._animate( toShow, toHide, data );
6237
        } else {
6238
            toHide.hide();
6239
            toShow.show();
6240
            this._toggleComplete( data );
6241
        }
6242
6243
        toHide.attr({
6244
            "aria-hidden": "true"
6245
        });
6246
        toHide.prev().attr({
6247
            "aria-selected": "false",
6248
            "aria-expanded": "false"
6249
        });
6250
        // if we're switching panels, remove the old header from the tab order
6251
        // if we're opening from collapsed state, remove the previous header from the tab order
6252
        // if we're collapsing, then keep the collapsing header in the tab order
6253
        if ( toShow.length && toHide.length ) {
6254
            toHide.prev().attr({
6255
                "tabIndex": -1,
6256
                "aria-expanded": "false"
6257
            });
6258
        } else if ( toShow.length ) {
6259
            this.headers.filter(function() {
6260
                return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
6261
            })
6262
            .attr( "tabIndex", -1 );
6263
        }
6264
6265
        toShow
6266
            .attr( "aria-hidden", "false" )
6267
            .prev()
6268
                .attr({
6269
                    "aria-selected": "true",
6270
                    "aria-expanded": "true",
6271
                    tabIndex: 0
6272
                });
6273
    },
6274
6275
    _animate: function( toShow, toHide, data ) {
6276
        var total, easing, duration,
6277
            that = this,
6278
            adjust = 0,
6279
            boxSizing = toShow.css( "box-sizing" ),
6280
            down = toShow.length &&
6281
                ( !toHide.length || ( toShow.index() < toHide.index() ) ),
6282
            animate = this.options.animate || {},
6283
            options = down && animate.down || animate,
6284
            complete = function() {
6285
                that._toggleComplete( data );
6286
            };
6287
6288
        if ( typeof options === "number" ) {
6289
            duration = options;
6290
        }
6291
        if ( typeof options === "string" ) {
6292
            easing = options;
6293
        }
6294
        // fall back from options to animation in case of partial down settings
6295
        easing = easing || options.easing || animate.easing;
6296
        duration = duration || options.duration || animate.duration;
6297
6298
        if ( !toHide.length ) {
6299
            return toShow.animate( this.showProps, duration, easing, complete );
6300
        }
6301
        if ( !toShow.length ) {
6302
            return toHide.animate( this.hideProps, duration, easing, complete );
6303
        }
6304
6305
        total = toShow.show().outerHeight();
6306
        toHide.animate( this.hideProps, {
6307
            duration: duration,
6308
            easing: easing,
6309
            step: function( now, fx ) {
6310
                fx.now = Math.round( now );
6311
            }
6312
        });
6313
        toShow
6314
            .hide()
6315
            .animate( this.showProps, {
6316
                duration: duration,
6317
                easing: easing,
6318
                complete: complete,
6319
                step: function( now, fx ) {
6320
                    fx.now = Math.round( now );
6321
                    if ( fx.prop !== "height" ) {
6322
                        if ( boxSizing === "content-box" ) {
6323
                            adjust += fx.now;
6324
                        }
6325
                    } else if ( that.options.heightStyle !== "content" ) {
6326
                        fx.now = Math.round( total - toHide.outerHeight() - adjust );
6327
                        adjust = 0;
6328
                    }
6329
                }
6330
            });
6331
    },
6332
6333
    _toggleComplete: function( data ) {
6334
        var toHide = data.oldPanel;
6335
6336
        toHide
6337
            .removeClass( "ui-accordion-content-active" )
6338
            .prev()
6339
                .removeClass( "ui-corner-top" )
6340
                .addClass( "ui-corner-all" );
6341
6342
        // Work around for rendering bug in IE (#5421)
6343
        if ( toHide.length ) {
6344
            toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
6345
        }
6346
        this._trigger( "activate", null, data );
6347
    }
6348
});
6349
6350
6351
/*!
6352
 * jQuery UI Menu 1.11.4
6353
 * http://jqueryui.com
6354
 *
6355
 * Copyright jQuery Foundation and other contributors
6356
 * Released under the MIT license.
6357
 * http://jquery.org/license
6358
 *
6359
 * http://api.jqueryui.com/menu/
6360
 */
6361
6362
6363
var menu = $.widget( "ui.menu", {
6364
    version: "1.11.4",
6365
    defaultElement: "<ul>",
6366
    delay: 300,
6367
    options: {
6368
        icons: {
6369
            submenu: "ui-icon-carat-1-e"
6370
        },
6371
        items: "> *",
6372
        menus: "ul",
6373
        position: {
6374
            my: "left-1 top",
6375
            at: "right top"
6376
        },
6377
        role: "menu",
6378
6379
        // callbacks
6380
        blur: null,
6381
        focus: null,
6382
        select: null
6383
    },
6384
6385
    _create: function() {
6386
        this.activeMenu = this.element;
6387
6388
        // Flag used to prevent firing of the click handler
6389
        // as the event bubbles up through nested menus
6390
        this.mouseHandled = false;
6391
        this.element
6392
            .uniqueId()
6393
            .addClass( "ui-menu ui-widget ui-widget-content" )
6394
            .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
6395
            .attr({
6396
                role: this.options.role,
6397
                tabIndex: 0
6398
            });
6399
6400
        if ( this.options.disabled ) {
6401
            this.element
6402
                .addClass( "ui-state-disabled" )
6403
                .attr( "aria-disabled", "true" );
6404
        }
6405
6406
        this._on({
6407
            // Prevent focus from sticking to links inside menu after clicking
6408
            // them (focus should always stay on UL during navigation).
6409
            "mousedown .ui-menu-item": function( event ) {
6410
                event.preventDefault();
6411
            },
6412
            "click .ui-menu-item": function( event ) {
6413
                var target = $( event.target );
6414
                if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
6415
                    this.select( event );
6416
6417
                    // Only set the mouseHandled flag if the event will bubble, see #9469.
6418
                    if ( !event.isPropagationStopped() ) {
6419
                        this.mouseHandled = true;
6420
                    }
6421
6422
                    // Open submenu on click
6423
                    if ( target.has( ".ui-menu" ).length ) {
6424
                        this.expand( event );
6425
                    } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
6426
6427
                        // Redirect focus to the menu
6428
                        this.element.trigger( "focus", [ true ] );
6429
6430
                        // If the active item is on the top level, let it stay active.
6431
                        // Otherwise, blur the active item since it is no longer visible.
6432
                        if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
6433
                            clearTimeout( this.timer );
6434
                        }
6435
                    }
6436
                }
6437
            },
6438
            "mouseenter .ui-menu-item": function( event ) {
6439
                // Ignore mouse events while typeahead is active, see #10458.
6440
                // Prevents focusing the wrong item when typeahead causes a scroll while the mouse
6441
                // is over an item in the menu
6442
                if ( this.previousFilter ) {
6443
                    return;
6444
                }
6445
                var target = $( event.currentTarget );
6446
                // Remove ui-state-active class from siblings of the newly focused menu item
6447
                // to avoid a jump caused by adjacent elements both having a class with a border
6448
                target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" );
6449
                this.focus( event, target );
6450
            },
6451
            mouseleave: "collapseAll",
6452
            "mouseleave .ui-menu": "collapseAll",
6453
            focus: function( event, keepActiveItem ) {
6454
                // If there's already an active item, keep it active
6455
                // If not, activate the first item
6456
                var item = this.active || this.element.find( this.options.items ).eq( 0 );
6457
6458
                if ( !keepActiveItem ) {
6459
                    this.focus( event, item );
6460
                }
6461
            },
6462
            blur: function( event ) {
6463
                this._delay(function() {
6464
                    if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
6465
                        this.collapseAll( event );
6466
                    }
6467
                });
6468
            },
6469
            keydown: "_keydown"
6470
        });
6471
6472
        this.refresh();
6473
6474
        // Clicks outside of a menu collapse any open menus
6475
        this._on( this.document, {
6476
            click: function( event ) {
6477
                if ( this._closeOnDocumentClick( event ) ) {
6478
                    this.collapseAll( event );
6479
                }
6480
6481
                // Reset the mouseHandled flag
6482
                this.mouseHandled = false;
6483
            }
6484
        });
6485
    },
6486
6487
    _destroy: function() {
6488
        // Destroy (sub)menus
6489
        this.element
6490
            .removeAttr( "aria-activedescendant" )
6491
            .find( ".ui-menu" ).addBack()
6492
                .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" )
6493
                .removeAttr( "role" )
6494
                .removeAttr( "tabIndex" )
6495
                .removeAttr( "aria-labelledby" )
6496
                .removeAttr( "aria-expanded" )
6497
                .removeAttr( "aria-hidden" )
6498
                .removeAttr( "aria-disabled" )
6499
                .removeUniqueId()
6500
                .show();
6501
6502
        // Destroy menu items
6503
        this.element.find( ".ui-menu-item" )
6504
            .removeClass( "ui-menu-item" )
6505
            .removeAttr( "role" )
6506
            .removeAttr( "aria-disabled" )
6507
            .removeUniqueId()
6508
            .removeClass( "ui-state-hover" )
6509
            .removeAttr( "tabIndex" )
6510
            .removeAttr( "role" )
6511
            .removeAttr( "aria-haspopup" )
6512
            .children().each( function() {
6513
                var elem = $( this );
6514
                if ( elem.data( "ui-menu-submenu-carat" ) ) {
6515
                    elem.remove();
6516
                }
6517
            });
6518
6519
        // Destroy menu dividers
6520
        this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
6521
    },
6522
6523
    _keydown: function( event ) {
6524
        var match, prev, character, skip,
6525
            preventDefault = true;
6526
6527
        switch ( event.keyCode ) {
6528
        case $.ui.keyCode.PAGE_UP:
6529
            this.previousPage( event );
6530
            break;
6531
        case $.ui.keyCode.PAGE_DOWN:
6532
            this.nextPage( event );
6533
            break;
6534
        case $.ui.keyCode.HOME:
6535
            this._move( "first", "first", event );
6536
            break;
6537
        case $.ui.keyCode.END:
6538
            this._move( "last", "last", event );
6539
            break;
6540
        case $.ui.keyCode.UP:
6541
            this.previous( event );
6542
            break;
6543
        case $.ui.keyCode.DOWN:
6544
            this.next( event );
6545
            break;
6546
        case $.ui.keyCode.LEFT:
6547
            this.collapse( event );
6548
            break;
6549
        case $.ui.keyCode.RIGHT:
6550
            if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
6551
                this.expand( event );
6552
            }
6553
            break;
6554
        case $.ui.keyCode.ENTER:
6555
        case $.ui.keyCode.SPACE:
6556
            this._activate( event );
6557
            break;
6558
        case $.ui.keyCode.ESCAPE:
6559
            this.collapse( event );
6560
            break;
6561
        default:
6562
            preventDefault = false;
6563
            prev = this.previousFilter || "";
6564
            character = String.fromCharCode( event.keyCode );
6565
            skip = false;
6566
6567
            clearTimeout( this.filterTimer );
6568
6569
            if ( character === prev ) {
6570
                skip = true;
6571
            } else {
6572
                character = prev + character;
6573
            }
6574
6575
            match = this._filterMenuItems( character );
6576
            match = skip && match.index( this.active.next() ) !== -1 ?
6577
                this.active.nextAll( ".ui-menu-item" ) :
6578
                match;
6579
6580
            // If no matches on the current filter, reset to the last character pressed
6581
            // to move down the menu to the first item that starts with that character
6582
            if ( !match.length ) {
6583
                character = String.fromCharCode( event.keyCode );
6584
                match = this._filterMenuItems( character );
6585
            }
6586
6587
            if ( match.length ) {
6588
                this.focus( event, match );
6589
                this.previousFilter = character;
6590
                this.filterTimer = this._delay(function() {
6591
                    delete this.previousFilter;
6592
                }, 1000 );
6593
            } else {
6594
                delete this.previousFilter;
6595
            }
6596
        }
6597
6598
        if ( preventDefault ) {
6599
            event.preventDefault();
6600
        }
6601
    },
6602
6603
    _activate: function( event ) {
6604
        if ( !this.active.is( ".ui-state-disabled" ) ) {
6605
            if ( this.active.is( "[aria-haspopup='true']" ) ) {
6606
                this.expand( event );
6607
            } else {
6608
                this.select( event );
6609
            }
6610
        }
6611
    },
6612
6613
    refresh: function() {
6614
        var menus, items,
6615
            that = this,
6616
            icon = this.options.icons.submenu,
6617
            submenus = this.element.find( this.options.menus );
6618
6619
        this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
6620
6621
        // Initialize nested menus
6622
        submenus.filter( ":not(.ui-menu)" )
6623
            .addClass( "ui-menu ui-widget ui-widget-content ui-front" )
6624
            .hide()
6625
            .attr({
6626
                role: this.options.role,
6627
                "aria-hidden": "true",
6628
                "aria-expanded": "false"
6629
            })
6630
            .each(function() {
6631
                var menu = $( this ),
6632
                    item = menu.parent(),
6633
                    submenuCarat = $( "<span>" )
6634
                        .addClass( "ui-menu-icon ui-icon " + icon )
6635
                        .data( "ui-menu-submenu-carat", true );
6636
6637
                item
6638
                    .attr( "aria-haspopup", "true" )
6639
                    .prepend( submenuCarat );
6640
                menu.attr( "aria-labelledby", item.attr( "id" ) );
6641
            });
6642
6643
        menus = submenus.add( this.element );
6644
        items = menus.find( this.options.items );
6645
6646
        // Initialize menu-items containing spaces and/or dashes only as dividers
6647
        items.not( ".ui-menu-item" ).each(function() {
6648
            var item = $( this );
6649
            if ( that._isDivider( item ) ) {
6650
                item.addClass( "ui-widget-content ui-menu-divider" );
6651
            }
6652
        });
6653
6654
        // Don't refresh list items that are already adapted
6655
        items.not( ".ui-menu-item, .ui-menu-divider" )
6656
            .addClass( "ui-menu-item" )
6657
            .uniqueId()
6658
            .attr({
6659
                tabIndex: -1,
6660
                role: this._itemRole()
6661
            });
6662
6663
        // Add aria-disabled attribute to any disabled menu item
6664
        items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
6665
6666
        // If the active item has been removed, blur the menu
6667
        if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
6668
            this.blur();
6669
        }
6670
    },
6671
6672
    _itemRole: function() {
6673
        return {
6674
            menu: "menuitem",
6675
            listbox: "option"
6676
        }[ this.options.role ];
6677
    },
6678
6679
    _setOption: function( key, value ) {
6680
        if ( key === "icons" ) {
6681
            this.element.find( ".ui-menu-icon" )
6682
                .removeClass( this.options.icons.submenu )
6683
                .addClass( value.submenu );
6684
        }
6685
        if ( key === "disabled" ) {
6686
            this.element
6687
                .toggleClass( "ui-state-disabled", !!value )
6688
                .attr( "aria-disabled", value );
6689
        }
6690
        this._super( key, value );
6691
    },
6692
6693
    focus: function( event, item ) {
6694
        var nested, focused;
6695
        this.blur( event, event && event.type === "focus" );
6696
6697
        this._scrollIntoView( item );
6698
6699
        this.active = item.first();
6700
        focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" );
6701
        // Only update aria-activedescendant if there's a role
6702
        // otherwise we assume focus is managed elsewhere
6703
        if ( this.options.role ) {
6704
            this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
6705
        }
6706
6707
        // Highlight active parent menu item, if any
6708
        this.active
6709
            .parent()
6710
            .closest( ".ui-menu-item" )
6711
            .addClass( "ui-state-active" );
6712
6713
        if ( event && event.type === "keydown" ) {
6714
            this._close();
6715
        } else {
6716
            this.timer = this._delay(function() {
6717
                this._close();
6718
            }, this.delay );
6719
        }
6720
6721
        nested = item.children( ".ui-menu" );
6722
        if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
6723
            this._startOpening(nested);
6724
        }
6725
        this.activeMenu = item.parent();
6726
6727
        this._trigger( "focus", event, { item: item } );
6728
    },
6729
6730
    _scrollIntoView: function( item ) {
6731
        var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
6732
        if ( this._hasScroll() ) {
6733
            borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
6734
            paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
6735
            offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
6736
            scroll = this.activeMenu.scrollTop();
6737
            elementHeight = this.activeMenu.height();
6738
            itemHeight = item.outerHeight();
6739
6740
            if ( offset < 0 ) {
6741
                this.activeMenu.scrollTop( scroll + offset );
6742
            } else if ( offset + itemHeight > elementHeight ) {
6743
                this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
6744
            }
6745
        }
6746
    },
6747
6748
    blur: function( event, fromFocus ) {
6749
        if ( !fromFocus ) {
6750
            clearTimeout( this.timer );
6751
        }
6752
6753
        if ( !this.active ) {
6754
            return;
6755
        }
6756
6757
        this.active.removeClass( "ui-state-focus" );
6758
        this.active = null;
6759
6760
        this._trigger( "blur", event, { item: this.active } );
6761
    },
6762
6763
    _startOpening: function( submenu ) {
6764
        clearTimeout( this.timer );
6765
6766
        // Don't open if already open fixes a Firefox bug that caused a .5 pixel
6767
        // shift in the submenu position when mousing over the carat icon
6768
        if ( submenu.attr( "aria-hidden" ) !== "true" ) {
6769
            return;
6770
        }
6771
6772
        this.timer = this._delay(function() {
6773
            this._close();
6774
            this._open( submenu );
6775
        }, this.delay );
6776
    },
6777
6778
    _open: function( submenu ) {
6779
        var position = $.extend({
6780
            of: this.active
6781
        }, this.options.position );
6782
6783
        clearTimeout( this.timer );
6784
        this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
6785
            .hide()
6786
            .attr( "aria-hidden", "true" );
6787
6788
        submenu
6789
            .show()
6790
            .removeAttr( "aria-hidden" )
6791
            .attr( "aria-expanded", "true" )
6792
            .position( position );
6793
    },
6794
6795
    collapseAll: function( event, all ) {
6796
        clearTimeout( this.timer );
6797
        this.timer = this._delay(function() {
6798
            // If we were passed an event, look for the submenu that contains the event
6799
            var currentMenu = all ? this.element :
6800
                $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
6801
6802
            // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
6803
            if ( !currentMenu.length ) {
6804
                currentMenu = this.element;
6805
            }
6806
6807
            this._close( currentMenu );
6808
6809
            this.blur( event );
6810
            this.activeMenu = currentMenu;
6811
        }, this.delay );
6812
    },
6813
6814
    // With no arguments, closes the currently active menu - if nothing is active
6815
    // it closes all menus.  If passed an argument, it will search for menus BELOW
6816
    _close: function( startMenu ) {
6817
        if ( !startMenu ) {
6818
            startMenu = this.active ? this.active.parent() : this.element;
6819
        }
6820
6821
        startMenu
6822
            .find( ".ui-menu" )
6823
                .hide()
6824
                .attr( "aria-hidden", "true" )
6825
                .attr( "aria-expanded", "false" )
6826
            .end()
6827
            .find( ".ui-state-active" ).not( ".ui-state-focus" )
6828
                .removeClass( "ui-state-active" );
6829
    },
6830
6831
    _closeOnDocumentClick: function( event ) {
6832
        return !$( event.target ).closest( ".ui-menu" ).length;
6833
    },
6834
6835
    _isDivider: function( item ) {
6836
6837
        // Match hyphen, em dash, en dash
6838
        return !/[^\-\u2014\u2013\s]/.test( item.text() );
6839
    },
6840
6841
    collapse: function( event ) {
6842
        var newItem = this.active &&
6843
            this.active.parent().closest( ".ui-menu-item", this.element );
6844
        if ( newItem && newItem.length ) {
6845
            this._close();
6846
            this.focus( event, newItem );
6847
        }
6848
    },
6849
6850
    expand: function( event ) {
6851
        var newItem = this.active &&
6852
            this.active
6853
                .children( ".ui-menu " )
6854
                .find( this.options.items )
6855
                .first();
6856
6857
        if ( newItem && newItem.length ) {
6858
            this._open( newItem.parent() );
6859
6860
            // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
6861
            this._delay(function() {
6862
                this.focus( event, newItem );
6863
            });
6864
        }
6865
    },
6866
6867
    next: function( event ) {
6868
        this._move( "next", "first", event );
6869
    },
6870
6871
    previous: function( event ) {
6872
        this._move( "prev", "last", event );
6873
    },
6874
6875
    isFirstItem: function() {
6876
        return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
6877
    },
6878
6879
    isLastItem: function() {
6880
        return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
6881
    },
6882
6883
    _move: function( direction, filter, event ) {
6884
        var next;
6885
        if ( this.active ) {
6886
            if ( direction === "first" || direction === "last" ) {
6887
                next = this.active
6888
                    [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
6889
                    .eq( -1 );
6890
            } else {
6891
                next = this.active
6892
                    [ direction + "All" ]( ".ui-menu-item" )
6893
                    .eq( 0 );
6894
            }
6895
        }
6896
        if ( !next || !next.length || !this.active ) {
6897
            next = this.activeMenu.find( this.options.items )[ filter ]();
6898
        }
6899
6900
        this.focus( event, next );
6901
    },
6902
6903
    nextPage: function( event ) {
6904
        var item, base, height;
6905
6906
        if ( !this.active ) {
6907
            this.next( event );
6908
            return;
6909
        }
6910
        if ( this.isLastItem() ) {
6911
            return;
6912
        }
6913
        if ( this._hasScroll() ) {
6914
            base = this.active.offset().top;
6915
            height = this.element.height();
6916
            this.active.nextAll( ".ui-menu-item" ).each(function() {
6917
                item = $( this );
6918
                return item.offset().top - base - height < 0;
6919
            });
6920
6921
            this.focus( event, item );
6922
        } else {
6923
            this.focus( event, this.activeMenu.find( this.options.items )
6924
                [ !this.active ? "first" : "last" ]() );
6925
        }
6926
    },
6927
6928
    previousPage: function( event ) {
6929
        var item, base, height;
6930
        if ( !this.active ) {
6931
            this.next( event );
6932
            return;
6933
        }
6934
        if ( this.isFirstItem() ) {
6935
            return;
6936
        }
6937
        if ( this._hasScroll() ) {
6938
            base = this.active.offset().top;
6939
            height = this.element.height();
6940
            this.active.prevAll( ".ui-menu-item" ).each(function() {
6941
                item = $( this );
6942
                return item.offset().top - base + height > 0;
6943
            });
6944
6945
            this.focus( event, item );
6946
        } else {
6947
            this.focus( event, this.activeMenu.find( this.options.items ).first() );
6948
        }
6949
    },
6950
6951
    _hasScroll: function() {
6952
        return this.element.outerHeight() < this.element.prop( "scrollHeight" );
6953
    },
6954
6955
    select: function( event ) {
6956
        // TODO: It should never be possible to not have an active item at this
6957
        // point, but the tests don't trigger mouseenter before click.
6958
        this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
6959
        var ui = { item: this.active };
6960
        if ( !this.active.has( ".ui-menu" ).length ) {
6961
            this.collapseAll( event, true );
6962
        }
6963
        this._trigger( "select", event, ui );
6964
    },
6965
6966
    _filterMenuItems: function(character) {
6967
        var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
6968
            regex = new RegExp( "^" + escapedCharacter, "i" );
6969
6970
        return this.activeMenu
6971
            .find( this.options.items )
6972
6973
            // Only match on items, not dividers or other content (#10571)
6974
            .filter( ".ui-menu-item" )
6975
            .filter(function() {
6976
                return regex.test( $.trim( $( this ).text() ) );
6977
            });
6978
    }
6979
});
6980
6981
6982
/*!
6983
 * jQuery UI Autocomplete 1.11.4
6984
 * http://jqueryui.com
6985
 *
6986
 * Copyright jQuery Foundation and other contributors
6987
 * Released under the MIT license.
6988
 * http://jquery.org/license
6989
 *
6990
 * http://api.jqueryui.com/autocomplete/
6991
 */
6992
6993
6994
$.widget( "ui.autocomplete", {
6995
    version: "1.11.4",
6996
    defaultElement: "<input>",
6997
    options: {
6998
        appendTo: null,
6999
        autoFocus: false,
7000
        delay: 300,
7001
        minLength: 1,
7002
        position: {
7003
            my: "left top",
7004
            at: "left bottom",
7005
            collision: "none"
7006
        },
7007
        source: null,
7008
7009
        // callbacks
7010
        change: null,
7011
        close: null,
7012
        focus: null,
7013
        open: null,
7014
        response: null,
7015
        search: null,
7016
        select: null
7017
    },
7018
7019
    requestIndex: 0,
7020
    pending: 0,
7021
7022
    _create: function() {
7023
        // Some browsers only repeat keydown events, not keypress events,
7024
        // so we use the suppressKeyPress flag to determine if we've already
7025
        // handled the keydown event. #7269
7026
        // Unfortunately the code for & in keypress is the same as the up arrow,
7027
        // so we use the suppressKeyPressRepeat flag to avoid handling keypress
7028
        // events when we know the keydown event was used to modify the
7029
        // search term. #7799
7030
        var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
7031
            nodeName = this.element[ 0 ].nodeName.toLowerCase(),
7032
            isTextarea = nodeName === "textarea",
7033
            isInput = nodeName === "input";
7034
7035
        this.isMultiLine =
7036
            // Textareas are always multi-line
7037
            isTextarea ? true :
7038
            // Inputs are always single-line, even if inside a contentEditable element
7039
            // IE also treats inputs as contentEditable
7040
            isInput ? false :
7041
            // All other element types are determined by whether or not they're contentEditable
7042
            this.element.prop( "isContentEditable" );
7043
7044
        this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
7045
        this.isNewMenu = true;
7046
7047
        this.element
7048
            .addClass( "ui-autocomplete-input" )
7049
            .attr( "autocomplete", "off" );
7050
7051
        this._on( this.element, {
7052
            keydown: function( event ) {
7053
                if ( this.element.prop( "readOnly" ) ) {
7054
                    suppressKeyPress = true;
7055
                    suppressInput = true;
7056
                    suppressKeyPressRepeat = true;
7057
                    return;
7058
                }
7059
7060
                suppressKeyPress = false;
7061
                suppressInput = false;
7062
                suppressKeyPressRepeat = false;
7063
                var keyCode = $.ui.keyCode;
7064
                switch ( event.keyCode ) {
7065
                case keyCode.PAGE_UP:
7066
                    suppressKeyPress = true;
7067
                    this._move( "previousPage", event );
7068
                    break;
7069
                case keyCode.PAGE_DOWN:
7070
                    suppressKeyPress = true;
7071
                    this._move( "nextPage", event );
7072
                    break;
7073
                case keyCode.UP:
7074
                    suppressKeyPress = true;
7075
                    this._keyEvent( "previous", event );
7076
                    break;
7077
                case keyCode.DOWN:
7078
                    suppressKeyPress = true;
7079
                    this._keyEvent( "next", event );
7080
                    break;
7081
                case keyCode.ENTER:
7082
                    // when menu is open and has focus
7083
                    if ( this.menu.active ) {
7084
                        // #6055 - Opera still allows the keypress to occur
7085
                        // which causes forms to submit
7086
                        suppressKeyPress = true;
7087
                        event.preventDefault();
7088
                        this.menu.select( event );
7089
                    }
7090
                    break;
7091
                case keyCode.TAB:
7092
                    if ( this.menu.active ) {
7093
                        this.menu.select( event );
7094
                    }
7095
                    break;
7096
                case keyCode.ESCAPE:
7097
                    if ( this.menu.element.is( ":visible" ) ) {
7098
                        if ( !this.isMultiLine ) {
7099
                            this._value( this.term );
7100
                        }
7101
                        this.close( event );
7102
                        // Different browsers have different default behavior for escape
7103
                        // Single press can mean undo or clear
7104
                        // Double press in IE means clear the whole form
7105
                        event.preventDefault();
7106
                    }
7107
                    break;
7108
                default:
7109
                    suppressKeyPressRepeat = true;
7110
                    // search timeout should be triggered before the input value is changed
7111
                    this._searchTimeout( event );
7112
                    break;
7113
                }
7114
            },
7115
            keypress: function( event ) {
7116
                if ( suppressKeyPress ) {
7117
                    suppressKeyPress = false;
7118
                    if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
7119
                        event.preventDefault();
7120
                    }
7121
                    return;
7122
                }
7123
                if ( suppressKeyPressRepeat ) {
7124
                    return;
7125
                }
7126
7127
                // replicate some key handlers to allow them to repeat in Firefox and Opera
7128
                var keyCode = $.ui.keyCode;
7129
                switch ( event.keyCode ) {
7130
                case keyCode.PAGE_UP:
7131
                    this._move( "previousPage", event );
7132
                    break;
7133
                case keyCode.PAGE_DOWN:
7134
                    this._move( "nextPage", event );
7135
                    break;
7136
                case keyCode.UP:
7137
                    this._keyEvent( "previous", event );
7138
                    break;
7139
                case keyCode.DOWN:
7140
                    this._keyEvent( "next", event );
7141
                    break;
7142
                }
7143
            },
7144
            input: function( event ) {
7145
                if ( suppressInput ) {
7146
                    suppressInput = false;
7147
                    event.preventDefault();
7148
                    return;
7149
                }
7150
                this._searchTimeout( event );
7151
            },
7152
            focus: function() {
7153
                this.selectedItem = null;
7154
                this.previous = this._value();
7155
            },
7156
            blur: function( event ) {
7157
                if ( this.cancelBlur ) {
7158
                    delete this.cancelBlur;
7159
                    return;
7160
                }
7161
7162
                clearTimeout( this.searching );
7163
                this.close( event );
7164
                this._change( event );
7165
            }
7166
        });
7167
7168
        this._initSource();
7169
        this.menu = $( "<ul>" )
7170
            .addClass( "ui-autocomplete ui-front" )
7171
            .appendTo( this._appendTo() )
7172
            .menu({
7173
                // disable ARIA support, the live region takes care of that
7174
                role: null
7175
            })
7176
            .hide()
7177
            .menu( "instance" );
7178
7179
        this._on( this.menu.element, {
7180
            mousedown: function( event ) {
7181
                // prevent moving focus out of the text field
7182
                event.preventDefault();
7183
7184
                // IE doesn't prevent moving focus even with event.preventDefault()
7185
                // so we set a flag to know when we should ignore the blur event
7186
                this.cancelBlur = true;
7187
                this._delay(function() {
7188
                    delete this.cancelBlur;
7189
                });
7190
7191
                // clicking on the scrollbar causes focus to shift to the body
7192
                // but we can't detect a mouseup or a click immediately afterward
7193
                // so we have to track the next mousedown and close the menu if
7194
                // the user clicks somewhere outside of the autocomplete
7195
                var menuElement = this.menu.element[ 0 ];
7196
                if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
7197
                    this._delay(function() {
7198
                        var that = this;
7199
                        this.document.one( "mousedown", function( event ) {
7200
                            if ( event.target !== that.element[ 0 ] &&
7201
                                    event.target !== menuElement &&
7202
                                    !$.contains( menuElement, event.target ) ) {
7203
                                that.close();
7204
                            }
7205
                        });
7206
                    });
7207
                }
7208
            },
7209
            menufocus: function( event, ui ) {
7210
                var label, item;
7211
                // support: Firefox
7212
                // Prevent accidental activation of menu items in Firefox (#7024 #9118)
7213
                if ( this.isNewMenu ) {
7214
                    this.isNewMenu = false;
7215
                    if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
7216
                        this.menu.blur();
7217
7218
                        this.document.one( "mousemove", function() {
7219
                            $( event.target ).trigger( event.originalEvent );
7220
                        });
7221
7222
                        return;
7223
                    }
7224
                }
7225
7226
                item = ui.item.data( "ui-autocomplete-item" );
7227
                if ( false !== this._trigger( "focus", event, { item: item } ) ) {
7228
                    // use value to match what will end up in the input, if it was a key event
7229
                    if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
7230
                        this._value( item.value );
7231
                    }
7232
                }
7233
7234
                // Announce the value in the liveRegion
7235
                label = ui.item.attr( "aria-label" ) || item.value;
7236
                if ( label && $.trim( label ).length ) {
7237
                    this.liveRegion.children().hide();
7238
                    $( "<div>" ).text( label ).appendTo( this.liveRegion );
7239
                }
7240
            },
7241
            menuselect: function( event, ui ) {
7242
                var item = ui.item.data( "ui-autocomplete-item" ),
7243
                    previous = this.previous;
7244
7245
                // only trigger when focus was lost (click on menu)
7246
                if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
7247
                    this.element.focus();
7248
                    this.previous = previous;
7249
                    // #6109 - IE triggers two focus events and the second
7250
                    // is asynchronous, so we need to reset the previous
7251
                    // term synchronously and asynchronously :-(
7252
                    this._delay(function() {
7253
                        this.previous = previous;
7254
                        this.selectedItem = item;
7255
                    });
7256
                }
7257
7258
                if ( false !== this._trigger( "select", event, { item: item } ) ) {
7259
                    this._value( item.value );
7260
                }
7261
                // reset the term after the select event
7262
                // this allows custom select handling to work properly
7263
                this.term = this._value();
7264
7265
                this.close( event );
7266
                this.selectedItem = item;
7267
            }
7268
        });
7269
7270
        this.liveRegion = $( "<span>", {
7271
                role: "status",
7272
                "aria-live": "assertive",
7273
                "aria-relevant": "additions"
7274
            })
7275
            .addClass( "ui-helper-hidden-accessible" )
7276
            .appendTo( this.document[ 0 ].body );
7277
7278
        // turning off autocomplete prevents the browser from remembering the
7279
        // value when navigating through history, so we re-enable autocomplete
7280
        // if the page is unloaded before the widget is destroyed. #7790
7281
        this._on( this.window, {
7282
            beforeunload: function() {
7283
                this.element.removeAttr( "autocomplete" );
7284
            }
7285
        });
7286
    },
7287
7288
    _destroy: function() {
7289
        clearTimeout( this.searching );
7290
        this.element
7291
            .removeClass( "ui-autocomplete-input" )
7292
            .removeAttr( "autocomplete" );
7293
        this.menu.element.remove();
7294
        this.liveRegion.remove();
7295
    },
7296
7297
    _setOption: function( key, value ) {
7298
        this._super( key, value );
7299
        if ( key === "source" ) {
7300
            this._initSource();
7301
        }
7302
        if ( key === "appendTo" ) {
7303
            this.menu.element.appendTo( this._appendTo() );
7304
        }
7305
        if ( key === "disabled" && value && this.xhr ) {
7306
            this.xhr.abort();
7307
        }
7308
    },
7309
7310
    _appendTo: function() {
7311
        var element = this.options.appendTo;
7312
7313
        if ( element ) {
7314
            element = element.jquery || element.nodeType ?
7315
                $( element ) :
7316
                this.document.find( element ).eq( 0 );
7317
        }
7318
7319
        if ( !element || !element[ 0 ] ) {
7320
            element = this.element.closest( ".ui-front" );
7321
        }
7322
7323
        if ( !element.length ) {
7324
            element = this.document[ 0 ].body;
7325
        }
7326
7327
        return element;
7328
    },
7329
7330
    _initSource: function() {
7331
        var array, url,
7332
            that = this;
7333
        if ( $.isArray( this.options.source ) ) {
7334
            array = this.options.source;
7335
            this.source = function( request, response ) {
7336
                response( $.ui.autocomplete.filter( array, request.term ) );
7337
            };
7338
        } else if ( typeof this.options.source === "string" ) {
7339
            url = this.options.source;
7340
            this.source = function( request, response ) {
7341
                if ( that.xhr ) {
7342
                    that.xhr.abort();
7343
                }
7344
                that.xhr = $.ajax({
7345
                    url: url,
7346
                    data: request,
7347
                    dataType: "json",
7348
                    success: function( data ) {
7349
                        response( data );
7350
                    },
7351
                    error: function() {
7352
                        response([]);
7353
                    }
7354
                });
7355
            };
7356
        } else {
7357
            this.source = this.options.source;
7358
        }
7359
    },
7360
7361
    _searchTimeout: function( event ) {
7362
        clearTimeout( this.searching );
7363
        this.searching = this._delay(function() {
7364
7365
            // Search if the value has changed, or if the user retypes the same value (see #7434)
7366
            var equalValues = this.term === this._value(),
7367
                menuVisible = this.menu.element.is( ":visible" ),
7368
                modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
7369
7370
            if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
7371
                this.selectedItem = null;
7372
                this.search( null, event );
7373
            }
7374
        }, this.options.delay );
7375
    },
7376
7377
    search: function( value, event ) {
7378
        value = value != null ? value : this._value();
7379
7380
        // always save the actual value, not the one passed as an argument
7381
        this.term = this._value();
7382
7383
        if ( value.length < this.options.minLength ) {
7384
            return this.close( event );
7385
        }
7386
7387
        if ( this._trigger( "search", event ) === false ) {
7388
            return;
7389
        }
7390
7391
        return this._search( value );
7392
    },
7393
7394
    _search: function( value ) {
7395
        this.pending++;
7396
        this.element.addClass( "ui-autocomplete-loading" );
7397
        this.cancelSearch = false;
7398
7399
        this.source( { term: value }, this._response() );
7400
    },
7401
7402
    _response: function() {
7403
        var index = ++this.requestIndex;
7404
7405
        return $.proxy(function( content ) {
7406
            if ( index === this.requestIndex ) {
7407
                this.__response( content );
7408
            }
7409
7410
            this.pending--;
7411
            if ( !this.pending ) {
7412
                this.element.removeClass( "ui-autocomplete-loading" );
7413
            }
7414
        }, this );
7415
    },
7416
7417
    __response: function( content ) {
7418
        if ( content ) {
7419
            content = this._normalize( content );
7420
        }
7421
        this._trigger( "response", null, { content: content } );
7422
        if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
7423
            this._suggest( content );
7424
            this._trigger( "open" );
7425
        } else {
7426
            // use ._close() instead of .close() so we don't cancel future searches
7427
            this._close();
7428
        }
7429
    },
7430
7431
    close: function( event ) {
7432
        this.cancelSearch = true;
7433
        this._close( event );
7434
    },
7435
7436
    _close: function( event ) {
7437
        if ( this.menu.element.is( ":visible" ) ) {
7438
            this.menu.element.hide();
7439
            this.menu.blur();
7440
            this.isNewMenu = true;
7441
            this._trigger( "close", event );
7442
        }
7443
    },
7444
7445
    _change: function( event ) {
7446
        if ( this.previous !== this._value() ) {
7447
            this._trigger( "change", event, { item: this.selectedItem } );
7448
        }
7449
    },
7450
7451
    _normalize: function( items ) {
7452
        // assume all items have the right format when the first item is complete
7453
        if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
7454
            return items;
7455
        }
7456
        return $.map( items, function( item ) {
7457
            if ( typeof item === "string" ) {
7458
                return {
7459
                    label: item,
7460
                    value: item
7461
                };
7462
            }
7463
            return $.extend( {}, item, {
7464
                label: item.label || item.value,
7465
                value: item.value || item.label
7466
            });
7467
        });
7468
    },
7469
7470
    _suggest: function( items ) {
7471
        var ul = this.menu.element.empty();
7472
        this._renderMenu( ul, items );
7473
        this.isNewMenu = true;
7474
        this.menu.refresh();
7475
7476
        // size and position menu
7477
        ul.show();
7478
        this._resizeMenu();
7479
        ul.position( $.extend({
7480
            of: this.element
7481
        }, this.options.position ) );
7482
7483
        if ( this.options.autoFocus ) {
7484
            this.menu.next();
7485
        }
7486
    },
7487
7488
    _resizeMenu: function() {
7489
        var ul = this.menu.element;
7490
        ul.outerWidth( Math.max(
7491
            // Firefox wraps long text (possibly a rounding bug)
7492
            // so we add 1px to avoid the wrapping (#7513)
7493
            ul.width( "" ).outerWidth() + 1,
7494
            this.element.outerWidth()
7495
        ) );
7496
    },
7497
7498
    _renderMenu: function( ul, items ) {
7499
        var that = this;
7500
        $.each( items, function( index, item ) {
7501
            that._renderItemData( ul, item );
7502
        });
7503
    },
7504
7505
    _renderItemData: function( ul, item ) {
7506
        return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
7507
    },
7508
7509
    _renderItem: function( ul, item ) {
7510
        return $( "<li>" ).text( item.label ).appendTo( ul );
7511
    },
7512
7513
    _move: function( direction, event ) {
7514
        if ( !this.menu.element.is( ":visible" ) ) {
7515
            this.search( null, event );
7516
            return;
7517
        }
7518
        if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
7519
                this.menu.isLastItem() && /^next/.test( direction ) ) {
7520
7521
            if ( !this.isMultiLine ) {
7522
                this._value( this.term );
7523
            }
7524
7525
            this.menu.blur();
7526
            return;
7527
        }
7528
        this.menu[ direction ]( event );
7529
    },
7530
7531
    widget: function() {
7532
        return this.menu.element;
7533
    },
7534
7535
    _value: function() {
7536
        return this.valueMethod.apply( this.element, arguments );
7537
    },
7538
7539
    _keyEvent: function( keyEvent, event ) {
7540
        if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
7541
            this._move( keyEvent, event );
7542
7543
            // prevents moving cursor to beginning/end of the text field in some browsers
7544
            event.preventDefault();
7545
        }
7546
    }
7547
});
7548
7549
$.extend( $.ui.autocomplete, {
7550
    escapeRegex: function( value ) {
7551
        return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
7552
    },
7553
    filter: function( array, term ) {
7554
        var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
7555
        return $.grep( array, function( value ) {
7556
            return matcher.test( value.label || value.value || value );
7557
        });
7558
    }
7559
});
7560
7561
// live region extension, adding a `messages` option
7562
// NOTE: This is an experimental API. We are still investigating
7563
// a full solution for string manipulation and internationalization.
7564
$.widget( "ui.autocomplete", $.ui.autocomplete, {
7565
    options: {
7566
        messages: {
7567
            noResults: "No search results.",
7568
            results: function( amount ) {
7569
                return amount + ( amount > 1 ? " results are" : " result is" ) +
7570
                    " available, use up and down arrow keys to navigate.";
7571
            }
7572
        }
7573
    },
7574
7575
    __response: function( content ) {
7576
        var message;
7577
        this._superApply( arguments );
7578
        if ( this.options.disabled || this.cancelSearch ) {
7579
            return;
7580
        }
7581
        if ( content && content.length ) {
7582
            message = this.options.messages.results( content.length );
7583
        } else {
7584
            message = this.options.messages.noResults;
7585
        }
7586
        this.liveRegion.children().hide();
7587
        $( "<div>" ).text( message ).appendTo( this.liveRegion );
7588
    }
7589
});
7590
7591
var autocomplete = $.ui.autocomplete;
7592
7593
7594
/*!
7595
 * jQuery UI Button 1.11.4
7596
 * http://jqueryui.com
7597
 *
7598
 * Copyright jQuery Foundation and other contributors
7599
 * Released under the MIT license.
7600
 * http://jquery.org/license
7601
 *
7602
 * http://api.jqueryui.com/button/
7603
 */
7604
7605
7606
var lastActive,
7607
    baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
7608
    typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
7609
    formResetHandler = function() {
7610
        var form = $( this );
7611
        setTimeout(function() {
7612
            form.find( ":ui-button" ).button( "refresh" );
7613
        }, 1 );
7614
    },
7615
    radioGroup = function( radio ) {
7616
        var name = radio.name,
7617
            form = radio.form,
7618
            radios = $( [] );
7619
        if ( name ) {
7620
            name = name.replace( /'/g, "\\'" );
7621
            if ( form ) {
7622
                radios = $( form ).find( "[name='" + name + "'][type=radio]" );
7623
            } else {
7624
                radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument )
7625
                    .filter(function() {
7626
                        return !this.form;
7627
                    });
7628
            }
7629
        }
7630
        return radios;
7631
    };
7632
7633
$.widget( "ui.button", {
7634
    version: "1.11.4",
7635
    defaultElement: "<button>",
7636
    options: {
7637
        disabled: null,
7638
        text: true,
7639
        label: null,
7640
        icons: {
7641
            primary: null,
7642
            secondary: null
7643
        }
7644
    },
7645
    _create: function() {
7646
        this.element.closest( "form" )
7647
            .unbind( "reset" + this.eventNamespace )
7648
            .bind( "reset" + this.eventNamespace, formResetHandler );
7649
7650
        if ( typeof this.options.disabled !== "boolean" ) {
7651
            this.options.disabled = !!this.element.prop( "disabled" );
7652
        } else {
7653
            this.element.prop( "disabled", this.options.disabled );
7654
        }
7655
7656
        this._determineButtonType();
7657
        this.hasTitle = !!this.buttonElement.attr( "title" );
7658
7659
        var that = this,
7660
            options = this.options,
7661
            toggleButton = this.type === "checkbox" || this.type === "radio",
7662
            activeClass = !toggleButton ? "ui-state-active" : "";
7663
7664
        if ( options.label === null ) {
7665
            options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
7666
        }
7667
7668
        this._hoverable( this.buttonElement );
7669
7670
        this.buttonElement
7671
            .addClass( baseClasses )
7672
            .attr( "role", "button" )
7673
            .bind( "mouseenter" + this.eventNamespace, function() {
7674
                if ( options.disabled ) {
7675
                    return;
7676
                }
7677
                if ( this === lastActive ) {
7678
                    $( this ).addClass( "ui-state-active" );
7679
                }
7680
            })
7681
            .bind( "mouseleave" + this.eventNamespace, function() {
7682
                if ( options.disabled ) {
7683
                    return;
7684
                }
7685
                $( this ).removeClass( activeClass );
7686
            })
7687
            .bind( "click" + this.eventNamespace, function( event ) {
7688
                if ( options.disabled ) {
7689
                    event.preventDefault();
7690
                    event.stopImmediatePropagation();
7691
                }
7692
            });
7693
7694
        // Can't use _focusable() because the element that receives focus
7695
        // and the element that gets the ui-state-focus class are different
7696
        this._on({
7697
            focus: function() {
7698
                this.buttonElement.addClass( "ui-state-focus" );
7699
            },
7700
            blur: function() {
7701
                this.buttonElement.removeClass( "ui-state-focus" );
7702
            }
7703
        });
7704
7705
        if ( toggleButton ) {
7706
            this.element.bind( "change" + this.eventNamespace, function() {
7707
                that.refresh();
7708
            });
7709
        }
7710
7711
        if ( this.type === "checkbox" ) {
7712
            this.buttonElement.bind( "click" + this.eventNamespace, function() {
7713
                if ( options.disabled ) {
7714
                    return false;
7715
                }
7716
            });
7717
        } else if ( this.type === "radio" ) {
7718
            this.buttonElement.bind( "click" + this.eventNamespace, function() {
7719
                if ( options.disabled ) {
7720
                    return false;
7721
                }
7722
                $( this ).addClass( "ui-state-active" );
7723
                that.buttonElement.attr( "aria-pressed", "true" );
7724
7725
                var radio = that.element[ 0 ];
7726
                radioGroup( radio )
7727
                    .not( radio )
7728
                    .map(function() {
7729
                        return $( this ).button( "widget" )[ 0 ];
7730
                    })
7731
                    .removeClass( "ui-state-active" )
7732
                    .attr( "aria-pressed", "false" );
7733
            });
7734
        } else {
7735
            this.buttonElement
7736
                .bind( "mousedown" + this.eventNamespace, function() {
7737
                    if ( options.disabled ) {
7738
                        return false;
7739
                    }
7740
                    $( this ).addClass( "ui-state-active" );
7741
                    lastActive = this;
7742
                    that.document.one( "mouseup", function() {
7743
                        lastActive = null;
7744
                    });
7745
                })
7746
                .bind( "mouseup" + this.eventNamespace, function() {
7747
                    if ( options.disabled ) {
7748
                        return false;
7749
                    }
7750
                    $( this ).removeClass( "ui-state-active" );
7751
                })
7752
                .bind( "keydown" + this.eventNamespace, function(event) {
7753
                    if ( options.disabled ) {
7754
                        return false;
7755
                    }
7756
                    if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
7757
                        $( this ).addClass( "ui-state-active" );
7758
                    }
7759
                })
7760
                // see #8559, we bind to blur here in case the button element loses
7761
                // focus between keydown and keyup, it would be left in an "active" state
7762
                .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
7763
                    $( this ).removeClass( "ui-state-active" );
7764
                });
7765
7766
            if ( this.buttonElement.is("a") ) {
7767
                this.buttonElement.keyup(function(event) {
7768
                    if ( event.keyCode === $.ui.keyCode.SPACE ) {
7769
                        // TODO pass through original event correctly (just as 2nd argument doesn't work)
7770
                        $( this ).click();
7771
                    }
7772
                });
7773
            }
7774
        }
7775
7776
        this._setOption( "disabled", options.disabled );
7777
        this._resetButton();
7778
    },
7779
7780
    _determineButtonType: function() {
7781
        var ancestor, labelSelector, checked;
7782
7783
        if ( this.element.is("[type=checkbox]") ) {
7784
            this.type = "checkbox";
7785
        } else if ( this.element.is("[type=radio]") ) {
7786
            this.type = "radio";
7787
        } else if ( this.element.is("input") ) {
7788
            this.type = "input";
7789
        } else {
7790
            this.type = "button";
7791
        }
7792
7793
        if ( this.type === "checkbox" || this.type === "radio" ) {
7794
            // we don't search against the document in case the element
7795
            // is disconnected from the DOM
7796
            ancestor = this.element.parents().last();
7797
            labelSelector = "label[for='" + this.element.attr("id") + "']";
7798
            this.buttonElement = ancestor.find( labelSelector );
7799
            if ( !this.buttonElement.length ) {
7800
                ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
7801
                this.buttonElement = ancestor.filter( labelSelector );
7802
                if ( !this.buttonElement.length ) {
7803
                    this.buttonElement = ancestor.find( labelSelector );
7804
                }
7805
            }
7806
            this.element.addClass( "ui-helper-hidden-accessible" );
7807
7808
            checked = this.element.is( ":checked" );
7809
            if ( checked ) {
7810
                this.buttonElement.addClass( "ui-state-active" );
7811
            }
7812
            this.buttonElement.prop( "aria-pressed", checked );
7813
        } else {
7814
            this.buttonElement = this.element;
7815
        }
7816
    },
7817
7818
    widget: function() {
7819
        return this.buttonElement;
7820
    },
7821
7822
    _destroy: function() {
7823
        this.element
7824
            .removeClass( "ui-helper-hidden-accessible" );
7825
        this.buttonElement
7826
            .removeClass( baseClasses + " ui-state-active " + typeClasses )
7827
            .removeAttr( "role" )
7828
            .removeAttr( "aria-pressed" )
7829
            .html( this.buttonElement.find(".ui-button-text").html() );
7830
7831
        if ( !this.hasTitle ) {
7832
            this.buttonElement.removeAttr( "title" );
7833
        }
7834
    },
7835
7836
    _setOption: function( key, value ) {
7837
        this._super( key, value );
7838
        if ( key === "disabled" ) {
7839
            this.widget().toggleClass( "ui-state-disabled", !!value );
7840
            this.element.prop( "disabled", !!value );
7841
            if ( value ) {
7842
                if ( this.type === "checkbox" || this.type === "radio" ) {
7843
                    this.buttonElement.removeClass( "ui-state-focus" );
7844
                } else {
7845
                    this.buttonElement.removeClass( "ui-state-focus ui-state-active" );
7846
                }
7847
            }
7848
            return;
7849
        }
7850
        this._resetButton();
7851
    },
7852
7853
    refresh: function() {
7854
        //See #8237 & #8828
7855
        var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
7856
7857
        if ( isDisabled !== this.options.disabled ) {
7858
            this._setOption( "disabled", isDisabled );
7859
        }
7860
        if ( this.type === "radio" ) {
7861
            radioGroup( this.element[0] ).each(function() {
7862
                if ( $( this ).is( ":checked" ) ) {
7863
                    $( this ).button( "widget" )
7864
                        .addClass( "ui-state-active" )
7865
                        .attr( "aria-pressed", "true" );
7866
                } else {
7867
                    $( this ).button( "widget" )
7868
                        .removeClass( "ui-state-active" )
7869
                        .attr( "aria-pressed", "false" );
7870
                }
7871
            });
7872
        } else if ( this.type === "checkbox" ) {
7873
            if ( this.element.is( ":checked" ) ) {
7874
                this.buttonElement
7875
                    .addClass( "ui-state-active" )
7876
                    .attr( "aria-pressed", "true" );
7877
            } else {
7878
                this.buttonElement
7879
                    .removeClass( "ui-state-active" )
7880
                    .attr( "aria-pressed", "false" );
7881
            }
7882
        }
7883
    },
7884
7885
    _resetButton: function() {
7886
        if ( this.type === "input" ) {
7887
            if ( this.options.label ) {
7888
                this.element.val( this.options.label );
7889
            }
7890
            return;
7891
        }
7892
        var buttonElement = this.buttonElement.removeClass( typeClasses ),
7893
            buttonText = $( "<span></span>", this.document[0] )
7894
                .addClass( "ui-button-text" )
7895
                .html( this.options.label )
7896
                .appendTo( buttonElement.empty() )
7897
                .text(),
7898
            icons = this.options.icons,
7899
            multipleIcons = icons.primary && icons.secondary,
7900
            buttonClasses = [];
7901
7902
        if ( icons.primary || icons.secondary ) {
7903
            if ( this.options.text ) {
7904
                buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
7905
            }
7906
7907
            if ( icons.primary ) {
7908
                buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
7909
            }
7910
7911
            if ( icons.secondary ) {
7912
                buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
7913
            }
7914
7915
            if ( !this.options.text ) {
7916
                buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
7917
7918
                if ( !this.hasTitle ) {
7919
                    buttonElement.attr( "title", $.trim( buttonText ) );
7920
                }
7921
            }
7922
        } else {
7923
            buttonClasses.push( "ui-button-text-only" );
7924
        }
7925
        buttonElement.addClass( buttonClasses.join( " " ) );
7926
    }
7927
});
7928
7929
$.widget( "ui.buttonset", {
7930
    version: "1.11.4",
7931
    options: {
7932
        items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
7933
    },
7934
7935
    _create: function() {
7936
        this.element.addClass( "ui-buttonset" );
7937
    },
7938
7939
    _init: function() {
7940
        this.refresh();
7941
    },
7942
7943
    _setOption: function( key, value ) {
7944
        if ( key === "disabled" ) {
7945
            this.buttons.button( "option", key, value );
7946
        }
7947
7948
        this._super( key, value );
7949
    },
7950
7951
    refresh: function() {
7952
        var rtl = this.element.css( "direction" ) === "rtl",
7953
            allButtons = this.element.find( this.options.items ),
7954
            existingButtons = allButtons.filter( ":ui-button" );
7955
7956
        // Initialize new buttons
7957
        allButtons.not( ":ui-button" ).button();
7958
7959
        // Refresh existing buttons
7960
        existingButtons.button( "refresh" );
7961
7962
        this.buttons = allButtons
7963
            .map(function() {
7964
                return $( this ).button( "widget" )[ 0 ];
7965
            })
7966
                .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
7967
                .filter( ":first" )
7968
                    .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
7969
                .end()
7970
                .filter( ":last" )
7971
                    .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
7972
                .end()
7973
            .end();
7974
    },
7975
7976
    _destroy: function() {
7977
        this.element.removeClass( "ui-buttonset" );
7978
        this.buttons
7979
            .map(function() {
7980
                return $( this ).button( "widget" )[ 0 ];
7981
            })
7982
                .removeClass( "ui-corner-left ui-corner-right" )
7983
            .end()
7984
            .button( "destroy" );
7985
    }
7986
});
7987
7988
var button = $.ui.button;
7989
7990
7991
/*!
7992
 * jQuery UI Dialog 1.11.4
7993
 * http://jqueryui.com
7994
 *
7995
 * Copyright jQuery Foundation and other contributors
7996
 * Released under the MIT license.
7997
 * http://jquery.org/license
7998
 *
7999
 * http://api.jqueryui.com/dialog/
8000
 */
8001
8002
8003
var dialog = $.widget( "ui.dialog", {
8004
    version: "1.11.4",
8005
    options: {
8006
        appendTo: "body",
8007
        autoOpen: true,
8008
        buttons: [],
8009
        closeOnEscape: true,
8010
        closeText: "Close",
8011
        dialogClass: "",
8012
        draggable: true,
8013
        hide: null,
8014
        height: "auto",
8015
        maxHeight: null,
8016
        maxWidth: null,
8017
        minHeight: 150,
8018
        minWidth: 150,
8019
        modal: false,
8020
        position: {
8021
            my: "center",
8022
            at: "center",
8023
            of: window,
8024
            collision: "fit",
8025
            // Ensure the titlebar is always visible
8026
            using: function( pos ) {
8027
                var topOffset = $( this ).css( pos ).offset().top;
8028
                if ( topOffset < 0 ) {
8029
                    $( this ).css( "top", pos.top - topOffset );
8030
                }
8031
            }
8032
        },
8033
        resizable: true,
8034
        show: null,
8035
        title: null,
8036
        width: 300,
8037
8038
        // callbacks
8039
        beforeClose: null,
8040
        close: null,
8041
        drag: null,
8042
        dragStart: null,
8043
        dragStop: null,
8044
        focus: null,
8045
        open: null,
8046
        resize: null,
8047
        resizeStart: null,
8048
        resizeStop: null
8049
    },
8050
8051
    sizeRelatedOptions: {
8052
        buttons: true,
8053
        height: true,
8054
        maxHeight: true,
8055
        maxWidth: true,
8056
        minHeight: true,
8057
        minWidth: true,
8058
        width: true
8059
    },
8060
8061
    resizableRelatedOptions: {
8062
        maxHeight: true,
8063
        maxWidth: true,
8064
        minHeight: true,
8065
        minWidth: true
8066
    },
8067
8068
    _create: function() {
8069
        this.originalCss = {
8070
            display: this.element[ 0 ].style.display,
8071
            width: this.element[ 0 ].style.width,
8072
            minHeight: this.element[ 0 ].style.minHeight,
8073
            maxHeight: this.element[ 0 ].style.maxHeight,
8074
            height: this.element[ 0 ].style.height
8075
        };
8076
        this.originalPosition = {
8077
            parent: this.element.parent(),
8078
            index: this.element.parent().children().index( this.element )
8079
        };
8080
        this.originalTitle = this.element.attr( "title" );
8081
        this.options.title = this.options.title || this.originalTitle;
8082
8083
        this._createWrapper();
8084
8085
        this.element
8086
            .show()
8087
            .removeAttr( "title" )
8088
            .addClass( "ui-dialog-content ui-widget-content" )
8089
            .appendTo( this.uiDialog );
8090
8091
        this._createTitlebar();
8092
        this._createButtonPane();
8093
8094
        if ( this.options.draggable && $.fn.draggable ) {
8095
            this._makeDraggable();
8096
        }
8097
        if ( this.options.resizable && $.fn.resizable ) {
8098
            this._makeResizable();
8099
        }
8100
8101
        this._isOpen = false;
8102
8103
        this._trackFocus();
8104
    },
8105
8106
    _init: function() {
8107
        if ( this.options.autoOpen ) {
8108
            this.open();
8109
        }
8110
    },
8111
8112
    _appendTo: function() {
8113
        var element = this.options.appendTo;
8114
        if ( element && (element.jquery || element.nodeType) ) {
8115
            return $( element );
8116
        }
8117
        return this.document.find( element || "body" ).eq( 0 );
8118
    },
8119
8120
    _destroy: function() {
8121
        var next,
8122
            originalPosition = this.originalPosition;
8123
8124
        this._untrackInstance();
8125
        this._destroyOverlay();
8126
8127
        this.element
8128
            .removeUniqueId()
8129
            .removeClass( "ui-dialog-content ui-widget-content" )
8130
            .css( this.originalCss )
8131
            // Without detaching first, the following becomes really slow
8132
            .detach();
8133
8134
        this.uiDialog.stop( true, true ).remove();
8135
8136
        if ( this.originalTitle ) {
8137
            this.element.attr( "title", this.originalTitle );
8138
        }
8139
8140
        next = originalPosition.parent.children().eq( originalPosition.index );
8141
        // Don't try to place the dialog next to itself (#8613)
8142
        if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
8143
            next.before( this.element );
8144
        } else {
8145
            originalPosition.parent.append( this.element );
8146
        }
8147
    },
8148
8149
    widget: function() {
8150
        return this.uiDialog;
8151
    },
8152
8153
    disable: $.noop,
8154
    enable: $.noop,
8155
8156
    close: function( event ) {
8157
        var activeElement,
8158
            that = this;
8159
8160
        if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
8161
            return;
8162
        }
8163
8164
        this._isOpen = false;
8165
        this._focusedElement = null;
8166
        this._destroyOverlay();
8167
        this._untrackInstance();
8168
8169
        if ( !this.opener.filter( ":focusable" ).focus().length ) {
8170
8171
            // support: IE9
8172
            // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
8173
            try {
8174
                activeElement = this.document[ 0 ].activeElement;
8175
8176
                // Support: IE9, IE10
8177
                // If the <body> is blurred, IE will switch windows, see #4520
8178
                if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {
8179
8180
                    // Hiding a focused element doesn't trigger blur in WebKit
8181
                    // so in case we have nothing to focus on, explicitly blur the active element
8182
                    // https://bugs.webkit.org/show_bug.cgi?id=47182
8183
                    $( activeElement ).blur();
8184
                }
8185
            } catch ( error ) {}
8186
        }
8187
8188
        this._hide( this.uiDialog, this.options.hide, function() {
8189
            that._trigger( "close", event );
8190
        });
8191
    },
8192
8193
    isOpen: function() {
8194
        return this._isOpen;
8195
    },
8196
8197
    moveToTop: function() {
8198
        this._moveToTop();
8199
    },
8200
8201
    _moveToTop: function( event, silent ) {
8202
        var moved = false,
8203
            zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map(function() {
8204
                return +$( this ).css( "z-index" );
8205
            }).get(),
8206
            zIndexMax = Math.max.apply( null, zIndices );
8207
8208
        if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
8209
            this.uiDialog.css( "z-index", zIndexMax + 1 );
8210
            moved = true;
8211
        }
8212
8213
        if ( moved && !silent ) {
8214
            this._trigger( "focus", event );
8215
        }
8216
        return moved;
8217
    },
8218
8219
    open: function() {
8220
        var that = this;
8221
        if ( this._isOpen ) {
8222
            if ( this._moveToTop() ) {
8223
                this._focusTabbable();
8224
            }
8225
            return;
8226
        }
8227
8228
        this._isOpen = true;
8229
        this.opener = $( this.document[ 0 ].activeElement );
8230
8231
        this._size();
8232
        this._position();
8233
        this._createOverlay();
8234
        this._moveToTop( null, true );
8235
8236
        // Ensure the overlay is moved to the top with the dialog, but only when
8237
        // opening. The overlay shouldn't move after the dialog is open so that
8238
        // modeless dialogs opened after the modal dialog stack properly.
8239
        if ( this.overlay ) {
8240
            this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
8241
        }
8242
8243
        this._show( this.uiDialog, this.options.show, function() {
8244
            that._focusTabbable();
8245
            that._trigger( "focus" );
8246
        });
8247
8248
        // Track the dialog immediately upon openening in case a focus event
8249
        // somehow occurs outside of the dialog before an element inside the
8250
        // dialog is focused (#10152)
8251
        this._makeFocusTarget();
8252
8253
        this._trigger( "open" );
8254
    },
8255
8256
    _focusTabbable: function() {
8257
        // Set focus to the first match:
8258
        // 1. An element that was focused previously
8259
        // 2. First element inside the dialog matching [autofocus]
8260
        // 3. Tabbable element inside the content element
8261
        // 4. Tabbable element inside the buttonpane
8262
        // 5. The close button
8263
        // 6. The dialog itself
8264
        var hasFocus = this._focusedElement;
8265
        if ( !hasFocus ) {
8266
            hasFocus = this.element.find( "[autofocus]" );
8267
        }
8268
        if ( !hasFocus.length ) {
8269
            hasFocus = this.element.find( ":tabbable" );
8270
        }
8271
        if ( !hasFocus.length ) {
8272
            hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
8273
        }
8274
        if ( !hasFocus.length ) {
8275
            hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
8276
        }
8277
        if ( !hasFocus.length ) {
8278
            hasFocus = this.uiDialog;
8279
        }
8280
        hasFocus.eq( 0 ).focus();
8281
    },
8282
8283
    _keepFocus: function( event ) {
8284
        function checkFocus() {
8285
            var activeElement = this.document[0].activeElement,
8286
                isActive = this.uiDialog[0] === activeElement ||
8287
                    $.contains( this.uiDialog[0], activeElement );
8288
            if ( !isActive ) {
8289
                this._focusTabbable();
8290
            }
8291
        }
8292
        event.preventDefault();
8293
        checkFocus.call( this );
8294
        // support: IE
8295
        // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
8296
        // so we check again later
8297
        this._delay( checkFocus );
8298
    },
8299
8300
    _createWrapper: function() {
8301
        this.uiDialog = $("<div>")
8302
            .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
8303
                this.options.dialogClass )
8304
            .hide()
8305
            .attr({
8306
                // Setting tabIndex makes the div focusable
8307
                tabIndex: -1,
8308
                role: "dialog"
8309
            })
8310
            .appendTo( this._appendTo() );
8311
8312
        this._on( this.uiDialog, {
8313
            keydown: function( event ) {
8314
                if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
8315
                        event.keyCode === $.ui.keyCode.ESCAPE ) {
8316
                    event.preventDefault();
8317
                    this.close( event );
8318
                    return;
8319
                }
8320
8321
                // prevent tabbing out of dialogs
8322
                if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
8323
                    return;
8324
                }
8325
                var tabbables = this.uiDialog.find( ":tabbable" ),
8326
                    first = tabbables.filter( ":first" ),
8327
                    last = tabbables.filter( ":last" );
8328
8329
                if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
8330
                    this._delay(function() {
8331
                        first.focus();
8332
                    });
8333
                    event.preventDefault();
8334
                } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
8335
                    this._delay(function() {
8336
                        last.focus();
8337
                    });
8338
                    event.preventDefault();
8339
                }
8340
            },
8341
            mousedown: function( event ) {
8342
                if ( this._moveToTop( event ) ) {
8343
                    this._focusTabbable();
8344
                }
8345
            }
8346
        });
8347
8348
        // We assume that any existing aria-describedby attribute means
8349
        // that the dialog content is marked up properly
8350
        // otherwise we brute force the content as the description
8351
        if ( !this.element.find( "[aria-describedby]" ).length ) {
8352
            this.uiDialog.attr({
8353
                "aria-describedby": this.element.uniqueId().attr( "id" )
8354
            });
8355
        }
8356
    },
8357
8358
    _createTitlebar: function() {
8359
        var uiDialogTitle;
8360
8361
        this.uiDialogTitlebar = $( "<div>" )
8362
            .addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" )
8363
            .prependTo( this.uiDialog );
8364
        this._on( this.uiDialogTitlebar, {
8365
            mousedown: function( event ) {
8366
                // Don't prevent click on close button (#8838)
8367
                // Focusing a dialog that is partially scrolled out of view
8368
                // causes the browser to scroll it into view, preventing the click event
8369
                if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
8370
                    // Dialog isn't getting focus when dragging (#8063)
8371
                    this.uiDialog.focus();
8372
                }
8373
            }
8374
        });
8375
8376
        // support: IE
8377
        // Use type="button" to prevent enter keypresses in textboxes from closing the
8378
        // dialog in IE (#9312)
8379
        this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
8380
            .button({
8381
                label: this.options.closeText,
8382
                icons: {
8383
                    primary: "ui-icon-closethick"
8384
                },
8385
                text: false
8386
            })
8387
            .addClass( "ui-dialog-titlebar-close" )
8388
            .appendTo( this.uiDialogTitlebar );
8389
        this._on( this.uiDialogTitlebarClose, {
8390
            click: function( event ) {
8391
                event.preventDefault();
8392
                this.close( event );
8393
            }
8394
        });
8395
8396
        uiDialogTitle = $( "<span>" )
8397
            .uniqueId()
8398
            .addClass( "ui-dialog-title" )
8399
            .prependTo( this.uiDialogTitlebar );
8400
        this._title( uiDialogTitle );
8401
8402
        this.uiDialog.attr({
8403
            "aria-labelledby": uiDialogTitle.attr( "id" )
8404
        });
8405
    },
8406
8407
    _title: function( title ) {
8408
        if ( !this.options.title ) {
8409
            title.html( "&#160;" );
8410
        }
8411
        title.text( this.options.title );
8412
    },
8413
8414
    _createButtonPane: function() {
8415
        this.uiDialogButtonPane = $( "<div>" )
8416
            .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
8417
8418
        this.uiButtonSet = $( "<div>" )
8419
            .addClass( "ui-dialog-buttonset" )
8420
            .appendTo( this.uiDialogButtonPane );
8421
8422
        this._createButtons();
8423
    },
8424
8425
    _createButtons: function() {
8426
        var that = this,
8427
            buttons = this.options.buttons;
8428
8429
        // if we already have a button pane, remove it
8430
        this.uiDialogButtonPane.remove();
8431
        this.uiButtonSet.empty();
8432
8433
        if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
8434
            this.uiDialog.removeClass( "ui-dialog-buttons" );
8435
            return;
8436
        }
8437
8438
        $.each( buttons, function( name, props ) {
8439
            var click, buttonOptions;
8440
            props = $.isFunction( props ) ?
8441
                { click: props, text: name } :
8442
                props;
8443
            // Default to a non-submitting button
8444
            props = $.extend( { type: "button" }, props );
8445
            // Change the context for the click callback to be the main element
8446
            click = props.click;
8447
            props.click = function() {
8448
                click.apply( that.element[ 0 ], arguments );
8449
            };
8450
            buttonOptions = {
8451
                icons: props.icons,
8452
                text: props.showText
8453
            };
8454
            delete props.icons;
8455
            delete props.showText;
8456
            $( "<button></button>", props )
8457
                .button( buttonOptions )
8458
                .appendTo( that.uiButtonSet );
8459
        });
8460
        this.uiDialog.addClass( "ui-dialog-buttons" );
8461
        this.uiDialogButtonPane.appendTo( this.uiDialog );
8462
    },
8463
8464
    _makeDraggable: function() {
8465
        var that = this,
8466
            options = this.options;
8467
8468
        function filteredUi( ui ) {
8469
            return {
8470
                position: ui.position,
8471
                offset: ui.offset
8472
            };
8473
        }
8474
8475
        this.uiDialog.draggable({
8476
            cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
8477
            handle: ".ui-dialog-titlebar",
8478
            containment: "document",
8479
            start: function( event, ui ) {
8480
                $( this ).addClass( "ui-dialog-dragging" );
8481
                that._blockFrames();
8482
                that._trigger( "dragStart", event, filteredUi( ui ) );
8483
            },
8484
            drag: function( event, ui ) {
8485
                that._trigger( "drag", event, filteredUi( ui ) );
8486
            },
8487
            stop: function( event, ui ) {
8488
                var left = ui.offset.left - that.document.scrollLeft(),
8489
                    top = ui.offset.top - that.document.scrollTop();
8490
8491
                options.position = {
8492
                    my: "left top",
8493
                    at: "left" + (left >= 0 ? "+" : "") + left + " " +
8494
                        "top" + (top >= 0 ? "+" : "") + top,
8495
                    of: that.window
8496
                };
8497
                $( this ).removeClass( "ui-dialog-dragging" );
8498
                that._unblockFrames();
8499
                that._trigger( "dragStop", event, filteredUi( ui ) );
8500
            }
8501
        });
8502
    },
8503
8504
    _makeResizable: function() {
8505
        var that = this,
8506
            options = this.options,
8507
            handles = options.resizable,
8508
            // .ui-resizable has position: relative defined in the stylesheet
8509
            // but dialogs have to use absolute or fixed positioning
8510
            position = this.uiDialog.css("position"),
8511
            resizeHandles = typeof handles === "string" ?
8512
                handles :
8513
                "n,e,s,w,se,sw,ne,nw";
8514
8515
        function filteredUi( ui ) {
8516
            return {
8517
                originalPosition: ui.originalPosition,
8518
                originalSize: ui.originalSize,
8519
                position: ui.position,
8520
                size: ui.size
8521
            };
8522
        }
8523
8524
        this.uiDialog.resizable({
8525
            cancel: ".ui-dialog-content",
8526
            containment: "document",
8527
            alsoResize: this.element,
8528
            maxWidth: options.maxWidth,
8529
            maxHeight: options.maxHeight,
8530
            minWidth: options.minWidth,
8531
            minHeight: this._minHeight(),
8532
            handles: resizeHandles,
8533
            start: function( event, ui ) {
8534
                $( this ).addClass( "ui-dialog-resizing" );
8535
                that._blockFrames();
8536
                that._trigger( "resizeStart", event, filteredUi( ui ) );
8537
            },
8538
            resize: function( event, ui ) {
8539
                that._trigger( "resize", event, filteredUi( ui ) );
8540
            },
8541
            stop: function( event, ui ) {
8542
                var offset = that.uiDialog.offset(),
8543
                    left = offset.left - that.document.scrollLeft(),
8544
                    top = offset.top - that.document.scrollTop();
8545
8546
                options.height = that.uiDialog.height();
8547
                options.width = that.uiDialog.width();
8548
                options.position = {
8549
                    my: "left top",
8550
                    at: "left" + (left >= 0 ? "+" : "") + left + " " +
8551
                        "top" + (top >= 0 ? "+" : "") + top,
8552
                    of: that.window
8553
                };
8554
                $( this ).removeClass( "ui-dialog-resizing" );
8555
                that._unblockFrames();
8556
                that._trigger( "resizeStop", event, filteredUi( ui ) );
8557
            }
8558
        })
8559
        .css( "position", position );
8560
    },
8561
8562
    _trackFocus: function() {
8563
        this._on( this.widget(), {
8564
            focusin: function( event ) {
8565
                this._makeFocusTarget();
8566
                this._focusedElement = $( event.target );
8567
            }
8568
        });
8569
    },
8570
8571
    _makeFocusTarget: function() {
8572
        this._untrackInstance();
8573
        this._trackingInstances().unshift( this );
8574
    },
8575
8576
    _untrackInstance: function() {
8577
        var instances = this._trackingInstances(),
8578
            exists = $.inArray( this, instances );
8579
        if ( exists !== -1 ) {
8580
            instances.splice( exists, 1 );
8581
        }
8582
    },
8583
8584
    _trackingInstances: function() {
8585
        var instances = this.document.data( "ui-dialog-instances" );
8586
        if ( !instances ) {
8587
            instances = [];
8588
            this.document.data( "ui-dialog-instances", instances );
8589
        }
8590
        return instances;
8591
    },
8592
8593
    _minHeight: function() {
8594
        var options = this.options;
8595
8596
        return options.height === "auto" ?
8597
            options.minHeight :
8598
            Math.min( options.minHeight, options.height );
8599
    },
8600
8601
    _position: function() {
8602
        // Need to show the dialog to get the actual offset in the position plugin
8603
        var isVisible = this.uiDialog.is( ":visible" );
8604
        if ( !isVisible ) {
8605
            this.uiDialog.show();
8606
        }
8607
        this.uiDialog.position( this.options.position );
8608
        if ( !isVisible ) {
8609
            this.uiDialog.hide();
8610
        }
8611
    },
8612
8613
    _setOptions: function( options ) {
8614
        var that = this,
8615
            resize = false,
8616
            resizableOptions = {};
8617
8618
        $.each( options, function( key, value ) {
8619
            that._setOption( key, value );
8620
8621
            if ( key in that.sizeRelatedOptions ) {
8622
                resize = true;
8623
            }
8624
            if ( key in that.resizableRelatedOptions ) {
8625
                resizableOptions[ key ] = value;
8626
            }
8627
        });
8628
8629
        if ( resize ) {
8630
            this._size();
8631
            this._position();
8632
        }
8633
        if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
8634
            this.uiDialog.resizable( "option", resizableOptions );
8635
        }
8636
    },
8637
8638
    _setOption: function( key, value ) {
8639
        var isDraggable, isResizable,
8640
            uiDialog = this.uiDialog;
8641
8642
        if ( key === "dialogClass" ) {
8643
            uiDialog
8644
                .removeClass( this.options.dialogClass )
8645
                .addClass( value );
8646
        }
8647
8648
        if ( key === "disabled" ) {
8649
            return;
8650
        }
8651
8652
        this._super( key, value );
8653
8654
        if ( key === "appendTo" ) {
8655
            this.uiDialog.appendTo( this._appendTo() );
8656
        }
8657
8658
        if ( key === "buttons" ) {
8659
            this._createButtons();
8660
        }
8661
8662
        if ( key === "closeText" ) {
8663
            this.uiDialogTitlebarClose.button({
8664
                // Ensure that we always pass a string
8665
                label: "" + value
8666
            });
8667
        }
8668
8669
        if ( key === "draggable" ) {
8670
            isDraggable = uiDialog.is( ":data(ui-draggable)" );
8671
            if ( isDraggable && !value ) {
8672
                uiDialog.draggable( "destroy" );
8673
            }
8674
8675
            if ( !isDraggable && value ) {
8676
                this._makeDraggable();
8677
            }
8678
        }
8679
8680
        if ( key === "position" ) {
8681
            this._position();
8682
        }
8683
8684
        if ( key === "resizable" ) {
8685
            // currently resizable, becoming non-resizable
8686
            isResizable = uiDialog.is( ":data(ui-resizable)" );
8687
            if ( isResizable && !value ) {
8688
                uiDialog.resizable( "destroy" );
8689
            }
8690
8691
            // currently resizable, changing handles
8692
            if ( isResizable && typeof value === "string" ) {
8693
                uiDialog.resizable( "option", "handles", value );
8694
            }
8695
8696
            // currently non-resizable, becoming resizable
8697
            if ( !isResizable && value !== false ) {
8698
                this._makeResizable();
8699
            }
8700
        }
8701
8702
        if ( key === "title" ) {
8703
            this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
8704
        }
8705
    },
8706
8707
    _size: function() {
8708
        // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
8709
        // divs will both have width and height set, so we need to reset them
8710
        var nonContentHeight, minContentHeight, maxContentHeight,
8711
            options = this.options;
8712
8713
        // Reset content sizing
8714
        this.element.show().css({
8715
            width: "auto",
8716
            minHeight: 0,
8717
            maxHeight: "none",
8718
            height: 0
8719
        });
8720
8721
        if ( options.minWidth > options.width ) {
8722
            options.width = options.minWidth;
8723
        }
8724
8725
        // reset wrapper sizing
8726
        // determine the height of all the non-content elements
8727
        nonContentHeight = this.uiDialog.css({
8728
                height: "auto",
8729
                width: options.width
8730
            })
8731
            .outerHeight();
8732
        minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
8733
        maxContentHeight = typeof options.maxHeight === "number" ?
8734
            Math.max( 0, options.maxHeight - nonContentHeight ) :
8735
            "none";
8736
8737
        if ( options.height === "auto" ) {
8738
            this.element.css({
8739
                minHeight: minContentHeight,
8740
                maxHeight: maxContentHeight,
8741
                height: "auto"
8742
            });
8743
        } else {
8744
            this.element.height( Math.max( 0, options.height - nonContentHeight ) );
8745
        }
8746
8747
        if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
8748
            this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
8749
        }
8750
    },
8751
8752
    _blockFrames: function() {
8753
        this.iframeBlocks = this.document.find( "iframe" ).map(function() {
8754
            var iframe = $( this );
8755
8756
            return $( "<div>" )
8757
                .css({
8758
                    position: "absolute",
8759
                    width: iframe.outerWidth(),
8760
                    height: iframe.outerHeight()
8761
                })
8762
                .appendTo( iframe.parent() )
8763
                .offset( iframe.offset() )[0];
8764
        });
8765
    },
8766
8767
    _unblockFrames: function() {
8768
        if ( this.iframeBlocks ) {
8769
            this.iframeBlocks.remove();
8770
            delete this.iframeBlocks;
8771
        }
8772
    },
8773
8774
    _allowInteraction: function( event ) {
8775
        if ( $( event.target ).closest( ".ui-dialog" ).length ) {
8776
            return true;
8777
        }
8778
8779
        // TODO: Remove hack when datepicker implements
8780
        // the .ui-front logic (#8989)
8781
        return !!$( event.target ).closest( ".ui-datepicker" ).length;
8782
    },
8783
8784
    _createOverlay: function() {
8785
        if ( !this.options.modal ) {
8786
            return;
8787
        }
8788
8789
        // We use a delay in case the overlay is created from an
8790
        // event that we're going to be cancelling (#2804)
8791
        var isOpening = true;
8792
        this._delay(function() {
8793
            isOpening = false;
8794
        });
8795
8796
        if ( !this.document.data( "ui-dialog-overlays" ) ) {
8797
8798
            // Prevent use of anchors and inputs
8799
            // Using _on() for an event handler shared across many instances is
8800
            // safe because the dialogs stack and must be closed in reverse order
8801
            this._on( this.document, {
8802
                focusin: function( event ) {
8803
                    if ( isOpening ) {
8804
                        return;
8805
                    }
8806
8807
                    if ( !this._allowInteraction( event ) ) {
8808
                        event.preventDefault();
8809
                        this._trackingInstances()[ 0 ]._focusTabbable();
8810
                    }
8811
                }
8812
            });
8813
        }
8814
8815
        this.overlay = $( "<div>" )
8816
            .addClass( "ui-widget-overlay ui-front" )
8817
            .appendTo( this._appendTo() );
8818
        this._on( this.overlay, {
8819
            mousedown: "_keepFocus"
8820
        });
8821
        this.document.data( "ui-dialog-overlays",
8822
            (this.document.data( "ui-dialog-overlays" ) || 0) + 1 );
8823
    },
8824
8825
    _destroyOverlay: function() {
8826
        if ( !this.options.modal ) {
8827
            return;
8828
        }
8829
8830
        if ( this.overlay ) {
8831
            var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
8832
8833
            if ( !overlays ) {
8834
                this.document
8835
                    .unbind( "focusin" )
8836
                    .removeData( "ui-dialog-overlays" );
8837
            } else {
8838
                this.document.data( "ui-dialog-overlays", overlays );
8839
            }
8840
8841
            this.overlay.remove();
8842
            this.overlay = null;
8843
        }
8844
    }
8845
});
8846
8847
8848
/*!
8849
 * jQuery UI Progressbar 1.11.4
8850
 * http://jqueryui.com
8851
 *
8852
 * Copyright jQuery Foundation and other contributors
8853
 * Released under the MIT license.
8854
 * http://jquery.org/license
8855
 *
8856
 * http://api.jqueryui.com/progressbar/
8857
 */
8858
8859
8860
var progressbar = $.widget( "ui.progressbar", {
8861
    version: "1.11.4",
8862
    options: {
8863
        max: 100,
8864
        value: 0,
8865
8866
        change: null,
8867
        complete: null
8868
    },
8869
8870
    min: 0,
8871
8872
    _create: function() {
8873
        // Constrain initial value
8874
        this.oldValue = this.options.value = this._constrainedValue();
8875
8876
        this.element
8877
            .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
8878
            .attr({
8879
                // Only set static values, aria-valuenow and aria-valuemax are
8880
                // set inside _refreshValue()
8881
                role: "progressbar",
8882
                "aria-valuemin": this.min
8883
            });
8884
8885
        this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
8886
            .appendTo( this.element );
8887
8888
        this._refreshValue();
8889
    },
8890
8891
    _destroy: function() {
8892
        this.element
8893
            .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
8894
            .removeAttr( "role" )
8895
            .removeAttr( "aria-valuemin" )
8896
            .removeAttr( "aria-valuemax" )
8897
            .removeAttr( "aria-valuenow" );
8898
8899
        this.valueDiv.remove();
8900
    },
8901
8902
    value: function( newValue ) {
8903
        if ( newValue === undefined ) {
8904
            return this.options.value;
8905
        }
8906
8907
        this.options.value = this._constrainedValue( newValue );
8908
        this._refreshValue();
8909
    },
8910
8911
    _constrainedValue: function( newValue ) {
8912
        if ( newValue === undefined ) {
8913
            newValue = this.options.value;
8914
        }
8915
8916
        this.indeterminate = newValue === false;
8917
8918
        // sanitize value
8919
        if ( typeof newValue !== "number" ) {
8920
            newValue = 0;
8921
        }
8922
8923
        return this.indeterminate ? false :
8924
            Math.min( this.options.max, Math.max( this.min, newValue ) );
8925
    },
8926
8927
    _setOptions: function( options ) {
8928
        // Ensure "value" option is set after other values (like max)
8929
        var value = options.value;
8930
        delete options.value;
8931
8932
        this._super( options );
8933
8934
        this.options.value = this._constrainedValue( value );
8935
        this._refreshValue();
8936
    },
8937
8938
    _setOption: function( key, value ) {
8939
        if ( key === "max" ) {
8940
            // Don't allow a max less than min
8941
            value = Math.max( this.min, value );
8942
        }
8943
        if ( key === "disabled" ) {
8944
            this.element
8945
                .toggleClass( "ui-state-disabled", !!value )
8946
                .attr( "aria-disabled", value );
8947
        }
8948
        this._super( key, value );
8949
    },
8950
8951
    _percentage: function() {
8952
        return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
8953
    },
8954
8955
    _refreshValue: function() {
8956
        var value = this.options.value,
8957
            percentage = this._percentage();
8958
8959
        this.valueDiv
8960
            .toggle( this.indeterminate || value > this.min )
8961
            .toggleClass( "ui-corner-right", value === this.options.max )
8962
            .width( percentage.toFixed(0) + "%" );
8963
8964
        this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
8965
8966
        if ( this.indeterminate ) {
8967
            this.element.removeAttr( "aria-valuenow" );
8968
            if ( !this.overlayDiv ) {
8969
                this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
8970
            }
8971
        } else {
8972
            this.element.attr({
8973
                "aria-valuemax": this.options.max,
8974
                "aria-valuenow": value
8975
            });
8976
            if ( this.overlayDiv ) {
8977
                this.overlayDiv.remove();
8978
                this.overlayDiv = null;
8979
            }
8980
        }
8981
8982
        if ( this.oldValue !== value ) {
8983
            this.oldValue = value;
8984
            this._trigger( "change" );
8985
        }
8986
        if ( value === this.options.max ) {
8987
            this._trigger( "complete" );
8988
        }
8989
    }
8990
});
8991
8992
8993
/*!
8994
 * jQuery UI Selectmenu 1.11.4
8995
 * http://jqueryui.com
8996
 *
8997
 * Copyright jQuery Foundation and other contributors
8998
 * Released under the MIT license.
8999
 * http://jquery.org/license
9000
 *
9001
 * http://api.jqueryui.com/selectmenu
9002
 */
9003
9004
9005
var selectmenu = $.widget( "ui.selectmenu", {
9006
    version: "1.11.4",
9007
    defaultElement: "<select>",
9008
    options: {
9009
        appendTo: null,
9010
        disabled: null,
9011
        icons: {
9012
            button: "ui-icon-triangle-1-s"
9013
        },
9014
        position: {
9015
            my: "left top",
9016
            at: "left bottom",
9017
            collision: "none"
9018
        },
9019
        width: null,
9020
9021
        // callbacks
9022
        change: null,
9023
        close: null,
9024
        focus: null,
9025
        open: null,
9026
        select: null
9027
    },
9028
9029
    _create: function() {
9030
        var selectmenuId = this.element.uniqueId().attr( "id" );
9031
        this.ids = {
9032
            element: selectmenuId,
9033
            button: selectmenuId + "-button",
9034
            menu: selectmenuId + "-menu"
9035
        };
9036
9037
        this._drawButton();
9038
        this._drawMenu();
9039
9040
        if ( this.options.disabled ) {
9041
            this.disable();
9042
        }
9043
    },
9044
9045
    _drawButton: function() {
9046
        var that = this;
9047
9048
        // Associate existing label with the new button
9049
        this.label = $( "label[for='" + this.ids.element + "']" ).attr( "for", this.ids.button );
9050
        this._on( this.label, {
9051
            click: function( event ) {
9052
                this.button.focus();
9053
                event.preventDefault();
9054
            }
9055
        });
9056
9057
        // Hide original select element
9058
        this.element.hide();
9059
9060
        // Create button
9061
        this.button = $( "<span>", {
9062
            "class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all",
9063
            tabindex: this.options.disabled ? -1 : 0,
9064
            id: this.ids.button,
9065
            role: "combobox",
9066
            "aria-expanded": "false",
9067
            "aria-autocomplete": "list",
9068
            "aria-owns": this.ids.menu,
9069
            "aria-haspopup": "true"
9070
        })
9071
            .insertAfter( this.element );
9072
9073
        $( "<span>", {
9074
            "class": "ui-icon " + this.options.icons.button
9075
        })
9076
            .prependTo( this.button );
9077
9078
        this.buttonText = $( "<span>", {
9079
            "class": "ui-selectmenu-text"
9080
        })
9081
            .appendTo( this.button );
9082
9083
        this._setText( this.buttonText, this.element.find( "option:selected" ).text() );
9084
        this._resizeButton();
9085
9086
        this._on( this.button, this._buttonEvents );
9087
        this.button.one( "focusin", function() {
9088
9089
            // Delay rendering the menu items until the button receives focus.
9090
            // The menu may have already been rendered via a programmatic open.
9091
            if ( !that.menuItems ) {
9092
                that._refreshMenu();
9093
            }
9094
        });
9095
        this._hoverable( this.button );
9096
        this._focusable( this.button );
9097
    },
9098
9099
    _drawMenu: function() {
9100
        var that = this;
9101
9102
        // Create menu
9103
        this.menu = $( "<ul>", {
9104
            "aria-hidden": "true",
9105
            "aria-labelledby": this.ids.button,
9106
            id: this.ids.menu
9107
        });
9108
9109
        // Wrap menu
9110
        this.menuWrap = $( "<div>", {
9111
            "class": "ui-selectmenu-menu ui-front"
9112
        })
9113
            .append( this.menu )
9114
            .appendTo( this._appendTo() );
9115
9116
        // Initialize menu widget
9117
        this.menuInstance = this.menu
9118
            .menu({
9119
                role: "listbox",
9120
                select: function( event, ui ) {
9121
                    event.preventDefault();
9122
9123
                    // support: IE8
9124
                    // If the item was selected via a click, the text selection
9125
                    // will be destroyed in IE
9126
                    that._setSelection();
9127
9128
                    that._select( ui.item.data( "ui-selectmenu-item" ), event );
9129
                },
9130
                focus: function( event, ui ) {
9131
                    var item = ui.item.data( "ui-selectmenu-item" );
9132
9133
                    // Prevent inital focus from firing and check if its a newly focused item
9134
                    if ( that.focusIndex != null && item.index !== that.focusIndex ) {
9135
                        that._trigger( "focus", event, { item: item } );
9136
                        if ( !that.isOpen ) {
9137
                            that._select( item, event );
9138
                        }
9139
                    }
9140
                    that.focusIndex = item.index;
9141
9142
                    that.button.attr( "aria-activedescendant",
9143
                        that.menuItems.eq( item.index ).attr( "id" ) );
9144
                }
9145
            })
9146
            .menu( "instance" );
9147
9148
        // Adjust menu styles to dropdown
9149
        this.menu
9150
            .addClass( "ui-corner-bottom" )
9151
            .removeClass( "ui-corner-all" );
9152
9153
        // Don't close the menu on mouseleave
9154
        this.menuInstance._off( this.menu, "mouseleave" );
9155
9156
        // Cancel the menu's collapseAll on document click
9157
        this.menuInstance._closeOnDocumentClick = function() {
9158
            return false;
9159
        };
9160
9161
        // Selects often contain empty items, but never contain dividers
9162
        this.menuInstance._isDivider = function() {
9163
            return false;
9164
        };
9165
    },
9166
9167
    refresh: function() {
9168
        this._refreshMenu();
9169
        this._setText( this.buttonText, this._getSelectedItem().text() );
9170
        if ( !this.options.width ) {
9171
            this._resizeButton();
9172
        }
9173
    },
9174
9175
    _refreshMenu: function() {
9176
        this.menu.empty();
9177
9178
        var item,
9179
            options = this.element.find( "option" );
9180
9181
        if ( !options.length ) {
9182
            return;
9183
        }
9184
9185
        this._parseOptions( options );
9186
        this._renderMenu( this.menu, this.items );
9187
9188
        this.menuInstance.refresh();
9189
        this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" );
9190
9191
        item = this._getSelectedItem();
9192
9193
        // Update the menu to have the correct item focused
9194
        this.menuInstance.focus( null, item );
9195
        this._setAria( item.data( "ui-selectmenu-item" ) );
9196
9197
        // Set disabled state
9198
        this._setOption( "disabled", this.element.prop( "disabled" ) );
9199
    },
9200
9201
    open: function( event ) {
9202
        if ( this.options.disabled ) {
9203
            return;
9204
        }
9205
9206
        // If this is the first time the menu is being opened, render the items
9207
        if ( !this.menuItems ) {
9208
            this._refreshMenu();
9209
        } else {
9210
9211
            // Menu clears focus on close, reset focus to selected item
9212
            this.menu.find( ".ui-state-focus" ).removeClass( "ui-state-focus" );
9213
            this.menuInstance.focus( null, this._getSelectedItem() );
9214
        }
9215
9216
        this.isOpen = true;
9217
        this._toggleAttr();
9218
        this._resizeMenu();
9219
        this._position();
9220
9221
        this._on( this.document, this._documentClick );
9222
9223
        this._trigger( "open", event );
9224
    },
9225
9226
    _position: function() {
9227
        this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
9228
    },
9229
9230
    close: function( event ) {
9231
        if ( !this.isOpen ) {
9232
            return;
9233
        }
9234
9235
        this.isOpen = false;
9236
        this._toggleAttr();
9237
9238
        this.range = null;
9239
        this._off( this.document );
9240
9241
        this._trigger( "close", event );
9242
    },
9243
9244
    widget: function() {
9245
        return this.button;
9246
    },
9247
9248
    menuWidget: function() {
9249
        return this.menu;
9250
    },
9251
9252
    _renderMenu: function( ul, items ) {
9253
        var that = this,
9254
            currentOptgroup = "";
9255
9256
        $.each( items, function( index, item ) {
9257
            if ( item.optgroup !== currentOptgroup ) {
9258
                $( "<li>", {
9259
                    "class": "ui-selectmenu-optgroup ui-menu-divider" +
9260
                        ( item.element.parent( "optgroup" ).prop( "disabled" ) ?
9261
                            " ui-state-disabled" :
9262
                            "" ),
9263
                    text: item.optgroup
9264
                })
9265
                    .appendTo( ul );
9266
9267
                currentOptgroup = item.optgroup;
9268
            }
9269
9270
            that._renderItemData( ul, item );
9271
        });
9272
    },
9273
9274
    _renderItemData: function( ul, item ) {
9275
        return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
9276
    },
9277
9278
    _renderItem: function( ul, item ) {
9279
        var li = $( "<li>" );
9280
9281
        if ( item.disabled ) {
9282
            li.addClass( "ui-state-disabled" );
9283
        }
9284
        this._setText( li, item.label );
9285
9286
        return li.appendTo( ul );
9287
    },
9288
9289
    _setText: function( element, value ) {
9290
        if ( value ) {
9291
            element.text( value );
9292
        } else {
9293
            element.html( "&#160;" );
9294
        }
9295
    },
9296
9297
    _move: function( direction, event ) {
9298
        var item, next,
9299
            filter = ".ui-menu-item";
9300
9301
        if ( this.isOpen ) {
9302
            item = this.menuItems.eq( this.focusIndex );
9303
        } else {
9304
            item = this.menuItems.eq( this.element[ 0 ].selectedIndex );
9305
            filter += ":not(.ui-state-disabled)";
9306
        }
9307
9308
        if ( direction === "first" || direction === "last" ) {
9309
            next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
9310
        } else {
9311
            next = item[ direction + "All" ]( filter ).eq( 0 );
9312
        }
9313
9314
        if ( next.length ) {
9315
            this.menuInstance.focus( event, next );
9316
        }
9317
    },
9318
9319
    _getSelectedItem: function() {
9320
        return this.menuItems.eq( this.element[ 0 ].selectedIndex );
9321
    },
9322
9323
    _toggle: function( event ) {
9324
        this[ this.isOpen ? "close" : "open" ]( event );
9325
    },
9326
9327
    _setSelection: function() {
9328
        var selection;
9329
9330
        if ( !this.range ) {
9331
            return;
9332
        }
9333
9334
        if ( window.getSelection ) {
9335
            selection = window.getSelection();
9336
            selection.removeAllRanges();
9337
            selection.addRange( this.range );
9338
9339
        // support: IE8
9340
        } else {
9341
            this.range.select();
9342
        }
9343
9344
        // support: IE
9345
        // Setting the text selection kills the button focus in IE, but
9346
        // restoring the focus doesn't kill the selection.
9347
        this.button.focus();
9348
    },
9349
9350
    _documentClick: {
9351
        mousedown: function( event ) {
9352
            if ( !this.isOpen ) {
9353
                return;
9354
            }
9355
9356
            if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + this.ids.button ).length ) {
9357
                this.close( event );
9358
            }
9359
        }
9360
    },
9361
9362
    _buttonEvents: {
9363
9364
        // Prevent text selection from being reset when interacting with the selectmenu (#10144)
9365
        mousedown: function() {
9366
            var selection;
9367
9368
            if ( window.getSelection ) {
9369
                selection = window.getSelection();
9370
                if ( selection.rangeCount ) {
9371
                    this.range = selection.getRangeAt( 0 );
9372
                }
9373
9374
            // support: IE8
9375
            } else {
9376
                this.range = document.selection.createRange();
9377
            }
9378
        },
9379
9380
        click: function( event ) {
9381
            this._setSelection();
9382
            this._toggle( event );
9383
        },
9384
9385
        keydown: function( event ) {
9386
            var preventDefault = true;
9387
            switch ( event.keyCode ) {
9388
                case $.ui.keyCode.TAB:
9389
                case $.ui.keyCode.ESCAPE:
9390
                    this.close( event );
9391
                    preventDefault = false;
9392
                    break;
9393
                case $.ui.keyCode.ENTER:
9394
                    if ( this.isOpen ) {
9395
                        this._selectFocusedItem( event );
9396
                    }
9397
                    break;
9398
                case $.ui.keyCode.UP:
9399
                    if ( event.altKey ) {
9400
                        this._toggle( event );
9401
                    } else {
9402
                        this._move( "prev", event );
9403
                    }
9404
                    break;
9405
                case $.ui.keyCode.DOWN:
9406
                    if ( event.altKey ) {
9407
                        this._toggle( event );
9408
                    } else {
9409
                        this._move( "next", event );
9410
                    }
9411
                    break;
9412
                case $.ui.keyCode.SPACE:
9413
                    if ( this.isOpen ) {
9414
                        this._selectFocusedItem( event );
9415
                    } else {
9416
                        this._toggle( event );
9417
                    }
9418
                    break;
9419
                case $.ui.keyCode.LEFT:
9420
                    this._move( "prev", event );
9421
                    break;
9422
                case $.ui.keyCode.RIGHT:
9423
                    this._move( "next", event );
9424
                    break;
9425
                case $.ui.keyCode.HOME:
9426
                case $.ui.keyCode.PAGE_UP:
9427
                    this._move( "first", event );
9428
                    break;
9429
                case $.ui.keyCode.END:
9430
                case $.ui.keyCode.PAGE_DOWN:
9431
                    this._move( "last", event );
9432
                    break;
9433
                default:
9434
                    this.menu.trigger( event );
9435
                    preventDefault = false;
9436
            }
9437
9438
            if ( preventDefault ) {
9439
                event.preventDefault();
9440
            }
9441
        }
9442
    },
9443
9444
    _selectFocusedItem: function( event ) {
9445
        var item = this.menuItems.eq( this.focusIndex );
9446
        if ( !item.hasClass( "ui-state-disabled" ) ) {
9447
            this._select( item.data( "ui-selectmenu-item" ), event );
9448
        }
9449
    },
9450
9451
    _select: function( item, event ) {
9452
        var oldIndex = this.element[ 0 ].selectedIndex;
9453
9454
        // Change native select element
9455
        this.element[ 0 ].selectedIndex = item.index;
9456
        this._setText( this.buttonText, item.label );
9457
        this._setAria( item );
9458
        this._trigger( "select", event, { item: item } );
9459
9460
        if ( item.index !== oldIndex ) {
9461
            this._trigger( "change", event, { item: item } );
9462
        }
9463
9464
        this.close( event );
9465
    },
9466
9467
    _setAria: function( item ) {
9468
        var id = this.menuItems.eq( item.index ).attr( "id" );
9469
9470
        this.button.attr({
9471
            "aria-labelledby": id,
9472
            "aria-activedescendant": id
9473
        });
9474
        this.menu.attr( "aria-activedescendant", id );
9475
    },
9476
9477
    _setOption: function( key, value ) {
9478
        if ( key === "icons" ) {
9479
            this.button.find( "span.ui-icon" )
9480
                .removeClass( this.options.icons.button )
9481
                .addClass( value.button );
9482
        }
9483
9484
        this._super( key, value );
9485
9486
        if ( key === "appendTo" ) {
9487
            this.menuWrap.appendTo( this._appendTo() );
9488
        }
9489
9490
        if ( key === "disabled" ) {
9491
            this.menuInstance.option( "disabled", value );
9492
            this.button
9493
                .toggleClass( "ui-state-disabled", value )
9494
                .attr( "aria-disabled", value );
9495
9496
            this.element.prop( "disabled", value );
9497
            if ( value ) {
9498
                this.button.attr( "tabindex", -1 );
9499
                this.close();
9500
            } else {
9501
                this.button.attr( "tabindex", 0 );
9502
            }
9503
        }
9504
9505
        if ( key === "width" ) {
9506
            this._resizeButton();
9507
        }
9508
    },
9509
9510
    _appendTo: function() {
9511
        var element = this.options.appendTo;
9512
9513
        if ( element ) {
9514
            element = element.jquery || element.nodeType ?
9515
                $( element ) :
9516
                this.document.find( element ).eq( 0 );
9517
        }
9518
9519
        if ( !element || !element[ 0 ] ) {
9520
            element = this.element.closest( ".ui-front" );
9521
        }
9522
9523
        if ( !element.length ) {
9524
            element = this.document[ 0 ].body;
9525
        }
9526
9527
        return element;
9528
    },
9529
9530
    _toggleAttr: function() {
9531
        this.button
9532
            .toggleClass( "ui-corner-top", this.isOpen )
9533
            .toggleClass( "ui-corner-all", !this.isOpen )
9534
            .attr( "aria-expanded", this.isOpen );
9535
        this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen );
9536
        this.menu.attr( "aria-hidden", !this.isOpen );
9537
    },
9538
9539
    _resizeButton: function() {
9540
        var width = this.options.width;
9541
9542
        if ( !width ) {
9543
            width = this.element.show().outerWidth();
9544
            this.element.hide();
9545
        }
9546
9547
        this.button.outerWidth( width );
9548
    },
9549
9550
    _resizeMenu: function() {
9551
        this.menu.outerWidth( Math.max(
9552
            this.button.outerWidth(),
9553
9554
            // support: IE10
9555
            // IE10 wraps long text (possibly a rounding bug)
9556
            // so we add 1px to avoid the wrapping
9557
            this.menu.width( "" ).outerWidth() + 1
9558
        ) );
9559
    },
9560
9561
    _getCreateOptions: function() {
9562
        return { disabled: this.element.prop( "disabled" ) };
9563
    },
9564
9565
    _parseOptions: function( options ) {
9566
        var data = [];
9567
        options.each(function( index, item ) {
9568
            var option = $( item ),
9569
                optgroup = option.parent( "optgroup" );
9570
            data.push({
9571
                element: option,
9572
                index: index,
9573
                value: option.val(),
9574
                label: option.text(),
9575
                optgroup: optgroup.attr( "label" ) || "",
9576
                disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
9577
            });
9578
        });
9579
        this.items = data;
9580
    },
9581
9582
    _destroy: function() {
9583
        this.menuWrap.remove();
9584
        this.button.remove();
9585
        this.element.show();
9586
        this.element.removeUniqueId();
9587
        this.label.attr( "for", this.ids.element );
9588
    }
9589
});
9590
9591
9592
/*!
9593
 * jQuery UI Slider 1.11.4
9594
 * http://jqueryui.com
9595
 *
9596
 * Copyright jQuery Foundation and other contributors
9597
 * Released under the MIT license.
9598
 * http://jquery.org/license
9599
 *
9600
 * http://api.jqueryui.com/slider/
9601
 */
9602
9603
9604
var slider = $.widget( "ui.slider", $.ui.mouse, {
9605
    version: "1.11.4",
9606
    widgetEventPrefix: "slide",
9607
9608
    options: {
9609
        animate: false,
9610
        distance: 0,
9611
        max: 100,
9612
        min: 0,
9613
        orientation: "horizontal",
9614
        range: false,
9615
        step: 1,
9616
        value: 0,
9617
        values: null,
9618
9619
        // callbacks
9620
        change: null,
9621
        slide: null,
9622
        start: null,
9623
        stop: null
9624
    },
9625
9626
    // number of pages in a slider
9627
    // (how many times can you page up/down to go through the whole range)
9628
    numPages: 5,
9629
9630
    _create: function() {
9631
        this._keySliding = false;
9632
        this._mouseSliding = false;
9633
        this._animateOff = true;
9634
        this._handleIndex = null;
9635
        this._detectOrientation();
9636
        this._mouseInit();
9637
        this._calculateNewMax();
9638
9639
        this.element
9640
            .addClass( "ui-slider" +
9641
                " ui-slider-" + this.orientation +
9642
                " ui-widget" +
9643
                " ui-widget-content" +
9644
                " ui-corner-all");
9645
9646
        this._refresh();
9647
        this._setOption( "disabled", this.options.disabled );
9648
9649
        this._animateOff = false;
9650
    },
9651
9652
    _refresh: function() {
9653
        this._createRange();
9654
        this._createHandles();
9655
        this._setupEvents();
9656
        this._refreshValue();
9657
    },
9658
9659
    _createHandles: function() {
9660
        var i, handleCount,
9661
            options = this.options,
9662
            existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
9663
            handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>",
9664
            handles = [];
9665
9666
        handleCount = ( options.values && options.values.length ) || 1;
9667
9668
        if ( existingHandles.length > handleCount ) {
9669
            existingHandles.slice( handleCount ).remove();
9670
            existingHandles = existingHandles.slice( 0, handleCount );
9671
        }
9672
9673
        for ( i = existingHandles.length; i < handleCount; i++ ) {
9674
            handles.push( handle );
9675
        }
9676
9677
        this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
9678
9679
        this.handle = this.handles.eq( 0 );
9680
9681
        this.handles.each(function( i ) {
9682
            $( this ).data( "ui-slider-handle-index", i );
9683
        });
9684
    },
9685
9686
    _createRange: function() {
9687
        var options = this.options,
9688
            classes = "";
9689
9690
        if ( options.range ) {
9691
            if ( options.range === true ) {
9692
                if ( !options.values ) {
9693
                    options.values = [ this._valueMin(), this._valueMin() ];
9694
                } else if ( options.values.length && options.values.length !== 2 ) {
9695
                    options.values = [ options.values[0], options.values[0] ];
9696
                } else if ( $.isArray( options.values ) ) {
9697
                    options.values = options.values.slice(0);
9698
                }
9699
            }
9700
9701
            if ( !this.range || !this.range.length ) {
9702
                this.range = $( "<div></div>" )
9703
                    .appendTo( this.element );
9704
9705
                classes = "ui-slider-range" +
9706
                // note: this isn't the most fittingly semantic framework class for this element,
9707
                // but worked best visually with a variety of themes
9708
                " ui-widget-header ui-corner-all";
9709
            } else {
9710
                this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
9711
                    // Handle range switching from true to min/max
9712
                    .css({
9713
                        "left": "",
9714
                        "bottom": ""
9715
                    });
9716
            }
9717
9718
            this.range.addClass( classes +
9719
                ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
9720
        } else {
9721
            if ( this.range ) {
9722
                this.range.remove();
9723
            }
9724
            this.range = null;
9725
        }
9726
    },
9727
9728
    _setupEvents: function() {
9729
        this._off( this.handles );
9730
        this._on( this.handles, this._handleEvents );
9731
        this._hoverable( this.handles );
9732
        this._focusable( this.handles );
9733
    },
9734
9735
    _destroy: function() {
9736
        this.handles.remove();
9737
        if ( this.range ) {
9738
            this.range.remove();
9739
        }
9740
9741
        this.element
9742
            .removeClass( "ui-slider" +
9743
                " ui-slider-horizontal" +
9744
                " ui-slider-vertical" +
9745
                " ui-widget" +
9746
                " ui-widget-content" +
9747
                " ui-corner-all" );
9748
9749
        this._mouseDestroy();
9750
    },
9751
9752
    _mouseCapture: function( event ) {
9753
        var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
9754
            that = this,
9755
            o = this.options;
9756
9757
        if ( o.disabled ) {
9758
            return false;
9759
        }
9760
9761
        this.elementSize = {
9762
            width: this.element.outerWidth(),
9763
            height: this.element.outerHeight()
9764
        };
9765
        this.elementOffset = this.element.offset();
9766
9767
        position = { x: event.pageX, y: event.pageY };
9768
        normValue = this._normValueFromMouse( position );
9769
        distance = this._valueMax() - this._valueMin() + 1;
9770
        this.handles.each(function( i ) {
9771
            var thisDistance = Math.abs( normValue - that.values(i) );
9772
            if (( distance > thisDistance ) ||
9773
                ( distance === thisDistance &&
9774
                    (i === that._lastChangedValue || that.values(i) === o.min ))) {
9775
                distance = thisDistance;
9776
                closestHandle = $( this );
9777
                index = i;
9778
            }
9779
        });
9780
9781
        allowed = this._start( event, index );
9782
        if ( allowed === false ) {
9783
            return false;
9784
        }
9785
        this._mouseSliding = true;
9786
9787
        this._handleIndex = index;
9788
9789
        closestHandle
9790
            .addClass( "ui-state-active" )
9791
            .focus();
9792
9793
        offset = closestHandle.offset();
9794
        mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
9795
        this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
9796
            left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
9797
            top: event.pageY - offset.top -
9798
                ( closestHandle.height() / 2 ) -
9799
                ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
9800
                ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
9801
                ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
9802
        };
9803
9804
        if ( !this.handles.hasClass( "ui-state-hover" ) ) {
9805
            this._slide( event, index, normValue );
9806
        }
9807
        this._animateOff = true;
9808
        return true;
9809
    },
9810
9811
    _mouseStart: function() {
9812
        return true;
9813
    },
9814
9815
    _mouseDrag: function( event ) {
9816
        var position = { x: event.pageX, y: event.pageY },
9817
            normValue = this._normValueFromMouse( position );
9818
9819
        this._slide( event, this._handleIndex, normValue );
9820
9821
        return false;
9822
    },
9823
9824
    _mouseStop: function( event ) {
9825
        this.handles.removeClass( "ui-state-active" );
9826
        this._mouseSliding = false;
9827
9828
        this._stop( event, this._handleIndex );
9829
        this._change( event, this._handleIndex );
9830
9831
        this._handleIndex = null;
9832
        this._clickOffset = null;
9833
        this._animateOff = false;
9834
9835
        return false;
9836
    },
9837
9838
    _detectOrientation: function() {
9839
        this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
9840
    },
9841
9842
    _normValueFromMouse: function( position ) {
9843
        var pixelTotal,
9844
            pixelMouse,
9845
            percentMouse,
9846
            valueTotal,
9847
            valueMouse;
9848
9849
        if ( this.orientation === "horizontal" ) {
9850
            pixelTotal = this.elementSize.width;
9851
            pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
9852
        } else {
9853
            pixelTotal = this.elementSize.height;
9854
            pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
9855
        }
9856
9857
        percentMouse = ( pixelMouse / pixelTotal );
9858
        if ( percentMouse > 1 ) {
9859
            percentMouse = 1;
9860
        }
9861
        if ( percentMouse < 0 ) {
9862
            percentMouse = 0;
9863
        }
9864
        if ( this.orientation === "vertical" ) {
9865
            percentMouse = 1 - percentMouse;
9866
        }
9867
9868
        valueTotal = this._valueMax() - this._valueMin();
9869
        valueMouse = this._valueMin() + percentMouse * valueTotal;
9870
9871
        return this._trimAlignValue( valueMouse );
9872
    },
9873
9874
    _start: function( event, index ) {
9875
        var uiHash = {
9876
            handle: this.handles[ index ],
9877
            value: this.value()
9878
        };
9879
        if ( this.options.values && this.options.values.length ) {
9880
            uiHash.value = this.values( index );
9881
            uiHash.values = this.values();
9882
        }
9883
        return this._trigger( "start", event, uiHash );
9884
    },
9885
9886
    _slide: function( event, index, newVal ) {
9887
        var otherVal,
9888
            newValues,
9889
            allowed;
9890
9891
        if ( this.options.values && this.options.values.length ) {
9892
            otherVal = this.values( index ? 0 : 1 );
9893
9894
            if ( ( this.options.values.length === 2 && this.options.range === true ) &&
9895
                    ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
9896
                ) {
9897
                newVal = otherVal;
9898
            }
9899
9900
            if ( newVal !== this.values( index ) ) {
9901
                newValues = this.values();
9902
                newValues[ index ] = newVal;
9903
                // A slide can be canceled by returning false from the slide callback
9904
                allowed = this._trigger( "slide", event, {
9905
                    handle: this.handles[ index ],
9906
                    value: newVal,
9907
                    values: newValues
9908
                } );
9909
                otherVal = this.values( index ? 0 : 1 );
9910
                if ( allowed !== false ) {
9911
                    this.values( index, newVal );
9912
                }
9913
            }
9914
        } else {
9915
            if ( newVal !== this.value() ) {
9916
                // A slide can be canceled by returning false from the slide callback
9917
                allowed = this._trigger( "slide", event, {
9918
                    handle: this.handles[ index ],
9919
                    value: newVal
9920
                } );
9921
                if ( allowed !== false ) {
9922
                    this.value( newVal );
9923
                }
9924
            }
9925
        }
9926
    },
9927
9928
    _stop: function( event, index ) {
9929
        var uiHash = {
9930
            handle: this.handles[ index ],
9931
            value: this.value()
9932
        };
9933
        if ( this.options.values && this.options.values.length ) {
9934
            uiHash.value = this.values( index );
9935
            uiHash.values = this.values();
9936
        }
9937
9938
        this._trigger( "stop", event, uiHash );
9939
    },
9940
9941
    _change: function( event, index ) {
9942
        if ( !this._keySliding && !this._mouseSliding ) {
9943
            var uiHash = {
9944
                handle: this.handles[ index ],
9945
                value: this.value()
9946
            };
9947
            if ( this.options.values && this.options.values.length ) {
9948
                uiHash.value = this.values( index );
9949
                uiHash.values = this.values();
9950
            }
9951
9952
            //store the last changed value index for reference when handles overlap
9953
            this._lastChangedValue = index;
9954
9955
            this._trigger( "change", event, uiHash );
9956
        }
9957
    },
9958
9959
    value: function( newValue ) {
9960
        if ( arguments.length ) {
9961
            this.options.value = this._trimAlignValue( newValue );
9962
            this._refreshValue();
9963
            this._change( null, 0 );
9964
            return;
9965
        }
9966
9967
        return this._value();
9968
    },
9969
9970
    values: function( index, newValue ) {
9971
        var vals,
9972
            newValues,
9973
            i;
9974
9975
        if ( arguments.length > 1 ) {
9976
            this.options.values[ index ] = this._trimAlignValue( newValue );
9977
            this._refreshValue();
9978
            this._change( null, index );
9979
            return;
9980
        }
9981
9982
        if ( arguments.length ) {
9983
            if ( $.isArray( arguments[ 0 ] ) ) {
9984
                vals = this.options.values;
9985
                newValues = arguments[ 0 ];
9986
                for ( i = 0; i < vals.length; i += 1 ) {
9987
                    vals[ i ] = this._trimAlignValue( newValues[ i ] );
9988
                    this._change( null, i );
9989
                }
9990
                this._refreshValue();
9991
            } else {
9992
                if ( this.options.values && this.options.values.length ) {
9993
                    return this._values( index );
9994
                } else {
9995
                    return this.value();
9996
                }
9997
            }
9998
        } else {
9999
            return this._values();
10000
        }
10001
    },
10002
10003
    _setOption: function( key, value ) {
10004
        var i,
10005
            valsLength = 0;
10006
10007
        if ( key === "range" && this.options.range === true ) {
10008
            if ( value === "min" ) {
10009
                this.options.value = this._values( 0 );
10010
                this.options.values = null;
10011
            } else if ( value === "max" ) {
10012
                this.options.value = this._values( this.options.values.length - 1 );
10013
                this.options.values = null;
10014
            }
10015
        }
10016
10017
        if ( $.isArray( this.options.values ) ) {
10018
            valsLength = this.options.values.length;
10019
        }
10020
10021
        if ( key === "disabled" ) {
10022
            this.element.toggleClass( "ui-state-disabled", !!value );
10023
        }
10024
10025
        this._super( key, value );
10026
10027
        switch ( key ) {
10028
            case "orientation":
10029
                this._detectOrientation();
10030
                this.element
10031
                    .removeClass( "ui-slider-horizontal ui-slider-vertical" )
10032
                    .addClass( "ui-slider-" + this.orientation );
10033
                this._refreshValue();
10034
10035
                // Reset positioning from previous orientation
10036
                this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
10037
                break;
10038
            case "value":
10039
                this._animateOff = true;
10040
                this._refreshValue();
10041
                this._change( null, 0 );
10042
                this._animateOff = false;
10043
                break;
10044
            case "values":
10045
                this._animateOff = true;
10046
                this._refreshValue();
10047
                for ( i = 0; i < valsLength; i += 1 ) {
10048
                    this._change( null, i );
10049
                }
10050
                this._animateOff = false;
10051
                break;
10052
            case "step":
10053
            case "min":
10054
            case "max":
10055
                this._animateOff = true;
10056
                this._calculateNewMax();
10057
                this._refreshValue();
10058
                this._animateOff = false;
10059
                break;
10060
            case "range":
10061
                this._animateOff = true;
10062
                this._refresh();
10063
                this._animateOff = false;
10064
                break;
10065
        }
10066
    },
10067
10068
    //internal value getter
10069
    // _value() returns value trimmed by min and max, aligned by step
10070
    _value: function() {
10071
        var val = this.options.value;
10072
        val = this._trimAlignValue( val );
10073
10074
        return val;
10075
    },
10076
10077
    //internal values getter
10078
    // _values() returns array of values trimmed by min and max, aligned by step
10079
    // _values( index ) returns single value trimmed by min and max, aligned by step
10080
    _values: function( index ) {
10081
        var val,
10082
            vals,
10083
            i;
10084
10085
        if ( arguments.length ) {
10086
            val = this.options.values[ index ];
10087
            val = this._trimAlignValue( val );
10088
10089
            return val;
10090
        } else if ( this.options.values && this.options.values.length ) {
10091
            // .slice() creates a copy of the array
10092
            // this copy gets trimmed by min and max and then returned
10093
            vals = this.options.values.slice();
10094
            for ( i = 0; i < vals.length; i += 1) {
10095
                vals[ i ] = this._trimAlignValue( vals[ i ] );
10096
            }
10097
10098
            return vals;
10099
        } else {
10100
            return [];
10101
        }
10102
    },
10103
10104
    // returns the step-aligned value that val is closest to, between (inclusive) min and max
10105
    _trimAlignValue: function( val ) {
10106
        if ( val <= this._valueMin() ) {
10107
            return this._valueMin();
10108
        }
10109
        if ( val >= this._valueMax() ) {
10110
            return this._valueMax();
10111
        }
10112
        var step = ( this.options.step > 0 ) ? this.options.step : 1,
10113
            valModStep = (val - this._valueMin()) % step,
10114
            alignValue = val - valModStep;
10115
10116
        if ( Math.abs(valModStep) * 2 >= step ) {
10117
            alignValue += ( valModStep > 0 ) ? step : ( -step );
10118
        }
10119
10120
        // Since JavaScript has problems with large floats, round
10121
        // the final value to 5 digits after the decimal point (see #4124)
10122
        return parseFloat( alignValue.toFixed(5) );
10123
    },
10124
10125
    _calculateNewMax: function() {
10126
        var max = this.options.max,
10127
            min = this._valueMin(),
10128
            step = this.options.step,
10129
            aboveMin = Math.floor( ( +( max - min ).toFixed( this._precision() ) ) / step ) * step;
10130
        max = aboveMin + min;
10131
        this.max = parseFloat( max.toFixed( this._precision() ) );
10132
    },
10133
10134
    _precision: function() {
10135
        var precision = this._precisionOf( this.options.step );
10136
        if ( this.options.min !== null ) {
10137
            precision = Math.max( precision, this._precisionOf( this.options.min ) );
10138
        }
10139
        return precision;
10140
    },
10141
10142
    _precisionOf: function( num ) {
10143
        var str = num.toString(),
10144
            decimal = str.indexOf( "." );
10145
        return decimal === -1 ? 0 : str.length - decimal - 1;
10146
    },
10147
10148
    _valueMin: function() {
10149
        return this.options.min;
10150
    },
10151
10152
    _valueMax: function() {
10153
        return this.max;
10154
    },
10155
10156
    _refreshValue: function() {
10157
        var lastValPercent, valPercent, value, valueMin, valueMax,
10158
            oRange = this.options.range,
10159
            o = this.options,
10160
            that = this,
10161
            animate = ( !this._animateOff ) ? o.animate : false,
10162
            _set = {};
10163
10164
        if ( this.options.values && this.options.values.length ) {
10165
            this.handles.each(function( i ) {
10166
                valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
10167
                _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
10168
                $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
10169
                if ( that.options.range === true ) {
10170
                    if ( that.orientation === "horizontal" ) {
10171
                        if ( i === 0 ) {
10172
                            that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
10173
                        }
10174
                        if ( i === 1 ) {
10175
                            that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
10176
                        }
10177
                    } else {
10178
                        if ( i === 0 ) {
10179
                            that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
10180
                        }
10181
                        if ( i === 1 ) {
10182
                            that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
10183
                        }
10184
                    }
10185
                }
10186
                lastValPercent = valPercent;
10187
            });
10188
        } else {
10189
            value = this.value();
10190
            valueMin = this._valueMin();
10191
            valueMax = this._valueMax();
10192
            valPercent = ( valueMax !== valueMin ) ?
10193
                    ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
10194
                    0;
10195
            _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
10196
            this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
10197
10198
            if ( oRange === "min" && this.orientation === "horizontal" ) {
10199
                this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
10200
            }
10201
            if ( oRange === "max" && this.orientation === "horizontal" ) {
10202
                this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
10203
            }
10204
            if ( oRange === "min" && this.orientation === "vertical" ) {
10205
                this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
10206
            }
10207
            if ( oRange === "max" && this.orientation === "vertical" ) {
10208
                this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
10209
            }
10210
        }
10211
    },
10212
10213
    _handleEvents: {
10214
        keydown: function( event ) {
10215
            var allowed, curVal, newVal, step,
10216
                index = $( event.target ).data( "ui-slider-handle-index" );
10217
10218
            switch ( event.keyCode ) {
10219
                case $.ui.keyCode.HOME:
10220
                case $.ui.keyCode.END:
10221
                case $.ui.keyCode.PAGE_UP:
10222
                case $.ui.keyCode.PAGE_DOWN:
10223
                case $.ui.keyCode.UP:
10224
                case $.ui.keyCode.RIGHT:
10225
                case $.ui.keyCode.DOWN:
10226
                case $.ui.keyCode.LEFT:
10227
                    event.preventDefault();
10228
                    if ( !this._keySliding ) {
10229
                        this._keySliding = true;
10230
                        $( event.target ).addClass( "ui-state-active" );
10231
                        allowed = this._start( event, index );
10232
                        if ( allowed === false ) {
10233
                            return;
10234
                        }
10235
                    }
10236
                    break;
10237
            }
10238
10239
            step = this.options.step;
10240
            if ( this.options.values && this.options.values.length ) {
10241
                curVal = newVal = this.values( index );
10242
            } else {
10243
                curVal = newVal = this.value();
10244
            }
10245
10246
            switch ( event.keyCode ) {
10247
                case $.ui.keyCode.HOME:
10248
                    newVal = this._valueMin();
10249
                    break;
10250
                case $.ui.keyCode.END:
10251
                    newVal = this._valueMax();
10252
                    break;
10253
                case $.ui.keyCode.PAGE_UP:
10254
                    newVal = this._trimAlignValue(
10255
                        curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
10256
                    );
10257
                    break;
10258
                case $.ui.keyCode.PAGE_DOWN:
10259
                    newVal = this._trimAlignValue(
10260
                        curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) );
10261
                    break;
10262
                case $.ui.keyCode.UP:
10263
                case $.ui.keyCode.RIGHT:
10264
                    if ( curVal === this._valueMax() ) {
10265
                        return;
10266
                    }
10267
                    newVal = this._trimAlignValue( curVal + step );
10268
                    break;
10269
                case $.ui.keyCode.DOWN:
10270
                case $.ui.keyCode.LEFT:
10271
                    if ( curVal === this._valueMin() ) {
10272
                        return;
10273
                    }
10274
                    newVal = this._trimAlignValue( curVal - step );
10275
                    break;
10276
            }
10277
10278
            this._slide( event, index, newVal );
10279
        },
10280
        keyup: function( event ) {
10281
            var index = $( event.target ).data( "ui-slider-handle-index" );
10282
10283
            if ( this._keySliding ) {
10284
                this._keySliding = false;
10285
                this._stop( event, index );
10286
                this._change( event, index );
10287
                $( event.target ).removeClass( "ui-state-active" );
10288
            }
10289
        }
10290
    }
10291
});
10292
10293
10294
/*!
10295
 * jQuery UI Spinner 1.11.4
10296
 * http://jqueryui.com
10297
 *
10298
 * Copyright jQuery Foundation and other contributors
10299
 * Released under the MIT license.
10300
 * http://jquery.org/license
10301
 *
10302
 * http://api.jqueryui.com/spinner/
10303
 */
10304
10305
10306
function spinner_modifier( fn ) {
10307
    return function() {
10308
        var previous = this.element.val();
10309
        fn.apply( this, arguments );
10310
        this._refresh();
10311
        if ( previous !== this.element.val() ) {
10312
            this._trigger( "change" );
10313
        }
10314
    };
10315
}
10316
10317
var spinner = $.widget( "ui.spinner", {
10318
    version: "1.11.4",
10319
    defaultElement: "<input>",
10320
    widgetEventPrefix: "spin",
10321
    options: {
10322
        culture: null,
10323
        icons: {
10324
            down: "ui-icon-triangle-1-s",
10325
            up: "ui-icon-triangle-1-n"
10326
        },
10327
        incremental: true,
10328
        max: null,
10329
        min: null,
10330
        numberFormat: null,
10331
        page: 10,
10332
        step: 1,
10333
10334
        change: null,
10335
        spin: null,
10336
        start: null,
10337
        stop: null
10338
    },
10339
10340
    _create: function() {
10341
        // handle string values that need to be parsed
10342
        this._setOption( "max", this.options.max );
10343
        this._setOption( "min", this.options.min );
10344
        this._setOption( "step", this.options.step );
10345
10346
        // Only format if there is a value, prevents the field from being marked
10347
        // as invalid in Firefox, see #9573.
10348
        if ( this.value() !== "" ) {
10349
            // Format the value, but don't constrain.
10350
            this._value( this.element.val(), true );
10351
        }
10352
10353
        this._draw();
10354
        this._on( this._events );
10355
        this._refresh();
10356
10357
        // turning off autocomplete prevents the browser from remembering the
10358
        // value when navigating through history, so we re-enable autocomplete
10359
        // if the page is unloaded before the widget is destroyed. #7790
10360
        this._on( this.window, {
10361
            beforeunload: function() {
10362
                this.element.removeAttr( "autocomplete" );
10363
            }
10364
        });
10365
    },
10366
10367
    _getCreateOptions: function() {
10368
        var options = {},
10369
            element = this.element;
10370
10371
        $.each( [ "min", "max", "step" ], function( i, option ) {
10372
            var value = element.attr( option );
10373
            if ( value !== undefined && value.length ) {
10374
                options[ option ] = value;
10375
            }
10376
        });
10377
10378
        return options;
10379
    },
10380
10381
    _events: {
10382
        keydown: function( event ) {
10383
            if ( this._start( event ) && this._keydown( event ) ) {
10384
                event.preventDefault();
10385
            }
10386
        },
10387
        keyup: "_stop",
10388
        focus: function() {
10389
            this.previous = this.element.val();
10390
        },
10391
        blur: function( event ) {
10392
            if ( this.cancelBlur ) {
10393
                delete this.cancelBlur;
10394
                return;
10395
            }
10396
10397
            this._stop();
10398
            this._refresh();
10399
            if ( this.previous !== this.element.val() ) {
10400
                this._trigger( "change", event );
10401
            }
10402
        },
10403
        mousewheel: function( event, delta ) {
10404
            if ( !delta ) {
10405
                return;
10406
            }
10407
            if ( !this.spinning && !this._start( event ) ) {
10408
                return false;
10409
            }
10410
10411
            this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
10412
            clearTimeout( this.mousewheelTimer );
10413
            this.mousewheelTimer = this._delay(function() {
10414
                if ( this.spinning ) {
10415
                    this._stop( event );
10416
                }
10417
            }, 100 );
10418
            event.preventDefault();
10419
        },
10420
        "mousedown .ui-spinner-button": function( event ) {
10421
            var previous;
10422
10423
            // We never want the buttons to have focus; whenever the user is
10424
            // interacting with the spinner, the focus should be on the input.
10425
            // If the input is focused then this.previous is properly set from
10426
            // when the input first received focus. If the input is not focused
10427
            // then we need to set this.previous based on the value before spinning.
10428
            previous = this.element[0] === this.document[0].activeElement ?
10429
                this.previous : this.element.val();
10430
            function checkFocus() {
10431
                var isActive = this.element[0] === this.document[0].activeElement;
10432
                if ( !isActive ) {
10433
                    this.element.focus();
10434
                    this.previous = previous;
10435
                    // support: IE
10436
                    // IE sets focus asynchronously, so we need to check if focus
10437
                    // moved off of the input because the user clicked on the button.
10438
                    this._delay(function() {
10439
                        this.previous = previous;
10440
                    });
10441
                }
10442
            }
10443
10444
            // ensure focus is on (or stays on) the text field
10445
            event.preventDefault();
10446
            checkFocus.call( this );
10447
10448
            // support: IE
10449
            // IE doesn't prevent moving focus even with event.preventDefault()
10450
            // so we set a flag to know when we should ignore the blur event
10451
            // and check (again) if focus moved off of the input.
10452
            this.cancelBlur = true;
10453
            this._delay(function() {
10454
                delete this.cancelBlur;
10455
                checkFocus.call( this );
10456
            });
10457
10458
            if ( this._start( event ) === false ) {
10459
                return;
10460
            }
10461
10462
            this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
10463
        },
10464
        "mouseup .ui-spinner-button": "_stop",
10465
        "mouseenter .ui-spinner-button": function( event ) {
10466
            // button will add ui-state-active if mouse was down while mouseleave and kept down
10467
            if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
10468
                return;
10469
            }
10470
10471
            if ( this._start( event ) === false ) {
10472
                return false;
10473
            }
10474
            this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
10475
        },
10476
        // TODO: do we really want to consider this a stop?
10477
        // shouldn't we just stop the repeater and wait until mouseup before
10478
        // we trigger the stop event?
10479
        "mouseleave .ui-spinner-button": "_stop"
10480
    },
10481
10482
    _draw: function() {
10483
        var uiSpinner = this.uiSpinner = this.element
10484
            .addClass( "ui-spinner-input" )
10485
            .attr( "autocomplete", "off" )
10486
            .wrap( this._uiSpinnerHtml() )
10487
            .parent()
10488
                // add buttons
10489
                .append( this._buttonHtml() );
10490
10491
        this.element.attr( "role", "spinbutton" );
10492
10493
        // button bindings
10494
        this.buttons = uiSpinner.find( ".ui-spinner-button" )
10495
            .attr( "tabIndex", -1 )
10496
            .button()
10497
            .removeClass( "ui-corner-all" );
10498
10499
        // IE 6 doesn't understand height: 50% for the buttons
10500
        // unless the wrapper has an explicit height
10501
        if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
10502
                uiSpinner.height() > 0 ) {
10503
            uiSpinner.height( uiSpinner.height() );
10504
        }
10505
10506
        // disable spinner if element was already disabled
10507
        if ( this.options.disabled ) {
10508
            this.disable();
10509
        }
10510
    },
10511
10512
    _keydown: function( event ) {
10513
        var options = this.options,
10514
            keyCode = $.ui.keyCode;
10515
10516
        switch ( event.keyCode ) {
10517
        case keyCode.UP:
10518
            this._repeat( null, 1, event );
10519
            return true;
10520
        case keyCode.DOWN:
10521
            this._repeat( null, -1, event );
10522
            return true;
10523
        case keyCode.PAGE_UP:
10524
            this._repeat( null, options.page, event );
10525
            return true;
10526
        case keyCode.PAGE_DOWN:
10527
            this._repeat( null, -options.page, event );
10528
            return true;
10529
        }
10530
10531
        return false;
10532
    },
10533
10534
    _uiSpinnerHtml: function() {
10535
        return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
10536
    },
10537
10538
    _buttonHtml: function() {
10539
        return "" +
10540
            "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
10541
                "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
10542
            "</a>" +
10543
            "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
10544
                "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
10545
            "</a>";
10546
    },
10547
10548
    _start: function( event ) {
10549
        if ( !this.spinning && this._trigger( "start", event ) === false ) {
10550
            return false;
10551
        }
10552
10553
        if ( !this.counter ) {
10554
            this.counter = 1;
10555
        }
10556
        this.spinning = true;
10557
        return true;
10558
    },
10559
10560
    _repeat: function( i, steps, event ) {
10561
        i = i || 500;
10562
10563
        clearTimeout( this.timer );
10564
        this.timer = this._delay(function() {
10565
            this._repeat( 40, steps, event );
10566
        }, i );
10567
10568
        this._spin( steps * this.options.step, event );
10569
    },
10570
10571
    _spin: function( step, event ) {
10572
        var value = this.value() || 0;
10573
10574
        if ( !this.counter ) {
10575
            this.counter = 1;
10576
        }
10577
10578
        value = this._adjustValue( value + step * this._increment( this.counter ) );
10579
10580
        if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
10581
            this._value( value );
10582
            this.counter++;
10583
        }
10584
    },
10585
10586
    _increment: function( i ) {
10587
        var incremental = this.options.incremental;
10588
10589
        if ( incremental ) {
10590
            return $.isFunction( incremental ) ?
10591
                incremental( i ) :
10592
                Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
10593
        }
10594
10595
        return 1;
10596
    },
10597
10598
    _precision: function() {
10599
        var precision = this._precisionOf( this.options.step );
10600
        if ( this.options.min !== null ) {
10601
            precision = Math.max( precision, this._precisionOf( this.options.min ) );
10602
        }
10603
        return precision;
10604
    },
10605
10606
    _precisionOf: function( num ) {
10607
        var str = num.toString(),
10608
            decimal = str.indexOf( "." );
10609
        return decimal === -1 ? 0 : str.length - decimal - 1;
10610
    },
10611
10612
    _adjustValue: function( value ) {
10613
        var base, aboveMin,
10614
            options = this.options;
10615
10616
        // make sure we're at a valid step
10617
        // - find out where we are relative to the base (min or 0)
10618
        base = options.min !== null ? options.min : 0;
10619
        aboveMin = value - base;
10620
        // - round to the nearest step
10621
        aboveMin = Math.round(aboveMin / options.step) * options.step;
10622
        // - rounding is based on 0, so adjust back to our base
10623
        value = base + aboveMin;
10624
10625
        // fix precision from bad JS floating point math
10626
        value = parseFloat( value.toFixed( this._precision() ) );
10627
10628
        // clamp the value
10629
        if ( options.max !== null && value > options.max) {
10630
            return options.max;
10631
        }
10632
        if ( options.min !== null && value < options.min ) {
10633
            return options.min;
10634
        }
10635
10636
        return value;
10637
    },
10638
10639
    _stop: function( event ) {
10640
        if ( !this.spinning ) {
10641
            return;
10642
        }
10643
10644
        clearTimeout( this.timer );
10645
        clearTimeout( this.mousewheelTimer );
10646
        this.counter = 0;
10647
        this.spinning = false;
10648
        this._trigger( "stop", event );
10649
    },
10650
10651
    _setOption: function( key, value ) {
10652
        if ( key === "culture" || key === "numberFormat" ) {
10653
            var prevValue = this._parse( this.element.val() );
10654
            this.options[ key ] = value;
10655
            this.element.val( this._format( prevValue ) );
10656
            return;
10657
        }
10658
10659
        if ( key === "max" || key === "min" || key === "step" ) {
10660
            if ( typeof value === "string" ) {
10661
                value = this._parse( value );
10662
            }
10663
        }
10664
        if ( key === "icons" ) {
10665
            this.buttons.first().find( ".ui-icon" )
10666
                .removeClass( this.options.icons.up )
10667
                .addClass( value.up );
10668
            this.buttons.last().find( ".ui-icon" )
10669
                .removeClass( this.options.icons.down )
10670
                .addClass( value.down );
10671
        }
10672
10673
        this._super( key, value );
10674
10675
        if ( key === "disabled" ) {
10676
            this.widget().toggleClass( "ui-state-disabled", !!value );
10677
            this.element.prop( "disabled", !!value );
10678
            this.buttons.button( value ? "disable" : "enable" );
10679
        }
10680
    },
10681
10682
    _setOptions: spinner_modifier(function( options ) {
10683
        this._super( options );
10684
    }),
10685
10686
    _parse: function( val ) {
10687
        if ( typeof val === "string" && val !== "" ) {
10688
            val = window.Globalize && this.options.numberFormat ?
10689
                Globalize.parseFloat( val, 10, this.options.culture ) : +val;
10690
        }
10691
        return val === "" || isNaN( val ) ? null : val;
10692
    },
10693
10694
    _format: function( value ) {
10695
        if ( value === "" ) {
10696
            return "";
10697
        }
10698
        return window.Globalize && this.options.numberFormat ?
10699
            Globalize.format( value, this.options.numberFormat, this.options.culture ) :
10700
            value;
10701
    },
10702
10703
    _refresh: function() {
10704
        this.element.attr({
10705
            "aria-valuemin": this.options.min,
10706
            "aria-valuemax": this.options.max,
10707
            // TODO: what should we do with values that can't be parsed?
10708
            "aria-valuenow": this._parse( this.element.val() )
10709
        });
10710
    },
10711
10712
    isValid: function() {
10713
        var value = this.value();
10714
10715
        // null is invalid
10716
        if ( value === null ) {
10717
            return false;
10718
        }
10719
10720
        // if value gets adjusted, it's invalid
10721
        return value === this._adjustValue( value );
10722
    },
10723
10724
    // update the value without triggering change
10725
    _value: function( value, allowAny ) {
10726
        var parsed;
10727
        if ( value !== "" ) {
10728
            parsed = this._parse( value );
10729
            if ( parsed !== null ) {
10730
                if ( !allowAny ) {
10731
                    parsed = this._adjustValue( parsed );
10732
                }
10733
                value = this._format( parsed );
10734
            }
10735
        }
10736
        this.element.val( value );
10737
        this._refresh();
10738
    },
10739
10740
    _destroy: function() {
10741
        this.element
10742
            .removeClass( "ui-spinner-input" )
10743
            .prop( "disabled", false )
10744
            .removeAttr( "autocomplete" )
10745
            .removeAttr( "role" )
10746
            .removeAttr( "aria-valuemin" )
10747
            .removeAttr( "aria-valuemax" )
10748
            .removeAttr( "aria-valuenow" );
10749
        this.uiSpinner.replaceWith( this.element );
10750
    },
10751
10752
    stepUp: spinner_modifier(function( steps ) {
10753
        this._stepUp( steps );
10754
    }),
10755
    _stepUp: function( steps ) {
10756
        if ( this._start() ) {
10757
            this._spin( (steps || 1) * this.options.step );
10758
            this._stop();
10759
        }
10760
    },
10761
10762
    stepDown: spinner_modifier(function( steps ) {
10763
        this._stepDown( steps );
10764
    }),
10765
    _stepDown: function( steps ) {
10766
        if ( this._start() ) {
10767
            this._spin( (steps || 1) * -this.options.step );
10768
            this._stop();
10769
        }
10770
    },
10771
10772
    pageUp: spinner_modifier(function( pages ) {
10773
        this._stepUp( (pages || 1) * this.options.page );
10774
    }),
10775
10776
    pageDown: spinner_modifier(function( pages ) {
10777
        this._stepDown( (pages || 1) * this.options.page );
10778
    }),
10779
10780
    value: function( newVal ) {
10781
        if ( !arguments.length ) {
10782
            return this._parse( this.element.val() );
10783
        }
10784
        spinner_modifier( this._value ).call( this, newVal );
10785
    },
10786
10787
    widget: function() {
10788
        return this.uiSpinner;
10789
    }
10790
});
10791
10792
10793
/*!
10794
 * jQuery UI Tabs 1.11.4
10795
 * http://jqueryui.com
10796
 *
10797
 * Copyright jQuery Foundation and other contributors
10798
 * Released under the MIT license.
10799
 * http://jquery.org/license
10800
 *
10801
 * http://api.jqueryui.com/tabs/
10802
 */
10803
10804
10805
var tabs = $.widget( "ui.tabs", {
10806
    version: "1.11.4",
10807
    delay: 300,
10808
    options: {
10809
        active: null,
10810
        collapsible: false,
10811
        event: "click",
10812
        heightStyle: "content",
10813
        hide: null,
10814
        show: null,
10815
10816
        // callbacks
10817
        activate: null,
10818
        beforeActivate: null,
10819
        beforeLoad: null,
10820
        load: null
10821
    },
10822
10823
    _isLocal: (function() {
10824
        var rhash = /#.*$/;
10825
10826
        return function( anchor ) {
10827
            var anchorUrl, locationUrl;
10828
10829
            // support: IE7
10830
            // IE7 doesn't normalize the href property when set via script (#9317)
10831
            anchor = anchor.cloneNode( false );
10832
10833
            anchorUrl = anchor.href.replace( rhash, "" );
10834
            locationUrl = location.href.replace( rhash, "" );
10835
10836
            // decoding may throw an error if the URL isn't UTF-8 (#9518)
10837
            try {
10838
                anchorUrl = decodeURIComponent( anchorUrl );
10839
            } catch ( error ) {}
10840
            try {
10841
                locationUrl = decodeURIComponent( locationUrl );
10842
            } catch ( error ) {}
10843
10844
            return anchor.hash.length > 1 && anchorUrl === locationUrl;
10845
        };
10846
    })(),
10847
10848
    _create: function() {
10849
        var that = this,
10850
            options = this.options;
10851
10852
        this.running = false;
10853
10854
        this.element
10855
            .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
10856
            .toggleClass( "ui-tabs-collapsible", options.collapsible );
10857
10858
        this._processTabs();
10859
        options.active = this._initialActive();
10860
10861
        // Take disabling tabs via class attribute from HTML
10862
        // into account and update option properly.
10863
        if ( $.isArray( options.disabled ) ) {
10864
            options.disabled = $.unique( options.disabled.concat(
10865
                $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
10866
                    return that.tabs.index( li );
10867
                })
10868
            ) ).sort();
10869
        }
10870
10871
        // check for length avoids error when initializing empty list
10872
        if ( this.options.active !== false && this.anchors.length ) {
10873
            this.active = this._findActive( options.active );
10874
        } else {
10875
            this.active = $();
10876
        }
10877
10878
        this._refresh();
10879
10880
        if ( this.active.length ) {
10881
            this.load( options.active );
10882
        }
10883
    },
10884
10885
    _initialActive: function() {
10886
        var active = this.options.active,
10887
            collapsible = this.options.collapsible,
10888
            locationHash = location.hash.substring( 1 );
10889
10890
        if ( active === null ) {
10891
            // check the fragment identifier in the URL
10892
            if ( locationHash ) {
10893
                this.tabs.each(function( i, tab ) {
10894
                    if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
10895
                        active = i;
10896
                        return false;
10897
                    }
10898
                });
10899
            }
10900
10901
            // check for a tab marked active via a class
10902
            if ( active === null ) {
10903
                active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
10904
            }
10905
10906
            // no active tab, set to false
10907
            if ( active === null || active === -1 ) {
10908
                active = this.tabs.length ? 0 : false;
10909
            }
10910
        }
10911
10912
        // handle numbers: negative, out of range
10913
        if ( active !== false ) {
10914
            active = this.tabs.index( this.tabs.eq( active ) );
10915
            if ( active === -1 ) {
10916
                active = collapsible ? false : 0;
10917
            }
10918
        }
10919
10920
        // don't allow collapsible: false and active: false
10921
        if ( !collapsible && active === false && this.anchors.length ) {
10922
            active = 0;
10923
        }
10924
10925
        return active;
10926
    },
10927
10928
    _getCreateEventData: function() {
10929
        return {
10930
            tab: this.active,
10931
            panel: !this.active.length ? $() : this._getPanelForTab( this.active )
10932
        };
10933
    },
10934
10935
    _tabKeydown: function( event ) {
10936
        var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
10937
            selectedIndex = this.tabs.index( focusedTab ),
10938
            goingForward = true;
10939
10940
        if ( this._handlePageNav( event ) ) {
10941
            return;
10942
        }
10943
10944
        switch ( event.keyCode ) {
10945
            case $.ui.keyCode.RIGHT:
10946
            case $.ui.keyCode.DOWN:
10947
                selectedIndex++;
10948
                break;
10949
            case $.ui.keyCode.UP:
10950
            case $.ui.keyCode.LEFT:
10951
                goingForward = false;
10952
                selectedIndex--;
10953
                break;
10954
            case $.ui.keyCode.END:
10955
                selectedIndex = this.anchors.length - 1;
10956
                break;
10957
            case $.ui.keyCode.HOME:
10958
                selectedIndex = 0;
10959
                break;
10960
            case $.ui.keyCode.SPACE:
10961
                // Activate only, no collapsing
10962
                event.preventDefault();
10963
                clearTimeout( this.activating );
10964
                this._activate( selectedIndex );
10965
                return;
10966
            case $.ui.keyCode.ENTER:
10967
                // Toggle (cancel delayed activation, allow collapsing)
10968
                event.preventDefault();
10969
                clearTimeout( this.activating );
10970
                // Determine if we should collapse or activate
10971
                this._activate( selectedIndex === this.options.active ? false : selectedIndex );
10972
                return;
10973
            default:
10974
                return;
10975
        }
10976
10977
        // Focus the appropriate tab, based on which key was pressed
10978
        event.preventDefault();
10979
        clearTimeout( this.activating );
10980
        selectedIndex = this._focusNextTab( selectedIndex, goingForward );
10981
10982
        // Navigating with control/command key will prevent automatic activation
10983
        if ( !event.ctrlKey && !event.metaKey ) {
10984
10985
            // Update aria-selected immediately so that AT think the tab is already selected.
10986
            // Otherwise AT may confuse the user by stating that they need to activate the tab,
10987
            // but the tab will already be activated by the time the announcement finishes.
10988
            focusedTab.attr( "aria-selected", "false" );
10989
            this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
10990
10991
            this.activating = this._delay(function() {
10992
                this.option( "active", selectedIndex );
10993
            }, this.delay );
10994
        }
10995
    },
10996
10997
    _panelKeydown: function( event ) {
10998
        if ( this._handlePageNav( event ) ) {
10999
            return;
11000
        }
11001
11002
        // Ctrl+up moves focus to the current tab
11003
        if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
11004
            event.preventDefault();
11005
            this.active.focus();
11006
        }
11007
    },
11008
11009
    // Alt+page up/down moves focus to the previous/next tab (and activates)
11010
    _handlePageNav: function( event ) {
11011
        if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
11012
            this._activate( this._focusNextTab( this.options.active - 1, false ) );
11013
            return true;
11014
        }
11015
        if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
11016
            this._activate( this._focusNextTab( this.options.active + 1, true ) );
11017
            return true;
11018
        }
11019
    },
11020
11021
    _findNextTab: function( index, goingForward ) {
11022
        var lastTabIndex = this.tabs.length - 1;
11023
11024
        function constrain() {
11025
            if ( index > lastTabIndex ) {
11026
                index = 0;
11027
            }
11028
            if ( index < 0 ) {
11029
                index = lastTabIndex;
11030
            }
11031
            return index;
11032
        }
11033
11034
        while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
11035
            index = goingForward ? index + 1 : index - 1;
11036
        }
11037
11038
        return index;
11039
    },
11040
11041
    _focusNextTab: function( index, goingForward ) {
11042
        index = this._findNextTab( index, goingForward );
11043
        this.tabs.eq( index ).focus();
11044
        return index;
11045
    },
11046
11047
    _setOption: function( key, value ) {
11048
        if ( key === "active" ) {
11049
            // _activate() will handle invalid values and update this.options
11050
            this._activate( value );
11051
            return;
11052
        }
11053
11054
        if ( key === "disabled" ) {
11055
            // don't use the widget factory's disabled handling
11056
            this._setupDisabled( value );
11057
            return;
11058
        }
11059
11060
        this._super( key, value);
11061
11062
        if ( key === "collapsible" ) {
11063
            this.element.toggleClass( "ui-tabs-collapsible", value );
11064
            // Setting collapsible: false while collapsed; open first panel
11065
            if ( !value && this.options.active === false ) {
11066
                this._activate( 0 );
11067
            }
11068
        }
11069
11070
        if ( key === "event" ) {
11071
            this._setupEvents( value );
11072
        }
11073
11074
        if ( key === "heightStyle" ) {
11075
            this._setupHeightStyle( value );
11076
        }
11077
    },
11078
11079
    _sanitizeSelector: function( hash ) {
11080
        return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
11081
    },
11082
11083
    refresh: function() {
11084
        var options = this.options,
11085
            lis = this.tablist.children( ":has(a[href])" );
11086
11087
        // get disabled tabs from class attribute from HTML
11088
        // this will get converted to a boolean if needed in _refresh()
11089
        options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
11090
            return lis.index( tab );
11091
        });
11092
11093
        this._processTabs();
11094
11095
        // was collapsed or no tabs
11096
        if ( options.active === false || !this.anchors.length ) {
11097
            options.active = false;
11098
            this.active = $();
11099
        // was active, but active tab is gone
11100
        } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
11101
            // all remaining tabs are disabled
11102
            if ( this.tabs.length === options.disabled.length ) {
11103
                options.active = false;
11104
                this.active = $();
11105
            // activate previous tab
11106
            } else {
11107
                this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
11108
            }
11109
        // was active, active tab still exists
11110
        } else {
11111
            // make sure active index is correct
11112
            options.active = this.tabs.index( this.active );
11113
        }
11114
11115
        this._refresh();
11116
    },
11117
11118
    _refresh: function() {
11119
        this._setupDisabled( this.options.disabled );
11120
        this._setupEvents( this.options.event );
11121
        this._setupHeightStyle( this.options.heightStyle );
11122
11123
        this.tabs.not( this.active ).attr({
11124
            "aria-selected": "false",
11125
            "aria-expanded": "false",
11126
            tabIndex: -1
11127
        });
11128
        this.panels.not( this._getPanelForTab( this.active ) )
11129
            .hide()
11130
            .attr({
11131
                "aria-hidden": "true"
11132
            });
11133
11134
        // Make sure one tab is in the tab order
11135
        if ( !this.active.length ) {
11136
            this.tabs.eq( 0 ).attr( "tabIndex", 0 );
11137
        } else {
11138
            this.active
11139
                .addClass( "ui-tabs-active ui-state-active" )
11140
                .attr({
11141
                    "aria-selected": "true",
11142
                    "aria-expanded": "true",
11143
                    tabIndex: 0
11144
                });
11145
            this._getPanelForTab( this.active )
11146
                .show()
11147
                .attr({
11148
                    "aria-hidden": "false"
11149
                });
11150
        }
11151
    },
11152
11153
    _processTabs: function() {
11154
        var that = this,
11155
            prevTabs = this.tabs,
11156
            prevAnchors = this.anchors,
11157
            prevPanels = this.panels;
11158
11159
        this.tablist = this._getList()
11160
            .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
11161
            .attr( "role", "tablist" )
11162
11163
            // Prevent users from focusing disabled tabs via click
11164
            .delegate( "> li", "mousedown" + this.eventNamespace, function( event ) {
11165
                if ( $( this ).is( ".ui-state-disabled" ) ) {
11166
                    event.preventDefault();
11167
                }
11168
            })
11169
11170
            // support: IE <9
11171
            // Preventing the default action in mousedown doesn't prevent IE
11172
            // from focusing the element, so if the anchor gets focused, blur.
11173
            // We don't have to worry about focusing the previously focused
11174
            // element since clicking on a non-focusable element should focus
11175
            // the body anyway.
11176
            .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
11177
                if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
11178
                    this.blur();
11179
                }
11180
            });
11181
11182
        this.tabs = this.tablist.find( "> li:has(a[href])" )
11183
            .addClass( "ui-state-default ui-corner-top" )
11184
            .attr({
11185
                role: "tab",
11186
                tabIndex: -1
11187
            });
11188
11189
        this.anchors = this.tabs.map(function() {
11190
                return $( "a", this )[ 0 ];
11191
            })
11192
            .addClass( "ui-tabs-anchor" )
11193
            .attr({
11194
                role: "presentation",
11195
                tabIndex: -1
11196
            });
11197
11198
        this.panels = $();
11199
11200
        this.anchors.each(function( i, anchor ) {
11201
            var selector, panel, panelId,
11202
                anchorId = $( anchor ).uniqueId().attr( "id" ),
11203
                tab = $( anchor ).closest( "li" ),
11204
                originalAriaControls = tab.attr( "aria-controls" );
11205
11206
            // inline tab
11207
            if ( that._isLocal( anchor ) ) {
11208
                selector = anchor.hash;
11209
                panelId = selector.substring( 1 );
11210
                panel = that.element.find( that._sanitizeSelector( selector ) );
11211
            // remote tab
11212
            } else {
11213
                // If the tab doesn't already have aria-controls,
11214
                // generate an id by using a throw-away element
11215
                panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
11216
                selector = "#" + panelId;
11217
                panel = that.element.find( selector );
11218
                if ( !panel.length ) {
11219
                    panel = that._createPanel( panelId );
11220
                    panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
11221
                }
11222
                panel.attr( "aria-live", "polite" );
11223
            }
11224
11225
            if ( panel.length) {
11226
                that.panels = that.panels.add( panel );
11227
            }
11228
            if ( originalAriaControls ) {
11229
                tab.data( "ui-tabs-aria-controls", originalAriaControls );
11230
            }
11231
            tab.attr({
11232
                "aria-controls": panelId,
11233
                "aria-labelledby": anchorId
11234
            });
11235
            panel.attr( "aria-labelledby", anchorId );
11236
        });
11237
11238
        this.panels
11239
            .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
11240
            .attr( "role", "tabpanel" );
11241
11242
        // Avoid memory leaks (#10056)
11243
        if ( prevTabs ) {
11244
            this._off( prevTabs.not( this.tabs ) );
11245
            this._off( prevAnchors.not( this.anchors ) );
11246
            this._off( prevPanels.not( this.panels ) );
11247
        }
11248
    },
11249
11250
    // allow overriding how to find the list for rare usage scenarios (#7715)
11251
    _getList: function() {
11252
        return this.tablist || this.element.find( "ol,ul" ).eq( 0 );
11253
    },
11254
11255
    _createPanel: function( id ) {
11256
        return $( "<div>" )
11257
            .attr( "id", id )
11258
            .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
11259
            .data( "ui-tabs-destroy", true );
11260
    },
11261
11262
    _setupDisabled: function( disabled ) {
11263
        if ( $.isArray( disabled ) ) {
11264
            if ( !disabled.length ) {
11265
                disabled = false;
11266
            } else if ( disabled.length === this.anchors.length ) {
11267
                disabled = true;
11268
            }
11269
        }
11270
11271
        // disable tabs
11272
        for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
11273
            if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
11274
                $( li )
11275
                    .addClass( "ui-state-disabled" )
11276
                    .attr( "aria-disabled", "true" );
11277
            } else {
11278
                $( li )
11279
                    .removeClass( "ui-state-disabled" )
11280
                    .removeAttr( "aria-disabled" );
11281
            }
11282
        }
11283
11284
        this.options.disabled = disabled;
11285
    },
11286
11287
    _setupEvents: function( event ) {
11288
        var events = {};
11289
        if ( event ) {
11290
            $.each( event.split(" "), function( index, eventName ) {
11291
                events[ eventName ] = "_eventHandler";
11292
            });
11293
        }
11294
11295
        this._off( this.anchors.add( this.tabs ).add( this.panels ) );
11296
        // Always prevent the default action, even when disabled
11297
        this._on( true, this.anchors, {
11298
            click: function( event ) {
11299
                event.preventDefault();
11300
            }
11301
        });
11302
        this._on( this.anchors, events );
11303
        this._on( this.tabs, { keydown: "_tabKeydown" } );
11304
        this._on( this.panels, { keydown: "_panelKeydown" } );
11305
11306
        this._focusable( this.tabs );
11307
        this._hoverable( this.tabs );
11308
    },
11309
11310
    _setupHeightStyle: function( heightStyle ) {
11311
        var maxHeight,
11312
            parent = this.element.parent();
11313
11314
        if ( heightStyle === "fill" ) {
11315
            maxHeight = parent.height();
11316
            maxHeight -= this.element.outerHeight() - this.element.height();
11317
11318
            this.element.siblings( ":visible" ).each(function() {
11319
                var elem = $( this ),
11320
                    position = elem.css( "position" );
11321
11322
                if ( position === "absolute" || position === "fixed" ) {
11323
                    return;
11324
                }
11325
                maxHeight -= elem.outerHeight( true );
11326
            });
11327
11328
            this.element.children().not( this.panels ).each(function() {
11329
                maxHeight -= $( this ).outerHeight( true );
11330
            });
11331
11332
            this.panels.each(function() {
11333
                $( this ).height( Math.max( 0, maxHeight -
11334
                    $( this ).innerHeight() + $( this ).height() ) );
11335
            })
11336
            .css( "overflow", "auto" );
11337
        } else if ( heightStyle === "auto" ) {
11338
            maxHeight = 0;
11339
            this.panels.each(function() {
11340
                maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
11341
            }).height( maxHeight );
11342
        }
11343
    },
11344
11345
    _eventHandler: function( event ) {
11346
        var options = this.options,
11347
            active = this.active,
11348
            anchor = $( event.currentTarget ),
11349
            tab = anchor.closest( "li" ),
11350
            clickedIsActive = tab[ 0 ] === active[ 0 ],
11351
            collapsing = clickedIsActive && options.collapsible,
11352
            toShow = collapsing ? $() : this._getPanelForTab( tab ),
11353
            toHide = !active.length ? $() : this._getPanelForTab( active ),
11354
            eventData = {
11355
                oldTab: active,
11356
                oldPanel: toHide,
11357
                newTab: collapsing ? $() : tab,
11358
                newPanel: toShow
11359
            };
11360
11361
        event.preventDefault();
11362
11363
        if ( tab.hasClass( "ui-state-disabled" ) ||
11364
                // tab is already loading
11365
                tab.hasClass( "ui-tabs-loading" ) ||
11366
                // can't switch durning an animation
11367
                this.running ||
11368
                // click on active header, but not collapsible
11369
                ( clickedIsActive && !options.collapsible ) ||
11370
                // allow canceling activation
11371
                ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
11372
            return;
11373
        }
11374
11375
        options.active = collapsing ? false : this.tabs.index( tab );
11376
11377
        this.active = clickedIsActive ? $() : tab;
11378
        if ( this.xhr ) {
11379
            this.xhr.abort();
11380
        }
11381
11382
        if ( !toHide.length && !toShow.length ) {
11383
            $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
11384
        }
11385
11386
        if ( toShow.length ) {
11387
            this.load( this.tabs.index( tab ), event );
11388
        }
11389
        this._toggle( event, eventData );
11390
    },
11391
11392
    // handles show/hide for selecting tabs
11393
    _toggle: function( event, eventData ) {
11394
        var that = this,
11395
            toShow = eventData.newPanel,
11396
            toHide = eventData.oldPanel;
11397
11398
        this.running = true;
11399
11400
        function complete() {
11401
            that.running = false;
11402
            that._trigger( "activate", event, eventData );
11403
        }
11404
11405
        function show() {
11406
            eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
11407
11408
            if ( toShow.length && that.options.show ) {
11409
                that._show( toShow, that.options.show, complete );
11410
            } else {
11411
                toShow.show();
11412
                complete();
11413
            }
11414
        }
11415
11416
        // start out by hiding, then showing, then completing
11417
        if ( toHide.length && this.options.hide ) {
11418
            this._hide( toHide, this.options.hide, function() {
11419
                eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
11420
                show();
11421
            });
11422
        } else {
11423
            eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
11424
            toHide.hide();
11425
            show();
11426
        }
11427
11428
        toHide.attr( "aria-hidden", "true" );
11429
        eventData.oldTab.attr({
11430
            "aria-selected": "false",
11431
            "aria-expanded": "false"
11432
        });
11433
        // If we're switching tabs, remove the old tab from the tab order.
11434
        // If we're opening from collapsed state, remove the previous tab from the tab order.
11435
        // If we're collapsing, then keep the collapsing tab in the tab order.
11436
        if ( toShow.length && toHide.length ) {
11437
            eventData.oldTab.attr( "tabIndex", -1 );
11438
        } else if ( toShow.length ) {
11439
            this.tabs.filter(function() {
11440
                return $( this ).attr( "tabIndex" ) === 0;
11441
            })
11442
            .attr( "tabIndex", -1 );
11443
        }
11444
11445
        toShow.attr( "aria-hidden", "false" );
11446
        eventData.newTab.attr({
11447
            "aria-selected": "true",
11448
            "aria-expanded": "true",
11449
            tabIndex: 0
11450
        });
11451
    },
11452
11453
    _activate: function( index ) {
11454
        var anchor,
11455
            active = this._findActive( index );
11456
11457
        // trying to activate the already active panel
11458
        if ( active[ 0 ] === this.active[ 0 ] ) {
11459
            return;
11460
        }
11461
11462
        // trying to collapse, simulate a click on the current active header
11463
        if ( !active.length ) {
11464
            active = this.active;
11465
        }
11466
11467
        anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
11468
        this._eventHandler({
11469
            target: anchor,
11470
            currentTarget: anchor,
11471
            preventDefault: $.noop
11472
        });
11473
    },
11474
11475
    _findActive: function( index ) {
11476
        return index === false ? $() : this.tabs.eq( index );
11477
    },
11478
11479
    _getIndex: function( index ) {
11480
        // meta-function to give users option to provide a href string instead of a numerical index.
11481
        if ( typeof index === "string" ) {
11482
            index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
11483
        }
11484
11485
        return index;
11486
    },
11487
11488
    _destroy: function() {
11489
        if ( this.xhr ) {
11490
            this.xhr.abort();
11491
        }
11492
11493
        this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
11494
11495
        this.tablist
11496
            .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
11497
            .removeAttr( "role" );
11498
11499
        this.anchors
11500
            .removeClass( "ui-tabs-anchor" )
11501
            .removeAttr( "role" )
11502
            .removeAttr( "tabIndex" )
11503
            .removeUniqueId();
11504
11505
        this.tablist.unbind( this.eventNamespace );
11506
11507
        this.tabs.add( this.panels ).each(function() {
11508
            if ( $.data( this, "ui-tabs-destroy" ) ) {
11509
                $( this ).remove();
11510
            } else {
11511
                $( this )
11512
                    .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
11513
                        "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
11514
                    .removeAttr( "tabIndex" )
11515
                    .removeAttr( "aria-live" )
11516
                    .removeAttr( "aria-busy" )
11517
                    .removeAttr( "aria-selected" )
11518
                    .removeAttr( "aria-labelledby" )
11519
                    .removeAttr( "aria-hidden" )
11520
                    .removeAttr( "aria-expanded" )
11521
                    .removeAttr( "role" );
11522
            }
11523
        });
11524
11525
        this.tabs.each(function() {
11526
            var li = $( this ),
11527
                prev = li.data( "ui-tabs-aria-controls" );
11528
            if ( prev ) {
11529
                li
11530
                    .attr( "aria-controls", prev )
11531
                    .removeData( "ui-tabs-aria-controls" );
11532
            } else {
11533
                li.removeAttr( "aria-controls" );
11534
            }
11535
        });
11536
11537
        this.panels.show();
11538
11539
        if ( this.options.heightStyle !== "content" ) {
11540
            this.panels.css( "height", "" );
11541
        }
11542
    },
11543
11544
    enable: function( index ) {
11545
        var disabled = this.options.disabled;
11546
        if ( disabled === false ) {
11547
            return;
11548
        }
11549
11550
        if ( index === undefined ) {
11551
            disabled = false;
11552
        } else {
11553
            index = this._getIndex( index );
11554
            if ( $.isArray( disabled ) ) {
11555
                disabled = $.map( disabled, function( num ) {
11556
                    return num !== index ? num : null;
11557
                });
11558
            } else {
11559
                disabled = $.map( this.tabs, function( li, num ) {
11560
                    return num !== index ? num : null;
11561
                });
11562
            }
11563
        }
11564
        this._setupDisabled( disabled );
11565
    },
11566
11567
    disable: function( index ) {
11568
        var disabled = this.options.disabled;
11569
        if ( disabled === true ) {
11570
            return;
11571
        }
11572
11573
        if ( index === undefined ) {
11574
            disabled = true;
11575
        } else {
11576
            index = this._getIndex( index );
11577
            if ( $.inArray( index, disabled ) !== -1 ) {
11578
                return;
11579
            }
11580
            if ( $.isArray( disabled ) ) {
11581
                disabled = $.merge( [ index ], disabled ).sort();
11582
            } else {
11583
                disabled = [ index ];
11584
            }
11585
        }
11586
        this._setupDisabled( disabled );
11587
    },
11588
11589
    load: function( index, event ) {
11590
        index = this._getIndex( index );
11591
        var that = this,
11592
            tab = this.tabs.eq( index ),
11593
            anchor = tab.find( ".ui-tabs-anchor" ),
11594
            panel = this._getPanelForTab( tab ),
11595
            eventData = {
11596
                tab: tab,
11597
                panel: panel
11598
            },
11599
            complete = function( jqXHR, status ) {
11600
                if ( status === "abort" ) {
11601
                    that.panels.stop( false, true );
11602
                }
11603
11604
                tab.removeClass( "ui-tabs-loading" );
11605
                panel.removeAttr( "aria-busy" );
11606
11607
                if ( jqXHR === that.xhr ) {
11608
                    delete that.xhr;
11609
                }
11610
            };
11611
11612
        // not remote
11613
        if ( this._isLocal( anchor[ 0 ] ) ) {
11614
            return;
11615
        }
11616
11617
        this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
11618
11619
        // support: jQuery <1.8
11620
        // jQuery <1.8 returns false if the request is canceled in beforeSend,
11621
        // but as of 1.8, $.ajax() always returns a jqXHR object.
11622
        if ( this.xhr && this.xhr.statusText !== "canceled" ) {
11623
            tab.addClass( "ui-tabs-loading" );
11624
            panel.attr( "aria-busy", "true" );
11625
11626
            this.xhr
11627
                .done(function( response, status, jqXHR ) {
11628
                    // support: jQuery <1.8
11629
                    // http://bugs.jquery.com/ticket/11778
11630
                    setTimeout(function() {
11631
                        panel.html( response );
11632
                        that._trigger( "load", event, eventData );
11633
11634
                        complete( jqXHR, status );
11635
                    }, 1 );
11636
                })
11637
                .fail(function( jqXHR, status ) {
11638
                    // support: jQuery <1.8
11639
                    // http://bugs.jquery.com/ticket/11778
11640
                    setTimeout(function() {
11641
                        complete( jqXHR, status );
11642
                    }, 1 );
11643
                });
11644
        }
11645
    },
11646
11647
    _ajaxSettings: function( anchor, event, eventData ) {
11648
        var that = this;
11649
        return {
11650
            url: anchor.attr( "href" ),
11651
            beforeSend: function( jqXHR, settings ) {
11652
                return that._trigger( "beforeLoad", event,
11653
                    $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
11654
            }
11655
        };
11656
    },
11657
11658
    _getPanelForTab: function( tab ) {
11659
        var id = $( tab ).attr( "aria-controls" );
11660
        return this.element.find( this._sanitizeSelector( "#" + id ) );
11661
    }
11662
});
11663
11664
11665
/*!
11666
 * jQuery UI Tooltip 1.11.4
11667
 * http://jqueryui.com
11668
 *
11669
 * Copyright jQuery Foundation and other contributors
11670
 * Released under the MIT license.
11671
 * http://jquery.org/license
11672
 *
11673
 * http://api.jqueryui.com/tooltip/
11674
 */
11675
11676
11677
var tooltip = $.widget( "ui.tooltip", {
11678
    version: "1.11.4",
11679
    options: {
11680
        content: function() {
11681
            // support: IE<9, Opera in jQuery <1.7
11682
            // .text() can't accept undefined, so coerce to a string
11683
            var title = $( this ).attr( "title" ) || "";
11684
            // Escape title, since we're going from an attribute to raw HTML
11685
            return $( "<a>" ).text( title ).html();
11686
        },
11687
        hide: true,
11688
        // Disabled elements have inconsistent behavior across browsers (#8661)
11689
        items: "[title]:not([disabled])",
11690
        position: {
11691
            my: "left top+15",
11692
            at: "left bottom",
11693
            collision: "flipfit flip"
11694
        },
11695
        show: true,
11696
        tooltipClass: null,
11697
        track: false,
11698
11699
        // callbacks
11700
        close: null,
11701
        open: null
11702
    },
11703
11704
    _addDescribedBy: function( elem, id ) {
11705
        var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
11706
        describedby.push( id );
11707
        elem
11708
            .data( "ui-tooltip-id", id )
11709
            .attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
11710
    },
11711
11712
    _removeDescribedBy: function( elem ) {
11713
        var id = elem.data( "ui-tooltip-id" ),
11714
            describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
11715
            index = $.inArray( id, describedby );
11716
11717
        if ( index !== -1 ) {
11718
            describedby.splice( index, 1 );
11719
        }
11720
11721
        elem.removeData( "ui-tooltip-id" );
11722
        describedby = $.trim( describedby.join( " " ) );
11723
        if ( describedby ) {
11724
            elem.attr( "aria-describedby", describedby );
11725
        } else {
11726
            elem.removeAttr( "aria-describedby" );
11727
        }
11728
    },
11729
11730
    _create: function() {
11731
        this._on({
11732
            mouseover: "open",
11733
            focusin: "open"
11734
        });
11735
11736
        // IDs of generated tooltips, needed for destroy
11737
        this.tooltips = {};
11738
11739
        // IDs of parent tooltips where we removed the title attribute
11740
        this.parents = {};
11741
11742
        if ( this.options.disabled ) {
11743
            this._disable();
11744
        }
11745
11746
        // Append the aria-live region so tooltips announce correctly
11747
        this.liveRegion = $( "<div>" )
11748
            .attr({
11749
                role: "log",
11750
                "aria-live": "assertive",
11751
                "aria-relevant": "additions"
11752
            })
11753
            .addClass( "ui-helper-hidden-accessible" )
11754
            .appendTo( this.document[ 0 ].body );
11755
    },
11756
11757
    _setOption: function( key, value ) {
11758
        var that = this;
11759
11760
        if ( key === "disabled" ) {
11761
            this[ value ? "_disable" : "_enable" ]();
11762
            this.options[ key ] = value;
11763
            // disable element style changes
11764
            return;
11765
        }
11766
11767
        this._super( key, value );
11768
11769
        if ( key === "content" ) {
11770
            $.each( this.tooltips, function( id, tooltipData ) {
11771
                that._updateContent( tooltipData.element );
11772
            });
11773
        }
11774
    },
11775
11776
    _disable: function() {
11777
        var that = this;
11778
11779
        // close open tooltips
11780
        $.each( this.tooltips, function( id, tooltipData ) {
11781
            var event = $.Event( "blur" );
11782
            event.target = event.currentTarget = tooltipData.element[ 0 ];
11783
            that.close( event, true );
11784
        });
11785
11786
        // remove title attributes to prevent native tooltips
11787
        this.element.find( this.options.items ).addBack().each(function() {
11788
            var element = $( this );
11789
            if ( element.is( "[title]" ) ) {
11790
                element
11791
                    .data( "ui-tooltip-title", element.attr( "title" ) )
11792
                    .removeAttr( "title" );
11793
            }
11794
        });
11795
    },
11796
11797
    _enable: function() {
11798
        // restore title attributes
11799
        this.element.find( this.options.items ).addBack().each(function() {
11800
            var element = $( this );
11801
            if ( element.data( "ui-tooltip-title" ) ) {
11802
                element.attr( "title", element.data( "ui-tooltip-title" ) );
11803
            }
11804
        });
11805
    },
11806
11807
    open: function( event ) {
11808
        var that = this,
11809
            target = $( event ? event.target : this.element )
11810
                // we need closest here due to mouseover bubbling,
11811
                // but always pointing at the same event target
11812
                .closest( this.options.items );
11813
11814
        // No element to show a tooltip for or the tooltip is already open
11815
        if ( !target.length || target.data( "ui-tooltip-id" ) ) {
11816
            return;
11817
        }
11818
11819
        if ( target.attr( "title" ) ) {
11820
            target.data( "ui-tooltip-title", target.attr( "title" ) );
11821
        }
11822
11823
        target.data( "ui-tooltip-open", true );
11824
11825
        // kill parent tooltips, custom or native, for hover
11826
        if ( event && event.type === "mouseover" ) {
11827
            target.parents().each(function() {
11828
                var parent = $( this ),
11829
                    blurEvent;
11830
                if ( parent.data( "ui-tooltip-open" ) ) {
11831
                    blurEvent = $.Event( "blur" );
11832
                    blurEvent.target = blurEvent.currentTarget = this;
11833
                    that.close( blurEvent, true );
11834
                }
11835
                if ( parent.attr( "title" ) ) {
11836
                    parent.uniqueId();
11837
                    that.parents[ this.id ] = {
11838
                        element: this,
11839
                        title: parent.attr( "title" )
11840
                    };
11841
                    parent.attr( "title", "" );
11842
                }
11843
            });
11844
        }
11845
11846
        this._registerCloseHandlers( event, target );
11847
        this._updateContent( target, event );
11848
    },
11849
11850
    _updateContent: function( target, event ) {
11851
        var content,
11852
            contentOption = this.options.content,
11853
            that = this,
11854
            eventType = event ? event.type : null;
11855
11856
        if ( typeof contentOption === "string" ) {
11857
            return this._open( event, target, contentOption );
11858
        }
11859
11860
        content = contentOption.call( target[0], function( response ) {
11861
11862
            // IE may instantly serve a cached response for ajax requests
11863
            // delay this call to _open so the other call to _open runs first
11864
            that._delay(function() {
11865
11866
                // Ignore async response if tooltip was closed already
11867
                if ( !target.data( "ui-tooltip-open" ) ) {
11868
                    return;
11869
                }
11870
11871
                // jQuery creates a special event for focusin when it doesn't
11872
                // exist natively. To improve performance, the native event
11873
                // object is reused and the type is changed. Therefore, we can't
11874
                // rely on the type being correct after the event finished
11875
                // bubbling, so we set it back to the previous value. (#8740)
11876
                if ( event ) {
11877
                    event.type = eventType;
11878
                }
11879
                this._open( event, target, response );
11880
            });
11881
        });
11882
        if ( content ) {
11883
            this._open( event, target, content );
11884
        }
11885
    },
11886
11887
    _open: function( event, target, content ) {
11888
        var tooltipData, tooltip, delayedShow, a11yContent,
11889
            positionOption = $.extend( {}, this.options.position );
11890
11891
        if ( !content ) {
11892
            return;
11893
        }
11894
11895
        // Content can be updated multiple times. If the tooltip already
11896
        // exists, then just update the content and bail.
11897
        tooltipData = this._find( target );
11898
        if ( tooltipData ) {
11899
            tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
11900
            return;
11901
        }
11902
11903
        // if we have a title, clear it to prevent the native tooltip
11904
        // we have to check first to avoid defining a title if none exists
11905
        // (we don't want to cause an element to start matching [title])
11906
        //
11907
        // We use removeAttr only for key events, to allow IE to export the correct
11908
        // accessible attributes. For mouse events, set to empty string to avoid
11909
        // native tooltip showing up (happens only when removing inside mouseover).
11910
        if ( target.is( "[title]" ) ) {
11911
            if ( event && event.type === "mouseover" ) {
11912
                target.attr( "title", "" );
11913
            } else {
11914
                target.removeAttr( "title" );
11915
            }
11916
        }
11917
11918
        tooltipData = this._tooltip( target );
11919
        tooltip = tooltipData.tooltip;
11920
        this._addDescribedBy( target, tooltip.attr( "id" ) );
11921
        tooltip.find( ".ui-tooltip-content" ).html( content );
11922
11923
        // Support: Voiceover on OS X, JAWS on IE <= 9
11924
        // JAWS announces deletions even when aria-relevant="additions"
11925
        // Voiceover will sometimes re-read the entire log region's contents from the beginning
11926
        this.liveRegion.children().hide();
11927
        if ( content.clone ) {
11928
            a11yContent = content.clone();
11929
            a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
11930
        } else {
11931
            a11yContent = content;
11932
        }
11933
        $( "<div>" ).html( a11yContent ).appendTo( this.liveRegion );
11934
11935
        function position( event ) {
11936
            positionOption.of = event;
11937
            if ( tooltip.is( ":hidden" ) ) {
11938
                return;
11939
            }
11940
            tooltip.position( positionOption );
11941
        }
11942
        if ( this.options.track && event && /^mouse/.test( event.type ) ) {
11943
            this._on( this.document, {
11944
                mousemove: position
11945
            });
11946
            // trigger once to override element-relative positioning
11947
            position( event );
11948
        } else {
11949
            tooltip.position( $.extend({
11950
                of: target
11951
            }, this.options.position ) );
11952
        }
11953
11954
        tooltip.hide();
11955
11956
        this._show( tooltip, this.options.show );
11957
        // Handle tracking tooltips that are shown with a delay (#8644). As soon
11958
        // as the tooltip is visible, position the tooltip using the most recent
11959
        // event.
11960
        if ( this.options.show && this.options.show.delay ) {
11961
            delayedShow = this.delayedShow = setInterval(function() {
11962
                if ( tooltip.is( ":visible" ) ) {
11963
                    position( positionOption.of );
11964
                    clearInterval( delayedShow );
11965
                }
11966
            }, $.fx.interval );
11967
        }
11968
11969
        this._trigger( "open", event, { tooltip: tooltip } );
11970
    },
11971
11972
    _registerCloseHandlers: function( event, target ) {
11973
        var events = {
11974
            keyup: function( event ) {
11975
                if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
11976
                    var fakeEvent = $.Event(event);
11977
                    fakeEvent.currentTarget = target[0];
11978
                    this.close( fakeEvent, true );
11979
                }
11980
            }
11981
        };
11982
11983
        // Only bind remove handler for delegated targets. Non-delegated
11984
        // tooltips will handle this in destroy.
11985
        if ( target[ 0 ] !== this.element[ 0 ] ) {
11986
            events.remove = function() {
11987
                this._removeTooltip( this._find( target ).tooltip );
11988
            };
11989
        }
11990
11991
        if ( !event || event.type === "mouseover" ) {
11992
            events.mouseleave = "close";
11993
        }
11994
        if ( !event || event.type === "focusin" ) {
11995
            events.focusout = "close";
11996
        }
11997
        this._on( true, target, events );
11998
    },
11999
12000
    close: function( event ) {
12001
        var tooltip,
12002
            that = this,
12003
            target = $( event ? event.currentTarget : this.element ),
12004
            tooltipData = this._find( target );
12005
12006
        // The tooltip may already be closed
12007
        if ( !tooltipData ) {
12008
12009
            // We set ui-tooltip-open immediately upon open (in open()), but only set the
12010
            // additional data once there's actually content to show (in _open()). So even if the
12011
            // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
12012
            // the period between open() and _open().
12013
            target.removeData( "ui-tooltip-open" );
12014
            return;
12015
        }
12016
12017
        tooltip = tooltipData.tooltip;
12018
12019
        // disabling closes the tooltip, so we need to track when we're closing
12020
        // to avoid an infinite loop in case the tooltip becomes disabled on close
12021
        if ( tooltipData.closing ) {
12022
            return;
12023
        }
12024
12025
        // Clear the interval for delayed tracking tooltips
12026
        clearInterval( this.delayedShow );
12027
12028
        // only set title if we had one before (see comment in _open())
12029
        // If the title attribute has changed since open(), don't restore
12030
        if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
12031
            target.attr( "title", target.data( "ui-tooltip-title" ) );
12032
        }
12033
12034
        this._removeDescribedBy( target );
12035
12036
        tooltipData.hiding = true;
12037
        tooltip.stop( true );
12038
        this._hide( tooltip, this.options.hide, function() {
12039
            that._removeTooltip( $( this ) );
12040
        });
12041
12042
        target.removeData( "ui-tooltip-open" );
12043
        this._off( target, "mouseleave focusout keyup" );
12044
12045
        // Remove 'remove' binding only on delegated targets
12046
        if ( target[ 0 ] !== this.element[ 0 ] ) {
12047
            this._off( target, "remove" );
12048
        }
12049
        this._off( this.document, "mousemove" );
12050
12051
        if ( event && event.type === "mouseleave" ) {
12052
            $.each( this.parents, function( id, parent ) {
12053
                $( parent.element ).attr( "title", parent.title );
12054
                delete that.parents[ id ];
12055
            });
12056
        }
12057
12058
        tooltipData.closing = true;
12059
        this._trigger( "close", event, { tooltip: tooltip } );
12060
        if ( !tooltipData.hiding ) {
12061
            tooltipData.closing = false;
12062
        }
12063
    },
12064
12065
    _tooltip: function( element ) {
12066
        var tooltip = $( "<div>" )
12067
                .attr( "role", "tooltip" )
12068
                .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
12069
                    ( this.options.tooltipClass || "" ) ),
12070
            id = tooltip.uniqueId().attr( "id" );
12071
12072
        $( "<div>" )
12073
            .addClass( "ui-tooltip-content" )
12074
            .appendTo( tooltip );
12075
12076
        tooltip.appendTo( this.document[0].body );
12077
12078
        return this.tooltips[ id ] = {
12079
            element: element,
12080
            tooltip: tooltip
12081
        };
12082
    },
12083
12084
    _find: function( target ) {
12085
        var id = target.data( "ui-tooltip-id" );
12086
        return id ? this.tooltips[ id ] : null;
12087
    },
12088
12089
    _removeTooltip: function( tooltip ) {
12090
        tooltip.remove();
12091
        delete this.tooltips[ tooltip.attr( "id" ) ];
12092
    },
12093
12094
    _destroy: function() {
12095
        var that = this;
12096
12097
        // close open tooltips
12098
        $.each( this.tooltips, function( id, tooltipData ) {
12099
            // Delegate to close method to handle common cleanup
12100
            var event = $.Event( "blur" ),
12101
                element = tooltipData.element;
12102
            event.target = event.currentTarget = element[ 0 ];
12103
            that.close( event, true );
12104
12105
            // Remove immediately; destroying an open tooltip doesn't use the
12106
            // hide animation
12107
            $( "#" + id ).remove();
12108
12109
            // Restore the title
12110
            if ( element.data( "ui-tooltip-title" ) ) {
12111
                // If the title attribute has changed since open(), don't restore
12112
                if ( !element.attr( "title" ) ) {
12113
                    element.attr( "title", element.data( "ui-tooltip-title" ) );
12114
                }
12115
                element.removeData( "ui-tooltip-title" );
12116
            }
12117
        });
12118
        this.liveRegion.remove();
12119
    }
12120
});
12121
12122
12123
/*!
12124
 * jQuery UI Effects 1.11.4
12125
 * http://jqueryui.com
12126
 *
12127
 * Copyright jQuery Foundation and other contributors
12128
 * Released under the MIT license.
12129
 * http://jquery.org/license
12130
 *
12131
 * http://api.jqueryui.com/category/effects-core/
12132
 */
12133
12134
12135
var dataSpace = "ui-effects-",
12136
12137
    // Create a local jQuery because jQuery Color relies on it and the
12138
    // global may not exist with AMD and a custom build (#10199)
12139
    jQuery = $;
12140
12141
$.effects = {
12142
    effect: {}
12143
};
12144
12145
/*!
12146
 * jQuery Color Animations v2.1.2
12147
 * https://github.com/jquery/jquery-color
12148
 *
12149
 * Copyright 2014 jQuery Foundation and other contributors
12150
 * Released under the MIT license.
12151
 * http://jquery.org/license
12152
 *
12153
 * Date: Wed Jan 16 08:47:09 2013 -0600
12154
 */
12155
(function( jQuery, undefined ) {
12156
12157
    var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
12158
12159
    // plusequals test for += 100 -= 100
12160
    rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
12161
    // a set of RE's that can match strings and generate color tuples.
12162
    stringParsers = [ {
12163
            re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
12164
            parse: function( execResult ) {
12165
                return [
12166
                    execResult[ 1 ],
12167
                    execResult[ 2 ],
12168
                    execResult[ 3 ],
12169
                    execResult[ 4 ]
12170
                ];
12171
            }
12172
        }, {
12173
            re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
12174
            parse: function( execResult ) {
12175
                return [
12176
                    execResult[ 1 ] * 2.55,
12177
                    execResult[ 2 ] * 2.55,
12178
                    execResult[ 3 ] * 2.55,
12179
                    execResult[ 4 ]
12180
                ];
12181
            }
12182
        }, {
12183
            // this regex ignores A-F because it's compared against an already lowercased string
12184
            re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
12185
            parse: function( execResult ) {
12186
                return [
12187
                    parseInt( execResult[ 1 ], 16 ),
12188
                    parseInt( execResult[ 2 ], 16 ),
12189
                    parseInt( execResult[ 3 ], 16 )
12190
                ];
12191
            }
12192
        }, {
12193
            // this regex ignores A-F because it's compared against an already lowercased string
12194
            re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
12195
            parse: function( execResult ) {
12196
                return [
12197
                    parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
12198
                    parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
12199
                    parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
12200
                ];
12201
            }
12202
        }, {
12203
            re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
12204
            space: "hsla",
12205
            parse: function( execResult ) {
12206
                return [
12207
                    execResult[ 1 ],
12208
                    execResult[ 2 ] / 100,
12209
                    execResult[ 3 ] / 100,
12210
                    execResult[ 4 ]
12211
                ];
12212
            }
12213
        } ],
12214
12215
    // jQuery.Color( )
12216
    color = jQuery.Color = function( color, green, blue, alpha ) {
12217
        return new jQuery.Color.fn.parse( color, green, blue, alpha );
12218
    },
12219
    spaces = {
12220
        rgba: {
12221
            props: {
12222
                red: {
12223
                    idx: 0,
12224
                    type: "byte"
12225
                },
12226
                green: {
12227
                    idx: 1,
12228
                    type: "byte"
12229
                },
12230
                blue: {
12231
                    idx: 2,
12232
                    type: "byte"
12233
                }
12234
            }
12235
        },
12236
12237
        hsla: {
12238
            props: {
12239
                hue: {
12240
                    idx: 0,
12241
                    type: "degrees"
12242
                },
12243
                saturation: {
12244
                    idx: 1,
12245
                    type: "percent"
12246
                },
12247
                lightness: {
12248
                    idx: 2,
12249
                    type: "percent"
12250
                }
12251
            }
12252
        }
12253
    },
12254
    propTypes = {
12255
        "byte": {
12256
            floor: true,
12257
            max: 255
12258
        },
12259
        "percent": {
12260
            max: 1
12261
        },
12262
        "degrees": {
12263
            mod: 360,
12264
            floor: true
12265
        }
12266
    },
12267
    support = color.support = {},
12268
12269
    // element for support tests
12270
    supportElem = jQuery( "<p>" )[ 0 ],
12271
12272
    // colors = jQuery.Color.names
12273
    colors,
12274
12275
    // local aliases of functions called often
12276
    each = jQuery.each;
12277
12278
// determine rgba support immediately
12279
supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
12280
support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
12281
12282
// define cache name and alpha properties
12283
// for rgba and hsla spaces
12284
each( spaces, function( spaceName, space ) {
12285
    space.cache = "_" + spaceName;
12286
    space.props.alpha = {
12287
        idx: 3,
12288
        type: "percent",
12289
        def: 1
12290
    };
12291
});
12292
12293
function clamp( value, prop, allowEmpty ) {
12294
    var type = propTypes[ prop.type ] || {};
12295
12296
    if ( value == null ) {
12297
        return (allowEmpty || !prop.def) ? null : prop.def;
12298
    }
12299
12300
    // ~~ is an short way of doing floor for positive numbers
12301
    value = type.floor ? ~~value : parseFloat( value );
12302
12303
    // IE will pass in empty strings as value for alpha,
12304
    // which will hit this case
12305
    if ( isNaN( value ) ) {
12306
        return prop.def;
12307
    }
12308
12309
    if ( type.mod ) {
12310
        // we add mod before modding to make sure that negatives values
12311
        // get converted properly: -10 -> 350
12312
        return (value + type.mod) % type.mod;
12313
    }
12314
12315
    // for now all property types without mod have min and max
12316
    return 0 > value ? 0 : type.max < value ? type.max : value;
12317
}
12318
12319
function stringParse( string ) {
12320
    var inst = color(),
12321
        rgba = inst._rgba = [];
12322
12323
    string = string.toLowerCase();
12324
12325
    each( stringParsers, function( i, parser ) {
12326
        var parsed,
12327
            match = parser.re.exec( string ),
12328
            values = match && parser.parse( match ),
12329
            spaceName = parser.space || "rgba";
12330
12331
        if ( values ) {
12332
            parsed = inst[ spaceName ]( values );
12333
12334
            // if this was an rgba parse the assignment might happen twice
12335
            // oh well....
12336
            inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
12337
            rgba = inst._rgba = parsed._rgba;
12338
12339
            // exit each( stringParsers ) here because we matched
12340
            return false;
12341
        }
12342
    });
12343
12344
    // Found a stringParser that handled it
12345
    if ( rgba.length ) {
12346
12347
        // if this came from a parsed string, force "transparent" when alpha is 0
12348
        // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
12349
        if ( rgba.join() === "0,0,0,0" ) {
12350
            jQuery.extend( rgba, colors.transparent );
12351
        }
12352
        return inst;
12353
    }
12354
12355
    // named colors
12356
    return colors[ string ];
12357
}
12358
12359
color.fn = jQuery.extend( color.prototype, {
12360
    parse: function( red, green, blue, alpha ) {
12361
        if ( red === undefined ) {
12362
            this._rgba = [ null, null, null, null ];
12363
            return this;
12364
        }
12365
        if ( red.jquery || red.nodeType ) {
12366
            red = jQuery( red ).css( green );
12367
            green = undefined;
12368
        }
12369
12370
        var inst = this,
12371
            type = jQuery.type( red ),
12372
            rgba = this._rgba = [];
12373
12374
        // more than 1 argument specified - assume ( red, green, blue, alpha )
12375
        if ( green !== undefined ) {
12376
            red = [ red, green, blue, alpha ];
12377
            type = "array";
12378
        }
12379
12380
        if ( type === "string" ) {
12381
            return this.parse( stringParse( red ) || colors._default );
12382
        }
12383
12384
        if ( type === "array" ) {
12385
            each( spaces.rgba.props, function( key, prop ) {
12386
                rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
12387
            });
12388
            return this;
12389
        }
12390
12391
        if ( type === "object" ) {
12392
            if ( red instanceof color ) {
12393
                each( spaces, function( spaceName, space ) {
12394
                    if ( red[ space.cache ] ) {
12395
                        inst[ space.cache ] = red[ space.cache ].slice();
12396
                    }
12397
                });
12398
            } else {
12399
                each( spaces, function( spaceName, space ) {
12400
                    var cache = space.cache;
12401
                    each( space.props, function( key, prop ) {
12402
12403
                        // if the cache doesn't exist, and we know how to convert
12404
                        if ( !inst[ cache ] && space.to ) {
12405
12406
                            // if the value was null, we don't need to copy it
12407
                            // if the key was alpha, we don't need to copy it either
12408
                            if ( key === "alpha" || red[ key ] == null ) {
12409
                                return;
12410
                            }
12411
                            inst[ cache ] = space.to( inst._rgba );
12412
                        }
12413
12414
                        // this is the only case where we allow nulls for ALL properties.
12415
                        // call clamp with alwaysAllowEmpty
12416
                        inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
12417
                    });
12418
12419
                    // everything defined but alpha?
12420
                    if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
12421
                        // use the default of 1
12422
                        inst[ cache ][ 3 ] = 1;
12423
                        if ( space.from ) {
12424
                            inst._rgba = space.from( inst[ cache ] );
12425
                        }
12426
                    }
12427
                });
12428
            }
12429
            return this;
12430
        }
12431
    },
12432
    is: function( compare ) {
12433
        var is = color( compare ),
12434
            same = true,
12435
            inst = this;
12436
12437
        each( spaces, function( _, space ) {
12438
            var localCache,
12439
                isCache = is[ space.cache ];
12440
            if (isCache) {
12441
                localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
12442
                each( space.props, function( _, prop ) {
12443
                    if ( isCache[ prop.idx ] != null ) {
12444
                        same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
12445
                        return same;
12446
                    }
12447
                });
12448
            }
12449
            return same;
12450
        });
12451
        return same;
12452
    },
12453
    _space: function() {
12454
        var used = [],
12455
            inst = this;
12456
        each( spaces, function( spaceName, space ) {
12457
            if ( inst[ space.cache ] ) {
12458
                used.push( spaceName );
12459
            }
12460
        });
12461
        return used.pop();
12462
    },
12463
    transition: function( other, distance ) {
12464
        var end = color( other ),
12465
            spaceName = end._space(),
12466
            space = spaces[ spaceName ],
12467
            startColor = this.alpha() === 0 ? color( "transparent" ) : this,
12468
            start = startColor[ space.cache ] || space.to( startColor._rgba ),
12469
            result = start.slice();
12470
12471
        end = end[ space.cache ];
12472
        each( space.props, function( key, prop ) {
12473
            var index = prop.idx,
12474
                startValue = start[ index ],
12475
                endValue = end[ index ],
12476
                type = propTypes[ prop.type ] || {};
12477
12478
            // if null, don't override start value
12479
            if ( endValue === null ) {
12480
                return;
12481
            }
12482
            // if null - use end
12483
            if ( startValue === null ) {
12484
                result[ index ] = endValue;
12485
            } else {
12486
                if ( type.mod ) {
12487
                    if ( endValue - startValue > type.mod / 2 ) {
12488
                        startValue += type.mod;
12489
                    } else if ( startValue - endValue > type.mod / 2 ) {
12490
                        startValue -= type.mod;
12491
                    }
12492
                }
12493
                result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
12494
            }
12495
        });
12496
        return this[ spaceName ]( result );
12497
    },
12498
    blend: function( opaque ) {
12499
        // if we are already opaque - return ourself
12500
        if ( this._rgba[ 3 ] === 1 ) {
12501
            return this;
12502
        }
12503
12504
        var rgb = this._rgba.slice(),
12505
            a = rgb.pop(),
12506
            blend = color( opaque )._rgba;
12507
12508
        return color( jQuery.map( rgb, function( v, i ) {
12509
            return ( 1 - a ) * blend[ i ] + a * v;
12510
        }));
12511
    },
12512
    toRgbaString: function() {
12513
        var prefix = "rgba(",
12514
            rgba = jQuery.map( this._rgba, function( v, i ) {
12515
                return v == null ? ( i > 2 ? 1 : 0 ) : v;
12516
            });
12517
12518
        if ( rgba[ 3 ] === 1 ) {
12519
            rgba.pop();
12520
            prefix = "rgb(";
12521
        }
12522
12523
        return prefix + rgba.join() + ")";
12524
    },
12525
    toHslaString: function() {
12526
        var prefix = "hsla(",
12527
            hsla = jQuery.map( this.hsla(), function( v, i ) {
12528
                if ( v == null ) {
12529
                    v = i > 2 ? 1 : 0;
12530
                }
12531
12532
                // catch 1 and 2
12533
                if ( i && i < 3 ) {
12534
                    v = Math.round( v * 100 ) + "%";
12535
                }
12536
                return v;
12537
            });
12538
12539
        if ( hsla[ 3 ] === 1 ) {
12540
            hsla.pop();
12541
            prefix = "hsl(";
12542
        }
12543
        return prefix + hsla.join() + ")";
12544
    },
12545
    toHexString: function( includeAlpha ) {
12546
        var rgba = this._rgba.slice(),
12547
            alpha = rgba.pop();
12548
12549
        if ( includeAlpha ) {
12550
            rgba.push( ~~( alpha * 255 ) );
12551
        }
12552
12553
        return "#" + jQuery.map( rgba, function( v ) {
12554
12555
            // default to 0 when nulls exist
12556
            v = ( v || 0 ).toString( 16 );
12557
            return v.length === 1 ? "0" + v : v;
12558
        }).join("");
12559
    },
12560
    toString: function() {
12561
        return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
12562
    }
12563
});
12564
color.fn.parse.prototype = color.fn;
12565
12566
// hsla conversions adapted from:
12567
// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
12568
12569
function hue2rgb( p, q, h ) {
12570
    h = ( h + 1 ) % 1;
12571
    if ( h * 6 < 1 ) {
12572
        return p + ( q - p ) * h * 6;
12573
    }
12574
    if ( h * 2 < 1) {
12575
        return q;
12576
    }
12577
    if ( h * 3 < 2 ) {
12578
        return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
12579
    }
12580
    return p;
12581
}
12582
12583
spaces.hsla.to = function( rgba ) {
12584
    if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
12585
        return [ null, null, null, rgba[ 3 ] ];
12586
    }
12587
    var r = rgba[ 0 ] / 255,
12588
        g = rgba[ 1 ] / 255,
12589
        b = rgba[ 2 ] / 255,
12590
        a = rgba[ 3 ],
12591
        max = Math.max( r, g, b ),
12592
        min = Math.min( r, g, b ),
12593
        diff = max - min,
12594
        add = max + min,
12595
        l = add * 0.5,
12596
        h, s;
12597
12598
    if ( min === max ) {
12599
        h = 0;
12600
    } else if ( r === max ) {
12601
        h = ( 60 * ( g - b ) / diff ) + 360;
12602
    } else if ( g === max ) {
12603
        h = ( 60 * ( b - r ) / diff ) + 120;
12604
    } else {
12605
        h = ( 60 * ( r - g ) / diff ) + 240;
12606
    }
12607
12608
    // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
12609
    // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
12610
    if ( diff === 0 ) {
12611
        s = 0;
12612
    } else if ( l <= 0.5 ) {
12613
        s = diff / add;
12614
    } else {
12615
        s = diff / ( 2 - add );
12616
    }
12617
    return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
12618
};
12619
12620
spaces.hsla.from = function( hsla ) {
12621
    if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
12622
        return [ null, null, null, hsla[ 3 ] ];
12623
    }
12624
    var h = hsla[ 0 ] / 360,
12625
        s = hsla[ 1 ],
12626
        l = hsla[ 2 ],
12627
        a = hsla[ 3 ],
12628
        q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
12629
        p = 2 * l - q;
12630
12631
    return [
12632
        Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
12633
        Math.round( hue2rgb( p, q, h ) * 255 ),
12634
        Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
12635
        a
12636
    ];
12637
};
12638
12639
each( spaces, function( spaceName, space ) {
12640
    var props = space.props,
12641
        cache = space.cache,
12642
        to = space.to,
12643
        from = space.from;
12644
12645
    // makes rgba() and hsla()
12646
    color.fn[ spaceName ] = function( value ) {
12647
12648
        // generate a cache for this space if it doesn't exist
12649
        if ( to && !this[ cache ] ) {
12650
            this[ cache ] = to( this._rgba );
12651
        }
12652
        if ( value === undefined ) {
12653
            return this[ cache ].slice();
12654
        }
12655
12656
        var ret,
12657
            type = jQuery.type( value ),
12658
            arr = ( type === "array" || type === "object" ) ? value : arguments,
12659
            local = this[ cache ].slice();
12660
12661
        each( props, function( key, prop ) {
12662
            var val = arr[ type === "object" ? key : prop.idx ];
12663
            if ( val == null ) {
12664
                val = local[ prop.idx ];
12665
            }
12666
            local[ prop.idx ] = clamp( val, prop );
12667
        });
12668
12669
        if ( from ) {
12670
            ret = color( from( local ) );
12671
            ret[ cache ] = local;
12672
            return ret;
12673
        } else {
12674
            return color( local );
12675
        }
12676
    };
12677
12678
    // makes red() green() blue() alpha() hue() saturation() lightness()
12679
    each( props, function( key, prop ) {
12680
        // alpha is included in more than one space
12681
        if ( color.fn[ key ] ) {
12682
            return;
12683
        }
12684
        color.fn[ key ] = function( value ) {
12685
            var vtype = jQuery.type( value ),
12686
                fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
12687
                local = this[ fn ](),
12688
                cur = local[ prop.idx ],
12689
                match;
12690
12691
            if ( vtype === "undefined" ) {
12692
                return cur;
12693
            }
12694
12695
            if ( vtype === "function" ) {
12696
                value = value.call( this, cur );
12697
                vtype = jQuery.type( value );
12698
            }
12699
            if ( value == null && prop.empty ) {
12700
                return this;
12701
            }
12702
            if ( vtype === "string" ) {
12703
                match = rplusequals.exec( value );
12704
                if ( match ) {
12705
                    value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
12706
                }
12707
            }
12708
            local[ prop.idx ] = value;
12709
            return this[ fn ]( local );
12710
        };
12711
    });
12712
});
12713
12714
// add cssHook and .fx.step function for each named hook.
12715
// accept a space separated string of properties
12716
color.hook = function( hook ) {
12717
    var hooks = hook.split( " " );
12718
    each( hooks, function( i, hook ) {
12719
        jQuery.cssHooks[ hook ] = {
12720
            set: function( elem, value ) {
12721
                var parsed, curElem,
12722
                    backgroundColor = "";
12723
12724
                if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
12725
                    value = color( parsed || value );
12726
                    if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
12727
                        curElem = hook === "backgroundColor" ? elem.parentNode : elem;
12728
                        while (
12729
                            (backgroundColor === "" || backgroundColor === "transparent") &&
12730
                            curElem && curElem.style
12731
                        ) {
12732
                            try {
12733
                                backgroundColor = jQuery.css( curElem, "backgroundColor" );
12734
                                curElem = curElem.parentNode;
12735
                            } catch ( e ) {
12736
                            }
12737
                        }
12738
12739
                        value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
12740
                            backgroundColor :
12741
                            "_default" );
12742
                    }
12743
12744
                    value = value.toRgbaString();
12745
                }
12746
                try {
12747
                    elem.style[ hook ] = value;
12748
                } catch ( e ) {
12749
                    // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
12750
                }
12751
            }
12752
        };
12753
        jQuery.fx.step[ hook ] = function( fx ) {
12754
            if ( !fx.colorInit ) {
12755
                fx.start = color( fx.elem, hook );
12756
                fx.end = color( fx.end );
12757
                fx.colorInit = true;
12758
            }
12759
            jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
12760
        };
12761
    });
12762
12763
};
12764
12765
color.hook( stepHooks );
12766
12767
jQuery.cssHooks.borderColor = {
12768
    expand: function( value ) {
12769
        var expanded = {};
12770
12771
        each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
12772
            expanded[ "border" + part + "Color" ] = value;
12773
        });
12774
        return expanded;
12775
    }
12776
};
12777
12778
// Basic color names only.
12779
// Usage of any of the other color names requires adding yourself or including
12780
// jquery.color.svg-names.js.
12781
colors = jQuery.Color.names = {
12782
    // 4.1. Basic color keywords
12783
    aqua: "#00ffff",
12784
    black: "#000000",
12785
    blue: "#0000ff",
12786
    fuchsia: "#ff00ff",
12787
    gray: "#808080",
12788
    green: "#008000",
12789
    lime: "#00ff00",
12790
    maroon: "#800000",
12791
    navy: "#000080",
12792
    olive: "#808000",
12793
    purple: "#800080",
12794
    red: "#ff0000",
12795
    silver: "#c0c0c0",
12796
    teal: "#008080",
12797
    white: "#ffffff",
12798
    yellow: "#ffff00",
12799
12800
    // 4.2.3. "transparent" color keyword
12801
    transparent: [ null, null, null, 0 ],
12802
12803
    _default: "#ffffff"
12804
};
12805
12806
})( jQuery );
12807
12808
/******************************************************************************/
12809
/****************************** CLASS ANIMATIONS ******************************/
12810
/******************************************************************************/
12811
(function() {
12812
12813
var classAnimationActions = [ "add", "remove", "toggle" ],
12814
    shorthandStyles = {
12815
        border: 1,
12816
        borderBottom: 1,
12817
        borderColor: 1,
12818
        borderLeft: 1,
12819
        borderRight: 1,
12820
        borderTop: 1,
12821
        borderWidth: 1,
12822
        margin: 1,
12823
        padding: 1
12824
    };
12825
12826
$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
12827
    $.fx.step[ prop ] = function( fx ) {
12828
        if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
12829
            jQuery.style( fx.elem, prop, fx.end );
12830
            fx.setAttr = true;
12831
        }
12832
    };
12833
});
12834
12835
function getElementStyles( elem ) {
12836
    var key, len,
12837
        style = elem.ownerDocument.defaultView ?
12838
            elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
12839
            elem.currentStyle,
12840
        styles = {};
12841
12842
    if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
12843
        len = style.length;
12844
        while ( len-- ) {
12845
            key = style[ len ];
12846
            if ( typeof style[ key ] === "string" ) {
12847
                styles[ $.camelCase( key ) ] = style[ key ];
12848
            }
12849
        }
12850
    // support: Opera, IE <9
12851
    } else {
12852
        for ( key in style ) {
12853
            if ( typeof style[ key ] === "string" ) {
12854
                styles[ key ] = style[ key ];
12855
            }
12856
        }
12857
    }
12858
12859
    return styles;
12860
}
12861
12862
function styleDifference( oldStyle, newStyle ) {
12863
    var diff = {},
12864
        name, value;
12865
12866
    for ( name in newStyle ) {
12867
        value = newStyle[ name ];
12868
        if ( oldStyle[ name ] !== value ) {
12869
            if ( !shorthandStyles[ name ] ) {
12870
                if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
12871
                    diff[ name ] = value;
12872
                }
12873
            }
12874
        }
12875
    }
12876
12877
    return diff;
12878
}
12879
12880
// support: jQuery <1.8
12881
if ( !$.fn.addBack ) {
12882
    $.fn.addBack = function( selector ) {
12883
        return this.add( selector == null ?
12884
            this.prevObject : this.prevObject.filter( selector )
12885
        );
12886
    };
12887
}
12888
12889
$.effects.animateClass = function( value, duration, easing, callback ) {
12890
    var o = $.speed( duration, easing, callback );
12891
12892
    return this.queue( function() {
12893
        var animated = $( this ),
12894
            baseClass = animated.attr( "class" ) || "",
12895
            applyClassChange,
12896
            allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
12897
12898
        // map the animated objects to store the original styles.
12899
        allAnimations = allAnimations.map(function() {
12900
            var el = $( this );
12901
            return {
12902
                el: el,
12903
                start: getElementStyles( this )
12904
            };
12905
        });
12906
12907
        // apply class change
12908
        applyClassChange = function() {
12909
            $.each( classAnimationActions, function(i, action) {
12910
                if ( value[ action ] ) {
12911
                    animated[ action + "Class" ]( value[ action ] );
12912
                }
12913
            });
12914
        };
12915
        applyClassChange();
12916
12917
        // map all animated objects again - calculate new styles and diff
12918
        allAnimations = allAnimations.map(function() {
12919
            this.end = getElementStyles( this.el[ 0 ] );
12920
            this.diff = styleDifference( this.start, this.end );
12921
            return this;
12922
        });
12923
12924
        // apply original class
12925
        animated.attr( "class", baseClass );
12926
12927
        // map all animated objects again - this time collecting a promise
12928
        allAnimations = allAnimations.map(function() {
12929
            var styleInfo = this,
12930
                dfd = $.Deferred(),
12931
                opts = $.extend({}, o, {
12932
                    queue: false,
12933
                    complete: function() {
12934
                        dfd.resolve( styleInfo );
12935
                    }
12936
                });
12937
12938
            this.el.animate( this.diff, opts );
12939
            return dfd.promise();
12940
        });
12941
12942
        // once all animations have completed:
12943
        $.when.apply( $, allAnimations.get() ).done(function() {
12944
12945
            // set the final class
12946
            applyClassChange();
12947
12948
            // for each animated element,
12949
            // clear all css properties that were animated
12950
            $.each( arguments, function() {
12951
                var el = this.el;
12952
                $.each( this.diff, function(key) {
12953
                    el.css( key, "" );
12954
                });
12955
            });
12956
12957
            // this is guarnteed to be there if you use jQuery.speed()
12958
            // it also handles dequeuing the next anim...
12959
            o.complete.call( animated[ 0 ] );
12960
        });
12961
    });
12962
};
12963
12964
$.fn.extend({
12965
    addClass: (function( orig ) {
12966
        return function( classNames, speed, easing, callback ) {
12967
            return speed ?
12968
                $.effects.animateClass.call( this,
12969
                    { add: classNames }, speed, easing, callback ) :
12970
                orig.apply( this, arguments );
12971
        };
12972
    })( $.fn.addClass ),
12973
12974
    removeClass: (function( orig ) {
12975
        return function( classNames, speed, easing, callback ) {
12976
            return arguments.length > 1 ?
12977
                $.effects.animateClass.call( this,
12978
                    { remove: classNames }, speed, easing, callback ) :
12979
                orig.apply( this, arguments );
12980
        };
12981
    })( $.fn.removeClass ),
12982
12983
    toggleClass: (function( orig ) {
12984
        return function( classNames, force, speed, easing, callback ) {
12985
            if ( typeof force === "boolean" || force === undefined ) {
12986
                if ( !speed ) {
12987
                    // without speed parameter
12988
                    return orig.apply( this, arguments );
12989
                } else {
12990
                    return $.effects.animateClass.call( this,
12991
                        (force ? { add: classNames } : { remove: classNames }),
12992
                        speed, easing, callback );
12993
                }
12994
            } else {
12995
                // without force parameter
12996
                return $.effects.animateClass.call( this,
12997
                    { toggle: classNames }, force, speed, easing );
12998
            }
12999
        };
13000
    })( $.fn.toggleClass ),
13001
13002
    switchClass: function( remove, add, speed, easing, callback) {
13003
        return $.effects.animateClass.call( this, {
13004
            add: add,
13005
            remove: remove
13006
        }, speed, easing, callback );
13007
    }
13008
});
13009
13010
})();
13011
13012
/******************************************************************************/
13013
/*********************************** EFFECTS **********************************/
13014
/******************************************************************************/
13015
13016
(function() {
13017
13018
$.extend( $.effects, {
13019
    version: "1.11.4",
13020
13021
    // Saves a set of properties in a data storage
13022
    save: function( element, set ) {
13023
        for ( var i = 0; i < set.length; i++ ) {
13024
            if ( set[ i ] !== null ) {
13025
                element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
13026
            }
13027
        }
13028
    },
13029
13030
    // Restores a set of previously saved properties from a data storage
13031
    restore: function( element, set ) {
13032
        var val, i;
13033
        for ( i = 0; i < set.length; i++ ) {
13034
            if ( set[ i ] !== null ) {
13035
                val = element.data( dataSpace + set[ i ] );
13036
                // support: jQuery 1.6.2
13037
                // http://bugs.jquery.com/ticket/9917
13038
                // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
13039
                // We can't differentiate between "" and 0 here, so we just assume
13040
                // empty string since it's likely to be a more common value...
13041
                if ( val === undefined ) {
13042
                    val = "";
13043
                }
13044
                element.css( set[ i ], val );
13045
            }
13046
        }
13047
    },
13048
13049
    setMode: function( el, mode ) {
13050
        if (mode === "toggle") {
13051
            mode = el.is( ":hidden" ) ? "show" : "hide";
13052
        }
13053
        return mode;
13054
    },
13055
13056
    // Translates a [top,left] array into a baseline value
13057
    // this should be a little more flexible in the future to handle a string & hash
13058
    getBaseline: function( origin, original ) {
13059
        var y, x;
13060
        switch ( origin[ 0 ] ) {
13061
            case "top": y = 0; break;
13062
            case "middle": y = 0.5; break;
13063
            case "bottom": y = 1; break;
13064
            default: y = origin[ 0 ] / original.height;
13065
        }
13066
        switch ( origin[ 1 ] ) {
13067
            case "left": x = 0; break;
13068
            case "center": x = 0.5; break;
13069
            case "right": x = 1; break;
13070
            default: x = origin[ 1 ] / original.width;
13071
        }
13072
        return {
13073
            x: x,
13074
            y: y
13075
        };
13076
    },
13077
13078
    // Wraps the element around a wrapper that copies position properties
13079
    createWrapper: function( element ) {
13080
13081
        // if the element is already wrapped, return it
13082
        if ( element.parent().is( ".ui-effects-wrapper" )) {
13083
            return element.parent();
13084
        }
13085
13086
        // wrap the element
13087
        var props = {
13088
                width: element.outerWidth(true),
13089
                height: element.outerHeight(true),
13090
                "float": element.css( "float" )
13091
            },
13092
            wrapper = $( "<div></div>" )
13093
                .addClass( "ui-effects-wrapper" )
13094
                .css({
13095
                    fontSize: "100%",
13096
                    background: "transparent",
13097
                    border: "none",
13098
                    margin: 0,
13099
                    padding: 0
13100
                }),
13101
            // Store the size in case width/height are defined in % - Fixes #5245
13102
            size = {
13103
                width: element.width(),
13104
                height: element.height()
13105
            },
13106
            active = document.activeElement;
13107
13108
        // support: Firefox
13109
        // Firefox incorrectly exposes anonymous content
13110
        // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
13111
        try {
13112
            active.id;
13113
        } catch ( e ) {
13114
            active = document.body;
13115
        }
13116
13117
        element.wrap( wrapper );
13118
13119
        // Fixes #7595 - Elements lose focus when wrapped.
13120
        if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
13121
            $( active ).focus();
13122
        }
13123
13124
        wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
13125
13126
        // transfer positioning properties to the wrapper
13127
        if ( element.css( "position" ) === "static" ) {
13128
            wrapper.css({ position: "relative" });
13129
            element.css({ position: "relative" });
13130
        } else {
13131
            $.extend( props, {
13132
                position: element.css( "position" ),
13133
                zIndex: element.css( "z-index" )
13134
            });
13135
            $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
13136
                props[ pos ] = element.css( pos );
13137
                if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
13138
                    props[ pos ] = "auto";
13139
                }
13140
            });
13141
            element.css({
13142
                position: "relative",
13143
                top: 0,
13144
                left: 0,
13145
                right: "auto",
13146
                bottom: "auto"
13147
            });
13148
        }
13149
        element.css(size);
13150
13151
        return wrapper.css( props ).show();
13152
    },
13153
13154
    removeWrapper: function( element ) {
13155
        var active = document.activeElement;
13156
13157
        if ( element.parent().is( ".ui-effects-wrapper" ) ) {
13158
            element.parent().replaceWith( element );
13159
13160
            // Fixes #7595 - Elements lose focus when wrapped.
13161
            if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
13162
                $( active ).focus();
13163
            }
13164
        }
13165
13166
        return element;
13167
    },
13168
13169
    setTransition: function( element, list, factor, value ) {
13170
        value = value || {};
13171
        $.each( list, function( i, x ) {
13172
            var unit = element.cssUnit( x );
13173
            if ( unit[ 0 ] > 0 ) {
13174
                value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
13175
            }
13176
        });
13177
        return value;
13178
    }
13179
});
13180
13181
// return an effect options object for the given parameters:
13182
function _normalizeArguments( effect, options, speed, callback ) {
13183
13184
    // allow passing all options as the first parameter
13185
    if ( $.isPlainObject( effect ) ) {
13186
        options = effect;
13187
        effect = effect.effect;
13188
    }
13189
13190
    // convert to an object
13191
    effect = { effect: effect };
13192
13193
    // catch (effect, null, ...)
13194
    if ( options == null ) {
13195
        options = {};
13196
    }
13197
13198
    // catch (effect, callback)
13199
    if ( $.isFunction( options ) ) {
13200
        callback = options;
13201
        speed = null;
13202
        options = {};
13203
    }
13204
13205
    // catch (effect, speed, ?)
13206
    if ( typeof options === "number" || $.fx.speeds[ options ] ) {
13207
        callback = speed;
13208
        speed = options;
13209
        options = {};
13210
    }
13211
13212
    // catch (effect, options, callback)
13213
    if ( $.isFunction( speed ) ) {
13214
        callback = speed;
13215
        speed = null;
13216
    }
13217
13218
    // add options to effect
13219
    if ( options ) {
13220
        $.extend( effect, options );
13221
    }
13222
13223
    speed = speed || options.duration;
13224
    effect.duration = $.fx.off ? 0 :
13225
        typeof speed === "number" ? speed :
13226
        speed in $.fx.speeds ? $.fx.speeds[ speed ] :
13227
        $.fx.speeds._default;
13228
13229
    effect.complete = callback || options.complete;
13230
13231
    return effect;
13232
}
13233
13234
function standardAnimationOption( option ) {
13235
    // Valid standard speeds (nothing, number, named speed)
13236
    if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
13237
        return true;
13238
    }
13239
13240
    // Invalid strings - treat as "normal" speed
13241
    if ( typeof option === "string" && !$.effects.effect[ option ] ) {
13242
        return true;
13243
    }
13244
13245
    // Complete callback
13246
    if ( $.isFunction( option ) ) {
13247
        return true;
13248
    }
13249
13250
    // Options hash (but not naming an effect)
13251
    if ( typeof option === "object" && !option.effect ) {
13252
        return true;
13253
    }
13254
13255
    // Didn't match any standard API
13256
    return false;
13257
}
13258
13259
$.fn.extend({
13260
    effect: function( /* effect, options, speed, callback */ ) {
13261
        var args = _normalizeArguments.apply( this, arguments ),
13262
            mode = args.mode,
13263
            queue = args.queue,
13264
            effectMethod = $.effects.effect[ args.effect ];
13265
13266
        if ( $.fx.off || !effectMethod ) {
13267
            // delegate to the original method (e.g., .show()) if possible
13268
            if ( mode ) {
13269
                return this[ mode ]( args.duration, args.complete );
13270
            } else {
13271
                return this.each( function() {
13272
                    if ( args.complete ) {
13273
                        args.complete.call( this );
13274
                    }
13275
                });
13276
            }
13277
        }
13278
13279
        function run( next ) {
13280
            var elem = $( this ),
13281
                complete = args.complete,
13282
                mode = args.mode;
13283
13284
            function done() {
13285
                if ( $.isFunction( complete ) ) {
13286
                    complete.call( elem[0] );
13287
                }
13288
                if ( $.isFunction( next ) ) {
13289
                    next();
13290
                }
13291
            }
13292
13293
            // If the element already has the correct final state, delegate to
13294
            // the core methods so the internal tracking of "olddisplay" works.
13295
            if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
13296
                elem[ mode ]();
13297
                done();
13298
            } else {
13299
                effectMethod.call( elem[0], args, done );
13300
            }
13301
        }
13302
13303
        return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
13304
    },
13305
13306
    show: (function( orig ) {
13307
        return function( option ) {
13308
            if ( standardAnimationOption( option ) ) {
13309
                return orig.apply( this, arguments );
13310
            } else {
13311
                var args = _normalizeArguments.apply( this, arguments );
13312
                args.mode = "show";
13313
                return this.effect.call( this, args );
13314
            }
13315
        };
13316
    })( $.fn.show ),
13317
13318
    hide: (function( orig ) {
13319
        return function( option ) {
13320
            if ( standardAnimationOption( option ) ) {
13321
                return orig.apply( this, arguments );
13322
            } else {
13323
                var args = _normalizeArguments.apply( this, arguments );
13324
                args.mode = "hide";
13325
                return this.effect.call( this, args );
13326
            }
13327
        };
13328
    })( $.fn.hide ),
13329
13330
    toggle: (function( orig ) {
13331
        return function( option ) {
13332
            if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
13333
                return orig.apply( this, arguments );
13334
            } else {
13335
                var args = _normalizeArguments.apply( this, arguments );
13336
                args.mode = "toggle";
13337
                return this.effect.call( this, args );
13338
            }
13339
        };
13340
    })( $.fn.toggle ),
13341
13342
    // helper functions
13343
    cssUnit: function(key) {
13344
        var style = this.css( key ),
13345
            val = [];
13346
13347
        $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
13348
            if ( style.indexOf( unit ) > 0 ) {
13349
                val = [ parseFloat( style ), unit ];
13350
            }
13351
        });
13352
        return val;
13353
    }
13354
});
13355
13356
})();
13357
13358
/******************************************************************************/
13359
/*********************************** EASING ***********************************/
13360
/******************************************************************************/
13361
13362
(function() {
13363
13364
// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
13365
13366
var baseEasings = {};
13367
13368
$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
13369
    baseEasings[ name ] = function( p ) {
13370
        return Math.pow( p, i + 2 );
13371
    };
13372
});
13373
13374
$.extend( baseEasings, {
13375
    Sine: function( p ) {
13376
        return 1 - Math.cos( p * Math.PI / 2 );
13377
    },
13378
    Circ: function( p ) {
13379
        return 1 - Math.sqrt( 1 - p * p );
13380
    },
13381
    Elastic: function( p ) {
13382
        return p === 0 || p === 1 ? p :
13383
            -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
13384
    },
13385
    Back: function( p ) {
13386
        return p * p * ( 3 * p - 2 );
13387
    },
13388
    Bounce: function( p ) {
13389
        var pow2,
13390
            bounce = 4;
13391
13392
        while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
13393
        return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
13394
    }
13395
});
13396
13397
$.each( baseEasings, function( name, easeIn ) {
13398
    $.easing[ "easeIn" + name ] = easeIn;
13399
    $.easing[ "easeOut" + name ] = function( p ) {
13400
        return 1 - easeIn( 1 - p );
13401
    };
13402
    $.easing[ "easeInOut" + name ] = function( p ) {
13403
        return p < 0.5 ?
13404
            easeIn( p * 2 ) / 2 :
13405
            1 - easeIn( p * -2 + 2 ) / 2;
13406
    };
13407
});
13408
13409
})();
13410
13411
var effect = $.effects;
13412
13413
13414
/*!
13415
 * jQuery UI Effects Blind 1.11.4
13416
 * http://jqueryui.com
13417
 *
13418
 * Copyright jQuery Foundation and other contributors
13419
 * Released under the MIT license.
13420
 * http://jquery.org/license
13421
 *
13422
 * http://api.jqueryui.com/blind-effect/
13423
 */
13424
13425
13426
var effectBlind = $.effects.effect.blind = function( o, done ) {
13427
    // Create element
13428
    var el = $( this ),
13429
        rvertical = /up|down|vertical/,
13430
        rpositivemotion = /up|left|vertical|horizontal/,
13431
        props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
13432
        mode = $.effects.setMode( el, o.mode || "hide" ),
13433
        direction = o.direction || "up",
13434
        vertical = rvertical.test( direction ),
13435
        ref = vertical ? "height" : "width",
13436
        ref2 = vertical ? "top" : "left",
13437
        motion = rpositivemotion.test( direction ),
13438
        animation = {},
13439
        show = mode === "show",
13440
        wrapper, distance, margin;
13441
13442
    // if already wrapped, the wrapper's properties are my property. #6245
13443
    if ( el.parent().is( ".ui-effects-wrapper" ) ) {
13444
        $.effects.save( el.parent(), props );
13445
    } else {
13446
        $.effects.save( el, props );
13447
    }
13448
    el.show();
13449
    wrapper = $.effects.createWrapper( el ).css({
13450
        overflow: "hidden"
13451
    });
13452
13453
    distance = wrapper[ ref ]();
13454
    margin = parseFloat( wrapper.css( ref2 ) ) || 0;
13455
13456
    animation[ ref ] = show ? distance : 0;
13457
    if ( !motion ) {
13458
        el
13459
            .css( vertical ? "bottom" : "right", 0 )
13460
            .css( vertical ? "top" : "left", "auto" )
13461
            .css({ position: "absolute" });
13462
13463
        animation[ ref2 ] = show ? margin : distance + margin;
13464
    }
13465
13466
    // start at 0 if we are showing
13467
    if ( show ) {
13468
        wrapper.css( ref, 0 );
13469
        if ( !motion ) {
13470
            wrapper.css( ref2, margin + distance );
13471
        }
13472
    }
13473
13474
    // Animate
13475
    wrapper.animate( animation, {
13476
        duration: o.duration,
13477
        easing: o.easing,
13478
        queue: false,
13479
        complete: function() {
13480
            if ( mode === "hide" ) {
13481
                el.hide();
13482
            }
13483
            $.effects.restore( el, props );
13484
            $.effects.removeWrapper( el );
13485
            done();
13486
        }
13487
    });
13488
};
13489
13490
13491
/*!
13492
 * jQuery UI Effects Bounce 1.11.4
13493
 * http://jqueryui.com
13494
 *
13495
 * Copyright jQuery Foundation and other contributors
13496
 * Released under the MIT license.
13497
 * http://jquery.org/license
13498
 *
13499
 * http://api.jqueryui.com/bounce-effect/
13500
 */
13501
13502
13503
var effectBounce = $.effects.effect.bounce = function( o, done ) {
13504
    var el = $( this ),
13505
        props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
13506
13507
        // defaults:
13508
        mode = $.effects.setMode( el, o.mode || "effect" ),
13509
        hide = mode === "hide",
13510
        show = mode === "show",
13511
        direction = o.direction || "up",
13512
        distance = o.distance,
13513
        times = o.times || 5,
13514
13515
        // number of internal animations
13516
        anims = times * 2 + ( show || hide ? 1 : 0 ),
13517
        speed = o.duration / anims,
13518
        easing = o.easing,
13519
13520
        // utility:
13521
        ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
13522
        motion = ( direction === "up" || direction === "left" ),
13523
        i,
13524
        upAnim,
13525
        downAnim,
13526
13527
        // we will need to re-assemble the queue to stack our animations in place
13528
        queue = el.queue(),
13529
        queuelen = queue.length;
13530
13531
    // Avoid touching opacity to prevent clearType and PNG issues in IE
13532
    if ( show || hide ) {
13533
        props.push( "opacity" );
13534
    }
13535
13536
    $.effects.save( el, props );
13537
    el.show();
13538
    $.effects.createWrapper( el ); // Create Wrapper
13539
13540
    // default distance for the BIGGEST bounce is the outer Distance / 3
13541
    if ( !distance ) {
13542
        distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
13543
    }
13544
13545
    if ( show ) {
13546
        downAnim = { opacity: 1 };
13547
        downAnim[ ref ] = 0;
13548
13549
        // if we are showing, force opacity 0 and set the initial position
13550
        // then do the "first" animation
13551
        el.css( "opacity", 0 )
13552
            .css( ref, motion ? -distance * 2 : distance * 2 )
13553
            .animate( downAnim, speed, easing );
13554
    }
13555
13556
    // start at the smallest distance if we are hiding
13557
    if ( hide ) {
13558
        distance = distance / Math.pow( 2, times - 1 );
13559
    }
13560
13561
    downAnim = {};
13562
    downAnim[ ref ] = 0;
13563
    // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
13564
    for ( i = 0; i < times; i++ ) {
13565
        upAnim = {};
13566
        upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
13567
13568
        el.animate( upAnim, speed, easing )
13569
            .animate( downAnim, speed, easing );
13570
13571
        distance = hide ? distance * 2 : distance / 2;
13572
    }
13573
13574
    // Last Bounce when Hiding
13575
    if ( hide ) {
13576
        upAnim = { opacity: 0 };
13577
        upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
13578
13579
        el.animate( upAnim, speed, easing );
13580
    }
13581
13582
    el.queue(function() {
13583
        if ( hide ) {
13584
            el.hide();
13585
        }
13586
        $.effects.restore( el, props );
13587
        $.effects.removeWrapper( el );
13588
        done();
13589
    });
13590
13591
    // inject all the animations we just queued to be first in line (after "inprogress")
13592
    if ( queuelen > 1) {
13593
        queue.splice.apply( queue,
13594
            [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
13595
    }
13596
    el.dequeue();
13597
13598
};
13599
13600
13601
/*!
13602
 * jQuery UI Effects Clip 1.11.4
13603
 * http://jqueryui.com
13604
 *
13605
 * Copyright jQuery Foundation and other contributors
13606
 * Released under the MIT license.
13607
 * http://jquery.org/license
13608
 *
13609
 * http://api.jqueryui.com/clip-effect/
13610
 */
13611
13612
13613
var effectClip = $.effects.effect.clip = function( o, done ) {
13614
    // Create element
13615
    var el = $( this ),
13616
        props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
13617
        mode = $.effects.setMode( el, o.mode || "hide" ),
13618
        show = mode === "show",
13619
        direction = o.direction || "vertical",
13620
        vert = direction === "vertical",
13621
        size = vert ? "height" : "width",
13622
        position = vert ? "top" : "left",
13623
        animation = {},
13624
        wrapper, animate, distance;
13625
13626
    // Save & Show
13627
    $.effects.save( el, props );
13628
    el.show();
13629
13630
    // Create Wrapper
13631
    wrapper = $.effects.createWrapper( el ).css({
13632
        overflow: "hidden"
13633
    });
13634
    animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
13635
    distance = animate[ size ]();
13636
13637
    // Shift
13638
    if ( show ) {
13639
        animate.css( size, 0 );
13640
        animate.css( position, distance / 2 );
13641
    }
13642
13643
    // Create Animation Object:
13644
    animation[ size ] = show ? distance : 0;
13645
    animation[ position ] = show ? 0 : distance / 2;
13646
13647
    // Animate
13648
    animate.animate( animation, {
13649
        queue: false,
13650
        duration: o.duration,
13651
        easing: o.easing,
13652
        complete: function() {
13653
            if ( !show ) {
13654
                el.hide();
13655
            }
13656
            $.effects.restore( el, props );
13657
            $.effects.removeWrapper( el );
13658
            done();
13659
        }
13660
    });
13661
13662
};
13663
13664
13665
/*!
13666
 * jQuery UI Effects Drop 1.11.4
13667
 * http://jqueryui.com
13668
 *
13669
 * Copyright jQuery Foundation and other contributors
13670
 * Released under the MIT license.
13671
 * http://jquery.org/license
13672
 *
13673
 * http://api.jqueryui.com/drop-effect/
13674
 */
13675
13676
13677
var effectDrop = $.effects.effect.drop = function( o, done ) {
13678
13679
    var el = $( this ),
13680
        props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
13681
        mode = $.effects.setMode( el, o.mode || "hide" ),
13682
        show = mode === "show",
13683
        direction = o.direction || "left",
13684
        ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
13685
        motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
13686
        animation = {
13687
            opacity: show ? 1 : 0
13688
        },
13689
        distance;
13690
13691
    // Adjust
13692
    $.effects.save( el, props );
13693
    el.show();
13694
    $.effects.createWrapper( el );
13695
13696
    distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
13697
13698
    if ( show ) {
13699
        el
13700
            .css( "opacity", 0 )
13701
            .css( ref, motion === "pos" ? -distance : distance );
13702
    }
13703
13704
    // Animation
13705
    animation[ ref ] = ( show ?
13706
        ( motion === "pos" ? "+=" : "-=" ) :
13707
        ( motion === "pos" ? "-=" : "+=" ) ) +
13708
        distance;
13709
13710
    // Animate
13711
    el.animate( animation, {
13712
        queue: false,
13713
        duration: o.duration,
13714
        easing: o.easing,
13715
        complete: function() {
13716
            if ( mode === "hide" ) {
13717
                el.hide();
13718
            }
13719
            $.effects.restore( el, props );
13720
            $.effects.removeWrapper( el );
13721
            done();
13722
        }
13723
    });
13724
};
13725
13726
13727
/*!
13728
 * jQuery UI Effects Explode 1.11.4
13729
 * http://jqueryui.com
13730
 *
13731
 * Copyright jQuery Foundation and other contributors
13732
 * Released under the MIT license.
13733
 * http://jquery.org/license
13734
 *
13735
 * http://api.jqueryui.com/explode-effect/
13736
 */
13737
13738
13739
var effectExplode = $.effects.effect.explode = function( o, done ) {
13740
13741
    var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
13742
        cells = rows,
13743
        el = $( this ),
13744
        mode = $.effects.setMode( el, o.mode || "hide" ),
13745
        show = mode === "show",
13746
13747
        // show and then visibility:hidden the element before calculating offset
13748
        offset = el.show().css( "visibility", "hidden" ).offset(),
13749
13750
        // width and height of a piece
13751
        width = Math.ceil( el.outerWidth() / cells ),
13752
        height = Math.ceil( el.outerHeight() / rows ),
13753
        pieces = [],
13754
13755
        // loop
13756
        i, j, left, top, mx, my;
13757
13758
    // children animate complete:
13759
    function childComplete() {
13760
        pieces.push( this );
13761
        if ( pieces.length === rows * cells ) {
13762
            animComplete();
13763
        }
13764
    }
13765
13766
    // clone the element for each row and cell.
13767
    for ( i = 0; i < rows ; i++ ) { // ===>
13768
        top = offset.top + i * height;
13769
        my = i - ( rows - 1 ) / 2 ;
13770
13771
        for ( j = 0; j < cells ; j++ ) { // |||
13772
            left = offset.left + j * width;
13773
            mx = j - ( cells - 1 ) / 2 ;
13774
13775
            // Create a clone of the now hidden main element that will be absolute positioned
13776
            // within a wrapper div off the -left and -top equal to size of our pieces
13777
            el
13778
                .clone()
13779
                .appendTo( "body" )
13780
                .wrap( "<div></div>" )
13781
                .css({
13782
                    position: "absolute",
13783
                    visibility: "visible",
13784
                    left: -j * width,
13785
                    top: -i * height
13786
                })
13787
13788
            // select the wrapper - make it overflow: hidden and absolute positioned based on
13789
            // where the original was located +left and +top equal to the size of pieces
13790
                .parent()
13791
                .addClass( "ui-effects-explode" )
13792
                .css({
13793
                    position: "absolute",
13794
                    overflow: "hidden",
13795
                    width: width,
13796
                    height: height,
13797
                    left: left + ( show ? mx * width : 0 ),
13798
                    top: top + ( show ? my * height : 0 ),
13799
                    opacity: show ? 0 : 1
13800
                }).animate({
13801
                    left: left + ( show ? 0 : mx * width ),
13802
                    top: top + ( show ? 0 : my * height ),
13803
                    opacity: show ? 1 : 0
13804
                }, o.duration || 500, o.easing, childComplete );
13805
        }
13806
    }
13807
13808
    function animComplete() {
13809
        el.css({
13810
            visibility: "visible"
13811
        });
13812
        $( pieces ).remove();
13813
        if ( !show ) {
13814
            el.hide();
13815
        }
13816
        done();
13817
    }
13818
};
13819
13820
13821
/*!
13822
 * jQuery UI Effects Fade 1.11.4
13823
 * http://jqueryui.com
13824
 *
13825
 * Copyright jQuery Foundation and other contributors
13826
 * Released under the MIT license.
13827
 * http://jquery.org/license
13828
 *
13829
 * http://api.jqueryui.com/fade-effect/
13830
 */
13831
13832
13833
var effectFade = $.effects.effect.fade = function( o, done ) {
13834
    var el = $( this ),
13835
        mode = $.effects.setMode( el, o.mode || "toggle" );
13836
13837
    el.animate({
13838
        opacity: mode
13839
    }, {
13840
        queue: false,
13841
        duration: o.duration,
13842
        easing: o.easing,
13843
        complete: done
13844
    });
13845
};
13846
13847
13848
/*!
13849
 * jQuery UI Effects Fold 1.11.4
13850
 * http://jqueryui.com
13851
 *
13852
 * Copyright jQuery Foundation and other contributors
13853
 * Released under the MIT license.
13854
 * http://jquery.org/license
13855
 *
13856
 * http://api.jqueryui.com/fold-effect/
13857
 */
13858
13859
13860
var effectFold = $.effects.effect.fold = function( o, done ) {
13861
13862
    // Create element
13863
    var el = $( this ),
13864
        props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
13865
        mode = $.effects.setMode( el, o.mode || "hide" ),
13866
        show = mode === "show",
13867
        hide = mode === "hide",
13868
        size = o.size || 15,
13869
        percent = /([0-9]+)%/.exec( size ),
13870
        horizFirst = !!o.horizFirst,
13871
        widthFirst = show !== horizFirst,
13872
        ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
13873
        duration = o.duration / 2,
13874
        wrapper, distance,
13875
        animation1 = {},
13876
        animation2 = {};
13877
13878
    $.effects.save( el, props );
13879
    el.show();
13880
13881
    // Create Wrapper
13882
    wrapper = $.effects.createWrapper( el ).css({
13883
        overflow: "hidden"
13884
    });
13885
    distance = widthFirst ?
13886
        [ wrapper.width(), wrapper.height() ] :
13887
        [ wrapper.height(), wrapper.width() ];
13888
13889
    if ( percent ) {
13890
        size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
13891
    }
13892
    if ( show ) {
13893
        wrapper.css( horizFirst ? {
13894
            height: 0,
13895
            width: size
13896
        } : {
13897
            height: size,
13898
            width: 0
13899
        });
13900
    }
13901
13902
    // Animation
13903
    animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
13904
    animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
13905
13906
    // Animate
13907
    wrapper
13908
        .animate( animation1, duration, o.easing )
13909
        .animate( animation2, duration, o.easing, function() {
13910
            if ( hide ) {
13911
                el.hide();
13912
            }
13913
            $.effects.restore( el, props );
13914
            $.effects.removeWrapper( el );
13915
            done();
13916
        });
13917
13918
};
13919
13920
13921
/*!
13922
 * jQuery UI Effects Highlight 1.11.4
13923
 * http://jqueryui.com
13924
 *
13925
 * Copyright jQuery Foundation and other contributors
13926
 * Released under the MIT license.
13927
 * http://jquery.org/license
13928
 *
13929
 * http://api.jqueryui.com/highlight-effect/
13930
 */
13931
13932
13933
var effectHighlight = $.effects.effect.highlight = function( o, done ) {
13934
    var elem = $( this ),
13935
        props = [ "backgroundImage", "backgroundColor", "opacity" ],
13936
        mode = $.effects.setMode( elem, o.mode || "show" ),
13937
        animation = {
13938
            backgroundColor: elem.css( "backgroundColor" )
13939
        };
13940
13941
    if (mode === "hide") {
13942
        animation.opacity = 0;
13943
    }
13944
13945
    $.effects.save( elem, props );
13946
13947
    elem
13948
        .show()
13949
        .css({
13950
            backgroundImage: "none",
13951
            backgroundColor: o.color || "#ffff99"
13952
        })
13953
        .animate( animation, {
13954
            queue: false,
13955
            duration: o.duration,
13956
            easing: o.easing,
13957
            complete: function() {
13958
                if ( mode === "hide" ) {
13959
                    elem.hide();
13960
                }
13961
                $.effects.restore( elem, props );
13962
                done();
13963
            }
13964
        });
13965
};
13966
13967
13968
/*!
13969
 * jQuery UI Effects Size 1.11.4
13970
 * http://jqueryui.com
13971
 *
13972
 * Copyright jQuery Foundation and other contributors
13973
 * Released under the MIT license.
13974
 * http://jquery.org/license
13975
 *
13976
 * http://api.jqueryui.com/size-effect/
13977
 */
13978
13979
13980
var effectSize = $.effects.effect.size = function( o, done ) {
13981
13982
    // Create element
13983
    var original, baseline, factor,
13984
        el = $( this ),
13985
        props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
13986
13987
        // Always restore
13988
        props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
13989
13990
        // Copy for children
13991
        props2 = [ "width", "height", "overflow" ],
13992
        cProps = [ "fontSize" ],
13993
        vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
13994
        hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
13995
13996
        // Set options
13997
        mode = $.effects.setMode( el, o.mode || "effect" ),
13998
        restore = o.restore || mode !== "effect",
13999
        scale = o.scale || "both",
14000
        origin = o.origin || [ "middle", "center" ],
14001
        position = el.css( "position" ),
14002
        props = restore ? props0 : props1,
14003
        zero = {
14004
            height: 0,
14005
            width: 0,
14006
            outerHeight: 0,
14007
            outerWidth: 0
14008
        };
14009
14010
    if ( mode === "show" ) {
14011
        el.show();
14012
    }
14013
    original = {
14014
        height: el.height(),
14015
        width: el.width(),
14016
        outerHeight: el.outerHeight(),
14017
        outerWidth: el.outerWidth()
14018
    };
14019
14020
    if ( o.mode === "toggle" && mode === "show" ) {
14021
        el.from = o.to || zero;
14022
        el.to = o.from || original;
14023
    } else {
14024
        el.from = o.from || ( mode === "show" ? zero : original );
14025
        el.to = o.to || ( mode === "hide" ? zero : original );
14026
    }
14027
14028
    // Set scaling factor
14029
    factor = {
14030
        from: {
14031
            y: el.from.height / original.height,
14032
            x: el.from.width / original.width
14033
        },
14034
        to: {
14035
            y: el.to.height / original.height,
14036
            x: el.to.width / original.width
14037
        }
14038
    };
14039
14040
    // Scale the css box
14041
    if ( scale === "box" || scale === "both" ) {
14042
14043
        // Vertical props scaling
14044
        if ( factor.from.y !== factor.to.y ) {
14045
            props = props.concat( vProps );
14046
            el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
14047
            el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
14048
        }
14049
14050
        // Horizontal props scaling
14051
        if ( factor.from.x !== factor.to.x ) {
14052
            props = props.concat( hProps );
14053
            el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
14054
            el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
14055
        }
14056
    }
14057
14058
    // Scale the content
14059
    if ( scale === "content" || scale === "both" ) {
14060
14061
        // Vertical props scaling
14062
        if ( factor.from.y !== factor.to.y ) {
14063
            props = props.concat( cProps ).concat( props2 );
14064
            el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
14065
            el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
14066
        }
14067
    }
14068
14069
    $.effects.save( el, props );
14070
    el.show();
14071
    $.effects.createWrapper( el );
14072
    el.css( "overflow", "hidden" ).css( el.from );
14073
14074
    // Adjust
14075
    if (origin) { // Calculate baseline shifts
14076
        baseline = $.effects.getBaseline( origin, original );
14077
        el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
14078
        el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
14079
        el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
14080
        el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
14081
    }
14082
    el.css( el.from ); // set top & left
14083
14084
    // Animate
14085
    if ( scale === "content" || scale === "both" ) { // Scale the children
14086
14087
        // Add margins/font-size
14088
        vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
14089
        hProps = hProps.concat([ "marginLeft", "marginRight" ]);
14090
        props2 = props0.concat(vProps).concat(hProps);
14091
14092
        el.find( "*[width]" ).each( function() {
14093
            var child = $( this ),
14094
                c_original = {
14095
                    height: child.height(),
14096
                    width: child.width(),
14097
                    outerHeight: child.outerHeight(),
14098
                    outerWidth: child.outerWidth()
14099
                };
14100
            if (restore) {
14101
                $.effects.save(child, props2);
14102
            }
14103
14104
            child.from = {
14105
                height: c_original.height * factor.from.y,
14106
                width: c_original.width * factor.from.x,
14107
                outerHeight: c_original.outerHeight * factor.from.y,
14108
                outerWidth: c_original.outerWidth * factor.from.x
14109
            };
14110
            child.to = {
14111
                height: c_original.height * factor.to.y,
14112
                width: c_original.width * factor.to.x,
14113
                outerHeight: c_original.height * factor.to.y,
14114
                outerWidth: c_original.width * factor.to.x
14115
            };
14116
14117
            // Vertical props scaling
14118
            if ( factor.from.y !== factor.to.y ) {
14119
                child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
14120
                child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
14121
            }
14122
14123
            // Horizontal props scaling
14124
            if ( factor.from.x !== factor.to.x ) {
14125
                child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
14126
                child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
14127
            }
14128
14129
            // Animate children
14130
            child.css( child.from );
14131
            child.animate( child.to, o.duration, o.easing, function() {
14132
14133
                // Restore children
14134
                if ( restore ) {
14135
                    $.effects.restore( child, props2 );
14136
                }
14137
            });
14138
        });
14139
    }
14140
14141
    // Animate
14142
    el.animate( el.to, {
14143
        queue: false,
14144
        duration: o.duration,
14145
        easing: o.easing,
14146
        complete: function() {
14147
            if ( el.to.opacity === 0 ) {
14148
                el.css( "opacity", el.from.opacity );
14149
            }
14150
            if ( mode === "hide" ) {
14151
                el.hide();
14152
            }
14153
            $.effects.restore( el, props );
14154
            if ( !restore ) {
14155
14156
                // we need to calculate our new positioning based on the scaling
14157
                if ( position === "static" ) {
14158
                    el.css({
14159
                        position: "relative",
14160
                        top: el.to.top,
14161
                        left: el.to.left
14162
                    });
14163
                } else {
14164
                    $.each([ "top", "left" ], function( idx, pos ) {
14165
                        el.css( pos, function( _, str ) {
14166
                            var val = parseInt( str, 10 ),
14167
                                toRef = idx ? el.to.left : el.to.top;
14168
14169
                            // if original was "auto", recalculate the new value from wrapper
14170
                            if ( str === "auto" ) {
14171
                                return toRef + "px";
14172
                            }
14173
14174
                            return val + toRef + "px";
14175
                        });
14176
                    });
14177
                }
14178
            }
14179
14180
            $.effects.removeWrapper( el );
14181
            done();
14182
        }
14183
    });
14184
14185
};
14186
14187
14188
/*!
14189
 * jQuery UI Effects Scale 1.11.4
14190
 * http://jqueryui.com
14191
 *
14192
 * Copyright jQuery Foundation and other contributors
14193
 * Released under the MIT license.
14194
 * http://jquery.org/license
14195
 *
14196
 * http://api.jqueryui.com/scale-effect/
14197
 */
14198
14199
14200
var effectScale = $.effects.effect.scale = function( o, done ) {
14201
14202
    // Create element
14203
    var el = $( this ),
14204
        options = $.extend( true, {}, o ),
14205
        mode = $.effects.setMode( el, o.mode || "effect" ),
14206
        percent = parseInt( o.percent, 10 ) ||
14207
            ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
14208
        direction = o.direction || "both",
14209
        origin = o.origin,
14210
        original = {
14211
            height: el.height(),
14212
            width: el.width(),
14213
            outerHeight: el.outerHeight(),
14214
            outerWidth: el.outerWidth()
14215
        },
14216
        factor = {
14217
            y: direction !== "horizontal" ? (percent / 100) : 1,
14218
            x: direction !== "vertical" ? (percent / 100) : 1
14219
        };
14220
14221
    // We are going to pass this effect to the size effect:
14222
    options.effect = "size";
14223
    options.queue = false;
14224
    options.complete = done;
14225
14226
    // Set default origin and restore for show/hide
14227
    if ( mode !== "effect" ) {
14228
        options.origin = origin || [ "middle", "center" ];
14229
        options.restore = true;
14230
    }
14231
14232
    options.from = o.from || ( mode === "show" ? {
14233
        height: 0,
14234
        width: 0,
14235
        outerHeight: 0,
14236
        outerWidth: 0
14237
    } : original );
14238
    options.to = {
14239
        height: original.height * factor.y,
14240
        width: original.width * factor.x,
14241
        outerHeight: original.outerHeight * factor.y,
14242
        outerWidth: original.outerWidth * factor.x
14243
    };
14244
14245
    // Fade option to support puff
14246
    if ( options.fade ) {
14247
        if ( mode === "show" ) {
14248
            options.from.opacity = 0;
14249
            options.to.opacity = 1;
14250
        }
14251
        if ( mode === "hide" ) {
14252
            options.from.opacity = 1;
14253
            options.to.opacity = 0;
14254
        }
14255
    }
14256
14257
    // Animate
14258
    el.effect( options );
14259
14260
};
14261
14262
14263
/*!
14264
 * jQuery UI Effects Puff 1.11.4
14265
 * http://jqueryui.com
14266
 *
14267
 * Copyright jQuery Foundation and other contributors
14268
 * Released under the MIT license.
14269
 * http://jquery.org/license
14270
 *
14271
 * http://api.jqueryui.com/puff-effect/
14272
 */
14273
14274
14275
var effectPuff = $.effects.effect.puff = function( o, done ) {
14276
    var elem = $( this ),
14277
        mode = $.effects.setMode( elem, o.mode || "hide" ),
14278
        hide = mode === "hide",
14279
        percent = parseInt( o.percent, 10 ) || 150,
14280
        factor = percent / 100,
14281
        original = {
14282
            height: elem.height(),
14283
            width: elem.width(),
14284
            outerHeight: elem.outerHeight(),
14285
            outerWidth: elem.outerWidth()
14286
        };
14287
14288
    $.extend( o, {
14289
        effect: "scale",
14290
        queue: false,
14291
        fade: true,
14292
        mode: mode,
14293
        complete: done,
14294
        percent: hide ? percent : 100,
14295
        from: hide ?
14296
            original :
14297
            {
14298
                height: original.height * factor,
14299
                width: original.width * factor,
14300
                outerHeight: original.outerHeight * factor,
14301
                outerWidth: original.outerWidth * factor
14302
            }
14303
    });
14304
14305
    elem.effect( o );
14306
};
14307
14308
14309
/*!
14310
 * jQuery UI Effects Pulsate 1.11.4
14311
 * http://jqueryui.com
14312
 *
14313
 * Copyright jQuery Foundation and other contributors
14314
 * Released under the MIT license.
14315
 * http://jquery.org/license
14316
 *
14317
 * http://api.jqueryui.com/pulsate-effect/
14318
 */
14319
14320
14321
var effectPulsate = $.effects.effect.pulsate = function( o, done ) {
14322
    var elem = $( this ),
14323
        mode = $.effects.setMode( elem, o.mode || "show" ),
14324
        show = mode === "show",
14325
        hide = mode === "hide",
14326
        showhide = ( show || mode === "hide" ),
14327
14328
        // showing or hiding leaves of the "last" animation
14329
        anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
14330
        duration = o.duration / anims,
14331
        animateTo = 0,
14332
        queue = elem.queue(),
14333
        queuelen = queue.length,
14334
        i;
14335
14336
    if ( show || !elem.is(":visible")) {
14337
        elem.css( "opacity", 0 ).show();
14338
        animateTo = 1;
14339
    }
14340
14341
    // anims - 1 opacity "toggles"
14342
    for ( i = 1; i < anims; i++ ) {
14343
        elem.animate({
14344
            opacity: animateTo
14345
        }, duration, o.easing );
14346
        animateTo = 1 - animateTo;
14347
    }
14348
14349
    elem.animate({
14350
        opacity: animateTo
14351
    }, duration, o.easing);
14352
14353
    elem.queue(function() {
14354
        if ( hide ) {
14355
            elem.hide();
14356
        }
14357
        done();
14358
    });
14359
14360
    // We just queued up "anims" animations, we need to put them next in the queue
14361
    if ( queuelen > 1 ) {
14362
        queue.splice.apply( queue,
14363
            [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
14364
    }
14365
    elem.dequeue();
14366
};
14367
14368
14369
/*!
14370
 * jQuery UI Effects Shake 1.11.4
14371
 * http://jqueryui.com
14372
 *
14373
 * Copyright jQuery Foundation and other contributors
14374
 * Released under the MIT license.
14375
 * http://jquery.org/license
14376
 *
14377
 * http://api.jqueryui.com/shake-effect/
14378
 */
14379
14380
14381
var effectShake = $.effects.effect.shake = function( o, done ) {
14382
14383
    var el = $( this ),
14384
        props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
14385
        mode = $.effects.setMode( el, o.mode || "effect" ),
14386
        direction = o.direction || "left",
14387
        distance = o.distance || 20,
14388
        times = o.times || 3,
14389
        anims = times * 2 + 1,
14390
        speed = Math.round( o.duration / anims ),
14391
        ref = (direction === "up" || direction === "down") ? "top" : "left",
14392
        positiveMotion = (direction === "up" || direction === "left"),
14393
        animation = {},
14394
        animation1 = {},
14395
        animation2 = {},
14396
        i,
14397
14398
        // we will need to re-assemble the queue to stack our animations in place
14399
        queue = el.queue(),
14400
        queuelen = queue.length;
14401
14402
    $.effects.save( el, props );
14403
    el.show();
14404
    $.effects.createWrapper( el );
14405
14406
    // Animation
14407
    animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
14408
    animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
14409
    animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
14410
14411
    // Animate
14412
    el.animate( animation, speed, o.easing );
14413
14414
    // Shakes
14415
    for ( i = 1; i < times; i++ ) {
14416
        el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
14417
    }
14418
    el
14419
        .animate( animation1, speed, o.easing )
14420
        .animate( animation, speed / 2, o.easing )
14421
        .queue(function() {
14422
            if ( mode === "hide" ) {
14423
                el.hide();
14424
            }
14425
            $.effects.restore( el, props );
14426
            $.effects.removeWrapper( el );
14427
            done();
14428
        });
14429
14430
    // inject all the animations we just queued to be first in line (after "inprogress")
14431
    if ( queuelen > 1) {
14432
        queue.splice.apply( queue,
14433
            [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
14434
    }
14435
    el.dequeue();
14436
14437
};
14438
14439
14440
/*!
14441
 * jQuery UI Effects Slide 1.11.4
14442
 * http://jqueryui.com
14443
 *
14444
 * Copyright jQuery Foundation and other contributors
14445
 * Released under the MIT license.
14446
 * http://jquery.org/license
14447
 *
14448
 * http://api.jqueryui.com/slide-effect/
14449
 */
14450
14451
14452
var effectSlide = $.effects.effect.slide = function( o, done ) {
14453
14454
    // Create element
14455
    var el = $( this ),
14456
        props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
14457
        mode = $.effects.setMode( el, o.mode || "show" ),
14458
        show = mode === "show",
14459
        direction = o.direction || "left",
14460
        ref = (direction === "up" || direction === "down") ? "top" : "left",
14461
        positiveMotion = (direction === "up" || direction === "left"),
14462
        distance,
14463
        animation = {};
14464
14465
    // Adjust
14466
    $.effects.save( el, props );
14467
    el.show();
14468
    distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
14469
14470
    $.effects.createWrapper( el ).css({
14471
        overflow: "hidden"
14472
    });
14473
14474
    if ( show ) {
14475
        el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
14476
    }
14477
14478
    // Animation
14479
    animation[ ref ] = ( show ?
14480
        ( positiveMotion ? "+=" : "-=") :
14481
        ( positiveMotion ? "-=" : "+=")) +
14482
        distance;
14483
14484
    // Animate
14485
    el.animate( animation, {
14486
        queue: false,
14487
        duration: o.duration,
14488
        easing: o.easing,
14489
        complete: function() {
14490
            if ( mode === "hide" ) {
14491
                el.hide();
14492
            }
14493
            $.effects.restore( el, props );
14494
            $.effects.removeWrapper( el );
14495
            done();
14496
        }
14497
    });
14498
};
14499
14500
14501
/*!
14502
 * jQuery UI Effects Transfer 1.11.4
14503
 * http://jqueryui.com
14504
 *
14505
 * Copyright jQuery Foundation and other contributors
14506
 * Released under the MIT license.
14507
 * http://jquery.org/license
14508
 *
14509
 * http://api.jqueryui.com/transfer-effect/
14510
 */
14511
14512
14513
var effectTransfer = $.effects.effect.transfer = function( o, done ) {
14514
    var elem = $( this ),
14515
        target = $( o.to ),
14516
        targetFixed = target.css( "position" ) === "fixed",
14517
        body = $("body"),
14518
        fixTop = targetFixed ? body.scrollTop() : 0,
14519
        fixLeft = targetFixed ? body.scrollLeft() : 0,
14520
        endPosition = target.offset(),
14521
        animation = {
14522
            top: endPosition.top - fixTop,
14523
            left: endPosition.left - fixLeft,
14524
            height: target.innerHeight(),
14525
            width: target.innerWidth()
14526
        },
14527
        startPosition = elem.offset(),
14528
        transfer = $( "<div class='ui-effects-transfer'></div>" )
14529
            .appendTo( document.body )
14530
            .addClass( o.className )
14531
            .css({
14532
                top: startPosition.top - fixTop,
14533
                left: startPosition.left - fixLeft,
14534
                height: elem.innerHeight(),
14535
                width: elem.innerWidth(),
14536
                position: targetFixed ? "fixed" : "absolute"
14537
            })
14538
            .animate( animation, o.duration, o.easing, function() {
14539
                transfer.remove();
14540
                done();
14541
            });
14542
};
14543
14544
14545
14546
}));