Statistics
| Branch: | Revision:

blinker / firefox.plugin / data / jquery-ui.js @ a03cd52e

History | View | Annotate | Download (459.566 KB)

1 a03cd52e Thies Pfeiffer
/*! jQuery UI - v1.11.4 - 2015-03-11
2
* http://jqueryui.com
3
* Includes: core.js, widget.js, mouse.js, position.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, draggable.js, droppable.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, menu.js, progressbar.js, resizable.js, selectable.js, selectmenu.js, slider.js, sortable.js, spinner.js, tabs.js, tooltip.js
4
* Copyright 2015 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 Accordion 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/accordion/
1561
 */
1562
1563
1564
var accordion = $.widget( "ui.accordion", {
1565
        version: "1.11.4",
1566
        options: {
1567
                active: 0,
1568
                animate: {},
1569
                collapsible: false,
1570
                event: "click",
1571
                header: "> li > :first-child,> :not(li):even",
1572
                heightStyle: "auto",
1573
                icons: {
1574
                        activeHeader: "ui-icon-triangle-1-s",
1575
                        header: "ui-icon-triangle-1-e"
1576
                },
1577
1578
                // callbacks
1579
                activate: null,
1580
                beforeActivate: null
1581
        },
1582
1583
        hideProps: {
1584
                borderTopWidth: "hide",
1585
                borderBottomWidth: "hide",
1586
                paddingTop: "hide",
1587
                paddingBottom: "hide",
1588
                height: "hide"
1589
        },
1590
1591
        showProps: {
1592
                borderTopWidth: "show",
1593
                borderBottomWidth: "show",
1594
                paddingTop: "show",
1595
                paddingBottom: "show",
1596
                height: "show"
1597
        },
1598
1599
        _create: function() {
1600
                var options = this.options;
1601
                this.prevShow = this.prevHide = $();
1602
                this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
1603
                        // ARIA
1604
                        .attr( "role", "tablist" );
1605
1606
                // don't allow collapsible: false and active: false / null
1607
                if ( !options.collapsible && (options.active === false || options.active == null) ) {
1608
                        options.active = 0;
1609
                }
1610
1611
                this._processPanels();
1612
                // handle negative values
1613
                if ( options.active < 0 ) {
1614
                        options.active += this.headers.length;
1615
                }
1616
                this._refresh();
1617
        },
1618
1619
        _getCreateEventData: function() {
1620
                return {
1621
                        header: this.active,
1622
                        panel: !this.active.length ? $() : this.active.next()
1623
                };
1624
        },
1625
1626
        _createIcons: function() {
1627
                var icons = this.options.icons;
1628
                if ( icons ) {
1629
                        $( "<span>" )
1630
                                .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
1631
                                .prependTo( this.headers );
1632
                        this.active.children( ".ui-accordion-header-icon" )
1633
                                .removeClass( icons.header )
1634
                                .addClass( icons.activeHeader );
1635
                        this.headers.addClass( "ui-accordion-icons" );
1636
                }
1637
        },
1638
1639
        _destroyIcons: function() {
1640
                this.headers
1641
                        .removeClass( "ui-accordion-icons" )
1642
                        .children( ".ui-accordion-header-icon" )
1643
                                .remove();
1644
        },
1645
1646
        _destroy: function() {
1647
                var contents;
1648
1649
                // clean up main element
1650
                this.element
1651
                        .removeClass( "ui-accordion ui-widget ui-helper-reset" )
1652
                        .removeAttr( "role" );
1653
1654
                // clean up headers
1655
                this.headers
1656
                        .removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " +
1657
                                "ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
1658
                        .removeAttr( "role" )
1659
                        .removeAttr( "aria-expanded" )
1660
                        .removeAttr( "aria-selected" )
1661
                        .removeAttr( "aria-controls" )
1662
                        .removeAttr( "tabIndex" )
1663
                        .removeUniqueId();
1664
1665
                this._destroyIcons();
1666
1667
                // clean up content panels
1668
                contents = this.headers.next()
1669
                        .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " +
1670
                                "ui-accordion-content ui-accordion-content-active ui-state-disabled" )
1671
                        .css( "display", "" )
1672
                        .removeAttr( "role" )
1673
                        .removeAttr( "aria-hidden" )
1674
                        .removeAttr( "aria-labelledby" )
1675
                        .removeUniqueId();
1676
1677
                if ( this.options.heightStyle !== "content" ) {
1678
                        contents.css( "height", "" );
1679
                }
1680
        },
1681
1682
        _setOption: function( key, value ) {
1683
                if ( key === "active" ) {
1684
                        // _activate() will handle invalid values and update this.options
1685
                        this._activate( value );
1686
                        return;
1687
                }
1688
1689
                if ( key === "event" ) {
1690
                        if ( this.options.event ) {
1691
                                this._off( this.headers, this.options.event );
1692
                        }
1693
                        this._setupEvents( value );
1694
                }
1695
1696
                this._super( key, value );
1697
1698
                // setting collapsible: false while collapsed; open first panel
1699
                if ( key === "collapsible" && !value && this.options.active === false ) {
1700
                        this._activate( 0 );
1701
                }
1702
1703
                if ( key === "icons" ) {
1704
                        this._destroyIcons();
1705
                        if ( value ) {
1706
                                this._createIcons();
1707
                        }
1708
                }
1709
1710
                // #5332 - opacity doesn't cascade to positioned elements in IE
1711
                // so we need to add the disabled class to the headers and panels
1712
                if ( key === "disabled" ) {
1713
                        this.element
1714
                                .toggleClass( "ui-state-disabled", !!value )
1715
                                .attr( "aria-disabled", value );
1716
                        this.headers.add( this.headers.next() )
1717
                                .toggleClass( "ui-state-disabled", !!value );
1718
                }
1719
        },
1720
1721
        _keydown: function( event ) {
1722
                if ( event.altKey || event.ctrlKey ) {
1723
                        return;
1724
                }
1725
1726
                var keyCode = $.ui.keyCode,
1727
                        length = this.headers.length,
1728
                        currentIndex = this.headers.index( event.target ),
1729
                        toFocus = false;
1730
1731
                switch ( event.keyCode ) {
1732
                        case keyCode.RIGHT:
1733
                        case keyCode.DOWN:
1734
                                toFocus = this.headers[ ( currentIndex + 1 ) % length ];
1735
                                break;
1736
                        case keyCode.LEFT:
1737
                        case keyCode.UP:
1738
                                toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
1739
                                break;
1740
                        case keyCode.SPACE:
1741
                        case keyCode.ENTER:
1742
                                this._eventHandler( event );
1743
                                break;
1744
                        case keyCode.HOME:
1745
                                toFocus = this.headers[ 0 ];
1746
                                break;
1747
                        case keyCode.END:
1748
                                toFocus = this.headers[ length - 1 ];
1749
                                break;
1750
                }
1751
1752
                if ( toFocus ) {
1753
                        $( event.target ).attr( "tabIndex", -1 );
1754
                        $( toFocus ).attr( "tabIndex", 0 );
1755
                        toFocus.focus();
1756
                        event.preventDefault();
1757
                }
1758
        },
1759
1760
        _panelKeyDown: function( event ) {
1761
                if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
1762
                        $( event.currentTarget ).prev().focus();
1763
                }
1764
        },
1765
1766
        refresh: function() {
1767
                var options = this.options;
1768
                this._processPanels();
1769
1770
                // was collapsed or no panel
1771
                if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
1772
                        options.active = false;
1773
                        this.active = $();
1774
                // active false only when collapsible is true
1775
                } else if ( options.active === false ) {
1776
                        this._activate( 0 );
1777
                // was active, but active panel is gone
1778
                } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
1779
                        // all remaining panel are disabled
1780
                        if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
1781
                                options.active = false;
1782
                                this.active = $();
1783
                        // activate previous panel
1784
                        } else {
1785
                                this._activate( Math.max( 0, options.active - 1 ) );
1786
                        }
1787
                // was active, active panel still exists
1788
                } else {
1789
                        // make sure active index is correct
1790
                        options.active = this.headers.index( this.active );
1791
                }
1792
1793
                this._destroyIcons();
1794
1795
                this._refresh();
1796
        },
1797
1798
        _processPanels: function() {
1799
                var prevHeaders = this.headers,
1800
                        prevPanels = this.panels;
1801
1802
                this.headers = this.element.find( this.options.header )
1803
                        .addClass( "ui-accordion-header ui-state-default ui-corner-all" );
1804
1805
                this.panels = this.headers.next()
1806
                        .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
1807
                        .filter( ":not(.ui-accordion-content-active)" )
1808
                        .hide();
1809
1810
                // Avoid memory leaks (#10056)
1811
                if ( prevPanels ) {
1812
                        this._off( prevHeaders.not( this.headers ) );
1813
                        this._off( prevPanels.not( this.panels ) );
1814
                }
1815
        },
1816
1817
        _refresh: function() {
1818
                var maxHeight,
1819
                        options = this.options,
1820
                        heightStyle = options.heightStyle,
1821
                        parent = this.element.parent();
1822
1823
                this.active = this._findActive( options.active )
1824
                        .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
1825
                        .removeClass( "ui-corner-all" );
1826
                this.active.next()
1827
                        .addClass( "ui-accordion-content-active" )
1828
                        .show();
1829
1830
                this.headers
1831
                        .attr( "role", "tab" )
1832
                        .each(function() {
1833
                                var header = $( this ),
1834
                                        headerId = header.uniqueId().attr( "id" ),
1835
                                        panel = header.next(),
1836
                                        panelId = panel.uniqueId().attr( "id" );
1837
                                header.attr( "aria-controls", panelId );
1838
                                panel.attr( "aria-labelledby", headerId );
1839
                        })
1840
                        .next()
1841
                                .attr( "role", "tabpanel" );
1842
1843
                this.headers
1844
                        .not( this.active )
1845
                        .attr({
1846
                                "aria-selected": "false",
1847
                                "aria-expanded": "false",
1848
                                tabIndex: -1
1849
                        })
1850
                        .next()
1851
                                .attr({
1852
                                        "aria-hidden": "true"
1853
                                })
1854
                                .hide();
1855
1856
                // make sure at least one header is in the tab order
1857
                if ( !this.active.length ) {
1858
                        this.headers.eq( 0 ).attr( "tabIndex", 0 );
1859
                } else {
1860
                        this.active.attr({
1861
                                "aria-selected": "true",
1862
                                "aria-expanded": "true",
1863
                                tabIndex: 0
1864
                        })
1865
                        .next()
1866
                                .attr({
1867
                                        "aria-hidden": "false"
1868
                                });
1869
                }
1870
1871
                this._createIcons();
1872
1873
                this._setupEvents( options.event );
1874
1875
                if ( heightStyle === "fill" ) {
1876
                        maxHeight = parent.height();
1877
                        this.element.siblings( ":visible" ).each(function() {
1878
                                var elem = $( this ),
1879
                                        position = elem.css( "position" );
1880
1881
                                if ( position === "absolute" || position === "fixed" ) {
1882
                                        return;
1883
                                }
1884
                                maxHeight -= elem.outerHeight( true );
1885
                        });
1886
1887
                        this.headers.each(function() {
1888
                                maxHeight -= $( this ).outerHeight( true );
1889
                        });
1890
1891
                        this.headers.next()
1892
                                .each(function() {
1893
                                        $( this ).height( Math.max( 0, maxHeight -
1894
                                                $( this ).innerHeight() + $( this ).height() ) );
1895
                                })
1896
                                .css( "overflow", "auto" );
1897
                } else if ( heightStyle === "auto" ) {
1898
                        maxHeight = 0;
1899
                        this.headers.next()
1900
                                .each(function() {
1901
                                        maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
1902
                                })
1903
                                .height( maxHeight );
1904
                }
1905
        },
1906
1907
        _activate: function( index ) {
1908
                var active = this._findActive( index )[ 0 ];
1909
1910
                // trying to activate the already active panel
1911
                if ( active === this.active[ 0 ] ) {
1912
                        return;
1913
                }
1914
1915
                // trying to collapse, simulate a click on the currently active header
1916
                active = active || this.active[ 0 ];
1917
1918
                this._eventHandler({
1919
                        target: active,
1920
                        currentTarget: active,
1921
                        preventDefault: $.noop
1922
                });
1923
        },
1924
1925
        _findActive: function( selector ) {
1926
                return typeof selector === "number" ? this.headers.eq( selector ) : $();
1927
        },
1928
1929
        _setupEvents: function( event ) {
1930
                var events = {
1931
                        keydown: "_keydown"
1932
                };
1933
                if ( event ) {
1934
                        $.each( event.split( " " ), function( index, eventName ) {
1935
                                events[ eventName ] = "_eventHandler";
1936
                        });
1937
                }
1938
1939
                this._off( this.headers.add( this.headers.next() ) );
1940
                this._on( this.headers, events );
1941
                this._on( this.headers.next(), { keydown: "_panelKeyDown" });
1942
                this._hoverable( this.headers );
1943
                this._focusable( this.headers );
1944
        },
1945
1946
        _eventHandler: function( event ) {
1947
                var options = this.options,
1948
                        active = this.active,
1949
                        clicked = $( event.currentTarget ),
1950
                        clickedIsActive = clicked[ 0 ] === active[ 0 ],
1951
                        collapsing = clickedIsActive && options.collapsible,
1952
                        toShow = collapsing ? $() : clicked.next(),
1953
                        toHide = active.next(),
1954
                        eventData = {
1955
                                oldHeader: active,
1956
                                oldPanel: toHide,
1957
                                newHeader: collapsing ? $() : clicked,
1958
                                newPanel: toShow
1959
                        };
1960
1961
                event.preventDefault();
1962
1963
                if (
1964
                                // click on active header, but not collapsible
1965
                                ( clickedIsActive && !options.collapsible ) ||
1966
                                // allow canceling activation
1967
                                ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
1968
                        return;
1969
                }
1970
1971
                options.active = collapsing ? false : this.headers.index( clicked );
1972
1973
                // when the call to ._toggle() comes after the class changes
1974
                // it causes a very odd bug in IE 8 (see #6720)
1975
                this.active = clickedIsActive ? $() : clicked;
1976
                this._toggle( eventData );
1977
1978
                // switch classes
1979
                // corner classes on the previously active header stay after the animation
1980
                active.removeClass( "ui-accordion-header-active ui-state-active" );
1981
                if ( options.icons ) {
1982
                        active.children( ".ui-accordion-header-icon" )
1983
                                .removeClass( options.icons.activeHeader )
1984
                                .addClass( options.icons.header );
1985
                }
1986
1987
                if ( !clickedIsActive ) {
1988
                        clicked
1989
                                .removeClass( "ui-corner-all" )
1990
                                .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
1991
                        if ( options.icons ) {
1992
                                clicked.children( ".ui-accordion-header-icon" )
1993
                                        .removeClass( options.icons.header )
1994
                                        .addClass( options.icons.activeHeader );
1995
                        }
1996
1997
                        clicked
1998
                                .next()
1999
                                .addClass( "ui-accordion-content-active" );
2000
                }
2001
        },
2002
2003
        _toggle: function( data ) {
2004
                var toShow = data.newPanel,
2005
                        toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
2006
2007
                // handle activating a panel during the animation for another activation
2008
                this.prevShow.add( this.prevHide ).stop( true, true );
2009
                this.prevShow = toShow;
2010
                this.prevHide = toHide;
2011
2012
                if ( this.options.animate ) {
2013
                        this._animate( toShow, toHide, data );
2014
                } else {
2015
                        toHide.hide();
2016
                        toShow.show();
2017
                        this._toggleComplete( data );
2018
                }
2019
2020
                toHide.attr({
2021
                        "aria-hidden": "true"
2022
                });
2023
                toHide.prev().attr({
2024
                        "aria-selected": "false",
2025
                        "aria-expanded": "false"
2026
                });
2027
                // if we're switching panels, remove the old header from the tab order
2028
                // if we're opening from collapsed state, remove the previous header from the tab order
2029
                // if we're collapsing, then keep the collapsing header in the tab order
2030
                if ( toShow.length && toHide.length ) {
2031
                        toHide.prev().attr({
2032
                                "tabIndex": -1,
2033
                                "aria-expanded": "false"
2034
                        });
2035
                } else if ( toShow.length ) {
2036
                        this.headers.filter(function() {
2037
                                return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
2038
                        })
2039
                        .attr( "tabIndex", -1 );
2040
                }
2041
2042
                toShow
2043
                        .attr( "aria-hidden", "false" )
2044
                        .prev()
2045
                                .attr({
2046
                                        "aria-selected": "true",
2047
                                        "aria-expanded": "true",
2048
                                        tabIndex: 0
2049
                                });
2050
        },
2051
2052
        _animate: function( toShow, toHide, data ) {
2053
                var total, easing, duration,
2054
                        that = this,
2055
                        adjust = 0,
2056
                        boxSizing = toShow.css( "box-sizing" ),
2057
                        down = toShow.length &&
2058
                                ( !toHide.length || ( toShow.index() < toHide.index() ) ),
2059
                        animate = this.options.animate || {},
2060
                        options = down && animate.down || animate,
2061
                        complete = function() {
2062
                                that._toggleComplete( data );
2063
                        };
2064
2065
                if ( typeof options === "number" ) {
2066
                        duration = options;
2067
                }
2068
                if ( typeof options === "string" ) {
2069
                        easing = options;
2070
                }
2071
                // fall back from options to animation in case of partial down settings
2072
                easing = easing || options.easing || animate.easing;
2073
                duration = duration || options.duration || animate.duration;
2074
2075
                if ( !toHide.length ) {
2076
                        return toShow.animate( this.showProps, duration, easing, complete );
2077
                }
2078
                if ( !toShow.length ) {
2079
                        return toHide.animate( this.hideProps, duration, easing, complete );
2080
                }
2081
2082
                total = toShow.show().outerHeight();
2083
                toHide.animate( this.hideProps, {
2084
                        duration: duration,
2085
                        easing: easing,
2086
                        step: function( now, fx ) {
2087
                                fx.now = Math.round( now );
2088
                        }
2089
                });
2090
                toShow
2091
                        .hide()
2092
                        .animate( this.showProps, {
2093
                                duration: duration,
2094
                                easing: easing,
2095
                                complete: complete,
2096
                                step: function( now, fx ) {
2097
                                        fx.now = Math.round( now );
2098
                                        if ( fx.prop !== "height" ) {
2099
                                                if ( boxSizing === "content-box" ) {
2100
                                                        adjust += fx.now;
2101
                                                }
2102
                                        } else if ( that.options.heightStyle !== "content" ) {
2103
                                                fx.now = Math.round( total - toHide.outerHeight() - adjust );
2104
                                                adjust = 0;
2105
                                        }
2106
                                }
2107
                        });
2108
        },
2109
2110
        _toggleComplete: function( data ) {
2111
                var toHide = data.oldPanel;
2112
2113
                toHide
2114
                        .removeClass( "ui-accordion-content-active" )
2115
                        .prev()
2116
                                .removeClass( "ui-corner-top" )
2117
                                .addClass( "ui-corner-all" );
2118
2119
                // Work around for rendering bug in IE (#5421)
2120
                if ( toHide.length ) {
2121
                        toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
2122
                }
2123
                this._trigger( "activate", null, data );
2124
        }
2125
});
2126
2127
2128
/*!
2129
 * jQuery UI Menu 1.11.4
2130
 * http://jqueryui.com
2131
 *
2132
 * Copyright jQuery Foundation and other contributors
2133
 * Released under the MIT license.
2134
 * http://jquery.org/license
2135
 *
2136
 * http://api.jqueryui.com/menu/
2137
 */
2138
2139
2140
var menu = $.widget( "ui.menu", {
2141
        version: "1.11.4",
2142
        defaultElement: "<ul>",
2143
        delay: 300,
2144
        options: {
2145
                icons: {
2146
                        submenu: "ui-icon-carat-1-e"
2147
                },
2148
                items: "> *",
2149
                menus: "ul",
2150
                position: {
2151
                        my: "left-1 top",
2152
                        at: "right top"
2153
                },
2154
                role: "menu",
2155
2156
                // callbacks
2157
                blur: null,
2158
                focus: null,
2159
                select: null
2160
        },
2161
2162
        _create: function() {
2163
                this.activeMenu = this.element;
2164
2165
                // Flag used to prevent firing of the click handler
2166
                // as the event bubbles up through nested menus
2167
                this.mouseHandled = false;
2168
                this.element
2169
                        .uniqueId()
2170
                        .addClass( "ui-menu ui-widget ui-widget-content" )
2171
                        .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
2172
                        .attr({
2173
                                role: this.options.role,
2174
                                tabIndex: 0
2175
                        });
2176
2177
                if ( this.options.disabled ) {
2178
                        this.element
2179
                                .addClass( "ui-state-disabled" )
2180
                                .attr( "aria-disabled", "true" );
2181
                }
2182
2183
                this._on({
2184
                        // Prevent focus from sticking to links inside menu after clicking
2185
                        // them (focus should always stay on UL during navigation).
2186
                        "mousedown .ui-menu-item": function( event ) {
2187
                                event.preventDefault();
2188
                        },
2189
                        "click .ui-menu-item": function( event ) {
2190
                                var target = $( event.target );
2191
                                if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
2192
                                        this.select( event );
2193
2194
                                        // Only set the mouseHandled flag if the event will bubble, see #9469.
2195
                                        if ( !event.isPropagationStopped() ) {
2196
                                                this.mouseHandled = true;
2197
                                        }
2198
2199
                                        // Open submenu on click
2200
                                        if ( target.has( ".ui-menu" ).length ) {
2201
                                                this.expand( event );
2202
                                        } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
2203
2204
                                                // Redirect focus to the menu
2205
                                                this.element.trigger( "focus", [ true ] );
2206
2207
                                                // If the active item is on the top level, let it stay active.
2208
                                                // Otherwise, blur the active item since it is no longer visible.
2209
                                                if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
2210
                                                        clearTimeout( this.timer );
2211
                                                }
2212
                                        }
2213
                                }
2214
                        },
2215
                        "mouseenter .ui-menu-item": function( event ) {
2216
                                // Ignore mouse events while typeahead is active, see #10458.
2217
                                // Prevents focusing the wrong item when typeahead causes a scroll while the mouse
2218
                                // is over an item in the menu
2219
                                if ( this.previousFilter ) {
2220
                                        return;
2221
                                }
2222
                                var target = $( event.currentTarget );
2223
                                // Remove ui-state-active class from siblings of the newly focused menu item
2224
                                // to avoid a jump caused by adjacent elements both having a class with a border
2225
                                target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" );
2226
                                this.focus( event, target );
2227
                        },
2228
                        mouseleave: "collapseAll",
2229
                        "mouseleave .ui-menu": "collapseAll",
2230
                        focus: function( event, keepActiveItem ) {
2231
                                // If there's already an active item, keep it active
2232
                                // If not, activate the first item
2233
                                var item = this.active || this.element.find( this.options.items ).eq( 0 );
2234
2235
                                if ( !keepActiveItem ) {
2236
                                        this.focus( event, item );
2237
                                }
2238
                        },
2239
                        blur: function( event ) {
2240
                                this._delay(function() {
2241
                                        if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
2242
                                                this.collapseAll( event );
2243
                                        }
2244
                                });
2245
                        },
2246
                        keydown: "_keydown"
2247
                });
2248
2249
                this.refresh();
2250
2251
                // Clicks outside of a menu collapse any open menus
2252
                this._on( this.document, {
2253
                        click: function( event ) {
2254
                                if ( this._closeOnDocumentClick( event ) ) {
2255
                                        this.collapseAll( event );
2256
                                }
2257
2258
                                // Reset the mouseHandled flag
2259
                                this.mouseHandled = false;
2260
                        }
2261
                });
2262
        },
2263
2264
        _destroy: function() {
2265
                // Destroy (sub)menus
2266
                this.element
2267
                        .removeAttr( "aria-activedescendant" )
2268
                        .find( ".ui-menu" ).addBack()
2269
                                .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" )
2270
                                .removeAttr( "role" )
2271
                                .removeAttr( "tabIndex" )
2272
                                .removeAttr( "aria-labelledby" )
2273
                                .removeAttr( "aria-expanded" )
2274
                                .removeAttr( "aria-hidden" )
2275
                                .removeAttr( "aria-disabled" )
2276
                                .removeUniqueId()
2277
                                .show();
2278
2279
                // Destroy menu items
2280
                this.element.find( ".ui-menu-item" )
2281
                        .removeClass( "ui-menu-item" )
2282
                        .removeAttr( "role" )
2283
                        .removeAttr( "aria-disabled" )
2284
                        .removeUniqueId()
2285
                        .removeClass( "ui-state-hover" )
2286
                        .removeAttr( "tabIndex" )
2287
                        .removeAttr( "role" )
2288
                        .removeAttr( "aria-haspopup" )
2289
                        .children().each( function() {
2290
                                var elem = $( this );
2291
                                if ( elem.data( "ui-menu-submenu-carat" ) ) {
2292
                                        elem.remove();
2293
                                }
2294
                        });
2295
2296
                // Destroy menu dividers
2297
                this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
2298
        },
2299
2300
        _keydown: function( event ) {
2301
                var match, prev, character, skip,
2302
                        preventDefault = true;
2303
2304
                switch ( event.keyCode ) {
2305
                case $.ui.keyCode.PAGE_UP:
2306
                        this.previousPage( event );
2307
                        break;
2308
                case $.ui.keyCode.PAGE_DOWN:
2309
                        this.nextPage( event );
2310
                        break;
2311
                case $.ui.keyCode.HOME:
2312
                        this._move( "first", "first", event );
2313
                        break;
2314
                case $.ui.keyCode.END:
2315
                        this._move( "last", "last", event );
2316
                        break;
2317
                case $.ui.keyCode.UP:
2318
                        this.previous( event );
2319
                        break;
2320
                case $.ui.keyCode.DOWN:
2321
                        this.next( event );
2322
                        break;
2323
                case $.ui.keyCode.LEFT:
2324
                        this.collapse( event );
2325
                        break;
2326
                case $.ui.keyCode.RIGHT:
2327
                        if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
2328
                                this.expand( event );
2329
                        }
2330
                        break;
2331
                case $.ui.keyCode.ENTER:
2332
                case $.ui.keyCode.SPACE:
2333
                        this._activate( event );
2334
                        break;
2335
                case $.ui.keyCode.ESCAPE:
2336
                        this.collapse( event );
2337
                        break;
2338
                default:
2339
                        preventDefault = false;
2340
                        prev = this.previousFilter || "";
2341
                        character = String.fromCharCode( event.keyCode );
2342
                        skip = false;
2343
2344
                        clearTimeout( this.filterTimer );
2345
2346
                        if ( character === prev ) {
2347
                                skip = true;
2348
                        } else {
2349
                                character = prev + character;
2350
                        }
2351
2352
                        match = this._filterMenuItems( character );
2353
                        match = skip && match.index( this.active.next() ) !== -1 ?
2354
                                this.active.nextAll( ".ui-menu-item" ) :
2355
                                match;
2356
2357
                        // If no matches on the current filter, reset to the last character pressed
2358
                        // to move down the menu to the first item that starts with that character
2359
                        if ( !match.length ) {
2360
                                character = String.fromCharCode( event.keyCode );
2361
                                match = this._filterMenuItems( character );
2362
                        }
2363
2364
                        if ( match.length ) {
2365
                                this.focus( event, match );
2366
                                this.previousFilter = character;
2367
                                this.filterTimer = this._delay(function() {
2368
                                        delete this.previousFilter;
2369
                                }, 1000 );
2370
                        } else {
2371
                                delete this.previousFilter;
2372
                        }
2373
                }
2374
2375
                if ( preventDefault ) {
2376
                        event.preventDefault();
2377
                }
2378
        },
2379
2380
        _activate: function( event ) {
2381
                if ( !this.active.is( ".ui-state-disabled" ) ) {
2382
                        if ( this.active.is( "[aria-haspopup='true']" ) ) {
2383
                                this.expand( event );
2384
                        } else {
2385
                                this.select( event );
2386
                        }
2387
                }
2388
        },
2389
2390
        refresh: function() {
2391
                var menus, items,
2392
                        that = this,
2393
                        icon = this.options.icons.submenu,
2394
                        submenus = this.element.find( this.options.menus );
2395
2396
                this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
2397
2398
                // Initialize nested menus
2399
                submenus.filter( ":not(.ui-menu)" )
2400
                        .addClass( "ui-menu ui-widget ui-widget-content ui-front" )
2401
                        .hide()
2402
                        .attr({
2403
                                role: this.options.role,
2404
                                "aria-hidden": "true",
2405
                                "aria-expanded": "false"
2406
                        })
2407
                        .each(function() {
2408
                                var menu = $( this ),
2409
                                        item = menu.parent(),
2410
                                        submenuCarat = $( "<span>" )
2411
                                                .addClass( "ui-menu-icon ui-icon " + icon )
2412
                                                .data( "ui-menu-submenu-carat", true );
2413
2414
                                item
2415
                                        .attr( "aria-haspopup", "true" )
2416
                                        .prepend( submenuCarat );
2417
                                menu.attr( "aria-labelledby", item.attr( "id" ) );
2418
                        });
2419
2420
                menus = submenus.add( this.element );
2421
                items = menus.find( this.options.items );
2422
2423
                // Initialize menu-items containing spaces and/or dashes only as dividers
2424
                items.not( ".ui-menu-item" ).each(function() {
2425
                        var item = $( this );
2426
                        if ( that._isDivider( item ) ) {
2427
                                item.addClass( "ui-widget-content ui-menu-divider" );
2428
                        }
2429
                });
2430
2431
                // Don't refresh list items that are already adapted
2432
                items.not( ".ui-menu-item, .ui-menu-divider" )
2433
                        .addClass( "ui-menu-item" )
2434
                        .uniqueId()
2435
                        .attr({
2436
                                tabIndex: -1,
2437
                                role: this._itemRole()
2438
                        });
2439
2440
                // Add aria-disabled attribute to any disabled menu item
2441
                items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
2442
2443
                // If the active item has been removed, blur the menu
2444
                if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
2445
                        this.blur();
2446
                }
2447
        },
2448
2449
        _itemRole: function() {
2450
                return {
2451
                        menu: "menuitem",
2452
                        listbox: "option"
2453
                }[ this.options.role ];
2454
        },
2455
2456
        _setOption: function( key, value ) {
2457
                if ( key === "icons" ) {
2458
                        this.element.find( ".ui-menu-icon" )
2459
                                .removeClass( this.options.icons.submenu )
2460
                                .addClass( value.submenu );
2461
                }
2462
                if ( key === "disabled" ) {
2463
                        this.element
2464
                                .toggleClass( "ui-state-disabled", !!value )
2465
                                .attr( "aria-disabled", value );
2466
                }
2467
                this._super( key, value );
2468
        },
2469
2470
        focus: function( event, item ) {
2471
                var nested, focused;
2472
                this.blur( event, event && event.type === "focus" );
2473
2474
                this._scrollIntoView( item );
2475
2476
                this.active = item.first();
2477
                focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" );
2478
                // Only update aria-activedescendant if there's a role
2479
                // otherwise we assume focus is managed elsewhere
2480
                if ( this.options.role ) {
2481
                        this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
2482
                }
2483
2484
                // Highlight active parent menu item, if any
2485
                this.active
2486
                        .parent()
2487
                        .closest( ".ui-menu-item" )
2488
                        .addClass( "ui-state-active" );
2489
2490
                if ( event && event.type === "keydown" ) {
2491
                        this._close();
2492
                } else {
2493
                        this.timer = this._delay(function() {
2494
                                this._close();
2495
                        }, this.delay );
2496
                }
2497
2498
                nested = item.children( ".ui-menu" );
2499
                if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
2500
                        this._startOpening(nested);
2501
                }
2502
                this.activeMenu = item.parent();
2503
2504
                this._trigger( "focus", event, { item: item } );
2505
        },
2506
2507
        _scrollIntoView: function( item ) {
2508
                var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
2509
                if ( this._hasScroll() ) {
2510
                        borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
2511
                        paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
2512
                        offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
2513
                        scroll = this.activeMenu.scrollTop();
2514
                        elementHeight = this.activeMenu.height();
2515
                        itemHeight = item.outerHeight();
2516
2517
                        if ( offset < 0 ) {
2518
                                this.activeMenu.scrollTop( scroll + offset );
2519
                        } else if ( offset + itemHeight > elementHeight ) {
2520
                                this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
2521
                        }
2522
                }
2523
        },
2524
2525
        blur: function( event, fromFocus ) {
2526
                if ( !fromFocus ) {
2527
                        clearTimeout( this.timer );
2528
                }
2529
2530
                if ( !this.active ) {
2531
                        return;
2532
                }
2533
2534
                this.active.removeClass( "ui-state-focus" );
2535
                this.active = null;
2536
2537
                this._trigger( "blur", event, { item: this.active } );
2538
        },
2539
2540
        _startOpening: function( submenu ) {
2541
                clearTimeout( this.timer );
2542
2543
                // Don't open if already open fixes a Firefox bug that caused a .5 pixel
2544
                // shift in the submenu position when mousing over the carat icon
2545
                if ( submenu.attr( "aria-hidden" ) !== "true" ) {
2546
                        return;
2547
                }
2548
2549
                this.timer = this._delay(function() {
2550
                        this._close();
2551
                        this._open( submenu );
2552
                }, this.delay );
2553
        },
2554
2555
        _open: function( submenu ) {
2556
                var position = $.extend({
2557
                        of: this.active
2558
                }, this.options.position );
2559
2560
                clearTimeout( this.timer );
2561
                this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
2562
                        .hide()
2563
                        .attr( "aria-hidden", "true" );
2564
2565
                submenu
2566
                        .show()
2567
                        .removeAttr( "aria-hidden" )
2568
                        .attr( "aria-expanded", "true" )
2569
                        .position( position );
2570
        },
2571
2572
        collapseAll: function( event, all ) {
2573
                clearTimeout( this.timer );
2574
                this.timer = this._delay(function() {
2575
                        // If we were passed an event, look for the submenu that contains the event
2576
                        var currentMenu = all ? this.element :
2577
                                $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
2578
2579
                        // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
2580
                        if ( !currentMenu.length ) {
2581
                                currentMenu = this.element;
2582
                        }
2583
2584
                        this._close( currentMenu );
2585
2586
                        this.blur( event );
2587
                        this.activeMenu = currentMenu;
2588
                }, this.delay );
2589
        },
2590
2591
        // With no arguments, closes the currently active menu - if nothing is active
2592
        // it closes all menus.  If passed an argument, it will search for menus BELOW
2593
        _close: function( startMenu ) {
2594
                if ( !startMenu ) {
2595
                        startMenu = this.active ? this.active.parent() : this.element;
2596
                }
2597
2598
                startMenu
2599
                        .find( ".ui-menu" )
2600
                                .hide()
2601
                                .attr( "aria-hidden", "true" )
2602
                                .attr( "aria-expanded", "false" )
2603
                        .end()
2604
                        .find( ".ui-state-active" ).not( ".ui-state-focus" )
2605
                                .removeClass( "ui-state-active" );
2606
        },
2607
2608
        _closeOnDocumentClick: function( event ) {
2609
                return !$( event.target ).closest( ".ui-menu" ).length;
2610
        },
2611
2612
        _isDivider: function( item ) {
2613
2614
                // Match hyphen, em dash, en dash
2615
                return !/[^\-\u2014\u2013\s]/.test( item.text() );
2616
        },
2617
2618
        collapse: function( event ) {
2619
                var newItem = this.active &&
2620
                        this.active.parent().closest( ".ui-menu-item", this.element );
2621
                if ( newItem && newItem.length ) {
2622
                        this._close();
2623
                        this.focus( event, newItem );
2624
                }
2625
        },
2626
2627
        expand: function( event ) {
2628
                var newItem = this.active &&
2629
                        this.active
2630
                                .children( ".ui-menu " )
2631
                                .find( this.options.items )
2632
                                .first();
2633
2634
                if ( newItem && newItem.length ) {
2635
                        this._open( newItem.parent() );
2636
2637
                        // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
2638
                        this._delay(function() {
2639
                                this.focus( event, newItem );
2640
                        });
2641
                }
2642
        },
2643
2644
        next: function( event ) {
2645
                this._move( "next", "first", event );
2646
        },
2647
2648
        previous: function( event ) {
2649
                this._move( "prev", "last", event );
2650
        },
2651
2652
        isFirstItem: function() {
2653
                return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
2654
        },
2655
2656
        isLastItem: function() {
2657
                return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
2658
        },
2659
2660
        _move: function( direction, filter, event ) {
2661
                var next;
2662
                if ( this.active ) {
2663
                        if ( direction === "first" || direction === "last" ) {
2664
                                next = this.active
2665
                                        [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
2666
                                        .eq( -1 );
2667
                        } else {
2668
                                next = this.active
2669
                                        [ direction + "All" ]( ".ui-menu-item" )
2670
                                        .eq( 0 );
2671
                        }
2672
                }
2673
                if ( !next || !next.length || !this.active ) {
2674
                        next = this.activeMenu.find( this.options.items )[ filter ]();
2675
                }
2676
2677
                this.focus( event, next );
2678
        },
2679
2680
        nextPage: function( event ) {
2681
                var item, base, height;
2682
2683
                if ( !this.active ) {
2684
                        this.next( event );
2685
                        return;
2686
                }
2687
                if ( this.isLastItem() ) {
2688
                        return;
2689
                }
2690
                if ( this._hasScroll() ) {
2691
                        base = this.active.offset().top;
2692
                        height = this.element.height();
2693
                        this.active.nextAll( ".ui-menu-item" ).each(function() {
2694
                                item = $( this );
2695
                                return item.offset().top - base - height < 0;
2696
                        });
2697
2698
                        this.focus( event, item );
2699
                } else {
2700
                        this.focus( event, this.activeMenu.find( this.options.items )
2701
                                [ !this.active ? "first" : "last" ]() );
2702
                }
2703
        },
2704
2705
        previousPage: function( event ) {
2706
                var item, base, height;
2707
                if ( !this.active ) {
2708
                        this.next( event );
2709
                        return;
2710
                }
2711
                if ( this.isFirstItem() ) {
2712
                        return;
2713
                }
2714
                if ( this._hasScroll() ) {
2715
                        base = this.active.offset().top;
2716
                        height = this.element.height();
2717
                        this.active.prevAll( ".ui-menu-item" ).each(function() {
2718
                                item = $( this );
2719
                                return item.offset().top - base + height > 0;
2720
                        });
2721
2722
                        this.focus( event, item );
2723
                } else {
2724
                        this.focus( event, this.activeMenu.find( this.options.items ).first() );
2725
                }
2726
        },
2727
2728
        _hasScroll: function() {
2729
                return this.element.outerHeight() < this.element.prop( "scrollHeight" );
2730
        },
2731
2732
        select: function( event ) {
2733
                // TODO: It should never be possible to not have an active item at this
2734
                // point, but the tests don't trigger mouseenter before click.
2735
                this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
2736
                var ui = { item: this.active };
2737
                if ( !this.active.has( ".ui-menu" ).length ) {
2738
                        this.collapseAll( event, true );
2739
                }
2740
                this._trigger( "select", event, ui );
2741
        },
2742
2743
        _filterMenuItems: function(character) {
2744
                var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
2745
                        regex = new RegExp( "^" + escapedCharacter, "i" );
2746
2747
                return this.activeMenu
2748
                        .find( this.options.items )
2749
2750
                        // Only match on items, not dividers or other content (#10571)
2751
                        .filter( ".ui-menu-item" )
2752
                        .filter(function() {
2753
                                return regex.test( $.trim( $( this ).text() ) );
2754
                        });
2755
        }
2756
});
2757
2758
2759
/*!
2760
 * jQuery UI Autocomplete 1.11.4
2761
 * http://jqueryui.com
2762
 *
2763
 * Copyright jQuery Foundation and other contributors
2764
 * Released under the MIT license.
2765
 * http://jquery.org/license
2766
 *
2767
 * http://api.jqueryui.com/autocomplete/
2768
 */
2769
2770
2771
$.widget( "ui.autocomplete", {
2772
        version: "1.11.4",
2773
        defaultElement: "<input>",
2774
        options: {
2775
                appendTo: null,
2776
                autoFocus: false,
2777
                delay: 300,
2778
                minLength: 1,
2779
                position: {
2780
                        my: "left top",
2781
                        at: "left bottom",
2782
                        collision: "none"
2783
                },
2784
                source: null,
2785
2786
                // callbacks
2787
                change: null,
2788
                close: null,
2789
                focus: null,
2790
                open: null,
2791
                response: null,
2792
                search: null,
2793
                select: null
2794
        },
2795
2796
        requestIndex: 0,
2797
        pending: 0,
2798
2799
        _create: function() {
2800
                // Some browsers only repeat keydown events, not keypress events,
2801
                // so we use the suppressKeyPress flag to determine if we've already
2802
                // handled the keydown event. #7269
2803
                // Unfortunately the code for & in keypress is the same as the up arrow,
2804
                // so we use the suppressKeyPressRepeat flag to avoid handling keypress
2805
                // events when we know the keydown event was used to modify the
2806
                // search term. #7799
2807
                var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
2808
                        nodeName = this.element[ 0 ].nodeName.toLowerCase(),
2809
                        isTextarea = nodeName === "textarea",
2810
                        isInput = nodeName === "input";
2811
2812
                this.isMultiLine =
2813
                        // Textareas are always multi-line
2814
                        isTextarea ? true :
2815
                        // Inputs are always single-line, even if inside a contentEditable element
2816
                        // IE also treats inputs as contentEditable
2817
                        isInput ? false :
2818
                        // All other element types are determined by whether or not they're contentEditable
2819
                        this.element.prop( "isContentEditable" );
2820
2821
                this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
2822
                this.isNewMenu = true;
2823
2824
                this.element
2825
                        .addClass( "ui-autocomplete-input" )
2826
                        .attr( "autocomplete", "off" );
2827
2828
                this._on( this.element, {
2829
                        keydown: function( event ) {
2830
                                if ( this.element.prop( "readOnly" ) ) {
2831
                                        suppressKeyPress = true;
2832
                                        suppressInput = true;
2833
                                        suppressKeyPressRepeat = true;
2834
                                        return;
2835
                                }
2836
2837
                                suppressKeyPress = false;
2838
                                suppressInput = false;
2839
                                suppressKeyPressRepeat = false;
2840
                                var keyCode = $.ui.keyCode;
2841
                                switch ( event.keyCode ) {
2842
                                case keyCode.PAGE_UP:
2843
                                        suppressKeyPress = true;
2844
                                        this._move( "previousPage", event );
2845
                                        break;
2846
                                case keyCode.PAGE_DOWN:
2847
                                        suppressKeyPress = true;
2848
                                        this._move( "nextPage", event );
2849
                                        break;
2850
                                case keyCode.UP:
2851
                                        suppressKeyPress = true;
2852
                                        this._keyEvent( "previous", event );
2853
                                        break;
2854
                                case keyCode.DOWN:
2855
                                        suppressKeyPress = true;
2856
                                        this._keyEvent( "next", event );
2857
                                        break;
2858
                                case keyCode.ENTER:
2859
                                        // when menu is open and has focus
2860
                                        if ( this.menu.active ) {
2861
                                                // #6055 - Opera still allows the keypress to occur
2862
                                                // which causes forms to submit
2863
                                                suppressKeyPress = true;
2864
                                                event.preventDefault();
2865
                                                this.menu.select( event );
2866
                                        }
2867
                                        break;
2868
                                case keyCode.TAB:
2869
                                        if ( this.menu.active ) {
2870
                                                this.menu.select( event );
2871
                                        }
2872
                                        break;
2873
                                case keyCode.ESCAPE:
2874
                                        if ( this.menu.element.is( ":visible" ) ) {
2875
                                                if ( !this.isMultiLine ) {
2876
                                                        this._value( this.term );
2877
                                                }
2878
                                                this.close( event );
2879
                                                // Different browsers have different default behavior for escape
2880
                                                // Single press can mean undo or clear
2881
                                                // Double press in IE means clear the whole form
2882
                                                event.preventDefault();
2883
                                        }
2884
                                        break;
2885
                                default:
2886
                                        suppressKeyPressRepeat = true;
2887
                                        // search timeout should be triggered before the input value is changed
2888
                                        this._searchTimeout( event );
2889
                                        break;
2890
                                }
2891
                        },
2892
                        keypress: function( event ) {
2893
                                if ( suppressKeyPress ) {
2894
                                        suppressKeyPress = false;
2895
                                        if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
2896
                                                event.preventDefault();
2897
                                        }
2898
                                        return;
2899
                                }
2900
                                if ( suppressKeyPressRepeat ) {
2901
                                        return;
2902
                                }
2903
2904
                                // replicate some key handlers to allow them to repeat in Firefox and Opera
2905
                                var keyCode = $.ui.keyCode;
2906
                                switch ( event.keyCode ) {
2907
                                case keyCode.PAGE_UP:
2908
                                        this._move( "previousPage", event );
2909
                                        break;
2910
                                case keyCode.PAGE_DOWN:
2911
                                        this._move( "nextPage", event );
2912
                                        break;
2913
                                case keyCode.UP:
2914
                                        this._keyEvent( "previous", event );
2915
                                        break;
2916
                                case keyCode.DOWN:
2917
                                        this._keyEvent( "next", event );
2918
                                        break;
2919
                                }
2920
                        },
2921
                        input: function( event ) {
2922
                                if ( suppressInput ) {
2923
                                        suppressInput = false;
2924
                                        event.preventDefault();
2925
                                        return;
2926
                                }
2927
                                this._searchTimeout( event );
2928
                        },
2929
                        focus: function() {
2930
                                this.selectedItem = null;
2931
                                this.previous = this._value();
2932
                        },
2933
                        blur: function( event ) {
2934
                                if ( this.cancelBlur ) {
2935
                                        delete this.cancelBlur;
2936
                                        return;
2937
                                }
2938
2939
                                clearTimeout( this.searching );
2940
                                this.close( event );
2941
                                this._change( event );
2942
                        }
2943
                });
2944
2945
                this._initSource();
2946
                this.menu = $( "<ul>" )
2947
                        .addClass( "ui-autocomplete ui-front" )
2948
                        .appendTo( this._appendTo() )
2949
                        .menu({
2950
                                // disable ARIA support, the live region takes care of that
2951
                                role: null
2952
                        })
2953
                        .hide()
2954
                        .menu( "instance" );
2955
2956
                this._on( this.menu.element, {
2957
                        mousedown: function( event ) {
2958
                                // prevent moving focus out of the text field
2959
                                event.preventDefault();
2960
2961
                                // IE doesn't prevent moving focus even with event.preventDefault()
2962
                                // so we set a flag to know when we should ignore the blur event
2963
                                this.cancelBlur = true;
2964
                                this._delay(function() {
2965
                                        delete this.cancelBlur;
2966
                                });
2967
2968
                                // clicking on the scrollbar causes focus to shift to the body
2969
                                // but we can't detect a mouseup or a click immediately afterward
2970
                                // so we have to track the next mousedown and close the menu if
2971
                                // the user clicks somewhere outside of the autocomplete
2972
                                var menuElement = this.menu.element[ 0 ];
2973
                                if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
2974
                                        this._delay(function() {
2975
                                                var that = this;
2976
                                                this.document.one( "mousedown", function( event ) {
2977
                                                        if ( event.target !== that.element[ 0 ] &&
2978
                                                                        event.target !== menuElement &&
2979
                                                                        !$.contains( menuElement, event.target ) ) {
2980
                                                                that.close();
2981
                                                        }
2982
                                                });
2983
                                        });
2984
                                }
2985
                        },
2986
                        menufocus: function( event, ui ) {
2987
                                var label, item;
2988
                                // support: Firefox
2989
                                // Prevent accidental activation of menu items in Firefox (#7024 #9118)
2990
                                if ( this.isNewMenu ) {
2991
                                        this.isNewMenu = false;
2992
                                        if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
2993
                                                this.menu.blur();
2994
2995
                                                this.document.one( "mousemove", function() {
2996
                                                        $( event.target ).trigger( event.originalEvent );
2997
                                                });
2998
2999
                                                return;
3000
                                        }
3001
                                }
3002
3003
                                item = ui.item.data( "ui-autocomplete-item" );
3004
                                if ( false !== this._trigger( "focus", event, { item: item } ) ) {
3005
                                        // use value to match what will end up in the input, if it was a key event
3006
                                        if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
3007
                                                this._value( item.value );
3008
                                        }
3009
                                }
3010
3011
                                // Announce the value in the liveRegion
3012
                                label = ui.item.attr( "aria-label" ) || item.value;
3013
                                if ( label && $.trim( label ).length ) {
3014
                                        this.liveRegion.children().hide();
3015
                                        $( "<div>" ).text( label ).appendTo( this.liveRegion );
3016
                                }
3017
                        },
3018
                        menuselect: function( event, ui ) {
3019
                                var item = ui.item.data( "ui-autocomplete-item" ),
3020
                                        previous = this.previous;
3021
3022
                                // only trigger when focus was lost (click on menu)
3023
                                if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
3024
                                        this.element.focus();
3025
                                        this.previous = previous;
3026
                                        // #6109 - IE triggers two focus events and the second
3027
                                        // is asynchronous, so we need to reset the previous
3028
                                        // term synchronously and asynchronously :-(
3029
                                        this._delay(function() {
3030
                                                this.previous = previous;
3031
                                                this.selectedItem = item;
3032
                                        });
3033
                                }
3034
3035
                                if ( false !== this._trigger( "select", event, { item: item } ) ) {
3036
                                        this._value( item.value );
3037
                                }
3038
                                // reset the term after the select event
3039
                                // this allows custom select handling to work properly
3040
                                this.term = this._value();
3041
3042
                                this.close( event );
3043
                                this.selectedItem = item;
3044
                        }
3045
                });
3046
3047
                this.liveRegion = $( "<span>", {
3048
                                role: "status",
3049
                                "aria-live": "assertive",
3050
                                "aria-relevant": "additions"
3051
                        })
3052
                        .addClass( "ui-helper-hidden-accessible" )
3053
                        .appendTo( this.document[ 0 ].body );
3054
3055
                // turning off autocomplete prevents the browser from remembering the
3056
                // value when navigating through history, so we re-enable autocomplete
3057
                // if the page is unloaded before the widget is destroyed. #7790
3058
                this._on( this.window, {
3059
                        beforeunload: function() {
3060
                                this.element.removeAttr( "autocomplete" );
3061
                        }
3062
                });
3063
        },
3064
3065
        _destroy: function() {
3066
                clearTimeout( this.searching );
3067
                this.element
3068
                        .removeClass( "ui-autocomplete-input" )
3069
                        .removeAttr( "autocomplete" );
3070
                this.menu.element.remove();
3071
                this.liveRegion.remove();
3072
        },
3073
3074
        _setOption: function( key, value ) {
3075
                this._super( key, value );
3076
                if ( key === "source" ) {
3077
                        this._initSource();
3078
                }
3079
                if ( key === "appendTo" ) {
3080
                        this.menu.element.appendTo( this._appendTo() );
3081
                }
3082
                if ( key === "disabled" && value && this.xhr ) {
3083
                        this.xhr.abort();
3084
                }
3085
        },
3086
3087
        _appendTo: function() {
3088
                var element = this.options.appendTo;
3089
3090
                if ( element ) {
3091
                        element = element.jquery || element.nodeType ?
3092
                                $( element ) :
3093
                                this.document.find( element ).eq( 0 );
3094
                }
3095
3096
                if ( !element || !element[ 0 ] ) {
3097
                        element = this.element.closest( ".ui-front" );
3098
                }
3099
3100
                if ( !element.length ) {
3101
                        element = this.document[ 0 ].body;
3102
                }
3103
3104
                return element;
3105
        },
3106
3107
        _initSource: function() {
3108
                var array, url,
3109
                        that = this;
3110
                if ( $.isArray( this.options.source ) ) {
3111
                        array = this.options.source;
3112
                        this.source = function( request, response ) {
3113
                                response( $.ui.autocomplete.filter( array, request.term ) );
3114
                        };
3115
                } else if ( typeof this.options.source === "string" ) {
3116
                        url = this.options.source;
3117
                        this.source = function( request, response ) {
3118
                                if ( that.xhr ) {
3119
                                        that.xhr.abort();
3120
                                }
3121
                                that.xhr = $.ajax({
3122
                                        url: url,
3123
                                        data: request,
3124
                                        dataType: "json",
3125
                                        success: function( data ) {
3126
                                                response( data );
3127
                                        },
3128
                                        error: function() {
3129
                                                response([]);
3130
                                        }
3131
                                });
3132
                        };
3133
                } else {
3134
                        this.source = this.options.source;
3135
                }
3136
        },
3137
3138
        _searchTimeout: function( event ) {
3139
                clearTimeout( this.searching );
3140
                this.searching = this._delay(function() {
3141
3142
                        // Search if the value has changed, or if the user retypes the same value (see #7434)
3143
                        var equalValues = this.term === this._value(),
3144
                                menuVisible = this.menu.element.is( ":visible" ),
3145
                                modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
3146
3147
                        if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
3148
                                this.selectedItem = null;
3149
                                this.search( null, event );
3150
                        }
3151
                }, this.options.delay );
3152
        },
3153
3154
        search: function( value, event ) {
3155
                value = value != null ? value : this._value();
3156
3157
                // always save the actual value, not the one passed as an argument
3158
                this.term = this._value();
3159
3160
                if ( value.length < this.options.minLength ) {
3161
                        return this.close( event );
3162
                }
3163
3164
                if ( this._trigger( "search", event ) === false ) {
3165
                        return;
3166
                }
3167
3168
                return this._search( value );
3169
        },
3170
3171
        _search: function( value ) {
3172
                this.pending++;
3173
                this.element.addClass( "ui-autocomplete-loading" );
3174
                this.cancelSearch = false;
3175
3176
                this.source( { term: value }, this._response() );
3177
        },
3178
3179
        _response: function() {
3180
                var index = ++this.requestIndex;
3181
3182
                return $.proxy(function( content ) {
3183
                        if ( index === this.requestIndex ) {
3184
                                this.__response( content );
3185
                        }
3186
3187
                        this.pending--;
3188
                        if ( !this.pending ) {
3189
                                this.element.removeClass( "ui-autocomplete-loading" );
3190
                        }
3191
                }, this );
3192
        },
3193
3194
        __response: function( content ) {
3195
                if ( content ) {
3196
                        content = this._normalize( content );
3197
                }
3198
                this._trigger( "response", null, { content: content } );
3199
                if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
3200
                        this._suggest( content );
3201
                        this._trigger( "open" );
3202
                } else {
3203
                        // use ._close() instead of .close() so we don't cancel future searches
3204
                        this._close();
3205
                }
3206
        },
3207
3208
        close: function( event ) {
3209
                this.cancelSearch = true;
3210
                this._close( event );
3211
        },
3212
3213
        _close: function( event ) {
3214
                if ( this.menu.element.is( ":visible" ) ) {
3215
                        this.menu.element.hide();
3216
                        this.menu.blur();
3217
                        this.isNewMenu = true;
3218
                        this._trigger( "close", event );
3219
                }
3220
        },
3221
3222
        _change: function( event ) {
3223
                if ( this.previous !== this._value() ) {
3224
                        this._trigger( "change", event, { item: this.selectedItem } );
3225
                }
3226
        },
3227
3228
        _normalize: function( items ) {
3229
                // assume all items have the right format when the first item is complete
3230
                if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
3231
                        return items;
3232
                }
3233
                return $.map( items, function( item ) {
3234
                        if ( typeof item === "string" ) {
3235
                                return {
3236
                                        label: item,
3237
                                        value: item
3238
                                };
3239
                        }
3240
                        return $.extend( {}, item, {
3241
                                label: item.label || item.value,
3242
                                value: item.value || item.label
3243
                        });
3244
                });
3245
        },
3246
3247
        _suggest: function( items ) {
3248
                var ul = this.menu.element.empty();
3249
                this._renderMenu( ul, items );
3250
                this.isNewMenu = true;
3251
                this.menu.refresh();
3252
3253
                // size and position menu
3254
                ul.show();
3255
                this._resizeMenu();
3256
                ul.position( $.extend({
3257
                        of: this.element
3258
                }, this.options.position ) );
3259
3260
                if ( this.options.autoFocus ) {
3261
                        this.menu.next();
3262
                }
3263
        },
3264
3265
        _resizeMenu: function() {
3266
                var ul = this.menu.element;
3267
                ul.outerWidth( Math.max(
3268
                        // Firefox wraps long text (possibly a rounding bug)
3269
                        // so we add 1px to avoid the wrapping (#7513)
3270
                        ul.width( "" ).outerWidth() + 1,
3271
                        this.element.outerWidth()
3272
                ) );
3273
        },
3274
3275
        _renderMenu: function( ul, items ) {
3276
                var that = this;
3277
                $.each( items, function( index, item ) {
3278
                        that._renderItemData( ul, item );
3279
                });
3280
        },
3281
3282
        _renderItemData: function( ul, item ) {
3283
                return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
3284
        },
3285
3286
        _renderItem: function( ul, item ) {
3287
                return $( "<li>" ).text( item.label ).appendTo( ul );
3288
        },
3289
3290
        _move: function( direction, event ) {
3291
                if ( !this.menu.element.is( ":visible" ) ) {
3292
                        this.search( null, event );
3293
                        return;
3294
                }
3295
                if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
3296
                                this.menu.isLastItem() && /^next/.test( direction ) ) {
3297
3298
                        if ( !this.isMultiLine ) {
3299
                                this._value( this.term );
3300
                        }
3301
3302
                        this.menu.blur();
3303
                        return;
3304
                }
3305
                this.menu[ direction ]( event );
3306
        },
3307
3308
        widget: function() {
3309
                return this.menu.element;
3310
        },
3311
3312
        _value: function() {
3313
                return this.valueMethod.apply( this.element, arguments );
3314
        },
3315
3316
        _keyEvent: function( keyEvent, event ) {
3317
                if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
3318
                        this._move( keyEvent, event );
3319
3320
                        // prevents moving cursor to beginning/end of the text field in some browsers
3321
                        event.preventDefault();
3322
                }
3323
        }
3324
});
3325
3326
$.extend( $.ui.autocomplete, {
3327
        escapeRegex: function( value ) {
3328
                return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
3329
        },
3330
        filter: function( array, term ) {
3331
                var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
3332
                return $.grep( array, function( value ) {
3333
                        return matcher.test( value.label || value.value || value );
3334
                });
3335
        }
3336
});
3337
3338
// live region extension, adding a `messages` option
3339
// NOTE: This is an experimental API. We are still investigating
3340
// a full solution for string manipulation and internationalization.
3341
$.widget( "ui.autocomplete", $.ui.autocomplete, {
3342
        options: {
3343
                messages: {
3344
                        noResults: "No search results.",
3345
                        results: function( amount ) {
3346
                                return amount + ( amount > 1 ? " results are" : " result is" ) +
3347
                                        " available, use up and down arrow keys to navigate.";
3348
                        }
3349
                }
3350
        },
3351
3352
        __response: function( content ) {
3353
                var message;
3354
                this._superApply( arguments );
3355
                if ( this.options.disabled || this.cancelSearch ) {
3356
                        return;
3357
                }
3358
                if ( content && content.length ) {
3359
                        message = this.options.messages.results( content.length );
3360
                } else {
3361
                        message = this.options.messages.noResults;
3362
                }
3363
                this.liveRegion.children().hide();
3364
                $( "<div>" ).text( message ).appendTo( this.liveRegion );
3365
        }
3366
});
3367
3368
var autocomplete = $.ui.autocomplete;
3369
3370
3371
/*!
3372
 * jQuery UI Button 1.11.4
3373
 * http://jqueryui.com
3374
 *
3375
 * Copyright jQuery Foundation and other contributors
3376
 * Released under the MIT license.
3377
 * http://jquery.org/license
3378
 *
3379
 * http://api.jqueryui.com/button/
3380
 */
3381
3382
3383
var lastActive,
3384
        baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
3385
        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",
3386
        formResetHandler = function() {
3387
                var form = $( this );
3388
                setTimeout(function() {
3389
                        form.find( ":ui-button" ).button( "refresh" );
3390
                }, 1 );
3391
        },
3392
        radioGroup = function( radio ) {
3393
                var name = radio.name,
3394
                        form = radio.form,
3395
                        radios = $( [] );
3396
                if ( name ) {
3397
                        name = name.replace( /'/g, "\\'" );
3398
                        if ( form ) {
3399
                                radios = $( form ).find( "[name='" + name + "'][type=radio]" );
3400
                        } else {
3401
                                radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument )
3402
                                        .filter(function() {
3403
                                                return !this.form;
3404
                                        });
3405
                        }
3406
                }
3407
                return radios;
3408
        };
3409
3410
$.widget( "ui.button", {
3411
        version: "1.11.4",
3412
        defaultElement: "<button>",
3413
        options: {
3414
                disabled: null,
3415
                text: true,
3416
                label: null,
3417
                icons: {
3418
                        primary: null,
3419
                        secondary: null
3420
                }
3421
        },
3422
        _create: function() {
3423
                this.element.closest( "form" )
3424
                        .unbind( "reset" + this.eventNamespace )
3425
                        .bind( "reset" + this.eventNamespace, formResetHandler );
3426
3427
                if ( typeof this.options.disabled !== "boolean" ) {
3428
                        this.options.disabled = !!this.element.prop( "disabled" );
3429
                } else {
3430
                        this.element.prop( "disabled", this.options.disabled );
3431
                }
3432
3433
                this._determineButtonType();
3434
                this.hasTitle = !!this.buttonElement.attr( "title" );
3435
3436
                var that = this,
3437
                        options = this.options,
3438
                        toggleButton = this.type === "checkbox" || this.type === "radio",
3439
                        activeClass = !toggleButton ? "ui-state-active" : "";
3440
3441
                if ( options.label === null ) {
3442
                        options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
3443
                }
3444
3445
                this._hoverable( this.buttonElement );
3446
3447
                this.buttonElement
3448
                        .addClass( baseClasses )
3449
                        .attr( "role", "button" )
3450
                        .bind( "mouseenter" + this.eventNamespace, function() {
3451
                                if ( options.disabled ) {
3452
                                        return;
3453
                                }
3454
                                if ( this === lastActive ) {
3455
                                        $( this ).addClass( "ui-state-active" );
3456
                                }
3457
                        })
3458
                        .bind( "mouseleave" + this.eventNamespace, function() {
3459
                                if ( options.disabled ) {
3460
                                        return;
3461
                                }
3462
                                $( this ).removeClass( activeClass );
3463
                        })
3464
                        .bind( "click" + this.eventNamespace, function( event ) {
3465
                                if ( options.disabled ) {
3466
                                        event.preventDefault();
3467
                                        event.stopImmediatePropagation();
3468
                                }
3469
                        });
3470
3471
                // Can't use _focusable() because the element that receives focus
3472
                // and the element that gets the ui-state-focus class are different
3473
                this._on({
3474
                        focus: function() {
3475
                                this.buttonElement.addClass( "ui-state-focus" );
3476
                        },
3477
                        blur: function() {
3478
                                this.buttonElement.removeClass( "ui-state-focus" );
3479
                        }
3480
                });
3481
3482
                if ( toggleButton ) {
3483
                        this.element.bind( "change" + this.eventNamespace, function() {
3484
                                that.refresh();
3485
                        });
3486
                }
3487
3488
                if ( this.type === "checkbox" ) {
3489
                        this.buttonElement.bind( "click" + this.eventNamespace, function() {
3490
                                if ( options.disabled ) {
3491
                                        return false;
3492
                                }
3493
                        });
3494
                } else if ( this.type === "radio" ) {
3495
                        this.buttonElement.bind( "click" + this.eventNamespace, function() {
3496
                                if ( options.disabled ) {
3497
                                        return false;
3498
                                }
3499
                                $( this ).addClass( "ui-state-active" );
3500
                                that.buttonElement.attr( "aria-pressed", "true" );
3501
3502
                                var radio = that.element[ 0 ];
3503
                                radioGroup( radio )
3504
                                        .not( radio )
3505
                                        .map(function() {
3506
                                                return $( this ).button( "widget" )[ 0 ];
3507
                                        })
3508
                                        .removeClass( "ui-state-active" )
3509
                                        .attr( "aria-pressed", "false" );
3510
                        });
3511
                } else {
3512
                        this.buttonElement
3513
                                .bind( "mousedown" + this.eventNamespace, function() {
3514
                                        if ( options.disabled ) {
3515
                                                return false;
3516
                                        }
3517
                                        $( this ).addClass( "ui-state-active" );
3518
                                        lastActive = this;
3519
                                        that.document.one( "mouseup", function() {
3520
                                                lastActive = null;
3521
                                        });
3522
                                })
3523
                                .bind( "mouseup" + this.eventNamespace, function() {
3524
                                        if ( options.disabled ) {
3525
                                                return false;
3526
                                        }
3527
                                        $( this ).removeClass( "ui-state-active" );
3528
                                })
3529
                                .bind( "keydown" + this.eventNamespace, function(event) {
3530
                                        if ( options.disabled ) {
3531
                                                return false;
3532
                                        }
3533
                                        if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
3534
                                                $( this ).addClass( "ui-state-active" );
3535
                                        }
3536
                                })
3537
                                // see #8559, we bind to blur here in case the button element loses
3538
                                // focus between keydown and keyup, it would be left in an "active" state
3539
                                .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
3540
                                        $( this ).removeClass( "ui-state-active" );
3541
                                });
3542
3543
                        if ( this.buttonElement.is("a") ) {
3544
                                this.buttonElement.keyup(function(event) {
3545
                                        if ( event.keyCode === $.ui.keyCode.SPACE ) {
3546
                                                // TODO pass through original event correctly (just as 2nd argument doesn't work)
3547
                                                $( this ).click();
3548
                                        }
3549
                                });
3550
                        }
3551
                }
3552
3553
                this._setOption( "disabled", options.disabled );
3554
                this._resetButton();
3555
        },
3556
3557
        _determineButtonType: function() {
3558
                var ancestor, labelSelector, checked;
3559
3560
                if ( this.element.is("[type=checkbox]") ) {
3561
                        this.type = "checkbox";
3562
                } else if ( this.element.is("[type=radio]") ) {
3563
                        this.type = "radio";
3564
                } else if ( this.element.is("input") ) {
3565
                        this.type = "input";
3566
                } else {
3567
                        this.type = "button";
3568
                }
3569
3570
                if ( this.type === "checkbox" || this.type === "radio" ) {
3571
                        // we don't search against the document in case the element
3572
                        // is disconnected from the DOM
3573
                        ancestor = this.element.parents().last();
3574
                        labelSelector = "label[for='" + this.element.attr("id") + "']";
3575
                        this.buttonElement = ancestor.find( labelSelector );
3576
                        if ( !this.buttonElement.length ) {
3577
                                ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
3578
                                this.buttonElement = ancestor.filter( labelSelector );
3579
                                if ( !this.buttonElement.length ) {
3580
                                        this.buttonElement = ancestor.find( labelSelector );
3581
                                }
3582
                        }
3583
                        this.element.addClass( "ui-helper-hidden-accessible" );
3584
3585
                        checked = this.element.is( ":checked" );
3586
                        if ( checked ) {
3587
                                this.buttonElement.addClass( "ui-state-active" );
3588
                        }
3589
                        this.buttonElement.prop( "aria-pressed", checked );
3590
                } else {
3591
                        this.buttonElement = this.element;
3592
                }
3593
        },
3594
3595
        widget: function() {
3596
                return this.buttonElement;
3597
        },
3598
3599
        _destroy: function() {
3600
                this.element
3601
                        .removeClass( "ui-helper-hidden-accessible" );
3602
                this.buttonElement
3603
                        .removeClass( baseClasses + " ui-state-active " + typeClasses )
3604
                        .removeAttr( "role" )
3605
                        .removeAttr( "aria-pressed" )
3606
                        .html( this.buttonElement.find(".ui-button-text").html() );
3607
3608
                if ( !this.hasTitle ) {
3609
                        this.buttonElement.removeAttr( "title" );
3610
                }
3611
        },
3612
3613
        _setOption: function( key, value ) {
3614
                this._super( key, value );
3615
                if ( key === "disabled" ) {
3616
                        this.widget().toggleClass( "ui-state-disabled", !!value );
3617
                        this.element.prop( "disabled", !!value );
3618
                        if ( value ) {
3619
                                if ( this.type === "checkbox" || this.type === "radio" ) {
3620
                                        this.buttonElement.removeClass( "ui-state-focus" );
3621
                                } else {
3622
                                        this.buttonElement.removeClass( "ui-state-focus ui-state-active" );
3623
                                }
3624
                        }
3625
                        return;
3626
                }
3627
                this._resetButton();
3628
        },
3629
3630
        refresh: function() {
3631
                //See #8237 & #8828
3632
                var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
3633
3634
                if ( isDisabled !== this.options.disabled ) {
3635
                        this._setOption( "disabled", isDisabled );
3636
                }
3637
                if ( this.type === "radio" ) {
3638
                        radioGroup( this.element[0] ).each(function() {
3639
                                if ( $( this ).is( ":checked" ) ) {
3640
                                        $( this ).button( "widget" )
3641
                                                .addClass( "ui-state-active" )
3642
                                                .attr( "aria-pressed", "true" );
3643
                                } else {
3644
                                        $( this ).button( "widget" )
3645
                                                .removeClass( "ui-state-active" )
3646
                                                .attr( "aria-pressed", "false" );
3647
                                }
3648
                        });
3649
                } else if ( this.type === "checkbox" ) {
3650
                        if ( this.element.is( ":checked" ) ) {
3651
                                this.buttonElement
3652
                                        .addClass( "ui-state-active" )
3653
                                        .attr( "aria-pressed", "true" );
3654
                        } else {
3655
                                this.buttonElement
3656
                                        .removeClass( "ui-state-active" )
3657
                                        .attr( "aria-pressed", "false" );
3658
                        }
3659
                }
3660
        },
3661
3662
        _resetButton: function() {
3663
                if ( this.type === "input" ) {
3664
                        if ( this.options.label ) {
3665
                                this.element.val( this.options.label );
3666
                        }
3667
                        return;
3668
                }
3669
                var buttonElement = this.buttonElement.removeClass( typeClasses ),
3670
                        buttonText = $( "<span></span>", this.document[0] )
3671
                                .addClass( "ui-button-text" )
3672
                                .html( this.options.label )
3673
                                .appendTo( buttonElement.empty() )
3674
                                .text(),
3675
                        icons = this.options.icons,
3676
                        multipleIcons = icons.primary && icons.secondary,
3677
                        buttonClasses = [];
3678
3679
                if ( icons.primary || icons.secondary ) {
3680
                        if ( this.options.text ) {
3681
                                buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
3682
                        }
3683
3684
                        if ( icons.primary ) {
3685
                                buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
3686
                        }
3687
3688
                        if ( icons.secondary ) {
3689
                                buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
3690
                        }
3691
3692
                        if ( !this.options.text ) {
3693
                                buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
3694
3695
                                if ( !this.hasTitle ) {
3696
                                        buttonElement.attr( "title", $.trim( buttonText ) );
3697
                                }
3698
                        }
3699
                } else {
3700
                        buttonClasses.push( "ui-button-text-only" );
3701
                }
3702
                buttonElement.addClass( buttonClasses.join( " " ) );
3703
        }
3704
});
3705
3706
$.widget( "ui.buttonset", {
3707
        version: "1.11.4",
3708
        options: {
3709
                items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
3710
        },
3711
3712
        _create: function() {
3713
                this.element.addClass( "ui-buttonset" );
3714
        },
3715
3716
        _init: function() {
3717
                this.refresh();
3718
        },
3719
3720
        _setOption: function( key, value ) {
3721
                if ( key === "disabled" ) {
3722
                        this.buttons.button( "option", key, value );
3723
                }
3724
3725
                this._super( key, value );
3726
        },
3727
3728
        refresh: function() {
3729
                var rtl = this.element.css( "direction" ) === "rtl",
3730
                        allButtons = this.element.find( this.options.items ),
3731
                        existingButtons = allButtons.filter( ":ui-button" );
3732
3733
                // Initialize new buttons
3734
                allButtons.not( ":ui-button" ).button();
3735
3736
                // Refresh existing buttons
3737
                existingButtons.button( "refresh" );
3738
3739
                this.buttons = allButtons
3740
                        .map(function() {
3741
                                return $( this ).button( "widget" )[ 0 ];
3742
                        })
3743
                                .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
3744
                                .filter( ":first" )
3745
                                        .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
3746
                                .end()
3747
                                .filter( ":last" )
3748
                                        .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
3749
                                .end()
3750
                        .end();
3751
        },
3752
3753
        _destroy: function() {
3754
                this.element.removeClass( "ui-buttonset" );
3755
                this.buttons
3756
                        .map(function() {
3757
                                return $( this ).button( "widget" )[ 0 ];
3758
                        })
3759
                                .removeClass( "ui-corner-left ui-corner-right" )
3760
                        .end()
3761
                        .button( "destroy" );
3762
        }
3763
});
3764
3765
var button = $.ui.button;
3766
3767
3768
/*!
3769
 * jQuery UI Datepicker 1.11.4
3770
 * http://jqueryui.com
3771
 *
3772
 * Copyright jQuery Foundation and other contributors
3773
 * Released under the MIT license.
3774
 * http://jquery.org/license
3775
 *
3776
 * http://api.jqueryui.com/datepicker/
3777
 */
3778
3779
3780
$.extend($.ui, { datepicker: { version: "1.11.4" } });
3781
3782
var datepicker_instActive;
3783
3784
function datepicker_getZindex( elem ) {
3785
        var position, value;
3786
        while ( elem.length && elem[ 0 ] !== document ) {
3787
                // Ignore z-index if position is set to a value where z-index is ignored by the browser
3788
                // This makes behavior of this function consistent across browsers
3789
                // WebKit always returns auto if the element is positioned
3790
                position = elem.css( "position" );
3791
                if ( position === "absolute" || position === "relative" || position === "fixed" ) {
3792
                        // IE returns 0 when zIndex is not specified
3793
                        // other browsers return a string
3794
                        // we ignore the case of nested elements with an explicit value of 0
3795
                        // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
3796
                        value = parseInt( elem.css( "zIndex" ), 10 );
3797
                        if ( !isNaN( value ) && value !== 0 ) {
3798
                                return value;
3799
                        }
3800
                }
3801
                elem = elem.parent();
3802
        }
3803
3804
        return 0;
3805
}
3806
/* Date picker manager.
3807
   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
3808
   Settings for (groups of) date pickers are maintained in an instance object,
3809
   allowing multiple different settings on the same page. */
3810
3811
function Datepicker() {
3812
        this._curInst = null; // The current instance in use
3813
        this._keyEvent = false; // If the last event was a key event
3814
        this._disabledInputs = []; // List of date picker inputs that have been disabled
3815
        this._datepickerShowing = false; // True if the popup picker is showing , false if not
3816
        this._inDialog = false; // True if showing within a "dialog", false if not
3817
        this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
3818
        this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
3819
        this._appendClass = "ui-datepicker-append"; // The name of the append marker class
3820
        this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
3821
        this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
3822
        this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
3823
        this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
3824
        this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
3825
        this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
3826
        this.regional = []; // Available regional settings, indexed by language code
3827
        this.regional[""] = { // Default regional settings
3828
                closeText: "Done", // Display text for close link
3829
                prevText: "Prev", // Display text for previous month link
3830
                nextText: "Next", // Display text for next month link
3831
                currentText: "Today", // Display text for current month link
3832
                monthNames: ["January","February","March","April","May","June",
3833
                        "July","August","September","October","November","December"], // Names of months for drop-down and formatting
3834
                monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
3835
                dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
3836
                dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
3837
                dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
3838
                weekHeader: "Wk", // Column header for week of the year
3839
                dateFormat: "mm/dd/yy", // See format options on parseDate
3840
                firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
3841
                isRTL: false, // True if right-to-left language, false if left-to-right
3842
                showMonthAfterYear: false, // True if the year select precedes month, false for month then year
3843
                yearSuffix: "" // Additional text to append to the year in the month headers
3844
        };
3845
        this._defaults = { // Global defaults for all the date picker instances
3846
                showOn: "focus", // "focus" for popup on focus,
3847
                        // "button" for trigger button, or "both" for either
3848
                showAnim: "fadeIn", // Name of jQuery animation for popup
3849
                showOptions: {}, // Options for enhanced animations
3850
                defaultDate: null, // Used when field is blank: actual date,
3851
                        // +/-number for offset from today, null for today
3852
                appendText: "", // Display text following the input box, e.g. showing the format
3853
                buttonText: "...", // Text for trigger button
3854
                buttonImage: "", // URL for trigger button image
3855
                buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
3856
                hideIfNoPrevNext: false, // True to hide next/previous month links
3857
                        // if not applicable, false to just disable them
3858
                navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
3859
                gotoCurrent: false, // True if today link goes back to current selection instead
3860
                changeMonth: false, // True if month can be selected directly, false if only prev/next
3861
                changeYear: false, // True if year can be selected directly, false if only prev/next
3862
                yearRange: "c-10:c+10", // Range of years to display in drop-down,
3863
                        // either relative to today's year (-nn:+nn), relative to currently displayed year
3864
                        // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
3865
                showOtherMonths: false, // True to show dates in other months, false to leave blank
3866
                selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
3867
                showWeek: false, // True to show week of the year, false to not show it
3868
                calculateWeek: this.iso8601Week, // How to calculate the week of the year,
3869
                        // takes a Date and returns the number of the week for it
3870
                shortYearCutoff: "+10", // Short year values < this are in the current century,
3871
                        // > this are in the previous century,
3872
                        // string value starting with "+" for current year + value
3873
                minDate: null, // The earliest selectable date, or null for no limit
3874
                maxDate: null, // The latest selectable date, or null for no limit
3875
                duration: "fast", // Duration of display/closure
3876
                beforeShowDay: null, // Function that takes a date and returns an array with
3877
                        // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
3878
                        // [2] = cell title (optional), e.g. $.datepicker.noWeekends
3879
                beforeShow: null, // Function that takes an input field and
3880
                        // returns a set of custom settings for the date picker
3881
                onSelect: null, // Define a callback function when a date is selected
3882
                onChangeMonthYear: null, // Define a callback function when the month or year is changed
3883
                onClose: null, // Define a callback function when the datepicker is closed
3884
                numberOfMonths: 1, // Number of months to show at a time
3885
                showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
3886
                stepMonths: 1, // Number of months to step back/forward
3887
                stepBigMonths: 12, // Number of months to step back/forward for the big links
3888
                altField: "", // Selector for an alternate field to store selected dates into
3889
                altFormat: "", // The date format to use for the alternate field
3890
                constrainInput: true, // The input is constrained by the current date format
3891
                showButtonPanel: false, // True to show button panel, false to not show it
3892
                autoSize: false, // True to size the input for the date format, false to leave as is
3893
                disabled: false // The initial disabled state
3894
        };
3895
        $.extend(this._defaults, this.regional[""]);
3896
        this.regional.en = $.extend( true, {}, this.regional[ "" ]);
3897
        this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
3898
        this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
3899
}
3900
3901
$.extend(Datepicker.prototype, {
3902
        /* Class name added to elements to indicate already configured with a date picker. */
3903
        markerClassName: "hasDatepicker",
3904
3905
        //Keep track of the maximum number of rows displayed (see #7043)
3906
        maxRows: 4,
3907
3908
        // TODO rename to "widget" when switching to widget factory
3909
        _widgetDatepicker: function() {
3910
                return this.dpDiv;
3911
        },
3912
3913
        /* Override the default settings for all instances of the date picker.
3914
         * @param  settings  object - the new settings to use as defaults (anonymous object)
3915
         * @return the manager object
3916
         */
3917
        setDefaults: function(settings) {
3918
                datepicker_extendRemove(this._defaults, settings || {});
3919
                return this;
3920
        },
3921
3922
        /* Attach the date picker to a jQuery selection.
3923
         * @param  target        element - the target input field or division or span
3924
         * @param  settings  object - the new settings to use for this date picker instance (anonymous)
3925
         */
3926
        _attachDatepicker: function(target, settings) {
3927
                var nodeName, inline, inst;
3928
                nodeName = target.nodeName.toLowerCase();
3929
                inline = (nodeName === "div" || nodeName === "span");
3930
                if (!target.id) {
3931
                        this.uuid += 1;
3932
                        target.id = "dp" + this.uuid;
3933
                }
3934
                inst = this._newInst($(target), inline);
3935
                inst.settings = $.extend({}, settings || {});
3936
                if (nodeName === "input") {
3937
                        this._connectDatepicker(target, inst);
3938
                } else if (inline) {
3939
                        this._inlineDatepicker(target, inst);
3940
                }
3941
        },
3942
3943
        /* Create a new instance object. */
3944
        _newInst: function(target, inline) {
3945
                var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
3946
                return {id: id, input: target, // associated target
3947
                        selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
3948
                        drawMonth: 0, drawYear: 0, // month being drawn
3949
                        inline: inline, // is datepicker inline or not
3950
                        dpDiv: (!inline ? this.dpDiv : // presentation div
3951
                        datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
3952
        },
3953
3954
        /* Attach the date picker to an input field. */
3955
        _connectDatepicker: function(target, inst) {
3956
                var input = $(target);
3957
                inst.append = $([]);
3958
                inst.trigger = $([]);
3959
                if (input.hasClass(this.markerClassName)) {
3960
                        return;
3961
                }
3962
                this._attachments(input, inst);
3963
                input.addClass(this.markerClassName).keydown(this._doKeyDown).
3964
                        keypress(this._doKeyPress).keyup(this._doKeyUp);
3965
                this._autoSize(inst);
3966
                $.data(target, "datepicker", inst);
3967
                //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
3968
                if( inst.settings.disabled ) {
3969
                        this._disableDatepicker( target );
3970
                }
3971
        },
3972
3973
        /* Make attachments based on settings. */
3974
        _attachments: function(input, inst) {
3975
                var showOn, buttonText, buttonImage,
3976
                        appendText = this._get(inst, "appendText"),
3977
                        isRTL = this._get(inst, "isRTL");
3978
3979
                if (inst.append) {
3980
                        inst.append.remove();
3981
                }
3982
                if (appendText) {
3983
                        inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
3984
                        input[isRTL ? "before" : "after"](inst.append);
3985
                }
3986
3987
                input.unbind("focus", this._showDatepicker);
3988
3989
                if (inst.trigger) {
3990
                        inst.trigger.remove();
3991
                }
3992
3993
                showOn = this._get(inst, "showOn");
3994
                if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
3995
                        input.focus(this._showDatepicker);
3996
                }
3997
                if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
3998
                        buttonText = this._get(inst, "buttonText");
3999
                        buttonImage = this._get(inst, "buttonImage");
4000
                        inst.trigger = $(this._get(inst, "buttonImageOnly") ?
4001
                                $("<img/>").addClass(this._triggerClass).
4002
                                        attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
4003
                                $("<button type='button'></button>").addClass(this._triggerClass).
4004
                                        html(!buttonImage ? buttonText : $("<img/>").attr(
4005
                                        { src:buttonImage, alt:buttonText, title:buttonText })));
4006
                        input[isRTL ? "before" : "after"](inst.trigger);
4007
                        inst.trigger.click(function() {
4008
                                if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
4009
                                        $.datepicker._hideDatepicker();
4010
                                } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
4011
                                        $.datepicker._hideDatepicker();
4012
                                        $.datepicker._showDatepicker(input[0]);
4013
                                } else {
4014
                                        $.datepicker._showDatepicker(input[0]);
4015
                                }
4016
                                return false;
4017
                        });
4018
                }
4019
        },
4020
4021
        /* Apply the maximum length for the date format. */
4022
        _autoSize: function(inst) {
4023
                if (this._get(inst, "autoSize") && !inst.inline) {
4024
                        var findMax, max, maxI, i,
4025
                                date = new Date(2009, 12 - 1, 20), // Ensure double digits
4026
                                dateFormat = this._get(inst, "dateFormat");
4027
4028
                        if (dateFormat.match(/[DM]/)) {
4029
                                findMax = function(names) {
4030
                                        max = 0;
4031
                                        maxI = 0;
4032
                                        for (i = 0; i < names.length; i++) {
4033
                                                if (names[i].length > max) {
4034
                                                        max = names[i].length;
4035
                                                        maxI = i;
4036
                                                }
4037
                                        }
4038
                                        return maxI;
4039
                                };
4040
                                date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
4041
                                        "monthNames" : "monthNamesShort"))));
4042
                                date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
4043
                                        "dayNames" : "dayNamesShort"))) + 20 - date.getDay());
4044
                        }
4045
                        inst.input.attr("size", this._formatDate(inst, date).length);
4046
                }
4047
        },
4048
4049
        /* Attach an inline date picker to a div. */
4050
        _inlineDatepicker: function(target, inst) {
4051
                var divSpan = $(target);
4052
                if (divSpan.hasClass(this.markerClassName)) {
4053
                        return;
4054
                }
4055
                divSpan.addClass(this.markerClassName).append(inst.dpDiv);
4056
                $.data(target, "datepicker", inst);
4057
                this._setDate(inst, this._getDefaultDate(inst), true);
4058
                this._updateDatepicker(inst);
4059
                this._updateAlternate(inst);
4060
                //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
4061
                if( inst.settings.disabled ) {
4062
                        this._disableDatepicker( target );
4063
                }
4064
                // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
4065
                // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
4066
                inst.dpDiv.css( "display", "block" );
4067
        },
4068
4069
        /* Pop-up the date picker in a "dialog" box.
4070
         * @param  input element - ignored
4071
         * @param  date        string or Date - the initial date to display
4072
         * @param  onSelect  function - the function to call when a date is selected
4073
         * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
4074
         * @param  pos int[2] - coordinates for the dialog's position within the screen or
4075
         *                                        event - with x/y coordinates or
4076
         *                                        leave empty for default (screen centre)
4077
         * @return the manager object
4078
         */
4079
        _dialogDatepicker: function(input, date, onSelect, settings, pos) {
4080
                var id, browserWidth, browserHeight, scrollX, scrollY,
4081
                        inst = this._dialogInst; // internal instance
4082
4083
                if (!inst) {
4084
                        this.uuid += 1;
4085
                        id = "dp" + this.uuid;
4086
                        this._dialogInput = $("<input type='text' id='" + id +
4087
                                "' style='position: absolute; top: -100px; width: 0px;'/>");
4088
                        this._dialogInput.keydown(this._doKeyDown);
4089
                        $("body").append(this._dialogInput);
4090
                        inst = this._dialogInst = this._newInst(this._dialogInput, false);
4091
                        inst.settings = {};
4092
                        $.data(this._dialogInput[0], "datepicker", inst);
4093
                }
4094
                datepicker_extendRemove(inst.settings, settings || {});
4095
                date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
4096
                this._dialogInput.val(date);
4097
4098
                this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
4099
                if (!this._pos) {
4100
                        browserWidth = document.documentElement.clientWidth;
4101
                        browserHeight = document.documentElement.clientHeight;
4102
                        scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
4103
                        scrollY = document.documentElement.scrollTop || document.body.scrollTop;
4104
                        this._pos = // should use actual width/height below
4105
                                [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
4106
                }
4107
4108
                // move input on screen for focus, but hidden behind dialog
4109
                this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
4110
                inst.settings.onSelect = onSelect;
4111
                this._inDialog = true;
4112
                this.dpDiv.addClass(this._dialogClass);
4113
                this._showDatepicker(this._dialogInput[0]);
4114
                if ($.blockUI) {
4115
                        $.blockUI(this.dpDiv);
4116
                }
4117
                $.data(this._dialogInput[0], "datepicker", inst);
4118
                return this;
4119
        },
4120
4121
        /* Detach a datepicker from its control.
4122
         * @param  target        element - the target input field or division or span
4123
         */
4124
        _destroyDatepicker: function(target) {
4125
                var nodeName,
4126
                        $target = $(target),
4127
                        inst = $.data(target, "datepicker");
4128
4129
                if (!$target.hasClass(this.markerClassName)) {
4130
                        return;
4131
                }
4132
4133
                nodeName = target.nodeName.toLowerCase();
4134
                $.removeData(target, "datepicker");
4135
                if (nodeName === "input") {
4136
                        inst.append.remove();
4137
                        inst.trigger.remove();
4138
                        $target.removeClass(this.markerClassName).
4139
                                unbind("focus", this._showDatepicker).
4140
                                unbind("keydown", this._doKeyDown).
4141
                                unbind("keypress", this._doKeyPress).
4142
                                unbind("keyup", this._doKeyUp);
4143
                } else if (nodeName === "div" || nodeName === "span") {
4144
                        $target.removeClass(this.markerClassName).empty();
4145
                }
4146
4147
                if ( datepicker_instActive === inst ) {
4148
                        datepicker_instActive = null;
4149
                }
4150
        },
4151
4152
        /* Enable the date picker to a jQuery selection.
4153
         * @param  target        element - the target input field or division or span
4154
         */
4155
        _enableDatepicker: function(target) {
4156
                var nodeName, inline,
4157
                        $target = $(target),
4158
                        inst = $.data(target, "datepicker");
4159
4160
                if (!$target.hasClass(this.markerClassName)) {
4161
                        return;
4162
                }
4163
4164
                nodeName = target.nodeName.toLowerCase();
4165
                if (nodeName === "input") {
4166
                        target.disabled = false;
4167
                        inst.trigger.filter("button").
4168
                                each(function() { this.disabled = false; }).end().
4169
                                filter("img").css({opacity: "1.0", cursor: ""});
4170
                } else if (nodeName === "div" || nodeName === "span") {
4171
                        inline = $target.children("." + this._inlineClass);
4172
                        inline.children().removeClass("ui-state-disabled");
4173
                        inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
4174
                                prop("disabled", false);
4175
                }
4176
                this._disabledInputs = $.map(this._disabledInputs,
4177
                        function(value) { return (value === target ? null : value); }); // delete entry
4178
        },
4179
4180
        /* Disable the date picker to a jQuery selection.
4181
         * @param  target        element - the target input field or division or span
4182
         */
4183
        _disableDatepicker: function(target) {
4184
                var nodeName, inline,
4185
                        $target = $(target),
4186
                        inst = $.data(target, "datepicker");
4187
4188
                if (!$target.hasClass(this.markerClassName)) {
4189
                        return;
4190
                }
4191
4192
                nodeName = target.nodeName.toLowerCase();
4193
                if (nodeName === "input") {
4194
                        target.disabled = true;
4195
                        inst.trigger.filter("button").
4196
                                each(function() { this.disabled = true; }).end().
4197
                                filter("img").css({opacity: "0.5", cursor: "default"});
4198
                } else if (nodeName === "div" || nodeName === "span") {
4199
                        inline = $target.children("." + this._inlineClass);
4200
                        inline.children().addClass("ui-state-disabled");
4201
                        inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
4202
                                prop("disabled", true);
4203
                }
4204
                this._disabledInputs = $.map(this._disabledInputs,
4205
                        function(value) { return (value === target ? null : value); }); // delete entry
4206
                this._disabledInputs[this._disabledInputs.length] = target;
4207
        },
4208
4209
        /* Is the first field in a jQuery collection disabled as a datepicker?
4210
         * @param  target        element - the target input field or division or span
4211
         * @return boolean - true if disabled, false if enabled
4212
         */
4213
        _isDisabledDatepicker: function(target) {
4214
                if (!target) {
4215
                        return false;
4216
                }
4217
                for (var i = 0; i < this._disabledInputs.length; i++) {
4218
                        if (this._disabledInputs[i] === target) {
4219
                                return true;
4220
                        }
4221
                }
4222
                return false;
4223
        },
4224
4225
        /* Retrieve the instance data for the target control.
4226
         * @param  target  element - the target input field or division or span
4227
         * @return  object - the associated instance data
4228
         * @throws  error if a jQuery problem getting data
4229
         */
4230
        _getInst: function(target) {
4231
                try {
4232
                        return $.data(target, "datepicker");
4233
                }
4234
                catch (err) {
4235
                        throw "Missing instance data for this datepicker";
4236
                }
4237
        },
4238
4239
        /* Update or retrieve the settings for a date picker attached to an input field or division.
4240
         * @param  target  element - the target input field or division or span
4241
         * @param  name        object - the new settings to update or
4242
         *                                string - the name of the setting to change or retrieve,
4243
         *                                when retrieving also "all" for all instance settings or
4244
         *                                "defaults" for all global defaults
4245
         * @param  value   any - the new value for the setting
4246
         *                                (omit if above is an object or to retrieve a value)
4247
         */
4248
        _optionDatepicker: function(target, name, value) {
4249
                var settings, date, minDate, maxDate,
4250
                        inst = this._getInst(target);
4251
4252
                if (arguments.length === 2 && typeof name === "string") {
4253
                        return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
4254
                                (inst ? (name === "all" ? $.extend({}, inst.settings) :
4255
                                this._get(inst, name)) : null));
4256
                }
4257
4258
                settings = name || {};
4259
                if (typeof name === "string") {
4260
                        settings = {};
4261
                        settings[name] = value;
4262
                }
4263
4264
                if (inst) {
4265
                        if (this._curInst === inst) {
4266
                                this._hideDatepicker();
4267
                        }
4268
4269
                        date = this._getDateDatepicker(target, true);
4270
                        minDate = this._getMinMaxDate(inst, "min");
4271
                        maxDate = this._getMinMaxDate(inst, "max");
4272
                        datepicker_extendRemove(inst.settings, settings);
4273
                        // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
4274
                        if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
4275
                                inst.settings.minDate = this._formatDate(inst, minDate);
4276
                        }
4277
                        if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
4278
                                inst.settings.maxDate = this._formatDate(inst, maxDate);
4279
                        }
4280
                        if ( "disabled" in settings ) {
4281
                                if ( settings.disabled ) {
4282
                                        this._disableDatepicker(target);
4283
                                } else {
4284
                                        this._enableDatepicker(target);
4285
                                }
4286
                        }
4287
                        this._attachments($(target), inst);
4288
                        this._autoSize(inst);
4289
                        this._setDate(inst, date);
4290
                        this._updateAlternate(inst);
4291
                        this._updateDatepicker(inst);
4292
                }
4293
        },
4294
4295
        // change method deprecated
4296
        _changeDatepicker: function(target, name, value) {
4297
                this._optionDatepicker(target, name, value);
4298
        },
4299
4300
        /* Redraw the date picker attached to an input field or division.
4301
         * @param  target  element - the target input field or division or span
4302
         */
4303
        _refreshDatepicker: function(target) {
4304
                var inst = this._getInst(target);
4305
                if (inst) {
4306
                        this._updateDatepicker(inst);
4307
                }
4308
        },
4309
4310
        /* Set the dates for a jQuery selection.
4311
         * @param  target element - the target input field or division or span
4312
         * @param  date        Date - the new date
4313
         */
4314
        _setDateDatepicker: function(target, date) {
4315
                var inst = this._getInst(target);
4316
                if (inst) {
4317
                        this._setDate(inst, date);
4318
                        this._updateDatepicker(inst);
4319
                        this._updateAlternate(inst);
4320
                }
4321
        },
4322
4323
        /* Get the date(s) for the first entry in a jQuery selection.
4324
         * @param  target element - the target input field or division or span
4325
         * @param  noDefault boolean - true if no default date is to be used
4326
         * @return Date - the current date
4327
         */
4328
        _getDateDatepicker: function(target, noDefault) {
4329
                var inst = this._getInst(target);
4330
                if (inst && !inst.inline) {
4331
                        this._setDateFromField(inst, noDefault);
4332
                }
4333
                return (inst ? this._getDate(inst) : null);
4334
        },
4335
4336
        /* Handle keystrokes. */
4337
        _doKeyDown: function(event) {
4338
                var onSelect, dateStr, sel,
4339
                        inst = $.datepicker._getInst(event.target),
4340
                        handled = true,
4341
                        isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
4342
4343
                inst._keyEvent = true;
4344
                if ($.datepicker._datepickerShowing) {
4345
                        switch (event.keyCode) {
4346
                                case 9: $.datepicker._hideDatepicker();
4347
                                                handled = false;
4348
                                                break; // hide on tab out
4349
                                case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
4350
                                                                        $.datepicker._currentClass + ")", inst.dpDiv);
4351
                                                if (sel[0]) {
4352
                                                        $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
4353
                                                }
4354
4355
                                                onSelect = $.datepicker._get(inst, "onSelect");
4356
                                                if (onSelect) {
4357
                                                        dateStr = $.datepicker._formatDate(inst);
4358
4359
                                                        // trigger custom callback
4360
                                                        onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
4361
                                                } else {
4362
                                                        $.datepicker._hideDatepicker();
4363
                                                }
4364
4365
                                                return false; // don't submit the form
4366
                                case 27: $.datepicker._hideDatepicker();
4367
                                                break; // hide on escape
4368
                                case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4369
                                                        -$.datepicker._get(inst, "stepBigMonths") :
4370
                                                        -$.datepicker._get(inst, "stepMonths")), "M");
4371
                                                break; // previous month/year on page up/+ ctrl
4372
                                case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4373
                                                        +$.datepicker._get(inst, "stepBigMonths") :
4374
                                                        +$.datepicker._get(inst, "stepMonths")), "M");
4375
                                                break; // next month/year on page down/+ ctrl
4376
                                case 35: if (event.ctrlKey || event.metaKey) {
4377
                                                        $.datepicker._clearDate(event.target);
4378
                                                }
4379
                                                handled = event.ctrlKey || event.metaKey;
4380
                                                break; // clear on ctrl or command +end
4381
                                case 36: if (event.ctrlKey || event.metaKey) {
4382
                                                        $.datepicker._gotoToday(event.target);
4383
                                                }
4384
                                                handled = event.ctrlKey || event.metaKey;
4385
                                                break; // current on ctrl or command +home
4386
                                case 37: if (event.ctrlKey || event.metaKey) {
4387
                                                        $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
4388
                                                }
4389
                                                handled = event.ctrlKey || event.metaKey;
4390
                                                // -1 day on ctrl or command +left
4391
                                                if (event.originalEvent.altKey) {
4392
                                                        $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4393
                                                                -$.datepicker._get(inst, "stepBigMonths") :
4394
                                                                -$.datepicker._get(inst, "stepMonths")), "M");
4395
                                                }
4396
                                                // next month/year on alt +left on Mac
4397
                                                break;
4398
                                case 38: if (event.ctrlKey || event.metaKey) {
4399
                                                        $.datepicker._adjustDate(event.target, -7, "D");
4400
                                                }
4401
                                                handled = event.ctrlKey || event.metaKey;
4402
                                                break; // -1 week on ctrl or command +up
4403
                                case 39: if (event.ctrlKey || event.metaKey) {
4404
                                                        $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
4405
                                                }
4406
                                                handled = event.ctrlKey || event.metaKey;
4407
                                                // +1 day on ctrl or command +right
4408
                                                if (event.originalEvent.altKey) {
4409
                                                        $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4410
                                                                +$.datepicker._get(inst, "stepBigMonths") :
4411
                                                                +$.datepicker._get(inst, "stepMonths")), "M");
4412
                                                }
4413
                                                // next month/year on alt +right
4414
                                                break;
4415
                                case 40: if (event.ctrlKey || event.metaKey) {
4416
                                                        $.datepicker._adjustDate(event.target, +7, "D");
4417
                                                }
4418
                                                handled = event.ctrlKey || event.metaKey;
4419
                                                break; // +1 week on ctrl or command +down
4420
                                default: handled = false;
4421
                        }
4422
                } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
4423
                        $.datepicker._showDatepicker(this);
4424
                } else {
4425
                        handled = false;
4426
                }
4427
4428
                if (handled) {
4429
                        event.preventDefault();
4430
                        event.stopPropagation();
4431
                }
4432
        },
4433
4434
        /* Filter entered characters - based on date format. */
4435
        _doKeyPress: function(event) {
4436
                var chars, chr,
4437
                        inst = $.datepicker._getInst(event.target);
4438
4439
                if ($.datepicker._get(inst, "constrainInput")) {
4440
                        chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
4441
                        chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
4442
                        return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
4443
                }
4444
        },
4445
4446
        /* Synchronise manual entry and field/alternate field. */
4447
        _doKeyUp: function(event) {
4448
                var date,
4449
                        inst = $.datepicker._getInst(event.target);
4450
4451
                if (inst.input.val() !== inst.lastVal) {
4452
                        try {
4453
                                date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
4454
                                        (inst.input ? inst.input.val() : null),
4455
                                        $.datepicker._getFormatConfig(inst));
4456
4457
                                if (date) { // only if valid
4458
                                        $.datepicker._setDateFromField(inst);
4459
                                        $.datepicker._updateAlternate(inst);
4460
                                        $.datepicker._updateDatepicker(inst);
4461
                                }
4462
                        }
4463
                        catch (err) {
4464
                        }
4465
                }
4466
                return true;
4467
        },
4468
4469
        /* Pop-up the date picker for a given input field.
4470
         * If false returned from beforeShow event handler do not show.
4471
         * @param  input  element - the input field attached to the date picker or
4472
         *                                        event - if triggered by focus
4473
         */
4474
        _showDatepicker: function(input) {
4475
                input = input.target || input;
4476
                if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
4477
                        input = $("input", input.parentNode)[0];
4478
                }
4479
4480
                if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
4481
                        return;
4482
                }
4483
4484
                var inst, beforeShow, beforeShowSettings, isFixed,
4485
                        offset, showAnim, duration;
4486
4487
                inst = $.datepicker._getInst(input);
4488
                if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
4489
                        $.datepicker._curInst.dpDiv.stop(true, true);
4490
                        if ( inst && $.datepicker._datepickerShowing ) {
4491
                                $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
4492
                        }
4493
                }
4494
4495
                beforeShow = $.datepicker._get(inst, "beforeShow");
4496
                beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
4497
                if(beforeShowSettings === false){
4498
                        return;
4499
                }
4500
                datepicker_extendRemove(inst.settings, beforeShowSettings);
4501
4502
                inst.lastVal = null;
4503
                $.datepicker._lastInput = input;
4504
                $.datepicker._setDateFromField(inst);
4505
4506
                if ($.datepicker._inDialog) { // hide cursor
4507
                        input.value = "";
4508
                }
4509
                if (!$.datepicker._pos) { // position below input
4510
                        $.datepicker._pos = $.datepicker._findPos(input);
4511
                        $.datepicker._pos[1] += input.offsetHeight; // add the height
4512
                }
4513
4514
                isFixed = false;
4515
                $(input).parents().each(function() {
4516
                        isFixed |= $(this).css("position") === "fixed";
4517
                        return !isFixed;
4518
                });
4519
4520
                offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
4521
                $.datepicker._pos = null;
4522
                //to avoid flashes on Firefox
4523
                inst.dpDiv.empty();
4524
                // determine sizing offscreen
4525
                inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
4526
                $.datepicker._updateDatepicker(inst);
4527
                // fix width for dynamic number of date pickers
4528
                // and adjust position before showing
4529
                offset = $.datepicker._checkOffset(inst, offset, isFixed);
4530
                inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
4531
                        "static" : (isFixed ? "fixed" : "absolute")), display: "none",
4532
                        left: offset.left + "px", top: offset.top + "px"});
4533
4534
                if (!inst.inline) {
4535
                        showAnim = $.datepicker._get(inst, "showAnim");
4536
                        duration = $.datepicker._get(inst, "duration");
4537
                        inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
4538
                        $.datepicker._datepickerShowing = true;
4539
4540
                        if ( $.effects && $.effects.effect[ showAnim ] ) {
4541
                                inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
4542
                        } else {
4543
                                inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
4544
                        }
4545
4546
                        if ( $.datepicker._shouldFocusInput( inst ) ) {
4547
                                inst.input.focus();
4548
                        }
4549
4550
                        $.datepicker._curInst = inst;
4551
                }
4552
        },
4553
4554
        /* Generate the date picker content. */
4555
        _updateDatepicker: function(inst) {
4556
                this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
4557
                datepicker_instActive = inst; // for delegate hover events
4558
                inst.dpDiv.empty().append(this._generateHTML(inst));
4559
                this._attachHandlers(inst);
4560
4561
                var origyearshtml,
4562
                        numMonths = this._getNumberOfMonths(inst),
4563
                        cols = numMonths[1],
4564
                        width = 17,
4565
                        activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
4566
4567
                if ( activeCell.length > 0 ) {
4568
                        datepicker_handleMouseover.apply( activeCell.get( 0 ) );
4569
                }
4570
4571
                inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
4572
                if (cols > 1) {
4573
                        inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
4574
                }
4575
                inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
4576
                        "Class"]("ui-datepicker-multi");
4577
                inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
4578
                        "Class"]("ui-datepicker-rtl");
4579
4580
                if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
4581
                        inst.input.focus();
4582
                }
4583
4584
                // deffered render of the years select (to avoid flashes on Firefox)
4585
                if( inst.yearshtml ){
4586
                        origyearshtml = inst.yearshtml;
4587
                        setTimeout(function(){
4588
                                //assure that inst.yearshtml didn't change.
4589
                                if( origyearshtml === inst.yearshtml && inst.yearshtml ){
4590
                                        inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
4591
                                }
4592
                                origyearshtml = inst.yearshtml = null;
4593
                        }, 0);
4594
                }
4595
        },
4596
4597
        // #6694 - don't focus the input if it's already focused
4598
        // this breaks the change event in IE
4599
        // Support: IE and jQuery <1.9
4600
        _shouldFocusInput: function( inst ) {
4601
                return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
4602
        },
4603
4604
        /* Check positioning to remain on screen. */
4605
        _checkOffset: function(inst, offset, isFixed) {
4606
                var dpWidth = inst.dpDiv.outerWidth(),
4607
                        dpHeight = inst.dpDiv.outerHeight(),
4608
                        inputWidth = inst.input ? inst.input.outerWidth() : 0,
4609
                        inputHeight = inst.input ? inst.input.outerHeight() : 0,
4610
                        viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
4611
                        viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
4612
4613
                offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
4614
                offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
4615
                offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
4616
4617
                // now check if datepicker is showing outside window viewport - move to a better place if so.
4618
                offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
4619
                        Math.abs(offset.left + dpWidth - viewWidth) : 0);
4620
                offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
4621
                        Math.abs(dpHeight + inputHeight) : 0);
4622
4623
                return offset;
4624
        },
4625
4626
        /* Find an object's position on the screen. */
4627
        _findPos: function(obj) {
4628
                var position,
4629
                        inst = this._getInst(obj),
4630
                        isRTL = this._get(inst, "isRTL");
4631
4632
                while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
4633
                        obj = obj[isRTL ? "previousSibling" : "nextSibling"];
4634
                }
4635
4636
                position = $(obj).offset();
4637
                return [position.left, position.top];
4638
        },
4639
4640
        /* Hide the date picker from view.
4641
         * @param  input  element - the input field attached to the date picker
4642
         */
4643
        _hideDatepicker: function(input) {
4644
                var showAnim, duration, postProcess, onClose,
4645
                        inst = this._curInst;
4646
4647
                if (!inst || (input && inst !== $.data(input, "datepicker"))) {
4648
                        return;
4649
                }
4650
4651
                if (this._datepickerShowing) {
4652
                        showAnim = this._get(inst, "showAnim");
4653
                        duration = this._get(inst, "duration");
4654
                        postProcess = function() {
4655
                                $.datepicker._tidyDialog(inst);
4656
                        };
4657
4658
                        // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
4659
                        if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
4660
                                inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
4661
                        } else {
4662
                                inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
4663
                                        (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
4664
                        }
4665
4666
                        if (!showAnim) {
4667
                                postProcess();
4668
                        }
4669
                        this._datepickerShowing = false;
4670
4671
                        onClose = this._get(inst, "onClose");
4672
                        if (onClose) {
4673
                                onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
4674
                        }
4675
4676
                        this._lastInput = null;
4677
                        if (this._inDialog) {
4678
                                this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
4679
                                if ($.blockUI) {
4680
                                        $.unblockUI();
4681
                                        $("body").append(this.dpDiv);
4682
                                }
4683
                        }
4684
                        this._inDialog = false;
4685
                }
4686
        },
4687
4688
        /* Tidy up after a dialog display. */
4689
        _tidyDialog: function(inst) {
4690
                inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
4691
        },
4692
4693
        /* Close date picker if clicked elsewhere. */
4694
        _checkExternalClick: function(event) {
4695
                if (!$.datepicker._curInst) {
4696
                        return;
4697
                }
4698
4699
                var $target = $(event.target),
4700
                        inst = $.datepicker._getInst($target[0]);
4701
4702
                if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
4703
                                $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
4704
                                !$target.hasClass($.datepicker.markerClassName) &&
4705
                                !$target.closest("." + $.datepicker._triggerClass).length &&
4706
                                $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
4707
                        ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
4708
                                $.datepicker._hideDatepicker();
4709
                }
4710
        },
4711
4712
        /* Adjust one of the date sub-fields. */
4713
        _adjustDate: function(id, offset, period) {
4714
                var target = $(id),
4715
                        inst = this._getInst(target[0]);
4716
4717
                if (this._isDisabledDatepicker(target[0])) {
4718
                        return;
4719
                }
4720
                this._adjustInstDate(inst, offset +
4721
                        (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
4722
                        period);
4723
                this._updateDatepicker(inst);
4724
        },
4725
4726
        /* Action for current link. */
4727
        _gotoToday: function(id) {
4728
                var date,
4729
                        target = $(id),
4730
                        inst = this._getInst(target[0]);
4731
4732
                if (this._get(inst, "gotoCurrent") && inst.currentDay) {
4733
                        inst.selectedDay = inst.currentDay;
4734
                        inst.drawMonth = inst.selectedMonth = inst.currentMonth;
4735
                        inst.drawYear = inst.selectedYear = inst.currentYear;
4736
                } else {
4737
                        date = new Date();
4738
                        inst.selectedDay = date.getDate();
4739
                        inst.drawMonth = inst.selectedMonth = date.getMonth();
4740
                        inst.drawYear = inst.selectedYear = date.getFullYear();
4741
                }
4742
                this._notifyChange(inst);
4743
                this._adjustDate(target);
4744
        },
4745
4746
        /* Action for selecting a new month/year. */
4747
        _selectMonthYear: function(id, select, period) {
4748
                var target = $(id),
4749
                        inst = this._getInst(target[0]);
4750
4751
                inst["selected" + (period === "M" ? "Month" : "Year")] =
4752
                inst["draw" + (period === "M" ? "Month" : "Year")] =
4753
                        parseInt(select.options[select.selectedIndex].value,10);
4754
4755
                this._notifyChange(inst);
4756
                this._adjustDate(target);
4757
        },
4758
4759
        /* Action for selecting a day. */
4760
        _selectDay: function(id, month, year, td) {
4761
                var inst,
4762
                        target = $(id);
4763
4764
                if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
4765
                        return;
4766
                }
4767
4768
                inst = this._getInst(target[0]);
4769
                inst.selectedDay = inst.currentDay = $("a", td).html();
4770
                inst.selectedMonth = inst.currentMonth = month;
4771
                inst.selectedYear = inst.currentYear = year;
4772
                this._selectDate(id, this._formatDate(inst,
4773
                        inst.currentDay, inst.currentMonth, inst.currentYear));
4774
        },
4775
4776
        /* Erase the input field and hide the date picker. */
4777
        _clearDate: function(id) {
4778
                var target = $(id);
4779
                this._selectDate(target, "");
4780
        },
4781
4782
        /* Update the input field with the selected date. */
4783
        _selectDate: function(id, dateStr) {
4784
                var onSelect,
4785
                        target = $(id),
4786
                        inst = this._getInst(target[0]);
4787
4788
                dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
4789
                if (inst.input) {
4790
                        inst.input.val(dateStr);
4791
                }
4792
                this._updateAlternate(inst);
4793
4794
                onSelect = this._get(inst, "onSelect");
4795
                if (onSelect) {
4796
                        onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
4797
                } else if (inst.input) {
4798
                        inst.input.trigger("change"); // fire the change event
4799
                }
4800
4801
                if (inst.inline){
4802
                        this._updateDatepicker(inst);
4803
                } else {
4804
                        this._hideDatepicker();
4805
                        this._lastInput = inst.input[0];
4806
                        if (typeof(inst.input[0]) !== "object") {
4807
                                inst.input.focus(); // restore focus
4808
                        }
4809
                        this._lastInput = null;
4810
                }
4811
        },
4812
4813
        /* Update any alternate field to synchronise with the main field. */
4814
        _updateAlternate: function(inst) {
4815
                var altFormat, date, dateStr,
4816
                        altField = this._get(inst, "altField");
4817
4818
                if (altField) { // update alternate field too
4819
                        altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
4820
                        date = this._getDate(inst);
4821
                        dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
4822
                        $(altField).each(function() { $(this).val(dateStr); });
4823
                }
4824
        },
4825
4826
        /* Set as beforeShowDay function to prevent selection of weekends.
4827
         * @param  date  Date - the date to customise
4828
         * @return [boolean, string] - is this date selectable?, what is its CSS class?
4829
         */
4830
        noWeekends: function(date) {
4831
                var day = date.getDay();
4832
                return [(day > 0 && day < 6), ""];
4833
        },
4834
4835
        /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
4836
         * @param  date  Date - the date to get the week for
4837
         * @return  number - the number of the week within the year that contains this date
4838
         */
4839
        iso8601Week: function(date) {
4840
                var time,
4841
                        checkDate = new Date(date.getTime());
4842
4843
                // Find Thursday of this week starting on Monday
4844
                checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
4845
4846
                time = checkDate.getTime();
4847
                checkDate.setMonth(0); // Compare with Jan 1
4848
                checkDate.setDate(1);
4849
                return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
4850
        },
4851
4852
        /* Parse a string value into a date object.
4853
         * See formatDate below for the possible formats.
4854
         *
4855
         * @param  format string - the expected format of the date
4856
         * @param  value string - the date in the above format
4857
         * @param  settings Object - attributes include:
4858
         *                                        shortYearCutoff  number - the cutoff year for determining the century (optional)
4859
         *                                        dayNamesShort        string[7] - abbreviated names of the days from Sunday (optional)
4860
         *                                        dayNames                string[7] - names of the days from Sunday (optional)
4861
         *                                        monthNamesShort string[12] - abbreviated names of the months (optional)
4862
         *                                        monthNames                string[12] - names of the months (optional)
4863
         * @return  Date - the extracted date value or null if value is blank
4864
         */
4865
        parseDate: function (format, value, settings) {
4866
                if (format == null || value == null) {
4867
                        throw "Invalid arguments";
4868
                }
4869
4870
                value = (typeof value === "object" ? value.toString() : value + "");
4871
                if (value === "") {
4872
                        return null;
4873
                }
4874
4875
                var iFormat, dim, extra,
4876
                        iValue = 0,
4877
                        shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
4878
                        shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
4879
                                new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
4880
                        dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
4881
                        dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
4882
                        monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
4883
                        monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
4884
                        year = -1,
4885
                        month = -1,
4886
                        day = -1,
4887
                        doy = -1,
4888
                        literal = false,
4889
                        date,
4890
                        // Check whether a format character is doubled
4891
                        lookAhead = function(match) {
4892
                                var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
4893
                                if (matches) {
4894
                                        iFormat++;
4895
                                }
4896
                                return matches;
4897
                        },
4898
                        // Extract a number from the string value
4899
                        getNumber = function(match) {
4900
                                var isDoubled = lookAhead(match),
4901
                                        size = (match === "@" ? 14 : (match === "!" ? 20 :
4902
                                        (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
4903
                                        minSize = (match === "y" ? size : 1),
4904
                                        digits = new RegExp("^\\d{" + minSize + "," + size + "}"),
4905
                                        num = value.substring(iValue).match(digits);
4906
                                if (!num) {
4907
                                        throw "Missing number at position " + iValue;
4908
                                }
4909
                                iValue += num[0].length;
4910
                                return parseInt(num[0], 10);
4911
                        },
4912
                        // Extract a name from the string value and convert to an index
4913
                        getName = function(match, shortNames, longNames) {
4914
                                var index = -1,
4915
                                        names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
4916
                                                return [ [k, v] ];
4917
                                        }).sort(function (a, b) {
4918
                                                return -(a[1].length - b[1].length);
4919
                                        });
4920
4921
                                $.each(names, function (i, pair) {
4922
                                        var name = pair[1];
4923
                                        if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
4924
                                                index = pair[0];
4925
                                                iValue += name.length;
4926
                                                return false;
4927
                                        }
4928
                                });
4929
                                if (index !== -1) {
4930
                                        return index + 1;
4931
                                } else {
4932
                                        throw "Unknown name at position " + iValue;
4933
                                }
4934
                        },
4935
                        // Confirm that a literal character matches the string value
4936
                        checkLiteral = function() {
4937
                                if (value.charAt(iValue) !== format.charAt(iFormat)) {
4938
                                        throw "Unexpected literal at position " + iValue;
4939
                                }
4940
                                iValue++;
4941
                        };
4942
4943
                for (iFormat = 0; iFormat < format.length; iFormat++) {
4944
                        if (literal) {
4945
                                if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
4946
                                        literal = false;
4947
                                } else {
4948
                                        checkLiteral();
4949
                                }
4950
                        } else {
4951
                                switch (format.charAt(iFormat)) {
4952
                                        case "d":
4953
                                                day = getNumber("d");
4954
                                                break;
4955
                                        case "D":
4956
                                                getName("D", dayNamesShort, dayNames);
4957
                                                break;
4958
                                        case "o":
4959
                                                doy = getNumber("o");
4960
                                                break;
4961
                                        case "m":
4962
                                                month = getNumber("m");
4963
                                                break;
4964
                                        case "M":
4965
                                                month = getName("M", monthNamesShort, monthNames);
4966
                                                break;
4967
                                        case "y":
4968
                                                year = getNumber("y");
4969
                                                break;
4970
                                        case "@":
4971
                                                date = new Date(getNumber("@"));
4972
                                                year = date.getFullYear();
4973
                                                month = date.getMonth() + 1;
4974
                                                day = date.getDate();
4975
                                                break;
4976
                                        case "!":
4977
                                                date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
4978
                                                year = date.getFullYear();
4979
                                                month = date.getMonth() + 1;
4980
                                                day = date.getDate();
4981
                                                break;
4982
                                        case "'":
4983
                                                if (lookAhead("'")){
4984
                                                        checkLiteral();
4985
                                                } else {
4986
                                                        literal = true;
4987
                                                }
4988
                                                break;
4989
                                        default:
4990
                                                checkLiteral();
4991
                                }
4992
                        }
4993
                }
4994
4995
                if (iValue < value.length){
4996
                        extra = value.substr(iValue);
4997
                        if (!/^\s+/.test(extra)) {
4998
                                throw "Extra/unparsed characters found in date: " + extra;
4999
                        }
5000
                }
5001
5002
                if (year === -1) {
5003
                        year = new Date().getFullYear();
5004
                } else if (year < 100) {
5005
                        year += new Date().getFullYear() - new Date().getFullYear() % 100 +
5006
                                (year <= shortYearCutoff ? 0 : -100);
5007
                }
5008
5009
                if (doy > -1) {
5010
                        month = 1;
5011
                        day = doy;
5012
                        do {
5013
                                dim = this._getDaysInMonth(year, month - 1);
5014
                                if (day <= dim) {
5015
                                        break;
5016
                                }
5017
                                month++;
5018
                                day -= dim;
5019
                        } while (true);
5020
                }
5021
5022
                date = this._daylightSavingAdjust(new Date(year, month - 1, day));
5023
                if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
5024
                        throw "Invalid date"; // E.g. 31/02/00
5025
                }
5026
                return date;
5027
        },
5028
5029
        /* Standard date formats. */
5030
        ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
5031
        COOKIE: "D, dd M yy",
5032
        ISO_8601: "yy-mm-dd",
5033
        RFC_822: "D, d M y",
5034
        RFC_850: "DD, dd-M-y",
5035
        RFC_1036: "D, d M y",
5036
        RFC_1123: "D, d M yy",
5037
        RFC_2822: "D, d M yy",
5038
        RSS: "D, d M y", // RFC 822
5039
        TICKS: "!",
5040
        TIMESTAMP: "@",
5041
        W3C: "yy-mm-dd", // ISO 8601
5042
5043
        _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
5044
                Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
5045
5046
        /* Format a date object into a string value.
5047
         * The format can be combinations of the following:
5048
         * d  - day of month (no leading zero)
5049
         * dd - day of month (two digit)
5050
         * o  - day of year (no leading zeros)
5051
         * oo - day of year (three digit)
5052
         * D  - day name short
5053
         * DD - day name long
5054
         * m  - month of year (no leading zero)
5055
         * mm - month of year (two digit)
5056
         * M  - month name short
5057
         * MM - month name long
5058
         * y  - year (two digit)
5059
         * yy - year (four digit)
5060
         * @ - Unix timestamp (ms since 01/01/1970)
5061
         * ! - Windows ticks (100ns since 01/01/0001)
5062
         * "..." - literal text
5063
         * '' - single quote
5064
         *
5065
         * @param  format string - the desired format of the date
5066
         * @param  date Date - the date value to format
5067
         * @param  settings Object - attributes include:
5068
         *                                        dayNamesShort        string[7] - abbreviated names of the days from Sunday (optional)
5069
         *                                        dayNames                string[7] - names of the days from Sunday (optional)
5070
         *                                        monthNamesShort string[12] - abbreviated names of the months (optional)
5071
         *                                        monthNames                string[12] - names of the months (optional)
5072
         * @return  string - the date in the above format
5073
         */
5074
        formatDate: function (format, date, settings) {
5075
                if (!date) {
5076
                        return "";
5077
                }
5078
5079
                var iFormat,
5080
                        dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
5081
                        dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
5082
                        monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
5083
                        monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
5084
                        // Check whether a format character is doubled
5085
                        lookAhead = function(match) {
5086
                                var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
5087
                                if (matches) {
5088
                                        iFormat++;
5089
                                }
5090
                                return matches;
5091
                        },
5092
                        // Format a number, with leading zero if necessary
5093
                        formatNumber = function(match, value, len) {
5094
                                var num = "" + value;
5095
                                if (lookAhead(match)) {
5096
                                        while (num.length < len) {
5097
                                                num = "0" + num;
5098
                                        }
5099
                                }
5100
                                return num;
5101
                        },
5102
                        // Format a name, short or long as requested
5103
                        formatName = function(match, value, shortNames, longNames) {
5104
                                return (lookAhead(match) ? longNames[value] : shortNames[value]);
5105
                        },
5106
                        output = "",
5107
                        literal = false;
5108
5109
                if (date) {
5110
                        for (iFormat = 0; iFormat < format.length; iFormat++) {
5111
                                if (literal) {
5112
                                        if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
5113
                                                literal = false;
5114
                                        } else {
5115
                                                output += format.charAt(iFormat);
5116
                                        }
5117
                                } else {
5118
                                        switch (format.charAt(iFormat)) {
5119
                                                case "d":
5120
                                                        output += formatNumber("d", date.getDate(), 2);
5121
                                                        break;
5122
                                                case "D":
5123
                                                        output += formatName("D", date.getDay(), dayNamesShort, dayNames);
5124
                                                        break;
5125
                                                case "o":
5126
                                                        output += formatNumber("o",
5127
                                                                Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
5128
                                                        break;
5129
                                                case "m":
5130
                                                        output += formatNumber("m", date.getMonth() + 1, 2);
5131
                                                        break;
5132
                                                case "M":
5133
                                                        output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
5134
                                                        break;
5135
                                                case "y":
5136
                                                        output += (lookAhead("y") ? date.getFullYear() :
5137
                                                                (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
5138
                                                        break;
5139
                                                case "@":
5140
                                                        output += date.getTime();
5141
                                                        break;
5142
                                                case "!":
5143
                                                        output += date.getTime() * 10000 + this._ticksTo1970;
5144
                                                        break;
5145
                                                case "'":
5146
                                                        if (lookAhead("'")) {
5147
                                                                output += "'";
5148
                                                        } else {
5149
                                                                literal = true;
5150
                                                        }
5151
                                                        break;
5152
                                                default:
5153
                                                        output += format.charAt(iFormat);
5154
                                        }
5155
                                }
5156
                        }
5157
                }
5158
                return output;
5159
        },
5160
5161
        /* Extract all possible characters from the date format. */
5162
        _possibleChars: function (format) {
5163
                var iFormat,
5164
                        chars = "",
5165
                        literal = false,
5166
                        // Check whether a format character is doubled
5167
                        lookAhead = function(match) {
5168
                                var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
5169
                                if (matches) {
5170
                                        iFormat++;
5171
                                }
5172
                                return matches;
5173
                        };
5174
5175
                for (iFormat = 0; iFormat < format.length; iFormat++) {
5176
                        if (literal) {
5177
                                if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
5178
                                        literal = false;
5179
                                } else {
5180
                                        chars += format.charAt(iFormat);
5181
                                }
5182
                        } else {
5183
                                switch (format.charAt(iFormat)) {
5184
                                        case "d": case "m": case "y": case "@":
5185
                                                chars += "0123456789";
5186
                                                break;
5187
                                        case "D": case "M":
5188
                                                return null; // Accept anything
5189
                                        case "'":
5190
                                                if (lookAhead("'")) {
5191
                                                        chars += "'";
5192
                                                } else {
5193
                                                        literal = true;
5194
                                                }
5195
                                                break;
5196
                                        default:
5197
                                                chars += format.charAt(iFormat);
5198
                                }
5199
                        }
5200
                }
5201
                return chars;
5202
        },
5203
5204
        /* Get a setting value, defaulting if necessary. */
5205
        _get: function(inst, name) {
5206
                return inst.settings[name] !== undefined ?
5207
                        inst.settings[name] : this._defaults[name];
5208
        },
5209
5210
        /* Parse existing date and initialise date picker. */
5211
        _setDateFromField: function(inst, noDefault) {
5212
                if (inst.input.val() === inst.lastVal) {
5213
                        return;
5214
                }
5215
5216
                var dateFormat = this._get(inst, "dateFormat"),
5217
                        dates = inst.lastVal = inst.input ? inst.input.val() : null,
5218
                        defaultDate = this._getDefaultDate(inst),
5219
                        date = defaultDate,
5220
                        settings = this._getFormatConfig(inst);
5221
5222
                try {
5223
                        date = this.parseDate(dateFormat, dates, settings) || defaultDate;
5224
                } catch (event) {
5225
                        dates = (noDefault ? "" : dates);
5226
                }
5227
                inst.selectedDay = date.getDate();
5228
                inst.drawMonth = inst.selectedMonth = date.getMonth();
5229
                inst.drawYear = inst.selectedYear = date.getFullYear();
5230
                inst.currentDay = (dates ? date.getDate() : 0);
5231
                inst.currentMonth = (dates ? date.getMonth() : 0);
5232
                inst.currentYear = (dates ? date.getFullYear() : 0);
5233
                this._adjustInstDate(inst);
5234
        },
5235
5236
        /* Retrieve the default date shown on opening. */
5237
        _getDefaultDate: function(inst) {
5238
                return this._restrictMinMax(inst,
5239
                        this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
5240
        },
5241
5242
        /* A date may be specified as an exact value or a relative one. */
5243
        _determineDate: function(inst, date, defaultDate) {
5244
                var offsetNumeric = function(offset) {
5245
                                var date = new Date();
5246
                                date.setDate(date.getDate() + offset);
5247
                                return date;
5248
                        },
5249
                        offsetString = function(offset) {
5250
                                try {
5251
                                        return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
5252
                                                offset, $.datepicker._getFormatConfig(inst));
5253
                                }
5254
                                catch (e) {
5255
                                        // Ignore
5256
                                }
5257
5258
                                var date = (offset.toLowerCase().match(/^c/) ?
5259
                                        $.datepicker._getDate(inst) : null) || new Date(),
5260
                                        year = date.getFullYear(),
5261
                                        month = date.getMonth(),
5262
                                        day = date.getDate(),
5263
                                        pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
5264
                                        matches = pattern.exec(offset);
5265
5266
                                while (matches) {
5267
                                        switch (matches[2] || "d") {
5268
                                                case "d" : case "D" :
5269
                                                        day += parseInt(matches[1],10); break;
5270
                                                case "w" : case "W" :
5271
                                                        day += parseInt(matches[1],10) * 7; break;
5272
                                                case "m" : case "M" :
5273
                                                        month += parseInt(matches[1],10);
5274
                                                        day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
5275
                                                        break;
5276
                                                case "y": case "Y" :
5277
                                                        year += parseInt(matches[1],10);
5278
                                                        day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
5279
                                                        break;
5280
                                        }
5281
                                        matches = pattern.exec(offset);
5282
                                }
5283
                                return new Date(year, month, day);
5284
                        },
5285
                        newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
5286
                                (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
5287
5288
                newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
5289
                if (newDate) {
5290
                        newDate.setHours(0);
5291
                        newDate.setMinutes(0);
5292
                        newDate.setSeconds(0);
5293
                        newDate.setMilliseconds(0);
5294
                }
5295
                return this._daylightSavingAdjust(newDate);
5296
        },
5297
5298
        /* Handle switch to/from daylight saving.
5299
         * Hours may be non-zero on daylight saving cut-over:
5300
         * > 12 when midnight changeover, but then cannot generate
5301
         * midnight datetime, so jump to 1AM, otherwise reset.
5302
         * @param  date  (Date) the date to check
5303
         * @return  (Date) the corrected date
5304
         */
5305
        _daylightSavingAdjust: function(date) {
5306
                if (!date) {
5307
                        return null;
5308
                }
5309
                date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
5310
                return date;
5311
        },
5312
5313
        /* Set the date(s) directly. */
5314
        _setDate: function(inst, date, noChange) {
5315
                var clear = !date,
5316
                        origMonth = inst.selectedMonth,
5317
                        origYear = inst.selectedYear,
5318
                        newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
5319
5320
                inst.selectedDay = inst.currentDay = newDate.getDate();
5321
                inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
5322
                inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
5323
                if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
5324
                        this._notifyChange(inst);
5325
                }
5326
                this._adjustInstDate(inst);
5327
                if (inst.input) {
5328
                        inst.input.val(clear ? "" : this._formatDate(inst));
5329
                }
5330
        },
5331
5332
        /* Retrieve the date(s) directly. */
5333
        _getDate: function(inst) {
5334
                var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
5335
                        this._daylightSavingAdjust(new Date(
5336
                        inst.currentYear, inst.currentMonth, inst.currentDay)));
5337
                        return startDate;
5338
        },
5339
5340
        /* Attach the onxxx handlers.  These are declared statically so
5341
         * they work with static code transformers like Caja.
5342
         */
5343
        _attachHandlers: function(inst) {
5344
                var stepMonths = this._get(inst, "stepMonths"),
5345
                        id = "#" + inst.id.replace( /\\\\/g, "\\" );
5346
                inst.dpDiv.find("[data-handler]").map(function () {
5347
                        var handler = {
5348
                                prev: function () {
5349
                                        $.datepicker._adjustDate(id, -stepMonths, "M");
5350
                                },
5351
                                next: function () {
5352
                                        $.datepicker._adjustDate(id, +stepMonths, "M");
5353
                                },
5354
                                hide: function () {
5355
                                        $.datepicker._hideDatepicker();
5356
                                },
5357
                                today: function () {
5358
                                        $.datepicker._gotoToday(id);
5359
                                },
5360
                                selectDay: function () {
5361
                                        $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
5362
                                        return false;
5363
                                },
5364
                                selectMonth: function () {
5365
                                        $.datepicker._selectMonthYear(id, this, "M");
5366
                                        return false;
5367
                                },
5368
                                selectYear: function () {
5369
                                        $.datepicker._selectMonthYear(id, this, "Y");
5370
                                        return false;
5371
                                }
5372
                        };
5373
                        $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
5374
                });
5375
        },
5376
5377
        /* Generate the HTML for the current state of the date picker. */
5378
        _generateHTML: function(inst) {
5379
                var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
5380
                        controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
5381
                        monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
5382
                        selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
5383
                        cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
5384
                        printDate, dRow, tbody, daySettings, otherMonth, unselectable,
5385
                        tempDate = new Date(),
5386
                        today = this._daylightSavingAdjust(
5387
                                new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
5388
                        isRTL = this._get(inst, "isRTL"),
5389
                        showButtonPanel = this._get(inst, "showButtonPanel"),
5390
                        hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
5391
                        navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
5392
                        numMonths = this._getNumberOfMonths(inst),
5393
                        showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
5394
                        stepMonths = this._get(inst, "stepMonths"),
5395
                        isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
5396
                        currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
5397
                                new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
5398
                        minDate = this._getMinMaxDate(inst, "min"),
5399
                        maxDate = this._getMinMaxDate(inst, "max"),
5400
                        drawMonth = inst.drawMonth - showCurrentAtPos,
5401
                        drawYear = inst.drawYear;
5402
5403
                if (drawMonth < 0) {
5404
                        drawMonth += 12;
5405
                        drawYear--;
5406
                }
5407
                if (maxDate) {
5408
                        maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
5409
                                maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
5410
                        maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
5411
                        while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
5412
                                drawMonth--;
5413
                                if (drawMonth < 0) {
5414
                                        drawMonth = 11;
5415
                                        drawYear--;
5416
                                }
5417
                        }
5418
                }
5419
                inst.drawMonth = drawMonth;
5420
                inst.drawYear = drawYear;
5421
5422
                prevText = this._get(inst, "prevText");
5423
                prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
5424
                        this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
5425
                        this._getFormatConfig(inst)));
5426
5427
                prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
5428
                        "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
5429
                        " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
5430
                        (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+ prevText +"'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>"));
5431
5432
                nextText = this._get(inst, "nextText");
5433
                nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
5434
                        this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
5435
                        this._getFormatConfig(inst)));
5436
5437
                next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
5438
                        "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
5439
                        " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
5440
                        (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+ nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>"));
5441
5442
                currentText = this._get(inst, "currentText");
5443
                gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
5444
                currentText = (!navigationAsDateFormat ? currentText :
5445
                        this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
5446
5447
                controls = (!inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" +
5448
                        this._get(inst, "closeText") + "</button>" : "");
5449
5450
                buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
5451
                        (this._isInRange(inst, gotoDate) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" +
5452
                        ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
5453
5454
                firstDay = parseInt(this._get(inst, "firstDay"),10);
5455
                firstDay = (isNaN(firstDay) ? 0 : firstDay);
5456
5457
                showWeek = this._get(inst, "showWeek");
5458
                dayNames = this._get(inst, "dayNames");
5459
                dayNamesMin = this._get(inst, "dayNamesMin");
5460
                monthNames = this._get(inst, "monthNames");
5461
                monthNamesShort = this._get(inst, "monthNamesShort");
5462
                beforeShowDay = this._get(inst, "beforeShowDay");
5463
                showOtherMonths = this._get(inst, "showOtherMonths");
5464
                selectOtherMonths = this._get(inst, "selectOtherMonths");
5465
                defaultDate = this._getDefaultDate(inst);
5466
                html = "";
5467
                dow;
5468
                for (row = 0; row < numMonths[0]; row++) {
5469
                        group = "";
5470
                        this.maxRows = 4;
5471
                        for (col = 0; col < numMonths[1]; col++) {
5472
                                selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
5473
                                cornerClass = " ui-corner-all";
5474
                                calender = "";
5475
                                if (isMultiMonth) {
5476
                                        calender += "<div class='ui-datepicker-group";
5477
                                        if (numMonths[1] > 1) {
5478
                                                switch (col) {
5479
                                                        case 0: calender += " ui-datepicker-group-first";
5480
                                                                cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
5481
                                                        case numMonths[1]-1: calender += " ui-datepicker-group-last";
5482
                                                                cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
5483
                                                        default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
5484
                                                }
5485
                                        }
5486
                                        calender += "'>";
5487
                                }
5488
                                calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
5489
                                        (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
5490
                                        (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
5491
                                        this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
5492
                                        row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
5493
                                        "</div><table class='ui-datepicker-calendar'><thead>" +
5494
                                        "<tr>";
5495
                                thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
5496
                                for (dow = 0; dow < 7; dow++) { // days of the week
5497
                                        day = (dow + firstDay) % 7;
5498
                                        thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
5499
                                                "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
5500
                                }
5501
                                calender += thead + "</tr></thead><tbody>";
5502
                                daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
5503
                                if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
5504
                                        inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
5505
                                }
5506
                                leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
5507
                                curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
5508
                                numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
5509
                                this.maxRows = numRows;
5510
                                printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
5511
                                for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
5512
                                        calender += "<tr>";
5513
                                        tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
5514
                                                this._get(inst, "calculateWeek")(printDate) + "</td>");
5515
                                        for (dow = 0; dow < 7; dow++) { // create date picker days
5516
                                                daySettings = (beforeShowDay ?
5517
                                                        beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
5518
                                                otherMonth = (printDate.getMonth() !== drawMonth);
5519
                                                unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
5520
                                                        (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
5521
                                                tbody += "<td class='" +
5522
                                                        ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
5523
                                                        (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
5524
                                                        ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
5525
                                                        (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
5526
                                                        // or defaultDate is current printedDate and defaultDate is selectedDate
5527
                                                        " " + this._dayOverClass : "") + // highlight selected day
5528
                                                        (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
5529
                                                        (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
5530
                                                        (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
5531
                                                        (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
5532
                                                        ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
5533
                                                        (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
5534
                                                        (otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
5535
                                                        (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
5536
                                                        (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
5537
                                                        (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
5538
                                                        (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
5539
                                                        "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
5540
                                                printDate.setDate(printDate.getDate() + 1);
5541
                                                printDate = this._daylightSavingAdjust(printDate);
5542
                                        }
5543
                                        calender += tbody + "</tr>";
5544
                                }
5545
                                drawMonth++;
5546
                                if (drawMonth > 11) {
5547
                                        drawMonth = 0;
5548
                                        drawYear++;
5549
                                }
5550
                                calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
5551
                                                        ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
5552
                                group += calender;
5553
                        }
5554
                        html += group;
5555
                }
5556
                html += buttonPanel;
5557
                inst._keyEvent = false;
5558
                return html;
5559
        },
5560
5561
        /* Generate the month and year header. */
5562
        _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
5563
                        secondary, monthNames, monthNamesShort) {
5564
5565
                var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
5566
                        changeMonth = this._get(inst, "changeMonth"),
5567
                        changeYear = this._get(inst, "changeYear"),
5568
                        showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
5569
                        html = "<div class='ui-datepicker-title'>",
5570
                        monthHtml = "";
5571
5572
                // month selection
5573
                if (secondary || !changeMonth) {
5574
                        monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
5575
                } else {
5576
                        inMinYear = (minDate && minDate.getFullYear() === drawYear);
5577
                        inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
5578
                        monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
5579
                        for ( month = 0; month < 12; month++) {
5580
                                if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
5581
                                        monthHtml += "<option value='" + month + "'" +
5582
                                                (month === drawMonth ? " selected='selected'" : "") +
5583
                                                ">" + monthNamesShort[month] + "</option>";
5584
                                }
5585
                        }
5586
                        monthHtml += "</select>";
5587
                }
5588
5589
                if (!showMonthAfterYear) {
5590
                        html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
5591
                }
5592
5593
                // year selection
5594
                if ( !inst.yearshtml ) {
5595
                        inst.yearshtml = "";
5596
                        if (secondary || !changeYear) {
5597
                                html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
5598
                        } else {
5599
                                // determine range of years to display
5600
                                years = this._get(inst, "yearRange").split(":");
5601
                                thisYear = new Date().getFullYear();
5602
                                determineYear = function(value) {
5603
                                        var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
5604
                                                (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
5605
                                                parseInt(value, 10)));
5606
                                        return (isNaN(year) ? thisYear : year);
5607
                                };
5608
                                year = determineYear(years[0]);
5609
                                endYear = Math.max(year, determineYear(years[1] || ""));
5610
                                year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
5611
                                endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
5612
                                inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
5613
                                for (; year <= endYear; year++) {
5614
                                        inst.yearshtml += "<option value='" + year + "'" +
5615
                                                (year === drawYear ? " selected='selected'" : "") +
5616
                                                ">" + year + "</option>";
5617
                                }
5618
                                inst.yearshtml += "</select>";
5619
5620
                                html += inst.yearshtml;
5621
                                inst.yearshtml = null;
5622
                        }
5623
                }
5624
5625
                html += this._get(inst, "yearSuffix");
5626
                if (showMonthAfterYear) {
5627
                        html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
5628
                }
5629
                html += "</div>"; // Close datepicker_header
5630
                return html;
5631
        },
5632
5633
        /* Adjust one of the date sub-fields. */
5634
        _adjustInstDate: function(inst, offset, period) {
5635
                var year = inst.drawYear + (period === "Y" ? offset : 0),
5636
                        month = inst.drawMonth + (period === "M" ? offset : 0),
5637
                        day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
5638
                        date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
5639
5640
                inst.selectedDay = date.getDate();
5641
                inst.drawMonth = inst.selectedMonth = date.getMonth();
5642
                inst.drawYear = inst.selectedYear = date.getFullYear();
5643
                if (period === "M" || period === "Y") {
5644
                        this._notifyChange(inst);
5645
                }
5646
        },
5647
5648
        /* Ensure a date is within any min/max bounds. */
5649
        _restrictMinMax: function(inst, date) {
5650
                var minDate = this._getMinMaxDate(inst, "min"),
5651
                        maxDate = this._getMinMaxDate(inst, "max"),
5652
                        newDate = (minDate && date < minDate ? minDate : date);
5653
                return (maxDate && newDate > maxDate ? maxDate : newDate);
5654
        },
5655
5656
        /* Notify change of month/year. */
5657
        _notifyChange: function(inst) {
5658
                var onChange = this._get(inst, "onChangeMonthYear");
5659
                if (onChange) {
5660
                        onChange.apply((inst.input ? inst.input[0] : null),
5661
                                [inst.selectedYear, inst.selectedMonth + 1, inst]);
5662
                }
5663
        },
5664
5665
        /* Determine the number of months to show. */
5666
        _getNumberOfMonths: function(inst) {
5667
                var numMonths = this._get(inst, "numberOfMonths");
5668
                return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
5669
        },
5670
5671
        /* Determine the current maximum date - ensure no time components are set. */
5672
        _getMinMaxDate: function(inst, minMax) {
5673
                return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
5674
        },
5675
5676
        /* Find the number of days in a given month. */
5677
        _getDaysInMonth: function(year, month) {
5678
                return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
5679
        },
5680
5681
        /* Find the day of the week of the first of a month. */
5682
        _getFirstDayOfMonth: function(year, month) {
5683
                return new Date(year, month, 1).getDay();
5684
        },
5685
5686
        /* Determines if we should allow a "next/prev" month display change. */
5687
        _canAdjustMonth: function(inst, offset, curYear, curMonth) {
5688
                var numMonths = this._getNumberOfMonths(inst),
5689
                        date = this._daylightSavingAdjust(new Date(curYear,
5690
                        curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
5691
5692
                if (offset < 0) {
5693
                        date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
5694
                }
5695
                return this._isInRange(inst, date);
5696
        },
5697
5698
        /* Is the given date in the accepted range? */
5699
        _isInRange: function(inst, date) {
5700
                var yearSplit, currentYear,
5701
                        minDate = this._getMinMaxDate(inst, "min"),
5702
                        maxDate = this._getMinMaxDate(inst, "max"),
5703
                        minYear = null,
5704
                        maxYear = null,
5705
                        years = this._get(inst, "yearRange");
5706
                        if (years){
5707
                                yearSplit = years.split(":");
5708
                                currentYear = new Date().getFullYear();
5709
                                minYear = parseInt(yearSplit[0], 10);
5710
                                maxYear = parseInt(yearSplit[1], 10);
5711
                                if ( yearSplit[0].match(/[+\-].*/) ) {
5712
                                        minYear += currentYear;
5713
                                }
5714
                                if ( yearSplit[1].match(/[+\-].*/) ) {
5715
                                        maxYear += currentYear;
5716
                                }
5717
                        }
5718
5719
                return ((!minDate || date.getTime() >= minDate.getTime()) &&
5720
                        (!maxDate || date.getTime() <= maxDate.getTime()) &&
5721
                        (!minYear || date.getFullYear() >= minYear) &&
5722
                        (!maxYear || date.getFullYear() <= maxYear));
5723
        },
5724
5725
        /* Provide the configuration settings for formatting/parsing. */
5726
        _getFormatConfig: function(inst) {
5727
                var shortYearCutoff = this._get(inst, "shortYearCutoff");
5728
                shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
5729
                        new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
5730
                return {shortYearCutoff: shortYearCutoff,
5731
                        dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
5732
                        monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
5733
        },
5734
5735
        /* Format the given date for display. */
5736
        _formatDate: function(inst, day, month, year) {
5737
                if (!day) {
5738
                        inst.currentDay = inst.selectedDay;
5739
                        inst.currentMonth = inst.selectedMonth;
5740
                        inst.currentYear = inst.selectedYear;
5741
                }
5742
                var date = (day ? (typeof day === "object" ? day :
5743
                        this._daylightSavingAdjust(new Date(year, month, day))) :
5744
                        this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
5745
                return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
5746
        }
5747
});
5748
5749
/*
5750
 * Bind hover events for datepicker elements.
5751
 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
5752
 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
5753
 */
5754
function datepicker_bindHover(dpDiv) {
5755
        var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
5756
        return dpDiv.delegate(selector, "mouseout", function() {
5757
                        $(this).removeClass("ui-state-hover");
5758
                        if (this.className.indexOf("ui-datepicker-prev") !== -1) {
5759
                                $(this).removeClass("ui-datepicker-prev-hover");
5760
                        }
5761
                        if (this.className.indexOf("ui-datepicker-next") !== -1) {
5762
                                $(this).removeClass("ui-datepicker-next-hover");
5763
                        }
5764
                })
5765
                .delegate( selector, "mouseover", datepicker_handleMouseover );
5766
}
5767
5768
function datepicker_handleMouseover() {
5769
        if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) {
5770
                $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
5771
                $(this).addClass("ui-state-hover");
5772
                if (this.className.indexOf("ui-datepicker-prev") !== -1) {
5773
                        $(this).addClass("ui-datepicker-prev-hover");
5774
                }
5775
                if (this.className.indexOf("ui-datepicker-next") !== -1) {
5776
                        $(this).addClass("ui-datepicker-next-hover");
5777
                }
5778
        }
5779
}
5780
5781
/* jQuery extend now ignores nulls! */
5782
function datepicker_extendRemove(target, props) {
5783
        $.extend(target, props);
5784
        for (var name in props) {
5785
                if (props[name] == null) {
5786
                        target[name] = props[name];
5787
                }
5788
        }
5789
        return target;
5790
}
5791
5792
/* Invoke the datepicker functionality.
5793
   @param  options  string - a command, optionally followed by additional parameters or
5794
                                        Object - settings for attaching new datepicker functionality
5795
   @return  jQuery object */
5796
$.fn.datepicker = function(options){
5797
5798
        /* Verify an empty collection wasn't passed - Fixes #6976 */
5799
        if ( !this.length ) {
5800
                return this;
5801
        }
5802
5803
        /* Initialise the date picker. */
5804
        if (!$.datepicker.initialized) {
5805
                $(document).mousedown($.datepicker._checkExternalClick);
5806
                $.datepicker.initialized = true;
5807
        }
5808
5809
        /* Append datepicker main container to body if not exist. */
5810
        if ($("#"+$.datepicker._mainDivId).length === 0) {
5811
                $("body").append($.datepicker.dpDiv);
5812
        }
5813
5814
        var otherArgs = Array.prototype.slice.call(arguments, 1);
5815
        if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
5816
                return $.datepicker["_" + options + "Datepicker"].
5817
                        apply($.datepicker, [this[0]].concat(otherArgs));
5818
        }
5819
        if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
5820
                return $.datepicker["_" + options + "Datepicker"].
5821
                        apply($.datepicker, [this[0]].concat(otherArgs));
5822
        }
5823
        return this.each(function() {
5824
                typeof options === "string" ?
5825
                        $.datepicker["_" + options + "Datepicker"].
5826
                                apply($.datepicker, [this].concat(otherArgs)) :
5827
                        $.datepicker._attachDatepicker(this, options);
5828
        });
5829
};
5830
5831
$.datepicker = new Datepicker(); // singleton instance
5832
$.datepicker.initialized = false;
5833
$.datepicker.uuid = new Date().getTime();
5834
$.datepicker.version = "1.11.4";
5835
5836
var datepicker = $.datepicker;
5837
5838
5839
/*!
5840
 * jQuery UI Draggable 1.11.4
5841
 * http://jqueryui.com
5842
 *
5843
 * Copyright jQuery Foundation and other contributors
5844
 * Released under the MIT license.
5845
 * http://jquery.org/license
5846
 *
5847
 * http://api.jqueryui.com/draggable/
5848
 */
5849
5850
5851
$.widget("ui.draggable", $.ui.mouse, {
5852
        version: "1.11.4",
5853
        widgetEventPrefix: "drag",
5854
        options: {
5855
                addClasses: true,
5856
                appendTo: "parent",
5857
                axis: false,
5858
                connectToSortable: false,
5859
                containment: false,
5860
                cursor: "auto",
5861
                cursorAt: false,
5862
                grid: false,
5863
                handle: false,
5864
                helper: "original",
5865
                iframeFix: false,
5866
                opacity: false,
5867
                refreshPositions: false,
5868
                revert: false,
5869
                revertDuration: 500,
5870
                scope: "default",
5871
                scroll: true,
5872
                scrollSensitivity: 20,
5873
                scrollSpeed: 20,
5874
                snap: false,
5875
                snapMode: "both",
5876
                snapTolerance: 20,
5877
                stack: false,
5878
                zIndex: false,
5879
5880
                // callbacks
5881
                drag: null,
5882
                start: null,
5883
                stop: null
5884
        },
5885
        _create: function() {
5886
5887
                if ( this.options.helper === "original" ) {
5888
                        this._setPositionRelative();
5889
                }
5890
                if (this.options.addClasses){
5891
                        this.element.addClass("ui-draggable");
5892
                }
5893
                if (this.options.disabled){
5894
                        this.element.addClass("ui-draggable-disabled");
5895
                }
5896
                this._setHandleClassName();
5897
5898
                this._mouseInit();
5899
        },
5900
5901
        _setOption: function( key, value ) {
5902
                this._super( key, value );
5903
                if ( key === "handle" ) {
5904
                        this._removeHandleClassName();
5905
                        this._setHandleClassName();
5906
                }
5907
        },
5908
5909
        _destroy: function() {
5910
                if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
5911
                        this.destroyOnClear = true;
5912
                        return;
5913
                }
5914
                this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
5915
                this._removeHandleClassName();
5916
                this._mouseDestroy();
5917
        },
5918
5919
        _mouseCapture: function(event) {
5920
                var o = this.options;
5921
5922
                this._blurActiveElement( event );
5923
5924
                // among others, prevent a drag on a resizable-handle
5925
                if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
5926
                        return false;
5927
                }
5928
5929
                //Quit if we're not on a valid handle
5930
                this.handle = this._getHandle(event);
5931
                if (!this.handle) {
5932
                        return false;
5933
                }
5934
5935
                this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
5936
5937
                return true;
5938
5939
        },
5940
5941
        _blockFrames: function( selector ) {
5942
                this.iframeBlocks = this.document.find( selector ).map(function() {
5943
                        var iframe = $( this );
5944
5945
                        return $( "<div>" )
5946
                                .css( "position", "absolute" )
5947
                                .appendTo( iframe.parent() )
5948
                                .outerWidth( iframe.outerWidth() )
5949
                                .outerHeight( iframe.outerHeight() )
5950
                                .offset( iframe.offset() )[ 0 ];
5951
                });
5952
        },
5953
5954
        _unblockFrames: function() {
5955
                if ( this.iframeBlocks ) {
5956
                        this.iframeBlocks.remove();
5957
                        delete this.iframeBlocks;
5958
                }
5959
        },
5960
5961
        _blurActiveElement: function( event ) {
5962
                var document = this.document[ 0 ];
5963
5964
                // Only need to blur if the event occurred on the draggable itself, see #10527
5965
                if ( !this.handleElement.is( event.target ) ) {
5966
                        return;
5967
                }
5968
5969
                // support: IE9
5970
                // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
5971
                try {
5972
5973
                        // Support: IE9, IE10
5974
                        // If the <body> is blurred, IE will switch windows, see #9520
5975
                        if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) {
5976
5977
                                // Blur any element that currently has focus, see #4261
5978
                                $( document.activeElement ).blur();
5979
                        }
5980
                } catch ( error ) {}
5981
        },
5982
5983
        _mouseStart: function(event) {
5984
5985
                var o = this.options;
5986
5987
                //Create and append the visible helper
5988
                this.helper = this._createHelper(event);
5989
5990
                this.helper.addClass("ui-draggable-dragging");
5991
5992
                //Cache the helper size
5993
                this._cacheHelperProportions();
5994
5995
                //If ddmanager is used for droppables, set the global draggable
5996
                if ($.ui.ddmanager) {
5997
                        $.ui.ddmanager.current = this;
5998
                }
5999
6000
                /*
6001
                 * - Position generation -
6002
                 * This block generates everything position related - it's the core of draggables.
6003
                 */
6004
6005
                //Cache the margins of the original element
6006
                this._cacheMargins();
6007
6008
                //Store the helper's css position
6009
                this.cssPosition = this.helper.css( "position" );
6010
                this.scrollParent = this.helper.scrollParent( true );
6011
                this.offsetParent = this.helper.offsetParent();
6012
                this.hasFixedAncestor = this.helper.parents().filter(function() {
6013
                                return $( this ).css( "position" ) === "fixed";
6014
                        }).length > 0;
6015
6016
                //The element's absolute position on the page minus margins
6017
                this.positionAbs = this.element.offset();
6018
                this._refreshOffsets( event );
6019
6020
                //Generate the original position
6021
                this.originalPosition = this.position = this._generatePosition( event, false );
6022
                this.originalPageX = event.pageX;
6023
                this.originalPageY = event.pageY;
6024
6025
                //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
6026
                (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
6027
6028
                //Set a containment if given in the options
6029
                this._setContainment();
6030
6031
                //Trigger event + callbacks
6032
                if (this._trigger("start", event) === false) {
6033
                        this._clear();
6034
                        return false;
6035
                }
6036
6037
                //Recache the helper size
6038
                this._cacheHelperProportions();
6039
6040
                //Prepare the droppable offsets
6041
                if ($.ui.ddmanager && !o.dropBehaviour) {
6042
                        $.ui.ddmanager.prepareOffsets(this, event);
6043
                }
6044
6045
                // Reset helper's right/bottom css if they're set and set explicit width/height instead
6046
                // as this prevents resizing of elements with right/bottom set (see #7772)
6047
                this._normalizeRightBottom();
6048
6049
                this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
6050
6051
                //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
6052
                if ( $.ui.ddmanager ) {
6053
                        $.ui.ddmanager.dragStart(this, event);
6054
                }
6055
6056
                return true;
6057
        },
6058
6059
        _refreshOffsets: function( event ) {
6060
                this.offset = {
6061
                        top: this.positionAbs.top - this.margins.top,
6062
                        left: this.positionAbs.left - this.margins.left,
6063
                        scroll: false,
6064
                        parent: this._getParentOffset(),
6065
                        relative: this._getRelativeOffset()
6066
                };
6067
6068
                this.offset.click = {
6069
                        left: event.pageX - this.offset.left,
6070
                        top: event.pageY - this.offset.top
6071
                };
6072
        },
6073
6074
        _mouseDrag: function(event, noPropagation) {
6075
                // reset any necessary cached properties (see #5009)
6076
                if ( this.hasFixedAncestor ) {
6077
                        this.offset.parent = this._getParentOffset();
6078
                }
6079
6080
                //Compute the helpers position
6081
                this.position = this._generatePosition( event, true );
6082
                this.positionAbs = this._convertPositionTo("absolute");
6083
6084
                //Call plugins and callbacks and use the resulting position if something is returned
6085
                if (!noPropagation) {
6086
                        var ui = this._uiHash();
6087
                        if (this._trigger("drag", event, ui) === false) {
6088
                                this._mouseUp({});
6089
                                return false;
6090
                        }
6091
                        this.position = ui.position;
6092
                }
6093
6094
                this.helper[ 0 ].style.left = this.position.left + "px";
6095
                this.helper[ 0 ].style.top = this.position.top + "px";
6096
6097
                if ($.ui.ddmanager) {
6098
                        $.ui.ddmanager.drag(this, event);
6099
                }
6100
6101
                return false;
6102
        },
6103
6104
        _mouseStop: function(event) {
6105
6106
                //If we are using droppables, inform the manager about the drop
6107
                var that = this,
6108
                        dropped = false;
6109
                if ($.ui.ddmanager && !this.options.dropBehaviour) {
6110
                        dropped = $.ui.ddmanager.drop(this, event);
6111
                }
6112
6113
                //if a drop comes from outside (a sortable)
6114
                if (this.dropped) {
6115
                        dropped = this.dropped;
6116
                        this.dropped = false;
6117
                }
6118
6119
                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))) {
6120
                        $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
6121
                                if (that._trigger("stop", event) !== false) {
6122
                                        that._clear();
6123
                                }
6124
                        });
6125
                } else {
6126
                        if (this._trigger("stop", event) !== false) {
6127
                                this._clear();
6128
                        }
6129
                }
6130
6131
                return false;
6132
        },
6133
6134
        _mouseUp: function( event ) {
6135
                this._unblockFrames();
6136
6137
                //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
6138
                if ( $.ui.ddmanager ) {
6139
                        $.ui.ddmanager.dragStop(this, event);
6140
                }
6141
6142
                // Only need to focus if the event occurred on the draggable itself, see #10527
6143
                if ( this.handleElement.is( event.target ) ) {
6144
                        // The interaction is over; whether or not the click resulted in a drag, focus the element
6145
                        this.element.focus();
6146
                }
6147
6148
                return $.ui.mouse.prototype._mouseUp.call(this, event);
6149
        },
6150
6151
        cancel: function() {
6152
6153
                if (this.helper.is(".ui-draggable-dragging")) {
6154
                        this._mouseUp({});
6155
                } else {
6156
                        this._clear();
6157
                }
6158
6159
                return this;
6160
6161
        },
6162
6163
        _getHandle: function(event) {
6164
                return this.options.handle ?
6165
                        !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
6166
                        true;
6167
        },
6168
6169
        _setHandleClassName: function() {
6170
                this.handleElement = this.options.handle ?
6171
                        this.element.find( this.options.handle ) : this.element;
6172
                this.handleElement.addClass( "ui-draggable-handle" );
6173
        },
6174
6175
        _removeHandleClassName: function() {
6176
                this.handleElement.removeClass( "ui-draggable-handle" );
6177
        },
6178
6179
        _createHelper: function(event) {
6180
6181
                var o = this.options,
6182
                        helperIsFunction = $.isFunction( o.helper ),
6183
                        helper = helperIsFunction ?
6184
                                $( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
6185
                                ( o.helper === "clone" ?
6186
                                        this.element.clone().removeAttr( "id" ) :
6187
                                        this.element );
6188
6189
                if (!helper.parents("body").length) {
6190
                        helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
6191
                }
6192
6193
                // http://bugs.jqueryui.com/ticket/9446
6194
                // a helper function can return the original element
6195
                // which wouldn't have been set to relative in _create
6196
                if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
6197
                        this._setPositionRelative();
6198
                }
6199
6200
                if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
6201
                        helper.css("position", "absolute");
6202
                }
6203
6204
                return helper;
6205
6206
        },
6207
6208
        _setPositionRelative: function() {
6209
                if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
6210
                        this.element[ 0 ].style.position = "relative";
6211
                }
6212
        },
6213
6214
        _adjustOffsetFromHelper: function(obj) {
6215
                if (typeof obj === "string") {
6216
                        obj = obj.split(" ");
6217
                }
6218
                if ($.isArray(obj)) {
6219
                        obj = { left: +obj[0], top: +obj[1] || 0 };
6220
                }
6221
                if ("left" in obj) {
6222
                        this.offset.click.left = obj.left + this.margins.left;
6223
                }
6224
                if ("right" in obj) {
6225
                        this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
6226
                }
6227
                if ("top" in obj) {
6228
                        this.offset.click.top = obj.top + this.margins.top;
6229
                }
6230
                if ("bottom" in obj) {
6231
                        this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
6232
                }
6233
        },
6234
6235
        _isRootNode: function( element ) {
6236
                return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
6237
        },
6238
6239
        _getParentOffset: function() {
6240
6241
                //Get the offsetParent and cache its position
6242
                var po = this.offsetParent.offset(),
6243
                        document = this.document[ 0 ];
6244
6245
                // This is a special case where we need to modify a offset calculated on start, since the following happened:
6246
                // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
6247
                // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
6248
                //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
6249
                if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
6250
                        po.left += this.scrollParent.scrollLeft();
6251
                        po.top += this.scrollParent.scrollTop();
6252
                }
6253
6254
                if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
6255
                        po = { top: 0, left: 0 };
6256
                }
6257
6258
                return {
6259
                        top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0),
6260
                        left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0)
6261
                };
6262
6263
        },
6264
6265
        _getRelativeOffset: function() {
6266
                if ( this.cssPosition !== "relative" ) {
6267
                        return { top: 0, left: 0 };
6268
                }
6269
6270
                var p = this.element.position(),
6271
                        scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
6272
6273
                return {
6274
                        top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
6275
                        left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
6276
                };
6277
6278
        },
6279
6280
        _cacheMargins: function() {
6281
                this.margins = {
6282
                        left: (parseInt(this.element.css("marginLeft"), 10) || 0),
6283
                        top: (parseInt(this.element.css("marginTop"), 10) || 0),
6284
                        right: (parseInt(this.element.css("marginRight"), 10) || 0),
6285
                        bottom: (parseInt(this.element.css("marginBottom"), 10) || 0)
6286
                };
6287
        },
6288
6289
        _cacheHelperProportions: function() {
6290
                this.helperProportions = {
6291
                        width: this.helper.outerWidth(),
6292
                        height: this.helper.outerHeight()
6293
                };
6294
        },
6295
6296
        _setContainment: function() {
6297
6298
                var isUserScrollable, c, ce,
6299
                        o = this.options,
6300
                        document = this.document[ 0 ];
6301
6302
                this.relativeContainer = null;
6303
6304
                if ( !o.containment ) {
6305
                        this.containment = null;
6306
                        return;
6307
                }
6308
6309
                if ( o.containment === "window" ) {
6310
                        this.containment = [
6311
                                $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
6312
                                $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
6313
                                $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
6314
                                $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
6315
                        ];
6316
                        return;
6317
                }
6318
6319
                if ( o.containment === "document") {
6320
                        this.containment = [
6321
                                0,
6322
                                0,
6323
                                $( document ).width() - this.helperProportions.width - this.margins.left,
6324
                                ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
6325
                        ];
6326
                        return;
6327
                }
6328
6329
                if ( o.containment.constructor === Array ) {
6330
                        this.containment = o.containment;
6331
                        return;
6332
                }
6333
6334
                if ( o.containment === "parent" ) {
6335
                        o.containment = this.helper[ 0 ].parentNode;
6336
                }
6337
6338
                c = $( o.containment );
6339
                ce = c[ 0 ];
6340
6341
                if ( !ce ) {
6342
                        return;
6343
                }
6344
6345
                isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
6346
6347
                this.containment = [
6348
                        ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
6349
                        ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
6350
                        ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
6351
                                ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
6352
                                ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
6353
                                this.helperProportions.width -
6354
                                this.margins.left -
6355
                                this.margins.right,
6356
                        ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
6357
                                ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
6358
                                ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
6359
                                this.helperProportions.height -
6360
                                this.margins.top -
6361
                                this.margins.bottom
6362
                ];
6363
                this.relativeContainer = c;
6364
        },
6365
6366
        _convertPositionTo: function(d, pos) {
6367
6368
                if (!pos) {
6369
                        pos = this.position;
6370
                }
6371
6372
                var mod = d === "absolute" ? 1 : -1,
6373
                        scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
6374
6375
                return {
6376
                        top: (
6377
                                pos.top        +                                                                                                                                // The absolute mouse position
6378
                                this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
6379
                                this.offset.parent.top * mod -                                                                                // The offsetParent's offset without borders (offset + border)
6380
                                ( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)
6381
                        ),
6382
                        left: (
6383
                                pos.left +                                                                                                                                // The absolute mouse position
6384
                                this.offset.relative.left * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
6385
                                this.offset.parent.left * mod        -                                                                                // The offsetParent's offset without borders (offset + border)
6386
                                ( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod)
6387
                        )
6388
                };
6389
6390
        },
6391
6392
        _generatePosition: function( event, constrainPosition ) {
6393
6394
                var containment, co, top, left,
6395
                        o = this.options,
6396
                        scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
6397
                        pageX = event.pageX,
6398
                        pageY = event.pageY;
6399
6400
                // Cache the scroll
6401
                if ( !scrollIsRootNode || !this.offset.scroll ) {
6402
                        this.offset.scroll = {
6403
                                top: this.scrollParent.scrollTop(),
6404
                                left: this.scrollParent.scrollLeft()
6405
                        };
6406
                }
6407
6408
                /*
6409
                 * - Position constraining -
6410
                 * Constrain the position to a mix of grid, containment.
6411
                 */
6412
6413
                // If we are not dragging yet, we won't check for options
6414
                if ( constrainPosition ) {
6415
                        if ( this.containment ) {
6416
                                if ( this.relativeContainer ){
6417
                                        co = this.relativeContainer.offset();
6418
                                        containment = [
6419
                                                this.containment[ 0 ] + co.left,
6420
                                                this.containment[ 1 ] + co.top,
6421
                                                this.containment[ 2 ] + co.left,
6422
                                                this.containment[ 3 ] + co.top
6423
                                        ];
6424
                                } else {
6425
                                        containment = this.containment;
6426
                                }
6427
6428
                                if (event.pageX - this.offset.click.left < containment[0]) {
6429
                                        pageX = containment[0] + this.offset.click.left;
6430
                                }
6431
                                if (event.pageY - this.offset.click.top < containment[1]) {
6432
                                        pageY = containment[1] + this.offset.click.top;
6433
                                }
6434
                                if (event.pageX - this.offset.click.left > containment[2]) {
6435
                                        pageX = containment[2] + this.offset.click.left;
6436
                                }
6437
                                if (event.pageY - this.offset.click.top > containment[3]) {
6438
                                        pageY = containment[3] + this.offset.click.top;
6439
                                }
6440
                        }
6441
6442
                        if (o.grid) {
6443
                                //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
6444
                                top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
6445
                                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;
6446
6447
                                left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
6448
                                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;
6449
                        }
6450
6451
                        if ( o.axis === "y" ) {
6452
                                pageX = this.originalPageX;
6453
                        }
6454
6455
                        if ( o.axis === "x" ) {
6456
                                pageY = this.originalPageY;
6457
                        }
6458
                }
6459
6460
                return {
6461
                        top: (
6462
                                pageY -                                                                                                                                        // The absolute mouse position
6463
                                this.offset.click.top        -                                                                                                // Click offset (relative to the element)
6464
                                this.offset.relative.top -                                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
6465
                                this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
6466
                                ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
6467
                        ),
6468
                        left: (
6469
                                pageX -                                                                                                                                        // The absolute mouse position
6470
                                this.offset.click.left -                                                                                                // Click offset (relative to the element)
6471
                                this.offset.relative.left -                                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
6472
                                this.offset.parent.left +                                                                                                // The offsetParent's offset without borders (offset + border)
6473
                                ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
6474
                        )
6475
                };
6476
6477
        },
6478
6479
        _clear: function() {
6480
                this.helper.removeClass("ui-draggable-dragging");
6481
                if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
6482
                        this.helper.remove();
6483
                }
6484
                this.helper = null;
6485
                this.cancelHelperRemoval = false;
6486
                if ( this.destroyOnClear ) {
6487
                        this.destroy();
6488
                }
6489
        },
6490
6491
        _normalizeRightBottom: function() {
6492
                if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) {
6493
                        this.helper.width( this.helper.width() );
6494
                        this.helper.css( "right", "auto" );
6495
                }
6496
                if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) {
6497
                        this.helper.height( this.helper.height() );
6498
                        this.helper.css( "bottom", "auto" );
6499
                }
6500
        },
6501
6502
        // From now on bulk stuff - mainly helpers
6503
6504
        _trigger: function( type, event, ui ) {
6505
                ui = ui || this._uiHash();
6506
                $.ui.plugin.call( this, type, [ event, ui, this ], true );
6507
6508
                // Absolute position and offset (see #6884 ) have to be recalculated after plugins
6509
                if ( /^(drag|start|stop)/.test( type ) ) {
6510
                        this.positionAbs = this._convertPositionTo( "absolute" );
6511
                        ui.offset = this.positionAbs;
6512
                }
6513
                return $.Widget.prototype._trigger.call( this, type, event, ui );
6514
        },
6515
6516
        plugins: {},
6517
6518
        _uiHash: function() {
6519
                return {
6520
                        helper: this.helper,
6521
                        position: this.position,
6522
                        originalPosition: this.originalPosition,
6523
                        offset: this.positionAbs
6524
                };
6525
        }
6526
6527
});
6528
6529
$.ui.plugin.add( "draggable", "connectToSortable", {
6530
        start: function( event, ui, draggable ) {
6531
                var uiSortable = $.extend( {}, ui, {
6532
                        item: draggable.element
6533
                });
6534
6535
                draggable.sortables = [];
6536
                $( draggable.options.connectToSortable ).each(function() {
6537
                        var sortable = $( this ).sortable( "instance" );
6538
6539
                        if ( sortable && !sortable.options.disabled ) {
6540
                                draggable.sortables.push( sortable );
6541
6542
                                // refreshPositions is called at drag start to refresh the containerCache
6543
                                // which is used in drag. This ensures it's initialized and synchronized
6544
                                // with any changes that might have happened on the page since initialization.
6545
                                sortable.refreshPositions();
6546
                                sortable._trigger("activate", event, uiSortable);
6547
                        }
6548
                });
6549
        },
6550
        stop: function( event, ui, draggable ) {
6551
                var uiSortable = $.extend( {}, ui, {
6552
                        item: draggable.element
6553
                });
6554
6555
                draggable.cancelHelperRemoval = false;
6556
6557
                $.each( draggable.sortables, function() {
6558
                        var sortable = this;
6559
6560
                        if ( sortable.isOver ) {
6561
                                sortable.isOver = 0;
6562
6563
                                // Allow this sortable to handle removing the helper
6564
                                draggable.cancelHelperRemoval = true;
6565
                                sortable.cancelHelperRemoval = false;
6566
6567
                                // Use _storedCSS To restore properties in the sortable,
6568
                                // as this also handles revert (#9675) since the draggable
6569
                                // may have modified them in unexpected ways (#8809)
6570
                                sortable._storedCSS = {
6571
                                        position: sortable.placeholder.css( "position" ),
6572
                                        top: sortable.placeholder.css( "top" ),
6573
                                        left: sortable.placeholder.css( "left" )
6574
                                };
6575
6576
                                sortable._mouseStop(event);
6577
6578
                                // Once drag has ended, the sortable should return to using
6579
                                // its original helper, not the shared helper from draggable
6580
                                sortable.options.helper = sortable.options._helper;
6581
                        } else {
6582
                                // Prevent this Sortable from removing the helper.
6583
                                // However, don't set the draggable to remove the helper
6584
                                // either as another connected Sortable may yet handle the removal.
6585
                                sortable.cancelHelperRemoval = true;
6586
6587
                                sortable._trigger( "deactivate", event, uiSortable );
6588
                        }
6589
                });
6590
        },
6591
        drag: function( event, ui, draggable ) {
6592
                $.each( draggable.sortables, function() {
6593
                        var innermostIntersecting = false,
6594
                                sortable = this;
6595
6596
                        // Copy over variables that sortable's _intersectsWith uses
6597
                        sortable.positionAbs = draggable.positionAbs;
6598
                        sortable.helperProportions = draggable.helperProportions;
6599
                        sortable.offset.click = draggable.offset.click;
6600
6601
                        if ( sortable._intersectsWith( sortable.containerCache ) ) {
6602
                                innermostIntersecting = true;
6603
6604
                                $.each( draggable.sortables, function() {
6605
                                        // Copy over variables that sortable's _intersectsWith uses
6606
                                        this.positionAbs = draggable.positionAbs;
6607
                                        this.helperProportions = draggable.helperProportions;
6608
                                        this.offset.click = draggable.offset.click;
6609
6610
                                        if ( this !== sortable &&
6611
                                                        this._intersectsWith( this.containerCache ) &&
6612
                                                        $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
6613
                                                innermostIntersecting = false;
6614
                                        }
6615
6616
                                        return innermostIntersecting;
6617
                                });
6618
                        }
6619
6620
                        if ( innermostIntersecting ) {
6621
                                // If it intersects, we use a little isOver variable and set it once,
6622
                                // so that the move-in stuff gets fired only once.
6623
                                if ( !sortable.isOver ) {
6624
                                        sortable.isOver = 1;
6625
6626
                                        // Store draggable's parent in case we need to reappend to it later.
6627
                                        draggable._parent = ui.helper.parent();
6628
6629
                                        sortable.currentItem = ui.helper
6630
                                                .appendTo( sortable.element )
6631
                                                .data( "ui-sortable-item", true );
6632
6633
                                        // Store helper option to later restore it
6634
                                        sortable.options._helper = sortable.options.helper;
6635
6636
                                        sortable.options.helper = function() {
6637
                                                return ui.helper[ 0 ];
6638
                                        };
6639
6640
                                        // Fire the start events of the sortable with our passed browser event,
6641
                                        // and our own helper (so it doesn't create a new one)
6642
                                        event.target = sortable.currentItem[ 0 ];
6643
                                        sortable._mouseCapture( event, true );
6644
                                        sortable._mouseStart( event, true, true );
6645
6646
                                        // Because the browser event is way off the new appended portlet,
6647
                                        // modify necessary variables to reflect the changes
6648
                                        sortable.offset.click.top = draggable.offset.click.top;
6649
                                        sortable.offset.click.left = draggable.offset.click.left;
6650
                                        sortable.offset.parent.left -= draggable.offset.parent.left -
6651
                                                sortable.offset.parent.left;
6652
                                        sortable.offset.parent.top -= draggable.offset.parent.top -
6653
                                                sortable.offset.parent.top;
6654
6655
                                        draggable._trigger( "toSortable", event );
6656
6657
                                        // Inform draggable that the helper is in a valid drop zone,
6658
                                        // used solely in the revert option to handle "valid/invalid".
6659
                                        draggable.dropped = sortable.element;
6660
6661
                                        // Need to refreshPositions of all sortables in the case that
6662
                                        // adding to one sortable changes the location of the other sortables (#9675)
6663
                                        $.each( draggable.sortables, function() {
6664
                                                this.refreshPositions();
6665
                                        });
6666
6667
                                        // hack so receive/update callbacks work (mostly)
6668
                                        draggable.currentItem = draggable.element;
6669
                                        sortable.fromOutside = draggable;
6670
                                }
6671
6672
                                if ( sortable.currentItem ) {
6673
                                        sortable._mouseDrag( event );
6674
                                        // Copy the sortable's position because the draggable's can potentially reflect
6675
                                        // a relative position, while sortable is always absolute, which the dragged
6676
                                        // element has now become. (#8809)
6677
                                        ui.position = sortable.position;
6678
                                }
6679
                        } else {
6680
                                // If it doesn't intersect with the sortable, and it intersected before,
6681
                                // we fake the drag stop of the sortable, but make sure it doesn't remove
6682
                                // the helper by using cancelHelperRemoval.
6683
                                if ( sortable.isOver ) {
6684
6685
                                        sortable.isOver = 0;
6686
                                        sortable.cancelHelperRemoval = true;
6687
6688
                                        // Calling sortable's mouseStop would trigger a revert,
6689
                                        // so revert must be temporarily false until after mouseStop is called.
6690
                                        sortable.options._revert = sortable.options.revert;
6691
                                        sortable.options.revert = false;
6692
6693
                                        sortable._trigger( "out", event, sortable._uiHash( sortable ) );
6694
                                        sortable._mouseStop( event, true );
6695
6696
                                        // restore sortable behaviors that were modfied
6697
                                        // when the draggable entered the sortable area (#9481)
6698
                                        sortable.options.revert = sortable.options._revert;
6699
                                        sortable.options.helper = sortable.options._helper;
6700
6701
                                        if ( sortable.placeholder ) {
6702
                                                sortable.placeholder.remove();
6703
                                        }
6704
6705
                                        // Restore and recalculate the draggable's offset considering the sortable
6706
                                        // may have modified them in unexpected ways. (#8809, #10669)
6707
                                        ui.helper.appendTo( draggable._parent );
6708
                                        draggable._refreshOffsets( event );
6709
                                        ui.position = draggable._generatePosition( event, true );
6710
6711
                                        draggable._trigger( "fromSortable", event );
6712
6713
                                        // Inform draggable that the helper is no longer in a valid drop zone
6714
                                        draggable.dropped = false;
6715
6716
                                        // Need to refreshPositions of all sortables just in case removing
6717
                                        // from one sortable changes the location of other sortables (#9675)
6718
                                        $.each( draggable.sortables, function() {
6719
                                                this.refreshPositions();
6720
                                        });
6721
                                }
6722
                        }
6723
                });
6724
        }
6725
});
6726
6727
$.ui.plugin.add("draggable", "cursor", {
6728
        start: function( event, ui, instance ) {
6729
                var t = $( "body" ),
6730
                        o = instance.options;
6731
6732
                if (t.css("cursor")) {
6733
                        o._cursor = t.css("cursor");
6734
                }
6735
                t.css("cursor", o.cursor);
6736
        },
6737
        stop: function( event, ui, instance ) {
6738
                var o = instance.options;
6739
                if (o._cursor) {
6740
                        $("body").css("cursor", o._cursor);
6741
                }
6742
        }
6743
});
6744
6745
$.ui.plugin.add("draggable", "opacity", {
6746
        start: function( event, ui, instance ) {
6747
                var t = $( ui.helper ),
6748
                        o = instance.options;
6749
                if (t.css("opacity")) {
6750
                        o._opacity = t.css("opacity");
6751
                }
6752
                t.css("opacity", o.opacity);
6753
        },
6754
        stop: function( event, ui, instance ) {
6755
                var o = instance.options;
6756
                if (o._opacity) {
6757
                        $(ui.helper).css("opacity", o._opacity);
6758
                }
6759
        }
6760
});
6761
6762
$.ui.plugin.add("draggable", "scroll", {
6763
        start: function( event, ui, i ) {
6764
                if ( !i.scrollParentNotHidden ) {
6765
                        i.scrollParentNotHidden = i.helper.scrollParent( false );
6766
                }
6767
6768
                if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
6769
                        i.overflowOffset = i.scrollParentNotHidden.offset();
6770
                }
6771
        },
6772
        drag: function( event, ui, i  ) {
6773
6774
                var o = i.options,
6775
                        scrolled = false,
6776
                        scrollParent = i.scrollParentNotHidden[ 0 ],
6777
                        document = i.document[ 0 ];
6778
6779
                if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
6780
                        if ( !o.axis || o.axis !== "x" ) {
6781
                                if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) {
6782
                                        scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
6783
                                } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
6784
                                        scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
6785
                                }
6786
                        }
6787
6788
                        if ( !o.axis || o.axis !== "y" ) {
6789
                                if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) {
6790
                                        scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
6791
                                } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
6792
                                        scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
6793
                                }
6794
                        }
6795
6796
                } else {
6797
6798
                        if (!o.axis || o.axis !== "x") {
6799
                                if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
6800
                                        scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
6801
                                } else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
6802
                                        scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
6803
                                }
6804
                        }
6805
6806
                        if (!o.axis || o.axis !== "y") {
6807
                                if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
6808
                                        scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
6809
                                } else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
6810
                                        scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
6811
                                }
6812
                        }
6813
6814
                }
6815
6816
                if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
6817
                        $.ui.ddmanager.prepareOffsets(i, event);
6818
                }
6819
6820
        }
6821
});
6822
6823
$.ui.plugin.add("draggable", "snap", {
6824
        start: function( event, ui, i ) {
6825
6826
                var o = i.options;
6827
6828
                i.snapElements = [];
6829
6830
                $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
6831
                        var $t = $(this),
6832
                                $o = $t.offset();
6833
                        if (this !== i.element[0]) {
6834
                                i.snapElements.push({
6835
                                        item: this,
6836
                                        width: $t.outerWidth(), height: $t.outerHeight(),
6837
                                        top: $o.top, left: $o.left
6838
                                });
6839
                        }
6840
                });
6841
6842
        },
6843
        drag: function( event, ui, inst ) {
6844
6845
                var ts, bs, ls, rs, l, r, t, b, i, first,
6846
                        o = inst.options,
6847
                        d = o.snapTolerance,
6848
                        x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
6849
                        y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
6850
6851
                for (i = inst.snapElements.length - 1; i >= 0; i--){
6852
6853
                        l = inst.snapElements[i].left - inst.margins.left;
6854
                        r = l + inst.snapElements[i].width;
6855
                        t = inst.snapElements[i].top - inst.margins.top;
6856
                        b = t + inst.snapElements[i].height;
6857
6858
                        if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
6859
                                if (inst.snapElements[i].snapping) {
6860
                                        (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
6861
                                }
6862
                                inst.snapElements[i].snapping = false;
6863
                                continue;
6864
                        }
6865
6866
                        if (o.snapMode !== "inner") {
6867
                                ts = Math.abs(t - y2) <= d;
6868
                                bs = Math.abs(b - y1) <= d;
6869
                                ls = Math.abs(l - x2) <= d;
6870
                                rs = Math.abs(r - x1) <= d;
6871
                                if (ts) {
6872
                                        ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top;
6873
                                }
6874
                                if (bs) {
6875
                                        ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top;
6876
                                }
6877
                                if (ls) {
6878
                                        ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left;
6879
                                }
6880
                                if (rs) {
6881
                                        ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left;
6882
                                }
6883
                        }
6884
6885
                        first = (ts || bs || ls || rs);
6886
6887
                        if (o.snapMode !== "outer") {
6888
                                ts = Math.abs(t - y1) <= d;
6889
                                bs = Math.abs(b - y2) <= d;
6890
                                ls = Math.abs(l - x1) <= d;
6891
                                rs = Math.abs(r - x2) <= d;
6892
                                if (ts) {
6893
                                        ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top;
6894
                                }
6895
                                if (bs) {
6896
                                        ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top;
6897
                                }
6898
                                if (ls) {
6899
                                        ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left;
6900
                                }
6901
                                if (rs) {
6902
                                        ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left;
6903
                                }
6904
                        }
6905
6906
                        if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
6907
                                (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
6908
                        }
6909
                        inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
6910
6911
                }
6912
6913
        }
6914
});
6915
6916
$.ui.plugin.add("draggable", "stack", {
6917
        start: function( event, ui, instance ) {
6918
                var min,
6919
                        o = instance.options,
6920
                        group = $.makeArray($(o.stack)).sort(function(a, b) {
6921
                                return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0);
6922
                        });
6923
6924
                if (!group.length) { return; }
6925
6926
                min = parseInt($(group[0]).css("zIndex"), 10) || 0;
6927
                $(group).each(function(i) {
6928
                        $(this).css("zIndex", min + i);
6929
                });
6930
                this.css("zIndex", (min + group.length));
6931
        }
6932
});
6933
6934
$.ui.plugin.add("draggable", "zIndex", {
6935
        start: function( event, ui, instance ) {
6936
                var t = $( ui.helper ),
6937
                        o = instance.options;
6938
6939
                if (t.css("zIndex")) {
6940
                        o._zIndex = t.css("zIndex");
6941
                }
6942
                t.css("zIndex", o.zIndex);
6943
        },
6944
        stop: function( event, ui, instance ) {
6945
                var o = instance.options;
6946
6947
                if (o._zIndex) {
6948
                        $(ui.helper).css("zIndex", o._zIndex);
6949
                }
6950
        }
6951
});
6952
6953
var draggable = $.ui.draggable;
6954
6955
6956
/*!
6957
 * jQuery UI Resizable 1.11.4
6958
 * http://jqueryui.com
6959
 *
6960
 * Copyright jQuery Foundation and other contributors
6961
 * Released under the MIT license.
6962
 * http://jquery.org/license
6963
 *
6964
 * http://api.jqueryui.com/resizable/
6965
 */
6966
6967
6968
$.widget("ui.resizable", $.ui.mouse, {
6969
        version: "1.11.4",
6970
        widgetEventPrefix: "resize",
6971
        options: {
6972
                alsoResize: false,
6973
                animate: false,
6974
                animateDuration: "slow",
6975
                animateEasing: "swing",
6976
                aspectRatio: false,
6977
                autoHide: false,
6978
                containment: false,
6979
                ghost: false,
6980
                grid: false,
6981
                handles: "e,s,se",
6982
                helper: false,
6983
                maxHeight: null,
6984
                maxWidth: null,
6985
                minHeight: 10,
6986
                minWidth: 10,
6987
                // See #7960
6988
                zIndex: 90,
6989
6990
                // callbacks
6991
                resize: null,
6992
                start: null,
6993
                stop: null
6994
        },
6995
6996
        _num: function( value ) {
6997
                return parseInt( value, 10 ) || 0;
6998
        },
6999
7000
        _isNumber: function( value ) {
7001
                return !isNaN( parseInt( value, 10 ) );
7002
        },
7003
7004
        _hasScroll: function( el, a ) {
7005
7006
                if ( $( el ).css( "overflow" ) === "hidden") {
7007
                        return false;
7008
                }
7009
7010
                var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
7011
                        has = false;
7012
7013
                if ( el[ scroll ] > 0 ) {
7014
                        return true;
7015
                }
7016
7017
                // TODO: determine which cases actually cause this to happen
7018
                // if the element doesn't have the scroll set, see if it's possible to
7019
                // set the scroll
7020
                el[ scroll ] = 1;
7021
                has = ( el[ scroll ] > 0 );
7022
                el[ scroll ] = 0;
7023
                return has;
7024
        },
7025
7026
        _create: function() {
7027
7028
                var n, i, handle, axis, hname,
7029
                        that = this,
7030
                        o = this.options;
7031
                this.element.addClass("ui-resizable");
7032
7033
                $.extend(this, {
7034
                        _aspectRatio: !!(o.aspectRatio),
7035
                        aspectRatio: o.aspectRatio,
7036
                        originalElement: this.element,
7037
                        _proportionallyResizeElements: [],
7038
                        _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
7039
                });
7040
7041
                // Wrap the element if it cannot hold child nodes
7042
                if (this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)) {
7043
7044
                        this.element.wrap(
7045
                                $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
7046
                                        position: this.element.css("position"),
7047
                                        width: this.element.outerWidth(),
7048
                                        height: this.element.outerHeight(),
7049
                                        top: this.element.css("top"),
7050
                                        left: this.element.css("left")
7051
                                })
7052
                        );
7053
7054
                        this.element = this.element.parent().data(
7055
                                "ui-resizable", this.element.resizable( "instance" )
7056
                        );
7057
7058
                        this.elementIsWrapper = true;
7059
7060
                        this.element.css({
7061
                                marginLeft: this.originalElement.css("marginLeft"),
7062
                                marginTop: this.originalElement.css("marginTop"),
7063
                                marginRight: this.originalElement.css("marginRight"),
7064
                                marginBottom: this.originalElement.css("marginBottom")
7065
                        });
7066
                        this.originalElement.css({
7067
                                marginLeft: 0,
7068
                                marginTop: 0,
7069
                                marginRight: 0,
7070
                                marginBottom: 0
7071
                        });
7072
                        // support: Safari
7073
                        // Prevent Safari textarea resize
7074
                        this.originalResizeStyle = this.originalElement.css("resize");
7075
                        this.originalElement.css("resize", "none");
7076
7077
                        this._proportionallyResizeElements.push( this.originalElement.css({
7078
                                position: "static",
7079
                                zoom: 1,
7080
                                display: "block"
7081
                        }) );
7082
7083
                        // support: IE9
7084
                        // avoid IE jump (hard set the margin)
7085
                        this.originalElement.css({ margin: this.originalElement.css("margin") });
7086
7087
                        this._proportionallyResize();
7088
                }
7089
7090
                this.handles = o.handles ||
7091
                        ( !$(".ui-resizable-handle", this.element).length ?
7092
                                "e,s,se" : {
7093
                                        n: ".ui-resizable-n",
7094
                                        e: ".ui-resizable-e",
7095
                                        s: ".ui-resizable-s",
7096
                                        w: ".ui-resizable-w",
7097
                                        se: ".ui-resizable-se",
7098
                                        sw: ".ui-resizable-sw",
7099
                                        ne: ".ui-resizable-ne",
7100
                                        nw: ".ui-resizable-nw"
7101
                                } );
7102
7103
                this._handles = $();
7104
                if ( this.handles.constructor === String ) {
7105
7106
                        if ( this.handles === "all") {
7107
                                this.handles = "n,e,s,w,se,sw,ne,nw";
7108
                        }
7109
7110
                        n = this.handles.split(",");
7111
                        this.handles = {};
7112
7113
                        for (i = 0; i < n.length; i++) {
7114
7115
                                handle = $.trim(n[i]);
7116
                                hname = "ui-resizable-" + handle;
7117
                                axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
7118
7119
                                axis.css({ zIndex: o.zIndex });
7120
7121
                                // TODO : What's going on here?
7122
                                if ("se" === handle) {
7123
                                        axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
7124
                                }
7125
7126
                                this.handles[handle] = ".ui-resizable-" + handle;
7127
                                this.element.append(axis);
7128
                        }
7129
7130
                }
7131
7132
                this._renderAxis = function(target) {
7133
7134
                        var i, axis, padPos, padWrapper;
7135
7136
                        target = target || this.element;
7137
7138
                        for (i in this.handles) {
7139
7140
                                if (this.handles[i].constructor === String) {
7141
                                        this.handles[i] = this.element.children( this.handles[ i ] ).first().show();
7142
                                } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
7143
                                        this.handles[ i ] = $( this.handles[ i ] );
7144
                                        this._on( this.handles[ i ], { "mousedown": that._mouseDown });
7145
                                }
7146
7147
                                if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)) {
7148
7149
                                        axis = $(this.handles[i], this.element);
7150
7151
                                        padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
7152
7153
                                        padPos = [ "padding",
7154
                                                /ne|nw|n/.test(i) ? "Top" :
7155
                                                /se|sw|s/.test(i) ? "Bottom" :
7156
                                                /^e$/.test(i) ? "Right" : "Left" ].join("");
7157
7158
                                        target.css(padPos, padWrapper);
7159
7160
                                        this._proportionallyResize();
7161
                                }
7162
7163
                                this._handles = this._handles.add( this.handles[ i ] );
7164
                        }
7165
                };
7166
7167
                // TODO: make renderAxis a prototype function
7168
                this._renderAxis(this.element);
7169
7170
                this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
7171
                this._handles.disableSelection();
7172
7173
                this._handles.mouseover(function() {
7174
                        if (!that.resizing) {
7175
                                if (this.className) {
7176
                                        axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
7177
                                }
7178
                                that.axis = axis && axis[1] ? axis[1] : "se";
7179
                        }
7180
                });
7181
7182
                if (o.autoHide) {
7183
                        this._handles.hide();
7184
                        $(this.element)
7185
                                .addClass("ui-resizable-autohide")
7186
                                .mouseenter(function() {
7187
                                        if (o.disabled) {
7188
                                                return;
7189
                                        }
7190
                                        $(this).removeClass("ui-resizable-autohide");
7191
                                        that._handles.show();
7192
                                })
7193
                                .mouseleave(function() {
7194
                                        if (o.disabled) {
7195
                                                return;
7196
                                        }
7197
                                        if (!that.resizing) {
7198
                                                $(this).addClass("ui-resizable-autohide");
7199
                                                that._handles.hide();
7200
                                        }
7201
                                });
7202
                }
7203
7204
                this._mouseInit();
7205
        },
7206
7207
        _destroy: function() {
7208
7209
                this._mouseDestroy();
7210
7211
                var wrapper,
7212
                        _destroy = function(exp) {
7213
                                $(exp)
7214
                                        .removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
7215
                                        .removeData("resizable")
7216
                                        .removeData("ui-resizable")
7217
                                        .unbind(".resizable")
7218
                                        .find(".ui-resizable-handle")
7219
                                                .remove();
7220
                        };
7221
7222
                // TODO: Unwrap at same DOM position
7223
                if (this.elementIsWrapper) {
7224
                        _destroy(this.element);
7225
                        wrapper = this.element;
7226
                        this.originalElement.css({
7227
                                position: wrapper.css("position"),
7228
                                width: wrapper.outerWidth(),
7229
                                height: wrapper.outerHeight(),
7230
                                top: wrapper.css("top"),
7231
                                left: wrapper.css("left")
7232
                        }).insertAfter( wrapper );
7233
                        wrapper.remove();
7234
                }
7235
7236
                this.originalElement.css("resize", this.originalResizeStyle);
7237
                _destroy(this.originalElement);
7238
7239
                return this;
7240
        },
7241
7242
        _mouseCapture: function(event) {
7243
                var i, handle,
7244
                        capture = false;
7245
7246
                for (i in this.handles) {
7247
                        handle = $(this.handles[i])[0];
7248
                        if (handle === event.target || $.contains(handle, event.target)) {
7249
                                capture = true;
7250
                        }
7251
                }
7252
7253
                return !this.options.disabled && capture;
7254
        },
7255
7256
        _mouseStart: function(event) {
7257
7258
                var curleft, curtop, cursor,
7259
                        o = this.options,
7260
                        el = this.element;
7261
7262
                this.resizing = true;
7263
7264
                this._renderProxy();
7265
7266
                curleft = this._num(this.helper.css("left"));
7267
                curtop = this._num(this.helper.css("top"));
7268
7269
                if (o.containment) {
7270
                        curleft += $(o.containment).scrollLeft() || 0;
7271
                        curtop += $(o.containment).scrollTop() || 0;
7272
                }
7273
7274
                this.offset = this.helper.offset();
7275
                this.position = { left: curleft, top: curtop };
7276
7277
                this.size = this._helper ? {
7278
                                width: this.helper.width(),
7279
                                height: this.helper.height()
7280
                        } : {
7281
                                width: el.width(),
7282
                                height: el.height()
7283
                        };
7284
7285
                this.originalSize = this._helper ? {
7286
                                width: el.outerWidth(),
7287
                                height: el.outerHeight()
7288
                        } : {
7289
                                width: el.width(),
7290
                                height: el.height()
7291
                        };
7292
7293
                this.sizeDiff = {
7294
                        width: el.outerWidth() - el.width(),
7295
                        height: el.outerHeight() - el.height()
7296
                };
7297
7298
                this.originalPosition = { left: curleft, top: curtop };
7299
                this.originalMousePosition = { left: event.pageX, top: event.pageY };
7300
7301
                this.aspectRatio = (typeof o.aspectRatio === "number") ?
7302
                        o.aspectRatio :
7303
                        ((this.originalSize.width / this.originalSize.height) || 1);
7304
7305
                cursor = $(".ui-resizable-" + this.axis).css("cursor");
7306
                $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
7307
7308
                el.addClass("ui-resizable-resizing");
7309
                this._propagate("start", event);
7310
                return true;
7311
        },
7312
7313
        _mouseDrag: function(event) {
7314
7315
                var data, props,
7316
                        smp = this.originalMousePosition,
7317
                        a = this.axis,
7318
                        dx = (event.pageX - smp.left) || 0,
7319
                        dy = (event.pageY - smp.top) || 0,
7320
                        trigger = this._change[a];
7321
7322
                this._updatePrevProperties();
7323
7324
                if (!trigger) {
7325
                        return false;
7326
                }
7327
7328
                data = trigger.apply(this, [ event, dx, dy ]);
7329
7330
                this._updateVirtualBoundaries(event.shiftKey);
7331
                if (this._aspectRatio || event.shiftKey) {
7332
                        data = this._updateRatio(data, event);
7333
                }
7334
7335
                data = this._respectSize(data, event);
7336
7337
                this._updateCache(data);
7338
7339
                this._propagate("resize", event);
7340
7341
                props = this._applyChanges();
7342
7343
                if ( !this._helper && this._proportionallyResizeElements.length ) {
7344
                        this._proportionallyResize();
7345
                }
7346
7347
                if ( !$.isEmptyObject( props ) ) {
7348
                        this._updatePrevProperties();
7349
                        this._trigger( "resize", event, this.ui() );
7350
                        this._applyChanges();
7351
                }
7352
7353
                return false;
7354
        },
7355
7356
        _mouseStop: function(event) {
7357
7358
                this.resizing = false;
7359
                var pr, ista, soffseth, soffsetw, s, left, top,
7360
                        o = this.options, that = this;
7361
7362
                if (this._helper) {
7363
7364
                        pr = this._proportionallyResizeElements;
7365
                        ista = pr.length && (/textarea/i).test(pr[0].nodeName);
7366
                        soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height;
7367
                        soffsetw = ista ? 0 : that.sizeDiff.width;
7368
7369
                        s = {
7370
                                width: (that.helper.width()  - soffsetw),
7371
                                height: (that.helper.height() - soffseth)
7372
                        };
7373
                        left = (parseInt(that.element.css("left"), 10) +
7374
                                (that.position.left - that.originalPosition.left)) || null;
7375
                        top = (parseInt(that.element.css("top"), 10) +
7376
                                (that.position.top - that.originalPosition.top)) || null;
7377
7378
                        if (!o.animate) {
7379
                                this.element.css($.extend(s, { top: top, left: left }));
7380
                        }
7381
7382
                        that.helper.height(that.size.height);
7383
                        that.helper.width(that.size.width);
7384
7385
                        if (this._helper && !o.animate) {
7386
                                this._proportionallyResize();
7387
                        }
7388
                }
7389
7390
                $("body").css("cursor", "auto");
7391
7392
                this.element.removeClass("ui-resizable-resizing");
7393
7394
                this._propagate("stop", event);
7395
7396
                if (this._helper) {
7397
                        this.helper.remove();
7398
                }
7399
7400
                return false;
7401
7402
        },
7403
7404
        _updatePrevProperties: function() {
7405
                this.prevPosition = {
7406
                        top: this.position.top,
7407
                        left: this.position.left
7408
                };
7409
                this.prevSize = {
7410
                        width: this.size.width,
7411
                        height: this.size.height
7412
                };
7413
        },
7414
7415
        _applyChanges: function() {
7416
                var props = {};
7417
7418
                if ( this.position.top !== this.prevPosition.top ) {
7419
                        props.top = this.position.top + "px";
7420
                }
7421
                if ( this.position.left !== this.prevPosition.left ) {
7422
                        props.left = this.position.left + "px";
7423
                }
7424
                if ( this.size.width !== this.prevSize.width ) {
7425
                        props.width = this.size.width + "px";
7426
                }
7427
                if ( this.size.height !== this.prevSize.height ) {
7428
                        props.height = this.size.height + "px";
7429
                }
7430
7431
                this.helper.css( props );
7432
7433
                return props;
7434
        },
7435
7436
        _updateVirtualBoundaries: function(forceAspectRatio) {
7437
                var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
7438
                        o = this.options;
7439
7440
                b = {
7441
                        minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0,
7442
                        maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity,
7443
                        minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0,
7444
                        maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity
7445
                };
7446
7447
                if (this._aspectRatio || forceAspectRatio) {
7448
                        pMinWidth = b.minHeight * this.aspectRatio;
7449
                        pMinHeight = b.minWidth / this.aspectRatio;
7450
                        pMaxWidth = b.maxHeight * this.aspectRatio;
7451
                        pMaxHeight = b.maxWidth / this.aspectRatio;
7452
7453
                        if (pMinWidth > b.minWidth) {
7454
                                b.minWidth = pMinWidth;
7455
                        }
7456
                        if (pMinHeight > b.minHeight) {
7457
                                b.minHeight = pMinHeight;
7458
                        }
7459
                        if (pMaxWidth < b.maxWidth) {
7460
                                b.maxWidth = pMaxWidth;
7461
                        }
7462
                        if (pMaxHeight < b.maxHeight) {
7463
                                b.maxHeight = pMaxHeight;
7464
                        }
7465
                }
7466
                this._vBoundaries = b;
7467
        },
7468
7469
        _updateCache: function(data) {
7470
                this.offset = this.helper.offset();
7471
                if (this._isNumber(data.left)) {
7472
                        this.position.left = data.left;
7473
                }
7474
                if (this._isNumber(data.top)) {
7475
                        this.position.top = data.top;
7476
                }
7477
                if (this._isNumber(data.height)) {
7478
                        this.size.height = data.height;
7479
                }
7480
                if (this._isNumber(data.width)) {
7481
                        this.size.width = data.width;
7482
                }
7483
        },
7484
7485
        _updateRatio: function( data ) {
7486
7487
                var cpos = this.position,
7488
                        csize = this.size,
7489
                        a = this.axis;
7490
7491
                if (this._isNumber(data.height)) {
7492
                        data.width = (data.height * this.aspectRatio);
7493
                } else if (this._isNumber(data.width)) {
7494
                        data.height = (data.width / this.aspectRatio);
7495
                }
7496
7497
                if (a === "sw") {
7498
                        data.left = cpos.left + (csize.width - data.width);
7499
                        data.top = null;
7500
                }
7501
                if (a === "nw") {
7502
                        data.top = cpos.top + (csize.height - data.height);
7503
                        data.left = cpos.left + (csize.width - data.width);
7504
                }
7505
7506
                return data;
7507
        },
7508
7509
        _respectSize: function( data ) {
7510
7511
                var o = this._vBoundaries,
7512
                        a = this.axis,
7513
                        ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width),
7514
                        ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
7515
                        isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width),
7516
                        isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
7517
                        dw = this.originalPosition.left + this.originalSize.width,
7518
                        dh = this.position.top + this.size.height,
7519
                        cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
7520
                if (isminw) {
7521
                        data.width = o.minWidth;
7522
                }
7523
                if (isminh) {
7524
                        data.height = o.minHeight;
7525
                }
7526
                if (ismaxw) {
7527
                        data.width = o.maxWidth;
7528
                }
7529
                if (ismaxh) {
7530
                        data.height = o.maxHeight;
7531
                }
7532
7533
                if (isminw && cw) {
7534
                        data.left = dw - o.minWidth;
7535
                }
7536
                if (ismaxw && cw) {
7537
                        data.left = dw - o.maxWidth;
7538
                }
7539
                if (isminh && ch) {
7540
                        data.top = dh - o.minHeight;
7541
                }
7542
                if (ismaxh && ch) {
7543
                        data.top = dh - o.maxHeight;
7544
                }
7545
7546
                // Fixing jump error on top/left - bug #2330
7547
                if (!data.width && !data.height && !data.left && data.top) {
7548
                        data.top = null;
7549
                } else if (!data.width && !data.height && !data.top && data.left) {
7550
                        data.left = null;
7551
                }
7552
7553
                return data;
7554
        },
7555
7556
        _getPaddingPlusBorderDimensions: function( element ) {
7557
                var i = 0,
7558
                        widths = [],
7559
                        borders = [
7560
                                element.css( "borderTopWidth" ),
7561
                                element.css( "borderRightWidth" ),
7562
                                element.css( "borderBottomWidth" ),
7563
                                element.css( "borderLeftWidth" )
7564
                        ],
7565
                        paddings = [
7566
                                element.css( "paddingTop" ),
7567
                                element.css( "paddingRight" ),
7568
                                element.css( "paddingBottom" ),
7569
                                element.css( "paddingLeft" )
7570
                        ];
7571
7572
                for ( ; i < 4; i++ ) {
7573
                        widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 );
7574
                        widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 );
7575
                }
7576
7577
                return {
7578
                        height: widths[ 0 ] + widths[ 2 ],
7579
                        width: widths[ 1 ] + widths[ 3 ]
7580
                };
7581
        },
7582
7583
        _proportionallyResize: function() {
7584
7585
                if (!this._proportionallyResizeElements.length) {
7586
                        return;
7587
                }
7588
7589
                var prel,
7590
                        i = 0,
7591
                        element = this.helper || this.element;
7592
7593
                for ( ; i < this._proportionallyResizeElements.length; i++) {
7594
7595
                        prel = this._proportionallyResizeElements[i];
7596
7597
                        // TODO: Seems like a bug to cache this.outerDimensions
7598
                        // considering that we are in a loop.
7599
                        if (!this.outerDimensions) {
7600
                                this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
7601
                        }
7602
7603
                        prel.css({
7604
                                height: (element.height() - this.outerDimensions.height) || 0,
7605
                                width: (element.width() - this.outerDimensions.width) || 0
7606
                        });
7607
7608
                }
7609
7610
        },
7611
7612
        _renderProxy: function() {
7613
7614
                var el = this.element, o = this.options;
7615
                this.elementOffset = el.offset();
7616
7617
                if (this._helper) {
7618
7619
                        this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
7620
7621
                        this.helper.addClass(this._helper).css({
7622
                                width: this.element.outerWidth() - 1,
7623
                                height: this.element.outerHeight() - 1,
7624
                                position: "absolute",
7625
                                left: this.elementOffset.left + "px",
7626
                                top: this.elementOffset.top + "px",
7627
                                zIndex: ++o.zIndex //TODO: Don't modify option
7628
                        });
7629
7630
                        this.helper
7631
                                .appendTo("body")
7632
                                .disableSelection();
7633
7634
                } else {
7635
                        this.helper = this.element;
7636
                }
7637
7638
        },
7639
7640
        _change: {
7641
                e: function(event, dx) {
7642
                        return { width: this.originalSize.width + dx };
7643
                },
7644
                w: function(event, dx) {
7645
                        var cs = this.originalSize, sp = this.originalPosition;
7646
                        return { left: sp.left + dx, width: cs.width - dx };
7647
                },
7648
                n: function(event, dx, dy) {
7649
                        var cs = this.originalSize, sp = this.originalPosition;
7650
                        return { top: sp.top + dy, height: cs.height - dy };
7651
                },
7652
                s: function(event, dx, dy) {
7653
                        return { height: this.originalSize.height + dy };
7654
                },
7655
                se: function(event, dx, dy) {
7656
                        return $.extend(this._change.s.apply(this, arguments),
7657
                                this._change.e.apply(this, [ event, dx, dy ]));
7658
                },
7659
                sw: function(event, dx, dy) {
7660
                        return $.extend(this._change.s.apply(this, arguments),
7661
                                this._change.w.apply(this, [ event, dx, dy ]));
7662
                },
7663
                ne: function(event, dx, dy) {
7664
                        return $.extend(this._change.n.apply(this, arguments),
7665
                                this._change.e.apply(this, [ event, dx, dy ]));
7666
                },
7667
                nw: function(event, dx, dy) {
7668
                        return $.extend(this._change.n.apply(this, arguments),
7669
                                this._change.w.apply(this, [ event, dx, dy ]));
7670
                }
7671
        },
7672
7673
        _propagate: function(n, event) {
7674
                $.ui.plugin.call(this, n, [ event, this.ui() ]);
7675
                (n !== "resize" && this._trigger(n, event, this.ui()));
7676
        },
7677
7678
        plugins: {},
7679
7680
        ui: function() {
7681
                return {
7682
                        originalElement: this.originalElement,
7683
                        element: this.element,
7684
                        helper: this.helper,
7685
                        position: this.position,
7686
                        size: this.size,
7687
                        originalSize: this.originalSize,
7688
                        originalPosition: this.originalPosition
7689
                };
7690
        }
7691
7692
});
7693
7694
/*
7695
 * Resizable Extensions
7696
 */
7697
7698
$.ui.plugin.add("resizable", "animate", {
7699
7700
        stop: function( event ) {
7701
                var that = $(this).resizable( "instance" ),
7702
                        o = that.options,
7703
                        pr = that._proportionallyResizeElements,
7704
                        ista = pr.length && (/textarea/i).test(pr[0].nodeName),
7705
                        soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height,
7706
                        soffsetw = ista ? 0 : that.sizeDiff.width,
7707
                        style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
7708
                        left = (parseInt(that.element.css("left"), 10) +
7709
                                (that.position.left - that.originalPosition.left)) || null,
7710
                        top = (parseInt(that.element.css("top"), 10) +
7711
                                (that.position.top - that.originalPosition.top)) || null;
7712
7713
                that.element.animate(
7714
                        $.extend(style, top && left ? { top: top, left: left } : {}), {
7715
                                duration: o.animateDuration,
7716
                                easing: o.animateEasing,
7717
                                step: function() {
7718
7719
                                        var data = {
7720
                                                width: parseInt(that.element.css("width"), 10),
7721
                                                height: parseInt(that.element.css("height"), 10),
7722
                                                top: parseInt(that.element.css("top"), 10),
7723
                                                left: parseInt(that.element.css("left"), 10)
7724
                                        };
7725
7726
                                        if (pr && pr.length) {
7727
                                                $(pr[0]).css({ width: data.width, height: data.height });
7728
                                        }
7729
7730
                                        // propagating resize, and updating values for each animation step
7731
                                        that._updateCache(data);
7732
                                        that._propagate("resize", event);
7733
7734
                                }
7735
                        }
7736
                );
7737
        }
7738
7739
});
7740
7741
$.ui.plugin.add( "resizable", "containment", {
7742
7743
        start: function() {
7744
                var element, p, co, ch, cw, width, height,
7745
                        that = $( this ).resizable( "instance" ),
7746
                        o = that.options,
7747
                        el = that.element,
7748
                        oc = o.containment,
7749
                        ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
7750
7751
                if ( !ce ) {
7752
                        return;
7753
                }
7754
7755
                that.containerElement = $( ce );
7756
7757
                if ( /document/.test( oc ) || oc === document ) {
7758
                        that.containerOffset = {
7759
                                left: 0,
7760
                                top: 0
7761
                        };
7762
                        that.containerPosition = {
7763
                                left: 0,
7764
                                top: 0
7765
                        };
7766
7767
                        that.parentData = {
7768
                                element: $( document ),
7769
                                left: 0,
7770
                                top: 0,
7771
                                width: $( document ).width(),
7772
                                height: $( document ).height() || document.body.parentNode.scrollHeight
7773
                        };
7774
                } else {
7775
                        element = $( ce );
7776
                        p = [];
7777
                        $([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) {
7778
                                p[ i ] = that._num( element.css( "padding" + name ) );
7779
                        });
7780
7781
                        that.containerOffset = element.offset();
7782
                        that.containerPosition = element.position();
7783
                        that.containerSize = {
7784
                                height: ( element.innerHeight() - p[ 3 ] ),
7785
                                width: ( element.innerWidth() - p[ 1 ] )
7786
                        };
7787
7788
                        co = that.containerOffset;
7789
                        ch = that.containerSize.height;
7790
                        cw = that.containerSize.width;
7791
                        width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
7792
                        height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
7793
7794
                        that.parentData = {
7795
                                element: ce,
7796
                                left: co.left,
7797
                                top: co.top,
7798
                                width: width,
7799
                                height: height
7800
                        };
7801
                }
7802
        },
7803
7804
        resize: function( event ) {
7805
                var woset, hoset, isParent, isOffsetRelative,
7806
                        that = $( this ).resizable( "instance" ),
7807
                        o = that.options,
7808
                        co = that.containerOffset,
7809
                        cp = that.position,
7810
                        pRatio = that._aspectRatio || event.shiftKey,
7811
                        cop = {
7812
                                top: 0,
7813
                                left: 0
7814
                        },
7815
                        ce = that.containerElement,
7816
                        continueResize = true;
7817
7818
                if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
7819
                        cop = co;
7820
                }
7821
7822
                if ( cp.left < ( that._helper ? co.left : 0 ) ) {
7823
                        that.size.width = that.size.width +
7824
                                ( that._helper ?
7825
                                        ( that.position.left - co.left ) :
7826
                                        ( that.position.left - cop.left ) );
7827
7828
                        if ( pRatio ) {
7829
                                that.size.height = that.size.width / that.aspectRatio;
7830
                                continueResize = false;
7831
                        }
7832
                        that.position.left = o.helper ? co.left : 0;
7833
                }
7834
7835
                if ( cp.top < ( that._helper ? co.top : 0 ) ) {
7836
                        that.size.height = that.size.height +
7837
                                ( that._helper ?
7838
                                        ( that.position.top - co.top ) :
7839
                                        that.position.top );
7840
7841
                        if ( pRatio ) {
7842
                                that.size.width = that.size.height * that.aspectRatio;
7843
                                continueResize = false;
7844
                        }
7845
                        that.position.top = that._helper ? co.top : 0;
7846
                }
7847
7848
                isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
7849
                isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
7850
7851
                if ( isParent && isOffsetRelative ) {
7852
                        that.offset.left = that.parentData.left + that.position.left;
7853
                        that.offset.top = that.parentData.top + that.position.top;
7854
                } else {
7855
                        that.offset.left = that.element.offset().left;
7856
                        that.offset.top = that.element.offset().top;
7857
                }
7858
7859
                woset = Math.abs( that.sizeDiff.width +
7860
                        (that._helper ?
7861
                                that.offset.left - cop.left :
7862
                                (that.offset.left - co.left)) );
7863
7864
                hoset = Math.abs( that.sizeDiff.height +
7865
                        (that._helper ?
7866
                                that.offset.top - cop.top :
7867
                                (that.offset.top - co.top)) );
7868
7869
                if ( woset + that.size.width >= that.parentData.width ) {
7870
                        that.size.width = that.parentData.width - woset;
7871
                        if ( pRatio ) {
7872
                                that.size.height = that.size.width / that.aspectRatio;
7873
                                continueResize = false;
7874
                        }
7875
                }
7876
7877
                if ( hoset + that.size.height >= that.parentData.height ) {
7878
                        that.size.height = that.parentData.height - hoset;
7879
                        if ( pRatio ) {
7880
                                that.size.width = that.size.height * that.aspectRatio;
7881
                                continueResize = false;
7882
                        }
7883
                }
7884
7885
                if ( !continueResize ) {
7886
                        that.position.left = that.prevPosition.left;
7887
                        that.position.top = that.prevPosition.top;
7888
                        that.size.width = that.prevSize.width;
7889
                        that.size.height = that.prevSize.height;
7890
                }
7891
        },
7892
7893
        stop: function() {
7894
                var that = $( this ).resizable( "instance" ),
7895
                        o = that.options,
7896
                        co = that.containerOffset,
7897
                        cop = that.containerPosition,
7898
                        ce = that.containerElement,
7899
                        helper = $( that.helper ),
7900
                        ho = helper.offset(),
7901
                        w = helper.outerWidth() - that.sizeDiff.width,
7902
                        h = helper.outerHeight() - that.sizeDiff.height;
7903
7904
                if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
7905
                        $( this ).css({
7906
                                left: ho.left - cop.left - co.left,
7907
                                width: w,
7908
                                height: h
7909
                        });
7910
                }
7911
7912
                if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
7913
                        $( this ).css({
7914
                                left: ho.left - cop.left - co.left,
7915
                                width: w,
7916
                                height: h
7917
                        });
7918
                }
7919
        }
7920
});
7921
7922
$.ui.plugin.add("resizable", "alsoResize", {
7923
7924
        start: function() {
7925
                var that = $(this).resizable( "instance" ),
7926
                        o = that.options;
7927
7928
                $(o.alsoResize).each(function() {
7929
                        var el = $(this);
7930
                        el.data("ui-resizable-alsoresize", {
7931
                                width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
7932
                                left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
7933
                        });
7934
                });
7935
        },
7936
7937
        resize: function(event, ui) {
7938
                var that = $(this).resizable( "instance" ),
7939
                        o = that.options,
7940
                        os = that.originalSize,
7941
                        op = that.originalPosition,
7942
                        delta = {
7943
                                height: (that.size.height - os.height) || 0,
7944
                                width: (that.size.width - os.width) || 0,
7945
                                top: (that.position.top - op.top) || 0,
7946
                                left: (that.position.left - op.left) || 0
7947
                        };
7948
7949
                        $(o.alsoResize).each(function() {
7950
                                var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
7951
                                        css = el.parents(ui.originalElement[0]).length ?
7952
                                                        [ "width", "height" ] :
7953
                                                        [ "width", "height", "top", "left" ];
7954
7955
                                $.each(css, function(i, prop) {
7956
                                        var sum = (start[prop] || 0) + (delta[prop] || 0);
7957
                                        if (sum && sum >= 0) {
7958
                                                style[prop] = sum || null;
7959
                                        }
7960
                                });
7961
7962
                                el.css(style);
7963
                        });
7964
        },
7965
7966
        stop: function() {
7967
                $(this).removeData("resizable-alsoresize");
7968
        }
7969
});
7970
7971
$.ui.plugin.add("resizable", "ghost", {
7972
7973
        start: function() {
7974
7975
                var that = $(this).resizable( "instance" ), o = that.options, cs = that.size;
7976
7977
                that.ghost = that.originalElement.clone();
7978
                that.ghost
7979
                        .css({
7980
                                opacity: 0.25,
7981
                                display: "block",
7982
                                position: "relative",
7983
                                height: cs.height,
7984
                                width: cs.width,
7985
                                margin: 0,
7986
                                left: 0,
7987
                                top: 0
7988
                        })
7989
                        .addClass("ui-resizable-ghost")
7990
                        .addClass(typeof o.ghost === "string" ? o.ghost : "");
7991
7992
                that.ghost.appendTo(that.helper);
7993
7994
        },
7995
7996
        resize: function() {
7997
                var that = $(this).resizable( "instance" );
7998
                if (that.ghost) {
7999
                        that.ghost.css({
8000
                                position: "relative",
8001
                                height: that.size.height,
8002
                                width: that.size.width
8003
                        });
8004
                }
8005
        },
8006
8007
        stop: function() {
8008
                var that = $(this).resizable( "instance" );
8009
                if (that.ghost && that.helper) {
8010
                        that.helper.get(0).removeChild(that.ghost.get(0));
8011
                }
8012
        }
8013
8014
});
8015
8016
$.ui.plugin.add("resizable", "grid", {
8017
8018
        resize: function() {
8019
                var outerDimensions,
8020
                        that = $(this).resizable( "instance" ),
8021
                        o = that.options,
8022
                        cs = that.size,
8023
                        os = that.originalSize,
8024
                        op = that.originalPosition,
8025
                        a = that.axis,
8026
                        grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
8027
                        gridX = (grid[0] || 1),
8028
                        gridY = (grid[1] || 1),
8029
                        ox = Math.round((cs.width - os.width) / gridX) * gridX,
8030
                        oy = Math.round((cs.height - os.height) / gridY) * gridY,
8031
                        newWidth = os.width + ox,
8032
                        newHeight = os.height + oy,
8033
                        isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
8034
                        isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
8035
                        isMinWidth = o.minWidth && (o.minWidth > newWidth),
8036
                        isMinHeight = o.minHeight && (o.minHeight > newHeight);
8037
8038
                o.grid = grid;
8039
8040
                if (isMinWidth) {
8041
                        newWidth += gridX;
8042
                }
8043
                if (isMinHeight) {
8044
                        newHeight += gridY;
8045
                }
8046
                if (isMaxWidth) {
8047
                        newWidth -= gridX;
8048
                }
8049
                if (isMaxHeight) {
8050
                        newHeight -= gridY;
8051
                }
8052
8053
                if (/^(se|s|e)$/.test(a)) {
8054
                        that.size.width = newWidth;
8055
                        that.size.height = newHeight;
8056
                } else if (/^(ne)$/.test(a)) {
8057
                        that.size.width = newWidth;
8058
                        that.size.height = newHeight;
8059
                        that.position.top = op.top - oy;
8060
                } else if (/^(sw)$/.test(a)) {
8061
                        that.size.width = newWidth;
8062
                        that.size.height = newHeight;
8063
                        that.position.left = op.left - ox;
8064
                } else {
8065
                        if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) {
8066
                                outerDimensions = that._getPaddingPlusBorderDimensions( this );
8067
                        }
8068
8069
                        if ( newHeight - gridY > 0 ) {
8070
                                that.size.height = newHeight;
8071
                                that.position.top = op.top - oy;
8072
                        } else {
8073
                                newHeight = gridY - outerDimensions.height;
8074
                                that.size.height = newHeight;
8075
                                that.position.top = op.top + os.height - newHeight;
8076
                        }
8077
                        if ( newWidth - gridX > 0 ) {
8078
                                that.size.width = newWidth;
8079
                                that.position.left = op.left - ox;
8080
                        } else {
8081
                                newWidth = gridX - outerDimensions.width;
8082
                                that.size.width = newWidth;
8083
                                that.position.left = op.left + os.width - newWidth;
8084
                        }
8085
                }
8086
        }
8087
8088
});
8089
8090
var resizable = $.ui.resizable;
8091
8092
8093
/*!
8094
 * jQuery UI Dialog 1.11.4
8095
 * http://jqueryui.com
8096
 *
8097
 * Copyright jQuery Foundation and other contributors
8098
 * Released under the MIT license.
8099
 * http://jquery.org/license
8100
 *
8101
 * http://api.jqueryui.com/dialog/
8102
 */
8103
8104
8105
var dialog = $.widget( "ui.dialog", {
8106
        version: "1.11.4",
8107
        options: {
8108
                appendTo: "body",
8109
                autoOpen: true,
8110
                buttons: [],
8111
                closeOnEscape: true,
8112
                closeText: "Close",
8113
                dialogClass: "",
8114
                draggable: true,
8115
                hide: null,
8116
                height: "auto",
8117
                maxHeight: null,
8118
                maxWidth: null,
8119
                minHeight: 150,
8120
                minWidth: 150,
8121
                modal: false,
8122
                position: {
8123
                        my: "center",
8124
                        at: "center",
8125
                        of: window,
8126
                        collision: "fit",
8127
                        // Ensure the titlebar is always visible
8128
                        using: function( pos ) {
8129
                                var topOffset = $( this ).css( pos ).offset().top;
8130
                                if ( topOffset < 0 ) {
8131
                                        $( this ).css( "top", pos.top - topOffset );
8132
                                }
8133
                        }
8134
                },
8135
                resizable: true,
8136
                show: null,
8137
                title: null,
8138
                width: 300,
8139
8140
                // callbacks
8141
                beforeClose: null,
8142
                close: null,
8143
                drag: null,
8144
                dragStart: null,
8145
                dragStop: null,
8146
                focus: null,
8147
                open: null,
8148
                resize: null,
8149
                resizeStart: null,
8150
                resizeStop: null
8151
        },
8152
8153
        sizeRelatedOptions: {
8154
                buttons: true,
8155
                height: true,
8156
                maxHeight: true,
8157
                maxWidth: true,
8158
                minHeight: true,
8159
                minWidth: true,
8160
                width: true
8161
        },
8162
8163
        resizableRelatedOptions: {
8164
                maxHeight: true,
8165
                maxWidth: true,
8166
                minHeight: true,
8167
                minWidth: true
8168
        },
8169
8170
        _create: function() {
8171
                this.originalCss = {
8172
                        display: this.element[ 0 ].style.display,
8173
                        width: this.element[ 0 ].style.width,
8174
                        minHeight: this.element[ 0 ].style.minHeight,
8175
                        maxHeight: this.element[ 0 ].style.maxHeight,
8176
                        height: this.element[ 0 ].style.height
8177
                };
8178
                this.originalPosition = {
8179
                        parent: this.element.parent(),
8180
                        index: this.element.parent().children().index( this.element )
8181
                };
8182
                this.originalTitle = this.element.attr( "title" );
8183
                this.options.title = this.options.title || this.originalTitle;
8184
8185
                this._createWrapper();
8186
8187
                this.element
8188
                        .show()
8189
                        .removeAttr( "title" )
8190
                        .addClass( "ui-dialog-content ui-widget-content" )
8191
                        .appendTo( this.uiDialog );
8192
8193
                this._createTitlebar();
8194
                this._createButtonPane();
8195
8196
                if ( this.options.draggable && $.fn.draggable ) {
8197
                        this._makeDraggable();
8198
                }
8199
                if ( this.options.resizable && $.fn.resizable ) {
8200
                        this._makeResizable();
8201
                }
8202
8203
                this._isOpen = false;
8204
8205
                this._trackFocus();
8206
        },
8207
8208
        _init: function() {
8209
                if ( this.options.autoOpen ) {
8210
                        this.open();
8211
                }
8212
        },
8213
8214
        _appendTo: function() {
8215
                var element = this.options.appendTo;
8216
                if ( element && (element.jquery || element.nodeType) ) {
8217
                        return $( element );
8218
                }
8219
                return this.document.find( element || "body" ).eq( 0 );
8220
        },
8221
8222
        _destroy: function() {
8223
                var next,
8224
                        originalPosition = this.originalPosition;
8225
8226
                this._untrackInstance();
8227
                this._destroyOverlay();
8228
8229
                this.element
8230
                        .removeUniqueId()
8231
                        .removeClass( "ui-dialog-content ui-widget-content" )
8232
                        .css( this.originalCss )
8233
                        // Without detaching first, the following becomes really slow
8234
                        .detach();
8235
8236
                this.uiDialog.stop( true, true ).remove();
8237
8238
                if ( this.originalTitle ) {
8239
                        this.element.attr( "title", this.originalTitle );
8240
                }
8241
8242
                next = originalPosition.parent.children().eq( originalPosition.index );
8243
                // Don't try to place the dialog next to itself (#8613)
8244
                if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
8245
                        next.before( this.element );
8246
                } else {
8247
                        originalPosition.parent.append( this.element );
8248
                }
8249
        },
8250
8251
        widget: function() {
8252
                return this.uiDialog;
8253
        },
8254
8255
        disable: $.noop,
8256
        enable: $.noop,
8257
8258
        close: function( event ) {
8259
                var activeElement,
8260
                        that = this;
8261
8262
                if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
8263
                        return;
8264
                }
8265
8266
                this._isOpen = false;
8267
                this._focusedElement = null;
8268
                this._destroyOverlay();
8269
                this._untrackInstance();
8270
8271
                if ( !this.opener.filter( ":focusable" ).focus().length ) {
8272
8273
                        // support: IE9
8274
                        // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
8275
                        try {
8276
                                activeElement = this.document[ 0 ].activeElement;
8277
8278
                                // Support: IE9, IE10
8279
                                // If the <body> is blurred, IE will switch windows, see #4520
8280
                                if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {
8281
8282
                                        // Hiding a focused element doesn't trigger blur in WebKit
8283
                                        // so in case we have nothing to focus on, explicitly blur the active element
8284
                                        // https://bugs.webkit.org/show_bug.cgi?id=47182
8285
                                        $( activeElement ).blur();
8286
                                }
8287
                        } catch ( error ) {}
8288
                }
8289
8290
                this._hide( this.uiDialog, this.options.hide, function() {
8291
                        that._trigger( "close", event );
8292
                });
8293
        },
8294
8295
        isOpen: function() {
8296
                return this._isOpen;
8297
        },
8298
8299
        moveToTop: function() {
8300
                this._moveToTop();
8301
        },
8302
8303
        _moveToTop: function( event, silent ) {
8304
                var moved = false,
8305
                        zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map(function() {
8306
                                return +$( this ).css( "z-index" );
8307
                        }).get(),
8308
                        zIndexMax = Math.max.apply( null, zIndices );
8309
8310
                if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
8311
                        this.uiDialog.css( "z-index", zIndexMax + 1 );
8312
                        moved = true;
8313
                }
8314
8315
                if ( moved && !silent ) {
8316
                        this._trigger( "focus", event );
8317
                }
8318
                return moved;
8319
        },
8320
8321
        open: function() {
8322
                var that = this;
8323
                if ( this._isOpen ) {
8324
                        if ( this._moveToTop() ) {
8325
                                this._focusTabbable();
8326
                        }
8327
                        return;
8328
                }
8329
8330
                this._isOpen = true;
8331
                this.opener = $( this.document[ 0 ].activeElement );
8332
8333
                this._size();
8334
                this._position();
8335
                this._createOverlay();
8336
                this._moveToTop( null, true );
8337
8338
                // Ensure the overlay is moved to the top with the dialog, but only when
8339
                // opening. The overlay shouldn't move after the dialog is open so that
8340
                // modeless dialogs opened after the modal dialog stack properly.
8341
                if ( this.overlay ) {
8342
                        this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
8343
                }
8344
8345
                this._show( this.uiDialog, this.options.show, function() {
8346
                        that._focusTabbable();
8347
                        that._trigger( "focus" );
8348
                });
8349
8350
                // Track the dialog immediately upon openening in case a focus event
8351
                // somehow occurs outside of the dialog before an element inside the
8352
                // dialog is focused (#10152)
8353
                this._makeFocusTarget();
8354
8355
                this._trigger( "open" );
8356
        },
8357
8358
        _focusTabbable: function() {
8359
                // Set focus to the first match:
8360
                // 1. An element that was focused previously
8361
                // 2. First element inside the dialog matching [autofocus]
8362
                // 3. Tabbable element inside the content element
8363
                // 4. Tabbable element inside the buttonpane
8364
                // 5. The close button
8365
                // 6. The dialog itself
8366
                var hasFocus = this._focusedElement;
8367
                if ( !hasFocus ) {
8368
                        hasFocus = this.element.find( "[autofocus]" );
8369
                }
8370
                if ( !hasFocus.length ) {
8371
                        hasFocus = this.element.find( ":tabbable" );
8372
                }
8373
                if ( !hasFocus.length ) {
8374
                        hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
8375
                }
8376
                if ( !hasFocus.length ) {
8377
                        hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
8378
                }
8379
                if ( !hasFocus.length ) {
8380
                        hasFocus = this.uiDialog;
8381
                }
8382
                hasFocus.eq( 0 ).focus();
8383
        },
8384
8385
        _keepFocus: function( event ) {
8386
                function checkFocus() {
8387
                        var activeElement = this.document[0].activeElement,
8388
                                isActive = this.uiDialog[0] === activeElement ||
8389
                                        $.contains( this.uiDialog[0], activeElement );
8390
                        if ( !isActive ) {
8391
                                this._focusTabbable();
8392
                        }
8393
                }
8394
                event.preventDefault();
8395
                checkFocus.call( this );
8396
                // support: IE
8397
                // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
8398
                // so we check again later
8399
                this._delay( checkFocus );
8400
        },
8401
8402
        _createWrapper: function() {
8403
                this.uiDialog = $("<div>")
8404
                        .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
8405
                                this.options.dialogClass )
8406
                        .hide()
8407
                        .attr({
8408
                                // Setting tabIndex makes the div focusable
8409
                                tabIndex: -1,
8410
                                role: "dialog"
8411
                        })
8412
                        .appendTo( this._appendTo() );
8413
8414
                this._on( this.uiDialog, {
8415
                        keydown: function( event ) {
8416
                                if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
8417
                                                event.keyCode === $.ui.keyCode.ESCAPE ) {
8418
                                        event.preventDefault();
8419
                                        this.close( event );
8420
                                        return;
8421
                                }
8422
8423
                                // prevent tabbing out of dialogs
8424
                                if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
8425
                                        return;
8426
                                }
8427
                                var tabbables = this.uiDialog.find( ":tabbable" ),
8428
                                        first = tabbables.filter( ":first" ),
8429
                                        last = tabbables.filter( ":last" );
8430
8431
                                if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
8432
                                        this._delay(function() {
8433
                                                first.focus();
8434
                                        });
8435
                                        event.preventDefault();
8436
                                } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
8437
                                        this._delay(function() {
8438
                                                last.focus();
8439
                                        });
8440
                                        event.preventDefault();
8441
                                }
8442
                        },
8443
                        mousedown: function( event ) {
8444
                                if ( this._moveToTop( event ) ) {
8445
                                        this._focusTabbable();
8446
                                }
8447
                        }
8448
                });
8449
8450
                // We assume that any existing aria-describedby attribute means
8451
                // that the dialog content is marked up properly
8452
                // otherwise we brute force the content as the description
8453
                if ( !this.element.find( "[aria-describedby]" ).length ) {
8454
                        this.uiDialog.attr({
8455
                                "aria-describedby": this.element.uniqueId().attr( "id" )
8456
                        });
8457
                }
8458
        },
8459
8460
        _createTitlebar: function() {
8461
                var uiDialogTitle;
8462
8463
                this.uiDialogTitlebar = $( "<div>" )
8464
                        .addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" )
8465
                        .prependTo( this.uiDialog );
8466
                this._on( this.uiDialogTitlebar, {
8467
                        mousedown: function( event ) {
8468
                                // Don't prevent click on close button (#8838)
8469
                                // Focusing a dialog that is partially scrolled out of view
8470
                                // causes the browser to scroll it into view, preventing the click event
8471
                                if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
8472
                                        // Dialog isn't getting focus when dragging (#8063)
8473
                                        this.uiDialog.focus();
8474
                                }
8475
                        }
8476
                });
8477
8478
                // support: IE
8479
                // Use type="button" to prevent enter keypresses in textboxes from closing the
8480
                // dialog in IE (#9312)
8481
                this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
8482
                        .button({
8483
                                label: this.options.closeText,
8484
                                icons: {
8485
                                        primary: "ui-icon-closethick"
8486
                                },
8487
                                text: false
8488
                        })
8489
                        .addClass( "ui-dialog-titlebar-close" )
8490
                        .appendTo( this.uiDialogTitlebar );
8491
                this._on( this.uiDialogTitlebarClose, {
8492
                        click: function( event ) {
8493
                                event.preventDefault();
8494
                                this.close( event );
8495
                        }
8496
                });
8497
8498
                uiDialogTitle = $( "<span>" )
8499
                        .uniqueId()
8500
                        .addClass( "ui-dialog-title" )
8501
                        .prependTo( this.uiDialogTitlebar );
8502
                this._title( uiDialogTitle );
8503
8504
                this.uiDialog.attr({
8505
                        "aria-labelledby": uiDialogTitle.attr( "id" )
8506
                });
8507
        },
8508
8509
        _title: function( title ) {
8510
                if ( !this.options.title ) {
8511
                        title.html( "&#160;" );
8512
                }
8513
                title.text( this.options.title );
8514
        },
8515
8516
        _createButtonPane: function() {
8517
                this.uiDialogButtonPane = $( "<div>" )
8518
                        .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
8519
8520
                this.uiButtonSet = $( "<div>" )
8521
                        .addClass( "ui-dialog-buttonset" )
8522
                        .appendTo( this.uiDialogButtonPane );
8523
8524
                this._createButtons();
8525
        },
8526
8527
        _createButtons: function() {
8528
                var that = this,
8529
                        buttons = this.options.buttons;
8530
8531
                // if we already have a button pane, remove it
8532
                this.uiDialogButtonPane.remove();
8533
                this.uiButtonSet.empty();
8534
8535
                if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
8536
                        this.uiDialog.removeClass( "ui-dialog-buttons" );
8537
                        return;
8538
                }
8539
8540
                $.each( buttons, function( name, props ) {
8541
                        var click, buttonOptions;
8542
                        props = $.isFunction( props ) ?
8543
                                { click: props, text: name } :
8544
                                props;
8545
                        // Default to a non-submitting button
8546
                        props = $.extend( { type: "button" }, props );
8547
                        // Change the context for the click callback to be the main element
8548
                        click = props.click;
8549
                        props.click = function() {
8550
                                click.apply( that.element[ 0 ], arguments );
8551
                        };
8552
                        buttonOptions = {
8553
                                icons: props.icons,
8554
                                text: props.showText
8555
                        };
8556
                        delete props.icons;
8557
                        delete props.showText;
8558
                        $( "<button></button>", props )
8559
                                .button( buttonOptions )
8560
                                .appendTo( that.uiButtonSet );
8561
                });
8562
                this.uiDialog.addClass( "ui-dialog-buttons" );
8563
                this.uiDialogButtonPane.appendTo( this.uiDialog );
8564
        },
8565
8566
        _makeDraggable: function() {
8567
                var that = this,
8568
                        options = this.options;
8569
8570
                function filteredUi( ui ) {
8571
                        return {
8572
                                position: ui.position,
8573
                                offset: ui.offset
8574
                        };
8575
                }
8576
8577
                this.uiDialog.draggable({
8578
                        cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
8579
                        handle: ".ui-dialog-titlebar",
8580
                        containment: "document",
8581
                        start: function( event, ui ) {
8582
                                $( this ).addClass( "ui-dialog-dragging" );
8583
                                that._blockFrames();
8584
                                that._trigger( "dragStart", event, filteredUi( ui ) );
8585
                        },
8586
                        drag: function( event, ui ) {
8587
                                that._trigger( "drag", event, filteredUi( ui ) );
8588
                        },
8589
                        stop: function( event, ui ) {
8590
                                var left = ui.offset.left - that.document.scrollLeft(),
8591
                                        top = ui.offset.top - that.document.scrollTop();
8592
8593
                                options.position = {
8594
                                        my: "left top",
8595
                                        at: "left" + (left >= 0 ? "+" : "") + left + " " +
8596
                                                "top" + (top >= 0 ? "+" : "") + top,
8597
                                        of: that.window
8598
                                };
8599
                                $( this ).removeClass( "ui-dialog-dragging" );
8600
                                that._unblockFrames();
8601
                                that._trigger( "dragStop", event, filteredUi( ui ) );
8602
                        }
8603
                });
8604
        },
8605
8606
        _makeResizable: function() {
8607
                var that = this,
8608
                        options = this.options,
8609
                        handles = options.resizable,
8610
                        // .ui-resizable has position: relative defined in the stylesheet
8611
                        // but dialogs have to use absolute or fixed positioning
8612
                        position = this.uiDialog.css("position"),
8613
                        resizeHandles = typeof handles === "string" ?
8614
                                handles        :
8615
                                "n,e,s,w,se,sw,ne,nw";
8616
8617
                function filteredUi( ui ) {
8618
                        return {
8619
                                originalPosition: ui.originalPosition,
8620
                                originalSize: ui.originalSize,
8621
                                position: ui.position,
8622
                                size: ui.size
8623
                        };
8624
                }
8625
8626
                this.uiDialog.resizable({
8627
                        cancel: ".ui-dialog-content",
8628
                        containment: "document",
8629
                        alsoResize: this.element,
8630
                        maxWidth: options.maxWidth,
8631
                        maxHeight: options.maxHeight,
8632
                        minWidth: options.minWidth,
8633
                        minHeight: this._minHeight(),
8634
                        handles: resizeHandles,
8635
                        start: function( event, ui ) {
8636
                                $( this ).addClass( "ui-dialog-resizing" );
8637
                                that._blockFrames();
8638
                                that._trigger( "resizeStart", event, filteredUi( ui ) );
8639
                        },
8640
                        resize: function( event, ui ) {
8641
                                that._trigger( "resize", event, filteredUi( ui ) );
8642
                        },
8643
                        stop: function( event, ui ) {
8644
                                var offset = that.uiDialog.offset(),
8645
                                        left = offset.left - that.document.scrollLeft(),
8646
                                        top = offset.top - that.document.scrollTop();
8647
8648
                                options.height = that.uiDialog.height();
8649
                                options.width = that.uiDialog.width();
8650
                                options.position = {
8651
                                        my: "left top",
8652
                                        at: "left" + (left >= 0 ? "+" : "") + left + " " +
8653
                                                "top" + (top >= 0 ? "+" : "") + top,
8654
                                        of: that.window
8655
                                };
8656
                                $( this ).removeClass( "ui-dialog-resizing" );
8657
                                that._unblockFrames();
8658
                                that._trigger( "resizeStop", event, filteredUi( ui ) );
8659
                        }
8660
                })
8661
                .css( "position", position );
8662
        },
8663
8664
        _trackFocus: function() {
8665
                this._on( this.widget(), {
8666
                        focusin: function( event ) {
8667
                                this._makeFocusTarget();
8668
                                this._focusedElement = $( event.target );
8669
                        }
8670
                });
8671
        },
8672
8673
        _makeFocusTarget: function() {
8674
                this._untrackInstance();
8675
                this._trackingInstances().unshift( this );
8676
        },
8677
8678
        _untrackInstance: function() {
8679
                var instances = this._trackingInstances(),
8680
                        exists = $.inArray( this, instances );
8681
                if ( exists !== -1 ) {
8682
                        instances.splice( exists, 1 );
8683
                }
8684
        },
8685
8686
        _trackingInstances: function() {
8687
                var instances = this.document.data( "ui-dialog-instances" );
8688
                if ( !instances ) {
8689
                        instances = [];
8690
                        this.document.data( "ui-dialog-instances", instances );
8691
                }
8692
                return instances;
8693
        },
8694
8695
        _minHeight: function() {
8696
                var options = this.options;
8697
8698
                return options.height === "auto" ?
8699
                        options.minHeight :
8700
                        Math.min( options.minHeight, options.height );
8701
        },
8702
8703
        _position: function() {
8704
                // Need to show the dialog to get the actual offset in the position plugin
8705
                var isVisible = this.uiDialog.is( ":visible" );
8706
                if ( !isVisible ) {
8707
                        this.uiDialog.show();
8708
                }
8709
                this.uiDialog.position( this.options.position );
8710
                if ( !isVisible ) {
8711
                        this.uiDialog.hide();
8712
                }
8713
        },
8714
8715
        _setOptions: function( options ) {
8716
                var that = this,
8717
                        resize = false,
8718
                        resizableOptions = {};
8719
8720
                $.each( options, function( key, value ) {
8721
                        that._setOption( key, value );
8722
8723
                        if ( key in that.sizeRelatedOptions ) {
8724
                                resize = true;
8725
                        }
8726
                        if ( key in that.resizableRelatedOptions ) {
8727
                                resizableOptions[ key ] = value;
8728
                        }
8729
                });
8730
8731
                if ( resize ) {
8732
                        this._size();
8733
                        this._position();
8734
                }
8735
                if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
8736
                        this.uiDialog.resizable( "option", resizableOptions );
8737
                }
8738
        },
8739
8740
        _setOption: function( key, value ) {
8741
                var isDraggable, isResizable,
8742
                        uiDialog = this.uiDialog;
8743
8744
                if ( key === "dialogClass" ) {
8745
                        uiDialog
8746
                                .removeClass( this.options.dialogClass )
8747
                                .addClass( value );
8748
                }
8749
8750
                if ( key === "disabled" ) {
8751
                        return;
8752
                }
8753
8754
                this._super( key, value );
8755
8756
                if ( key === "appendTo" ) {
8757
                        this.uiDialog.appendTo( this._appendTo() );
8758
                }
8759
8760
                if ( key === "buttons" ) {
8761
                        this._createButtons();
8762
                }
8763
8764
                if ( key === "closeText" ) {
8765
                        this.uiDialogTitlebarClose.button({
8766
                                // Ensure that we always pass a string
8767
                                label: "" + value
8768
                        });
8769
                }
8770
8771
                if ( key === "draggable" ) {
8772
                        isDraggable = uiDialog.is( ":data(ui-draggable)" );
8773
                        if ( isDraggable && !value ) {
8774
                                uiDialog.draggable( "destroy" );
8775
                        }
8776
8777
                        if ( !isDraggable && value ) {
8778
                                this._makeDraggable();
8779
                        }
8780
                }
8781
8782
                if ( key === "position" ) {
8783
                        this._position();
8784
                }
8785
8786
                if ( key === "resizable" ) {
8787
                        // currently resizable, becoming non-resizable
8788
                        isResizable = uiDialog.is( ":data(ui-resizable)" );
8789
                        if ( isResizable && !value ) {
8790
                                uiDialog.resizable( "destroy" );
8791
                        }
8792
8793
                        // currently resizable, changing handles
8794
                        if ( isResizable && typeof value === "string" ) {
8795
                                uiDialog.resizable( "option", "handles", value );
8796
                        }
8797
8798
                        // currently non-resizable, becoming resizable
8799
                        if ( !isResizable && value !== false ) {
8800
                                this._makeResizable();
8801
                        }
8802
                }
8803
8804
                if ( key === "title" ) {
8805
                        this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
8806
                }
8807
        },
8808
8809
        _size: function() {
8810
                // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
8811
                // divs will both have width and height set, so we need to reset them
8812
                var nonContentHeight, minContentHeight, maxContentHeight,
8813
                        options = this.options;
8814
8815
                // Reset content sizing
8816
                this.element.show().css({
8817
                        width: "auto",
8818
                        minHeight: 0,
8819
                        maxHeight: "none",
8820
                        height: 0
8821
                });
8822
8823
                if ( options.minWidth > options.width ) {
8824
                        options.width = options.minWidth;
8825
                }
8826
8827
                // reset wrapper sizing
8828
                // determine the height of all the non-content elements
8829
                nonContentHeight = this.uiDialog.css({
8830
                                height: "auto",
8831
                                width: options.width
8832
                        })
8833
                        .outerHeight();
8834
                minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
8835
                maxContentHeight = typeof options.maxHeight === "number" ?
8836
                        Math.max( 0, options.maxHeight - nonContentHeight ) :
8837
                        "none";
8838
8839
                if ( options.height === "auto" ) {
8840
                        this.element.css({
8841
                                minHeight: minContentHeight,
8842
                                maxHeight: maxContentHeight,
8843
                                height: "auto"
8844
                        });
8845
                } else {
8846
                        this.element.height( Math.max( 0, options.height - nonContentHeight ) );
8847
                }
8848
8849
                if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
8850
                        this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
8851
                }
8852
        },
8853
8854
        _blockFrames: function() {
8855
                this.iframeBlocks = this.document.find( "iframe" ).map(function() {
8856
                        var iframe = $( this );
8857
8858
                        return $( "<div>" )
8859
                                .css({
8860
                                        position: "absolute",
8861
                                        width: iframe.outerWidth(),
8862
                                        height: iframe.outerHeight()
8863
                                })
8864
                                .appendTo( iframe.parent() )
8865
                                .offset( iframe.offset() )[0];
8866
                });
8867
        },
8868
8869
        _unblockFrames: function() {
8870
                if ( this.iframeBlocks ) {
8871
                        this.iframeBlocks.remove();
8872
                        delete this.iframeBlocks;
8873
                }
8874
        },
8875
8876
        _allowInteraction: function( event ) {
8877
                if ( $( event.target ).closest( ".ui-dialog" ).length ) {
8878
                        return true;
8879
                }
8880
8881
                // TODO: Remove hack when datepicker implements
8882
                // the .ui-front logic (#8989)
8883
                return !!$( event.target ).closest( ".ui-datepicker" ).length;
8884
        },
8885
8886
        _createOverlay: function() {
8887
                if ( !this.options.modal ) {
8888
                        return;
8889
                }
8890
8891
                // We use a delay in case the overlay is created from an
8892
                // event that we're going to be cancelling (#2804)
8893
                var isOpening = true;
8894
                this._delay(function() {
8895
                        isOpening = false;
8896
                });
8897
8898
                if ( !this.document.data( "ui-dialog-overlays" ) ) {
8899
8900
                        // Prevent use of anchors and inputs
8901
                        // Using _on() for an event handler shared across many instances is
8902
                        // safe because the dialogs stack and must be closed in reverse order
8903
                        this._on( this.document, {
8904
                                focusin: function( event ) {
8905
                                        if ( isOpening ) {
8906
                                                return;
8907
                                        }
8908
8909
                                        if ( !this._allowInteraction( event ) ) {
8910
                                                event.preventDefault();
8911
                                                this._trackingInstances()[ 0 ]._focusTabbable();
8912
                                        }
8913
                                }
8914
                        });
8915
                }
8916
8917
                this.overlay = $( "<div>" )
8918
                        .addClass( "ui-widget-overlay ui-front" )
8919
                        .appendTo( this._appendTo() );
8920
                this._on( this.overlay, {
8921
                        mousedown: "_keepFocus"
8922
                });
8923
                this.document.data( "ui-dialog-overlays",
8924
                        (this.document.data( "ui-dialog-overlays" ) || 0) + 1 );
8925
        },
8926
8927
        _destroyOverlay: function() {
8928
                if ( !this.options.modal ) {
8929
                        return;
8930
                }
8931
8932
                if ( this.overlay ) {
8933
                        var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
8934
8935
                        if ( !overlays ) {
8936
                                this.document
8937
                                        .unbind( "focusin" )
8938
                                        .removeData( "ui-dialog-overlays" );
8939
                        } else {
8940
                                this.document.data( "ui-dialog-overlays", overlays );
8941
                        }
8942
8943
                        this.overlay.remove();
8944
                        this.overlay = null;
8945
                }
8946
        }
8947
});
8948
8949
8950
/*!
8951
 * jQuery UI Droppable 1.11.4
8952
 * http://jqueryui.com
8953
 *
8954
 * Copyright jQuery Foundation and other contributors
8955
 * Released under the MIT license.
8956
 * http://jquery.org/license
8957
 *
8958
 * http://api.jqueryui.com/droppable/
8959
 */
8960
8961
8962
$.widget( "ui.droppable", {
8963
        version: "1.11.4",
8964
        widgetEventPrefix: "drop",
8965
        options: {
8966
                accept: "*",
8967
                activeClass: false,
8968
                addClasses: true,
8969
                greedy: false,
8970
                hoverClass: false,
8971
                scope: "default",
8972
                tolerance: "intersect",
8973
8974
                // callbacks
8975
                activate: null,
8976
                deactivate: null,
8977
                drop: null,
8978
                out: null,
8979
                over: null
8980
        },
8981
        _create: function() {
8982
8983
                var proportions,
8984
                        o = this.options,
8985
                        accept = o.accept;
8986
8987
                this.isover = false;
8988
                this.isout = true;
8989
8990
                this.accept = $.isFunction( accept ) ? accept : function( d ) {
8991
                        return d.is( accept );
8992
                };
8993
8994
                this.proportions = function( /* valueToWrite */ ) {
8995
                        if ( arguments.length ) {
8996
                                // Store the droppable's proportions
8997
                                proportions = arguments[ 0 ];
8998
                        } else {
8999
                                // Retrieve or derive the droppable's proportions
9000
                                return proportions ?
9001
                                        proportions :
9002
                                        proportions = {
9003
                                                width: this.element[ 0 ].offsetWidth,
9004
                                                height: this.element[ 0 ].offsetHeight
9005
                                        };
9006
                        }
9007
                };
9008
9009
                this._addToManager( o.scope );
9010
9011
                o.addClasses && this.element.addClass( "ui-droppable" );
9012
9013
        },
9014
9015
        _addToManager: function( scope ) {
9016
                // Add the reference and positions to the manager
9017
                $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
9018
                $.ui.ddmanager.droppables[ scope ].push( this );
9019
        },
9020
9021
        _splice: function( drop ) {
9022
                var i = 0;
9023
                for ( ; i < drop.length; i++ ) {
9024
                        if ( drop[ i ] === this ) {
9025
                                drop.splice( i, 1 );
9026
                        }
9027
                }
9028
        },
9029
9030
        _destroy: function() {
9031
                var drop = $.ui.ddmanager.droppables[ this.options.scope ];
9032
9033
                this._splice( drop );
9034
9035
                this.element.removeClass( "ui-droppable ui-droppable-disabled" );
9036
        },
9037
9038
        _setOption: function( key, value ) {
9039
9040
                if ( key === "accept" ) {
9041
                        this.accept = $.isFunction( value ) ? value : function( d ) {
9042
                                return d.is( value );
9043
                        };
9044
                } else if ( key === "scope" ) {
9045
                        var drop = $.ui.ddmanager.droppables[ this.options.scope ];
9046
9047
                        this._splice( drop );
9048
                        this._addToManager( value );
9049
                }
9050
9051
                this._super( key, value );
9052
        },
9053
9054
        _activate: function( event ) {
9055
                var draggable = $.ui.ddmanager.current;
9056
                if ( this.options.activeClass ) {
9057
                        this.element.addClass( this.options.activeClass );
9058
                }
9059
                if ( draggable ){
9060
                        this._trigger( "activate", event, this.ui( draggable ) );
9061
                }
9062
        },
9063
9064
        _deactivate: function( event ) {
9065
                var draggable = $.ui.ddmanager.current;
9066
                if ( this.options.activeClass ) {
9067
                        this.element.removeClass( this.options.activeClass );
9068
                }
9069
                if ( draggable ){
9070
                        this._trigger( "deactivate", event, this.ui( draggable ) );
9071
                }
9072
        },
9073
9074
        _over: function( event ) {
9075
9076
                var draggable = $.ui.ddmanager.current;
9077
9078
                // Bail if draggable and droppable are same element
9079
                if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
9080
                        return;
9081
                }
9082
9083
                if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
9084
                        if ( this.options.hoverClass ) {
9085
                                this.element.addClass( this.options.hoverClass );
9086
                        }
9087
                        this._trigger( "over", event, this.ui( draggable ) );
9088
                }
9089
9090
        },
9091
9092
        _out: function( event ) {
9093
9094
                var draggable = $.ui.ddmanager.current;
9095
9096
                // Bail if draggable and droppable are same element
9097
                if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
9098
                        return;
9099
                }
9100
9101
                if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
9102
                        if ( this.options.hoverClass ) {
9103
                                this.element.removeClass( this.options.hoverClass );
9104
                        }
9105
                        this._trigger( "out", event, this.ui( draggable ) );
9106
                }
9107
9108
        },
9109
9110
        _drop: function( event, custom ) {
9111
9112
                var draggable = custom || $.ui.ddmanager.current,
9113
                        childrenIntersection = false;
9114
9115
                // Bail if draggable and droppable are same element
9116
                if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
9117
                        return false;
9118
                }
9119
9120
                this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() {
9121
                        var inst = $( this ).droppable( "instance" );
9122
                        if (
9123
                                inst.options.greedy &&
9124
                                !inst.options.disabled &&
9125
                                inst.options.scope === draggable.options.scope &&
9126
                                inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) &&
9127
                                $.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event )
9128
                        ) { childrenIntersection = true; return false; }
9129
                });
9130
                if ( childrenIntersection ) {
9131
                        return false;
9132
                }
9133
9134
                if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
9135
                        if ( this.options.activeClass ) {
9136
                                this.element.removeClass( this.options.activeClass );
9137
                        }
9138
                        if ( this.options.hoverClass ) {
9139
                                this.element.removeClass( this.options.hoverClass );
9140
                        }
9141
                        this._trigger( "drop", event, this.ui( draggable ) );
9142
                        return this.element;
9143
                }
9144
9145
                return false;
9146
9147
        },
9148
9149
        ui: function( c ) {
9150
                return {
9151
                        draggable: ( c.currentItem || c.element ),
9152
                        helper: c.helper,
9153
                        position: c.position,
9154
                        offset: c.positionAbs
9155
                };
9156
        }
9157
9158
});
9159
9160
$.ui.intersect = (function() {
9161
        function isOverAxis( x, reference, size ) {
9162
                return ( x >= reference ) && ( x < ( reference + size ) );
9163
        }
9164
9165
        return function( draggable, droppable, toleranceMode, event ) {
9166
9167
                if ( !droppable.offset ) {
9168
                        return false;
9169
                }
9170
9171
                var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left,
9172
                        y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top,
9173
                        x2 = x1 + draggable.helperProportions.width,
9174
                        y2 = y1 + draggable.helperProportions.height,
9175
                        l = droppable.offset.left,
9176
                        t = droppable.offset.top,
9177
                        r = l + droppable.proportions().width,
9178
                        b = t + droppable.proportions().height;
9179
9180
                switch ( toleranceMode ) {
9181
                case "fit":
9182
                        return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
9183
                case "intersect":
9184
                        return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
9185
                                x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
9186
                                t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
9187
                                y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
9188
                case "pointer":
9189
                        return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width );
9190
                case "touch":
9191
                        return (
9192
                                ( y1 >= t && y1 <= b ) || // Top edge touching
9193
                                ( y2 >= t && y2 <= b ) || // Bottom edge touching
9194
                                ( y1 < t && y2 > b ) // Surrounded vertically
9195
                        ) && (
9196
                                ( x1 >= l && x1 <= r ) || // Left edge touching
9197
                                ( x2 >= l && x2 <= r ) || // Right edge touching
9198
                                ( x1 < l && x2 > r ) // Surrounded horizontally
9199
                        );
9200
                default:
9201
                        return false;
9202
                }
9203
        };
9204
})();
9205
9206
/*
9207
        This manager tracks offsets of draggables and droppables
9208
*/
9209
$.ui.ddmanager = {
9210
        current: null,
9211
        droppables: { "default": [] },
9212
        prepareOffsets: function( t, event ) {
9213
9214
                var i, j,
9215
                        m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
9216
                        type = event ? event.type : null, // workaround for #2317
9217
                        list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
9218
9219
                droppablesLoop: for ( i = 0; i < m.length; i++ ) {
9220
9221
                        // No disabled and non-accepted
9222
                        if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) {
9223
                                continue;
9224
                        }
9225
9226
                        // Filter out elements in the current dragged item
9227
                        for ( j = 0; j < list.length; j++ ) {
9228
                                if ( list[ j ] === m[ i ].element[ 0 ] ) {
9229
                                        m[ i ].proportions().height = 0;
9230
                                        continue droppablesLoop;
9231
                                }
9232
                        }
9233
9234
                        m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
9235
                        if ( !m[ i ].visible ) {
9236
                                continue;
9237
                        }
9238
9239
                        // Activate the droppable if used directly from draggables
9240
                        if ( type === "mousedown" ) {
9241
                                m[ i ]._activate.call( m[ i ], event );
9242
                        }
9243
9244
                        m[ i ].offset = m[ i ].element.offset();
9245
                        m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
9246
9247
                }
9248
9249
        },
9250
        drop: function( draggable, event ) {
9251
9252
                var dropped = false;
9253
                // Create a copy of the droppables in case the list changes during the drop (#9116)
9254
                $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
9255
9256
                        if ( !this.options ) {
9257
                                return;
9258
                        }
9259
                        if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
9260
                                dropped = this._drop.call( this, event ) || dropped;
9261
                        }
9262
9263
                        if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
9264
                                this.isout = true;
9265
                                this.isover = false;
9266
                                this._deactivate.call( this, event );
9267
                        }
9268
9269
                });
9270
                return dropped;
9271
9272
        },
9273
        dragStart: function( draggable, event ) {
9274
                // Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
9275
                draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
9276
                        if ( !draggable.options.refreshPositions ) {
9277
                                $.ui.ddmanager.prepareOffsets( draggable, event );
9278
                        }
9279
                });
9280
        },
9281
        drag: function( draggable, event ) {
9282
9283
                // If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
9284
                if ( draggable.options.refreshPositions ) {
9285
                        $.ui.ddmanager.prepareOffsets( draggable, event );
9286
                }
9287
9288
                // Run through all droppables and check their positions based on specific tolerance options
9289
                $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
9290
9291
                        if ( this.options.disabled || this.greedyChild || !this.visible ) {
9292
                                return;
9293
                        }
9294
9295
                        var parentInstance, scope, parent,
9296
                                intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
9297
                                c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null );
9298
                        if ( !c ) {
9299
                                return;
9300
                        }
9301
9302
                        if ( this.options.greedy ) {
9303
                                // find droppable parents with same scope
9304
                                scope = this.options.scope;
9305
                                parent = this.element.parents( ":data(ui-droppable)" ).filter(function() {
9306
                                        return $( this ).droppable( "instance" ).options.scope === scope;
9307
                                });
9308
9309
                                if ( parent.length ) {
9310
                                        parentInstance = $( parent[ 0 ] ).droppable( "instance" );
9311
                                        parentInstance.greedyChild = ( c === "isover" );
9312
                                }
9313
                        }
9314
9315
                        // we just moved into a greedy child
9316
                        if ( parentInstance && c === "isover" ) {
9317
                                parentInstance.isover = false;
9318
                                parentInstance.isout = true;
9319
                                parentInstance._out.call( parentInstance, event );
9320
                        }
9321
9322
                        this[ c ] = true;
9323
                        this[c === "isout" ? "isover" : "isout"] = false;
9324
                        this[c === "isover" ? "_over" : "_out"].call( this, event );
9325
9326
                        // we just moved out of a greedy child
9327
                        if ( parentInstance && c === "isout" ) {
9328
                                parentInstance.isout = false;
9329
                                parentInstance.isover = true;
9330
                                parentInstance._over.call( parentInstance, event );
9331
                        }
9332
                });
9333
9334
        },
9335
        dragStop: function( draggable, event ) {
9336
                draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
9337
                // Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
9338
                if ( !draggable.options.refreshPositions ) {
9339
                        $.ui.ddmanager.prepareOffsets( draggable, event );
9340
                }
9341
        }
9342
};
9343
9344
var droppable = $.ui.droppable;
9345
9346
9347
/*!
9348
 * jQuery UI Effects 1.11.4
9349
 * http://jqueryui.com
9350
 *
9351
 * Copyright jQuery Foundation and other contributors
9352
 * Released under the MIT license.
9353
 * http://jquery.org/license
9354
 *
9355
 * http://api.jqueryui.com/category/effects-core/
9356
 */
9357
9358
9359
var dataSpace = "ui-effects-",
9360
9361
        // Create a local jQuery because jQuery Color relies on it and the
9362
        // global may not exist with AMD and a custom build (#10199)
9363
        jQuery = $;
9364
9365
$.effects = {
9366
        effect: {}
9367
};
9368
9369
/*!
9370
 * jQuery Color Animations v2.1.2
9371
 * https://github.com/jquery/jquery-color
9372
 *
9373
 * Copyright 2014 jQuery Foundation and other contributors
9374
 * Released under the MIT license.
9375
 * http://jquery.org/license
9376
 *
9377
 * Date: Wed Jan 16 08:47:09 2013 -0600
9378
 */
9379
(function( jQuery, undefined ) {
9380
9381
        var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
9382
9383
        // plusequals test for += 100 -= 100
9384
        rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
9385
        // a set of RE's that can match strings and generate color tuples.
9386
        stringParsers = [ {
9387
                        re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
9388
                        parse: function( execResult ) {
9389
                                return [
9390
                                        execResult[ 1 ],
9391
                                        execResult[ 2 ],
9392
                                        execResult[ 3 ],
9393
                                        execResult[ 4 ]
9394
                                ];
9395
                        }
9396
                }, {
9397
                        re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
9398
                        parse: function( execResult ) {
9399
                                return [
9400
                                        execResult[ 1 ] * 2.55,
9401
                                        execResult[ 2 ] * 2.55,
9402
                                        execResult[ 3 ] * 2.55,
9403
                                        execResult[ 4 ]
9404
                                ];
9405
                        }
9406
                }, {
9407
                        // this regex ignores A-F because it's compared against an already lowercased string
9408
                        re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
9409
                        parse: function( execResult ) {
9410
                                return [
9411
                                        parseInt( execResult[ 1 ], 16 ),
9412
                                        parseInt( execResult[ 2 ], 16 ),
9413
                                        parseInt( execResult[ 3 ], 16 )
9414
                                ];
9415
                        }
9416
                }, {
9417
                        // this regex ignores A-F because it's compared against an already lowercased string
9418
                        re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
9419
                        parse: function( execResult ) {
9420
                                return [
9421
                                        parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
9422
                                        parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
9423
                                        parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
9424
                                ];
9425
                        }
9426
                }, {
9427
                        re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
9428
                        space: "hsla",
9429
                        parse: function( execResult ) {
9430
                                return [
9431
                                        execResult[ 1 ],
9432
                                        execResult[ 2 ] / 100,
9433
                                        execResult[ 3 ] / 100,
9434
                                        execResult[ 4 ]
9435
                                ];
9436
                        }
9437
                } ],
9438
9439
        // jQuery.Color( )
9440
        color = jQuery.Color = function( color, green, blue, alpha ) {
9441
                return new jQuery.Color.fn.parse( color, green, blue, alpha );
9442
        },
9443
        spaces = {
9444
                rgba: {
9445
                        props: {
9446
                                red: {
9447
                                        idx: 0,
9448
                                        type: "byte"
9449
                                },
9450
                                green: {
9451
                                        idx: 1,
9452
                                        type: "byte"
9453
                                },
9454
                                blue: {
9455
                                        idx: 2,
9456
                                        type: "byte"
9457
                                }
9458
                        }
9459
                },
9460
9461
                hsla: {
9462
                        props: {
9463
                                hue: {
9464
                                        idx: 0,
9465
                                        type: "degrees"
9466
                                },
9467
                                saturation: {
9468
                                        idx: 1,
9469
                                        type: "percent"
9470
                                },
9471
                                lightness: {
9472
                                        idx: 2,
9473
                                        type: "percent"
9474
                                }
9475
                        }
9476
                }
9477
        },
9478
        propTypes = {
9479
                "byte": {
9480
                        floor: true,
9481
                        max: 255
9482
                },
9483
                "percent": {
9484
                        max: 1
9485
                },
9486
                "degrees": {
9487
                        mod: 360,
9488
                        floor: true
9489
                }
9490
        },
9491
        support = color.support = {},
9492
9493
        // element for support tests
9494
        supportElem = jQuery( "<p>" )[ 0 ],
9495
9496
        // colors = jQuery.Color.names
9497
        colors,
9498
9499
        // local aliases of functions called often
9500
        each = jQuery.each;
9501
9502
// determine rgba support immediately
9503
supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
9504
support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
9505
9506
// define cache name and alpha properties
9507
// for rgba and hsla spaces
9508
each( spaces, function( spaceName, space ) {
9509
        space.cache = "_" + spaceName;
9510
        space.props.alpha = {
9511
                idx: 3,
9512
                type: "percent",
9513
                def: 1
9514
        };
9515
});
9516
9517
function clamp( value, prop, allowEmpty ) {
9518
        var type = propTypes[ prop.type ] || {};
9519
9520
        if ( value == null ) {
9521
                return (allowEmpty || !prop.def) ? null : prop.def;
9522
        }
9523
9524
        // ~~ is an short way of doing floor for positive numbers
9525
        value = type.floor ? ~~value : parseFloat( value );
9526
9527
        // IE will pass in empty strings as value for alpha,
9528
        // which will hit this case
9529
        if ( isNaN( value ) ) {
9530
                return prop.def;
9531
        }
9532
9533
        if ( type.mod ) {
9534
                // we add mod before modding to make sure that negatives values
9535
                // get converted properly: -10 -> 350
9536
                return (value + type.mod) % type.mod;
9537
        }
9538
9539
        // for now all property types without mod have min and max
9540
        return 0 > value ? 0 : type.max < value ? type.max : value;
9541
}
9542
9543
function stringParse( string ) {
9544
        var inst = color(),
9545
                rgba = inst._rgba = [];
9546
9547
        string = string.toLowerCase();
9548
9549
        each( stringParsers, function( i, parser ) {
9550
                var parsed,
9551
                        match = parser.re.exec( string ),
9552
                        values = match && parser.parse( match ),
9553
                        spaceName = parser.space || "rgba";
9554
9555
                if ( values ) {
9556
                        parsed = inst[ spaceName ]( values );
9557
9558
                        // if this was an rgba parse the assignment might happen twice
9559
                        // oh well....
9560
                        inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
9561
                        rgba = inst._rgba = parsed._rgba;
9562
9563
                        // exit each( stringParsers ) here because we matched
9564
                        return false;
9565
                }
9566
        });
9567
9568
        // Found a stringParser that handled it
9569
        if ( rgba.length ) {
9570
9571
                // if this came from a parsed string, force "transparent" when alpha is 0
9572
                // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
9573
                if ( rgba.join() === "0,0,0,0" ) {
9574
                        jQuery.extend( rgba, colors.transparent );
9575
                }
9576
                return inst;
9577
        }
9578
9579
        // named colors
9580
        return colors[ string ];
9581
}
9582
9583
color.fn = jQuery.extend( color.prototype, {
9584
        parse: function( red, green, blue, alpha ) {
9585
                if ( red === undefined ) {
9586
                        this._rgba = [ null, null, null, null ];
9587
                        return this;
9588
                }
9589
                if ( red.jquery || red.nodeType ) {
9590
                        red = jQuery( red ).css( green );
9591
                        green = undefined;
9592
                }
9593
9594
                var inst = this,
9595
                        type = jQuery.type( red ),
9596
                        rgba = this._rgba = [];
9597
9598
                // more than 1 argument specified - assume ( red, green, blue, alpha )
9599
                if ( green !== undefined ) {
9600
                        red = [ red, green, blue, alpha ];
9601
                        type = "array";
9602
                }
9603
9604
                if ( type === "string" ) {
9605
                        return this.parse( stringParse( red ) || colors._default );
9606
                }
9607
9608
                if ( type === "array" ) {
9609
                        each( spaces.rgba.props, function( key, prop ) {
9610
                                rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
9611
                        });
9612
                        return this;
9613
                }
9614
9615
                if ( type === "object" ) {
9616
                        if ( red instanceof color ) {
9617
                                each( spaces, function( spaceName, space ) {
9618
                                        if ( red[ space.cache ] ) {
9619
                                                inst[ space.cache ] = red[ space.cache ].slice();
9620
                                        }
9621
                                });
9622
                        } else {
9623
                                each( spaces, function( spaceName, space ) {
9624
                                        var cache = space.cache;
9625
                                        each( space.props, function( key, prop ) {
9626
9627
                                                // if the cache doesn't exist, and we know how to convert
9628
                                                if ( !inst[ cache ] && space.to ) {
9629
9630
                                                        // if the value was null, we don't need to copy it
9631
                                                        // if the key was alpha, we don't need to copy it either
9632
                                                        if ( key === "alpha" || red[ key ] == null ) {
9633
                                                                return;
9634
                                                        }
9635
                                                        inst[ cache ] = space.to( inst._rgba );
9636
                                                }
9637
9638
                                                // this is the only case where we allow nulls for ALL properties.
9639
                                                // call clamp with alwaysAllowEmpty
9640
                                                inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
9641
                                        });
9642
9643
                                        // everything defined but alpha?
9644
                                        if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
9645
                                                // use the default of 1
9646
                                                inst[ cache ][ 3 ] = 1;
9647
                                                if ( space.from ) {
9648
                                                        inst._rgba = space.from( inst[ cache ] );
9649
                                                }
9650
                                        }
9651
                                });
9652
                        }
9653
                        return this;
9654
                }
9655
        },
9656
        is: function( compare ) {
9657
                var is = color( compare ),
9658
                        same = true,
9659
                        inst = this;
9660
9661
                each( spaces, function( _, space ) {
9662
                        var localCache,
9663
                                isCache = is[ space.cache ];
9664
                        if (isCache) {
9665
                                localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
9666
                                each( space.props, function( _, prop ) {
9667
                                        if ( isCache[ prop.idx ] != null ) {
9668
                                                same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
9669
                                                return same;
9670
                                        }
9671
                                });
9672
                        }
9673
                        return same;
9674
                });
9675
                return same;
9676
        },
9677
        _space: function() {
9678
                var used = [],
9679
                        inst = this;
9680
                each( spaces, function( spaceName, space ) {
9681
                        if ( inst[ space.cache ] ) {
9682
                                used.push( spaceName );
9683
                        }
9684
                });
9685
                return used.pop();
9686
        },
9687
        transition: function( other, distance ) {
9688
                var end = color( other ),
9689
                        spaceName = end._space(),
9690
                        space = spaces[ spaceName ],
9691
                        startColor = this.alpha() === 0 ? color( "transparent" ) : this,
9692
                        start = startColor[ space.cache ] || space.to( startColor._rgba ),
9693
                        result = start.slice();
9694
9695
                end = end[ space.cache ];
9696
                each( space.props, function( key, prop ) {
9697
                        var index = prop.idx,
9698
                                startValue = start[ index ],
9699
                                endValue = end[ index ],
9700
                                type = propTypes[ prop.type ] || {};
9701
9702
                        // if null, don't override start value
9703
                        if ( endValue === null ) {
9704
                                return;
9705
                        }
9706
                        // if null - use end
9707
                        if ( startValue === null ) {
9708
                                result[ index ] = endValue;
9709
                        } else {
9710
                                if ( type.mod ) {
9711
                                        if ( endValue - startValue > type.mod / 2 ) {
9712
                                                startValue += type.mod;
9713
                                        } else if ( startValue - endValue > type.mod / 2 ) {
9714
                                                startValue -= type.mod;
9715
                                        }
9716
                                }
9717
                                result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
9718
                        }
9719
                });
9720
                return this[ spaceName ]( result );
9721
        },
9722
        blend: function( opaque ) {
9723
                // if we are already opaque - return ourself
9724
                if ( this._rgba[ 3 ] === 1 ) {
9725
                        return this;
9726
                }
9727
9728
                var rgb = this._rgba.slice(),
9729
                        a = rgb.pop(),
9730
                        blend = color( opaque )._rgba;
9731
9732
                return color( jQuery.map( rgb, function( v, i ) {
9733
                        return ( 1 - a ) * blend[ i ] + a * v;
9734
                }));
9735
        },
9736
        toRgbaString: function() {
9737
                var prefix = "rgba(",
9738
                        rgba = jQuery.map( this._rgba, function( v, i ) {
9739
                                return v == null ? ( i > 2 ? 1 : 0 ) : v;
9740
                        });
9741
9742
                if ( rgba[ 3 ] === 1 ) {
9743
                        rgba.pop();
9744
                        prefix = "rgb(";
9745
                }
9746
9747
                return prefix + rgba.join() + ")";
9748
        },
9749
        toHslaString: function() {
9750
                var prefix = "hsla(",
9751
                        hsla = jQuery.map( this.hsla(), function( v, i ) {
9752
                                if ( v == null ) {
9753
                                        v = i > 2 ? 1 : 0;
9754
                                }
9755
9756
                                // catch 1 and 2
9757
                                if ( i && i < 3 ) {
9758
                                        v = Math.round( v * 100 ) + "%";
9759
                                }
9760
                                return v;
9761
                        });
9762
9763
                if ( hsla[ 3 ] === 1 ) {
9764
                        hsla.pop();
9765
                        prefix = "hsl(";
9766
                }
9767
                return prefix + hsla.join() + ")";
9768
        },
9769
        toHexString: function( includeAlpha ) {
9770
                var rgba = this._rgba.slice(),
9771
                        alpha = rgba.pop();
9772
9773
                if ( includeAlpha ) {
9774
                        rgba.push( ~~( alpha * 255 ) );
9775
                }
9776
9777
                return "#" + jQuery.map( rgba, function( v ) {
9778
9779
                        // default to 0 when nulls exist
9780
                        v = ( v || 0 ).toString( 16 );
9781
                        return v.length === 1 ? "0" + v : v;
9782
                }).join("");
9783
        },
9784
        toString: function() {
9785
                return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
9786
        }
9787
});
9788
color.fn.parse.prototype = color.fn;
9789
9790
// hsla conversions adapted from:
9791
// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
9792
9793
function hue2rgb( p, q, h ) {
9794
        h = ( h + 1 ) % 1;
9795
        if ( h * 6 < 1 ) {
9796
                return p + ( q - p ) * h * 6;
9797
        }
9798
        if ( h * 2 < 1) {
9799
                return q;
9800
        }
9801
        if ( h * 3 < 2 ) {
9802
                return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
9803
        }
9804
        return p;
9805
}
9806
9807
spaces.hsla.to = function( rgba ) {
9808
        if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
9809
                return [ null, null, null, rgba[ 3 ] ];
9810
        }
9811
        var r = rgba[ 0 ] / 255,
9812
                g = rgba[ 1 ] / 255,
9813
                b = rgba[ 2 ] / 255,
9814
                a = rgba[ 3 ],
9815
                max = Math.max( r, g, b ),
9816
                min = Math.min( r, g, b ),
9817
                diff = max - min,
9818
                add = max + min,
9819
                l = add * 0.5,
9820
                h, s;
9821
9822
        if ( min === max ) {
9823
                h = 0;
9824
        } else if ( r === max ) {
9825
                h = ( 60 * ( g - b ) / diff ) + 360;
9826
        } else if ( g === max ) {
9827
                h = ( 60 * ( b - r ) / diff ) + 120;
9828
        } else {
9829
                h = ( 60 * ( r - g ) / diff ) + 240;
9830
        }
9831
9832
        // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
9833
        // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
9834
        if ( diff === 0 ) {
9835
                s = 0;
9836
        } else if ( l <= 0.5 ) {
9837
                s = diff / add;
9838
        } else {
9839
                s = diff / ( 2 - add );
9840
        }
9841
        return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
9842
};
9843
9844
spaces.hsla.from = function( hsla ) {
9845
        if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
9846
                return [ null, null, null, hsla[ 3 ] ];
9847
        }
9848
        var h = hsla[ 0 ] / 360,
9849
                s = hsla[ 1 ],
9850
                l = hsla[ 2 ],
9851
                a = hsla[ 3 ],
9852
                q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
9853
                p = 2 * l - q;
9854
9855
        return [
9856
                Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
9857
                Math.round( hue2rgb( p, q, h ) * 255 ),
9858
                Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
9859
                a
9860
        ];
9861
};
9862
9863
each( spaces, function( spaceName, space ) {
9864
        var props = space.props,
9865
                cache = space.cache,
9866
                to = space.to,
9867
                from = space.from;
9868
9869
        // makes rgba() and hsla()
9870
        color.fn[ spaceName ] = function( value ) {
9871
9872
                // generate a cache for this space if it doesn't exist
9873
                if ( to && !this[ cache ] ) {
9874
                        this[ cache ] = to( this._rgba );
9875
                }
9876
                if ( value === undefined ) {
9877
                        return this[ cache ].slice();
9878
                }
9879
9880
                var ret,
9881
                        type = jQuery.type( value ),
9882
                        arr = ( type === "array" || type === "object" ) ? value : arguments,
9883
                        local = this[ cache ].slice();
9884
9885
                each( props, function( key, prop ) {
9886
                        var val = arr[ type === "object" ? key : prop.idx ];
9887
                        if ( val == null ) {
9888
                                val = local[ prop.idx ];
9889
                        }
9890
                        local[ prop.idx ] = clamp( val, prop );
9891
                });
9892
9893
                if ( from ) {
9894
                        ret = color( from( local ) );
9895
                        ret[ cache ] = local;
9896
                        return ret;
9897
                } else {
9898
                        return color( local );
9899
                }
9900
        };
9901
9902
        // makes red() green() blue() alpha() hue() saturation() lightness()
9903
        each( props, function( key, prop ) {
9904
                // alpha is included in more than one space
9905
                if ( color.fn[ key ] ) {
9906
                        return;
9907
                }
9908
                color.fn[ key ] = function( value ) {
9909
                        var vtype = jQuery.type( value ),
9910
                                fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
9911
                                local = this[ fn ](),
9912
                                cur = local[ prop.idx ],
9913
                                match;
9914
9915
                        if ( vtype === "undefined" ) {
9916
                                return cur;
9917
                        }
9918
9919
                        if ( vtype === "function" ) {
9920
                                value = value.call( this, cur );
9921
                                vtype = jQuery.type( value );
9922
                        }
9923
                        if ( value == null && prop.empty ) {
9924
                                return this;
9925
                        }
9926
                        if ( vtype === "string" ) {
9927
                                match = rplusequals.exec( value );
9928
                                if ( match ) {
9929
                                        value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
9930
                                }
9931
                        }
9932
                        local[ prop.idx ] = value;
9933
                        return this[ fn ]( local );
9934
                };
9935
        });
9936
});
9937
9938
// add cssHook and .fx.step function for each named hook.
9939
// accept a space separated string of properties
9940
color.hook = function( hook ) {
9941
        var hooks = hook.split( " " );
9942
        each( hooks, function( i, hook ) {
9943
                jQuery.cssHooks[ hook ] = {
9944
                        set: function( elem, value ) {
9945
                                var parsed, curElem,
9946
                                        backgroundColor = "";
9947
9948
                                if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
9949
                                        value = color( parsed || value );
9950
                                        if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
9951
                                                curElem = hook === "backgroundColor" ? elem.parentNode : elem;
9952
                                                while (
9953
                                                        (backgroundColor === "" || backgroundColor === "transparent") &&
9954
                                                        curElem && curElem.style
9955
                                                ) {
9956
                                                        try {
9957
                                                                backgroundColor = jQuery.css( curElem, "backgroundColor" );
9958
                                                                curElem = curElem.parentNode;
9959
                                                        } catch ( e ) {
9960
                                                        }
9961
                                                }
9962
9963
                                                value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
9964
                                                        backgroundColor :
9965
                                                        "_default" );
9966
                                        }
9967
9968
                                        value = value.toRgbaString();
9969
                                }
9970
                                try {
9971
                                        elem.style[ hook ] = value;
9972
                                } catch ( e ) {
9973
                                        // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
9974
                                }
9975
                        }
9976
                };
9977
                jQuery.fx.step[ hook ] = function( fx ) {
9978
                        if ( !fx.colorInit ) {
9979
                                fx.start = color( fx.elem, hook );
9980
                                fx.end = color( fx.end );
9981
                                fx.colorInit = true;
9982
                        }
9983
                        jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
9984
                };
9985
        });
9986
9987
};
9988
9989
color.hook( stepHooks );
9990
9991
jQuery.cssHooks.borderColor = {
9992
        expand: function( value ) {
9993
                var expanded = {};
9994
9995
                each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
9996
                        expanded[ "border" + part + "Color" ] = value;
9997
                });
9998
                return expanded;
9999
        }
10000
};
10001
10002
// Basic color names only.
10003
// Usage of any of the other color names requires adding yourself or including
10004
// jquery.color.svg-names.js.
10005
colors = jQuery.Color.names = {
10006
        // 4.1. Basic color keywords
10007
        aqua: "#00ffff",
10008
        black: "#000000",
10009
        blue: "#0000ff",
10010
        fuchsia: "#ff00ff",
10011
        gray: "#808080",
10012
        green: "#008000",
10013
        lime: "#00ff00",
10014
        maroon: "#800000",
10015
        navy: "#000080",
10016
        olive: "#808000",
10017
        purple: "#800080",
10018
        red: "#ff0000",
10019
        silver: "#c0c0c0",
10020
        teal: "#008080",
10021
        white: "#ffffff",
10022
        yellow: "#ffff00",
10023
10024
        // 4.2.3. "transparent" color keyword
10025
        transparent: [ null, null, null, 0 ],
10026
10027
        _default: "#ffffff"
10028
};
10029
10030
})( jQuery );
10031
10032
/******************************************************************************/
10033
/****************************** CLASS ANIMATIONS ******************************/
10034
/******************************************************************************/
10035
(function() {
10036
10037
var classAnimationActions = [ "add", "remove", "toggle" ],
10038
        shorthandStyles = {
10039
                border: 1,
10040
                borderBottom: 1,
10041
                borderColor: 1,
10042
                borderLeft: 1,
10043
                borderRight: 1,
10044
                borderTop: 1,
10045
                borderWidth: 1,
10046
                margin: 1,
10047
                padding: 1
10048
        };
10049
10050
$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
10051
        $.fx.step[ prop ] = function( fx ) {
10052
                if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
10053
                        jQuery.style( fx.elem, prop, fx.end );
10054
                        fx.setAttr = true;
10055
                }
10056
        };
10057
});
10058
10059
function getElementStyles( elem ) {
10060
        var key, len,
10061
                style = elem.ownerDocument.defaultView ?
10062
                        elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
10063
                        elem.currentStyle,
10064
                styles = {};
10065
10066
        if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
10067
                len = style.length;
10068
                while ( len-- ) {
10069
                        key = style[ len ];
10070
                        if ( typeof style[ key ] === "string" ) {
10071
                                styles[ $.camelCase( key ) ] = style[ key ];
10072
                        }
10073
                }
10074
        // support: Opera, IE <9
10075
        } else {
10076
                for ( key in style ) {
10077
                        if ( typeof style[ key ] === "string" ) {
10078
                                styles[ key ] = style[ key ];
10079
                        }
10080
                }
10081
        }
10082
10083
        return styles;
10084
}
10085
10086
function styleDifference( oldStyle, newStyle ) {
10087
        var diff = {},
10088
                name, value;
10089
10090
        for ( name in newStyle ) {
10091
                value = newStyle[ name ];
10092
                if ( oldStyle[ name ] !== value ) {
10093
                        if ( !shorthandStyles[ name ] ) {
10094
                                if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
10095
                                        diff[ name ] = value;
10096
                                }
10097
                        }
10098
                }
10099
        }
10100
10101
        return diff;
10102
}
10103
10104
// support: jQuery <1.8
10105
if ( !$.fn.addBack ) {
10106
        $.fn.addBack = function( selector ) {
10107
                return this.add( selector == null ?
10108
                        this.prevObject : this.prevObject.filter( selector )
10109
                );
10110
        };
10111
}
10112
10113
$.effects.animateClass = function( value, duration, easing, callback ) {
10114
        var o = $.speed( duration, easing, callback );
10115
10116
        return this.queue( function() {
10117
                var animated = $( this ),
10118
                        baseClass = animated.attr( "class" ) || "",
10119
                        applyClassChange,
10120
                        allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
10121
10122
                // map the animated objects to store the original styles.
10123
                allAnimations = allAnimations.map(function() {
10124
                        var el = $( this );
10125
                        return {
10126
                                el: el,
10127
                                start: getElementStyles( this )
10128
                        };
10129
                });
10130
10131
                // apply class change
10132
                applyClassChange = function() {
10133
                        $.each( classAnimationActions, function(i, action) {
10134
                                if ( value[ action ] ) {
10135
                                        animated[ action + "Class" ]( value[ action ] );
10136
                                }
10137
                        });
10138
                };
10139
                applyClassChange();
10140
10141
                // map all animated objects again - calculate new styles and diff
10142
                allAnimations = allAnimations.map(function() {
10143
                        this.end = getElementStyles( this.el[ 0 ] );
10144
                        this.diff = styleDifference( this.start, this.end );
10145
                        return this;
10146
                });
10147
10148
                // apply original class
10149
                animated.attr( "class", baseClass );
10150
10151
                // map all animated objects again - this time collecting a promise
10152
                allAnimations = allAnimations.map(function() {
10153
                        var styleInfo = this,
10154
                                dfd = $.Deferred(),
10155
                                opts = $.extend({}, o, {
10156
                                        queue: false,
10157
                                        complete: function() {
10158
                                                dfd.resolve( styleInfo );
10159
                                        }
10160
                                });
10161
10162
                        this.el.animate( this.diff, opts );
10163
                        return dfd.promise();
10164
                });
10165
10166
                // once all animations have completed:
10167
                $.when.apply( $, allAnimations.get() ).done(function() {
10168
10169
                        // set the final class
10170
                        applyClassChange();
10171
10172
                        // for each animated element,
10173
                        // clear all css properties that were animated
10174
                        $.each( arguments, function() {
10175
                                var el = this.el;
10176
                                $.each( this.diff, function(key) {
10177
                                        el.css( key, "" );
10178
                                });
10179
                        });
10180
10181
                        // this is guarnteed to be there if you use jQuery.speed()
10182
                        // it also handles dequeuing the next anim...
10183
                        o.complete.call( animated[ 0 ] );
10184
                });
10185
        });
10186
};
10187
10188
$.fn.extend({
10189
        addClass: (function( orig ) {
10190
                return function( classNames, speed, easing, callback ) {
10191
                        return speed ?
10192
                                $.effects.animateClass.call( this,
10193
                                        { add: classNames }, speed, easing, callback ) :
10194
                                orig.apply( this, arguments );
10195
                };
10196
        })( $.fn.addClass ),
10197
10198
        removeClass: (function( orig ) {
10199
                return function( classNames, speed, easing, callback ) {
10200
                        return arguments.length > 1 ?
10201
                                $.effects.animateClass.call( this,
10202
                                        { remove: classNames }, speed, easing, callback ) :
10203
                                orig.apply( this, arguments );
10204
                };
10205
        })( $.fn.removeClass ),
10206
10207
        toggleClass: (function( orig ) {
10208
                return function( classNames, force, speed, easing, callback ) {
10209
                        if ( typeof force === "boolean" || force === undefined ) {
10210
                                if ( !speed ) {
10211
                                        // without speed parameter
10212
                                        return orig.apply( this, arguments );
10213
                                } else {
10214
                                        return $.effects.animateClass.call( this,
10215
                                                (force ? { add: classNames } : { remove: classNames }),
10216
                                                speed, easing, callback );
10217
                                }
10218
                        } else {
10219
                                // without force parameter
10220
                                return $.effects.animateClass.call( this,
10221
                                        { toggle: classNames }, force, speed, easing );
10222
                        }
10223
                };
10224
        })( $.fn.toggleClass ),
10225
10226
        switchClass: function( remove, add, speed, easing, callback) {
10227
                return $.effects.animateClass.call( this, {
10228
                        add: add,
10229
                        remove: remove
10230
                }, speed, easing, callback );
10231
        }
10232
});
10233
10234
})();
10235
10236
/******************************************************************************/
10237
/*********************************** EFFECTS **********************************/
10238
/******************************************************************************/
10239
10240
(function() {
10241
10242
$.extend( $.effects, {
10243
        version: "1.11.4",
10244
10245
        // Saves a set of properties in a data storage
10246
        save: function( element, set ) {
10247
                for ( var i = 0; i < set.length; i++ ) {
10248
                        if ( set[ i ] !== null ) {
10249
                                element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
10250
                        }
10251
                }
10252
        },
10253
10254
        // Restores a set of previously saved properties from a data storage
10255
        restore: function( element, set ) {
10256
                var val, i;
10257
                for ( i = 0; i < set.length; i++ ) {
10258
                        if ( set[ i ] !== null ) {
10259
                                val = element.data( dataSpace + set[ i ] );
10260
                                // support: jQuery 1.6.2
10261
                                // http://bugs.jquery.com/ticket/9917
10262
                                // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
10263
                                // We can't differentiate between "" and 0 here, so we just assume
10264
                                // empty string since it's likely to be a more common value...
10265
                                if ( val === undefined ) {
10266
                                        val = "";
10267
                                }
10268
                                element.css( set[ i ], val );
10269
                        }
10270
                }
10271
        },
10272
10273
        setMode: function( el, mode ) {
10274
                if (mode === "toggle") {
10275
                        mode = el.is( ":hidden" ) ? "show" : "hide";
10276
                }
10277
                return mode;
10278
        },
10279
10280
        // Translates a [top,left] array into a baseline value
10281
        // this should be a little more flexible in the future to handle a string & hash
10282
        getBaseline: function( origin, original ) {
10283
                var y, x;
10284
                switch ( origin[ 0 ] ) {
10285
                        case "top": y = 0; break;
10286
                        case "middle": y = 0.5; break;
10287
                        case "bottom": y = 1; break;
10288
                        default: y = origin[ 0 ] / original.height;
10289
                }
10290
                switch ( origin[ 1 ] ) {
10291
                        case "left": x = 0; break;
10292
                        case "center": x = 0.5; break;
10293
                        case "right": x = 1; break;
10294
                        default: x = origin[ 1 ] / original.width;
10295
                }
10296
                return {
10297
                        x: x,
10298
                        y: y
10299
                };
10300
        },
10301
10302
        // Wraps the element around a wrapper that copies position properties
10303
        createWrapper: function( element ) {
10304
10305
                // if the element is already wrapped, return it
10306
                if ( element.parent().is( ".ui-effects-wrapper" )) {
10307
                        return element.parent();
10308
                }
10309
10310
                // wrap the element
10311
                var props = {
10312
                                width: element.outerWidth(true),
10313
                                height: element.outerHeight(true),
10314
                                "float": element.css( "float" )
10315
                        },
10316
                        wrapper = $( "<div></div>" )
10317
                                .addClass( "ui-effects-wrapper" )
10318
                                .css({
10319
                                        fontSize: "100%",
10320
                                        background: "transparent",
10321
                                        border: "none",
10322
                                        margin: 0,
10323
                                        padding: 0
10324
                                }),
10325
                        // Store the size in case width/height are defined in % - Fixes #5245
10326
                        size = {
10327
                                width: element.width(),
10328
                                height: element.height()
10329
                        },
10330
                        active = document.activeElement;
10331
10332
                // support: Firefox
10333
                // Firefox incorrectly exposes anonymous content
10334
                // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
10335
                try {
10336
                        active.id;
10337
                } catch ( e ) {
10338
                        active = document.body;
10339
                }
10340
10341
                element.wrap( wrapper );
10342
10343
                // Fixes #7595 - Elements lose focus when wrapped.
10344
                if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
10345
                        $( active ).focus();
10346
                }
10347
10348
                wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
10349
10350
                // transfer positioning properties to the wrapper
10351
                if ( element.css( "position" ) === "static" ) {
10352
                        wrapper.css({ position: "relative" });
10353
                        element.css({ position: "relative" });
10354
                } else {
10355
                        $.extend( props, {
10356
                                position: element.css( "position" ),
10357
                                zIndex: element.css( "z-index" )
10358
                        });
10359
                        $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
10360
                                props[ pos ] = element.css( pos );
10361
                                if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
10362
                                        props[ pos ] = "auto";
10363
                                }
10364
                        });
10365
                        element.css({
10366
                                position: "relative",
10367
                                top: 0,
10368
                                left: 0,
10369
                                right: "auto",
10370
                                bottom: "auto"
10371
                        });
10372
                }
10373
                element.css(size);
10374
10375
                return wrapper.css( props ).show();
10376
        },
10377
10378
        removeWrapper: function( element ) {
10379
                var active = document.activeElement;
10380
10381
                if ( element.parent().is( ".ui-effects-wrapper" ) ) {
10382
                        element.parent().replaceWith( element );
10383
10384
                        // Fixes #7595 - Elements lose focus when wrapped.
10385
                        if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
10386
                                $( active ).focus();
10387
                        }
10388
                }
10389
10390
                return element;
10391
        },
10392
10393
        setTransition: function( element, list, factor, value ) {
10394
                value = value || {};
10395
                $.each( list, function( i, x ) {
10396
                        var unit = element.cssUnit( x );
10397
                        if ( unit[ 0 ] > 0 ) {
10398
                                value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
10399
                        }
10400
                });
10401
                return value;
10402
        }
10403
});
10404
10405
// return an effect options object for the given parameters:
10406
function _normalizeArguments( effect, options, speed, callback ) {
10407
10408
        // allow passing all options as the first parameter
10409
        if ( $.isPlainObject( effect ) ) {
10410
                options = effect;
10411
                effect = effect.effect;
10412
        }
10413
10414
        // convert to an object
10415
        effect = { effect: effect };
10416
10417
        // catch (effect, null, ...)
10418
        if ( options == null ) {
10419
                options = {};
10420
        }
10421
10422
        // catch (effect, callback)
10423
        if ( $.isFunction( options ) ) {
10424
                callback = options;
10425
                speed = null;
10426
                options = {};
10427
        }
10428
10429
        // catch (effect, speed, ?)
10430
        if ( typeof options === "number" || $.fx.speeds[ options ] ) {
10431
                callback = speed;
10432
                speed = options;
10433
                options = {};
10434
        }
10435
10436
        // catch (effect, options, callback)
10437
        if ( $.isFunction( speed ) ) {
10438
                callback = speed;
10439
                speed = null;
10440
        }
10441
10442
        // add options to effect
10443
        if ( options ) {
10444
                $.extend( effect, options );
10445
        }
10446
10447
        speed = speed || options.duration;
10448
        effect.duration = $.fx.off ? 0 :
10449
                typeof speed === "number" ? speed :
10450
                speed in $.fx.speeds ? $.fx.speeds[ speed ] :
10451
                $.fx.speeds._default;
10452
10453
        effect.complete = callback || options.complete;
10454
10455
        return effect;
10456
}
10457
10458
function standardAnimationOption( option ) {
10459
        // Valid standard speeds (nothing, number, named speed)
10460
        if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
10461
                return true;
10462
        }
10463
10464
        // Invalid strings - treat as "normal" speed
10465
        if ( typeof option === "string" && !$.effects.effect[ option ] ) {
10466
                return true;
10467
        }
10468
10469
        // Complete callback
10470
        if ( $.isFunction( option ) ) {
10471
                return true;
10472
        }
10473
10474
        // Options hash (but not naming an effect)
10475
        if ( typeof option === "object" && !option.effect ) {
10476
                return true;
10477
        }
10478
10479
        // Didn't match any standard API
10480
        return false;
10481
}
10482
10483
$.fn.extend({
10484
        effect: function( /* effect, options, speed, callback */ ) {
10485
                var args = _normalizeArguments.apply( this, arguments ),
10486
                        mode = args.mode,
10487
                        queue = args.queue,
10488
                        effectMethod = $.effects.effect[ args.effect ];
10489
10490
                if ( $.fx.off || !effectMethod ) {
10491
                        // delegate to the original method (e.g., .show()) if possible
10492
                        if ( mode ) {
10493
                                return this[ mode ]( args.duration, args.complete );
10494
                        } else {
10495
                                return this.each( function() {
10496
                                        if ( args.complete ) {
10497
                                                args.complete.call( this );
10498
                                        }
10499
                                });
10500
                        }
10501
                }
10502
10503
                function run( next ) {
10504
                        var elem = $( this ),
10505
                                complete = args.complete,
10506
                                mode = args.mode;
10507
10508
                        function done() {
10509
                                if ( $.isFunction( complete ) ) {
10510
                                        complete.call( elem[0] );
10511
                                }
10512
                                if ( $.isFunction( next ) ) {
10513
                                        next();
10514
                                }
10515
                        }
10516
10517
                        // If the element already has the correct final state, delegate to
10518
                        // the core methods so the internal tracking of "olddisplay" works.
10519
                        if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
10520
                                elem[ mode ]();
10521
                                done();
10522
                        } else {
10523
                                effectMethod.call( elem[0], args, done );
10524
                        }
10525
                }
10526
10527
                return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
10528
        },
10529
10530
        show: (function( orig ) {
10531
                return function( option ) {
10532
                        if ( standardAnimationOption( option ) ) {
10533
                                return orig.apply( this, arguments );
10534
                        } else {
10535
                                var args = _normalizeArguments.apply( this, arguments );
10536
                                args.mode = "show";
10537
                                return this.effect.call( this, args );
10538
                        }
10539
                };
10540
        })( $.fn.show ),
10541
10542
        hide: (function( orig ) {
10543
                return function( option ) {
10544
                        if ( standardAnimationOption( option ) ) {
10545
                                return orig.apply( this, arguments );
10546
                        } else {
10547
                                var args = _normalizeArguments.apply( this, arguments );
10548
                                args.mode = "hide";
10549
                                return this.effect.call( this, args );
10550
                        }
10551
                };
10552
        })( $.fn.hide ),
10553
10554
        toggle: (function( orig ) {
10555
                return function( option ) {
10556
                        if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
10557
                                return orig.apply( this, arguments );
10558
                        } else {
10559
                                var args = _normalizeArguments.apply( this, arguments );
10560
                                args.mode = "toggle";
10561
                                return this.effect.call( this, args );
10562
                        }
10563
                };
10564
        })( $.fn.toggle ),
10565
10566
        // helper functions
10567
        cssUnit: function(key) {
10568
                var style = this.css( key ),
10569
                        val = [];
10570
10571
                $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
10572
                        if ( style.indexOf( unit ) > 0 ) {
10573
                                val = [ parseFloat( style ), unit ];
10574
                        }
10575
                });
10576
                return val;
10577
        }
10578
});
10579
10580
})();
10581
10582
/******************************************************************************/
10583
/*********************************** EASING ***********************************/
10584
/******************************************************************************/
10585
10586
(function() {
10587
10588
// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
10589
10590
var baseEasings = {};
10591
10592
$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
10593
        baseEasings[ name ] = function( p ) {
10594
                return Math.pow( p, i + 2 );
10595
        };
10596
});
10597
10598
$.extend( baseEasings, {
10599
        Sine: function( p ) {
10600
                return 1 - Math.cos( p * Math.PI / 2 );
10601
        },
10602
        Circ: function( p ) {
10603
                return 1 - Math.sqrt( 1 - p * p );
10604
        },
10605
        Elastic: function( p ) {
10606
                return p === 0 || p === 1 ? p :
10607
                        -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
10608
        },
10609
        Back: function( p ) {
10610
                return p * p * ( 3 * p - 2 );
10611
        },
10612
        Bounce: function( p ) {
10613
                var pow2,
10614
                        bounce = 4;
10615
10616
                while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
10617
                return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
10618
        }
10619
});
10620
10621
$.each( baseEasings, function( name, easeIn ) {
10622
        $.easing[ "easeIn" + name ] = easeIn;
10623
        $.easing[ "easeOut" + name ] = function( p ) {
10624
                return 1 - easeIn( 1 - p );
10625
        };
10626
        $.easing[ "easeInOut" + name ] = function( p ) {
10627
                return p < 0.5 ?
10628
                        easeIn( p * 2 ) / 2 :
10629
                        1 - easeIn( p * -2 + 2 ) / 2;
10630
        };
10631
});
10632
10633
})();
10634
10635
var effect = $.effects;
10636
10637
10638
/*!
10639
 * jQuery UI Effects Blind 1.11.4
10640
 * http://jqueryui.com
10641
 *
10642
 * Copyright jQuery Foundation and other contributors
10643
 * Released under the MIT license.
10644
 * http://jquery.org/license
10645
 *
10646
 * http://api.jqueryui.com/blind-effect/
10647
 */
10648
10649
10650
var effectBlind = $.effects.effect.blind = function( o, done ) {
10651
        // Create element
10652
        var el = $( this ),
10653
                rvertical = /up|down|vertical/,
10654
                rpositivemotion = /up|left|vertical|horizontal/,
10655
                props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10656
                mode = $.effects.setMode( el, o.mode || "hide" ),
10657
                direction = o.direction || "up",
10658
                vertical = rvertical.test( direction ),
10659
                ref = vertical ? "height" : "width",
10660
                ref2 = vertical ? "top" : "left",
10661
                motion = rpositivemotion.test( direction ),
10662
                animation = {},
10663
                show = mode === "show",
10664
                wrapper, distance, margin;
10665
10666
        // if already wrapped, the wrapper's properties are my property. #6245
10667
        if ( el.parent().is( ".ui-effects-wrapper" ) ) {
10668
                $.effects.save( el.parent(), props );
10669
        } else {
10670
                $.effects.save( el, props );
10671
        }
10672
        el.show();
10673
        wrapper = $.effects.createWrapper( el ).css({
10674
                overflow: "hidden"
10675
        });
10676
10677
        distance = wrapper[ ref ]();
10678
        margin = parseFloat( wrapper.css( ref2 ) ) || 0;
10679
10680
        animation[ ref ] = show ? distance : 0;
10681
        if ( !motion ) {
10682
                el
10683
                        .css( vertical ? "bottom" : "right", 0 )
10684
                        .css( vertical ? "top" : "left", "auto" )
10685
                        .css({ position: "absolute" });
10686
10687
                animation[ ref2 ] = show ? margin : distance + margin;
10688
        }
10689
10690
        // start at 0 if we are showing
10691
        if ( show ) {
10692
                wrapper.css( ref, 0 );
10693
                if ( !motion ) {
10694
                        wrapper.css( ref2, margin + distance );
10695
                }
10696
        }
10697
10698
        // Animate
10699
        wrapper.animate( animation, {
10700
                duration: o.duration,
10701
                easing: o.easing,
10702
                queue: false,
10703
                complete: function() {
10704
                        if ( mode === "hide" ) {
10705
                                el.hide();
10706
                        }
10707
                        $.effects.restore( el, props );
10708
                        $.effects.removeWrapper( el );
10709
                        done();
10710
                }
10711
        });
10712
};
10713
10714
10715
/*!
10716
 * jQuery UI Effects Bounce 1.11.4
10717
 * http://jqueryui.com
10718
 *
10719
 * Copyright jQuery Foundation and other contributors
10720
 * Released under the MIT license.
10721
 * http://jquery.org/license
10722
 *
10723
 * http://api.jqueryui.com/bounce-effect/
10724
 */
10725
10726
10727
var effectBounce = $.effects.effect.bounce = function( o, done ) {
10728
        var el = $( this ),
10729
                props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10730
10731
                // defaults:
10732
                mode = $.effects.setMode( el, o.mode || "effect" ),
10733
                hide = mode === "hide",
10734
                show = mode === "show",
10735
                direction = o.direction || "up",
10736
                distance = o.distance,
10737
                times = o.times || 5,
10738
10739
                // number of internal animations
10740
                anims = times * 2 + ( show || hide ? 1 : 0 ),
10741
                speed = o.duration / anims,
10742
                easing = o.easing,
10743
10744
                // utility:
10745
                ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10746
                motion = ( direction === "up" || direction === "left" ),
10747
                i,
10748
                upAnim,
10749
                downAnim,
10750
10751
                // we will need to re-assemble the queue to stack our animations in place
10752
                queue = el.queue(),
10753
                queuelen = queue.length;
10754
10755
        // Avoid touching opacity to prevent clearType and PNG issues in IE
10756
        if ( show || hide ) {
10757
                props.push( "opacity" );
10758
        }
10759
10760
        $.effects.save( el, props );
10761
        el.show();
10762
        $.effects.createWrapper( el ); // Create Wrapper
10763
10764
        // default distance for the BIGGEST bounce is the outer Distance / 3
10765
        if ( !distance ) {
10766
                distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
10767
        }
10768
10769
        if ( show ) {
10770
                downAnim = { opacity: 1 };
10771
                downAnim[ ref ] = 0;
10772
10773
                // if we are showing, force opacity 0 and set the initial position
10774
                // then do the "first" animation
10775
                el.css( "opacity", 0 )
10776
                        .css( ref, motion ? -distance * 2 : distance * 2 )
10777
                        .animate( downAnim, speed, easing );
10778
        }
10779
10780
        // start at the smallest distance if we are hiding
10781
        if ( hide ) {
10782
                distance = distance / Math.pow( 2, times - 1 );
10783
        }
10784
10785
        downAnim = {};
10786
        downAnim[ ref ] = 0;
10787
        // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
10788
        for ( i = 0; i < times; i++ ) {
10789
                upAnim = {};
10790
                upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10791
10792
                el.animate( upAnim, speed, easing )
10793
                        .animate( downAnim, speed, easing );
10794
10795
                distance = hide ? distance * 2 : distance / 2;
10796
        }
10797
10798
        // Last Bounce when Hiding
10799
        if ( hide ) {
10800
                upAnim = { opacity: 0 };
10801
                upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10802
10803
                el.animate( upAnim, speed, easing );
10804
        }
10805
10806
        el.queue(function() {
10807
                if ( hide ) {
10808
                        el.hide();
10809
                }
10810
                $.effects.restore( el, props );
10811
                $.effects.removeWrapper( el );
10812
                done();
10813
        });
10814
10815
        // inject all the animations we just queued to be first in line (after "inprogress")
10816
        if ( queuelen > 1) {
10817
                queue.splice.apply( queue,
10818
                        [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10819
        }
10820
        el.dequeue();
10821
10822
};
10823
10824
10825
/*!
10826
 * jQuery UI Effects Clip 1.11.4
10827
 * http://jqueryui.com
10828
 *
10829
 * Copyright jQuery Foundation and other contributors
10830
 * Released under the MIT license.
10831
 * http://jquery.org/license
10832
 *
10833
 * http://api.jqueryui.com/clip-effect/
10834
 */
10835
10836
10837
var effectClip = $.effects.effect.clip = function( o, done ) {
10838
        // Create element
10839
        var el = $( this ),
10840
                props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10841
                mode = $.effects.setMode( el, o.mode || "hide" ),
10842
                show = mode === "show",
10843
                direction = o.direction || "vertical",
10844
                vert = direction === "vertical",
10845
                size = vert ? "height" : "width",
10846
                position = vert ? "top" : "left",
10847
                animation = {},
10848
                wrapper, animate, distance;
10849
10850
        // Save & Show
10851
        $.effects.save( el, props );
10852
        el.show();
10853
10854
        // Create Wrapper
10855
        wrapper = $.effects.createWrapper( el ).css({
10856
                overflow: "hidden"
10857
        });
10858
        animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
10859
        distance = animate[ size ]();
10860
10861
        // Shift
10862
        if ( show ) {
10863
                animate.css( size, 0 );
10864
                animate.css( position, distance / 2 );
10865
        }
10866
10867
        // Create Animation Object:
10868
        animation[ size ] = show ? distance : 0;
10869
        animation[ position ] = show ? 0 : distance / 2;
10870
10871
        // Animate
10872
        animate.animate( animation, {
10873
                queue: false,
10874
                duration: o.duration,
10875
                easing: o.easing,
10876
                complete: function() {
10877
                        if ( !show ) {
10878
                                el.hide();
10879
                        }
10880
                        $.effects.restore( el, props );
10881
                        $.effects.removeWrapper( el );
10882
                        done();
10883
                }
10884
        });
10885
10886
};
10887
10888
10889
/*!
10890
 * jQuery UI Effects Drop 1.11.4
10891
 * http://jqueryui.com
10892
 *
10893
 * Copyright jQuery Foundation and other contributors
10894
 * Released under the MIT license.
10895
 * http://jquery.org/license
10896
 *
10897
 * http://api.jqueryui.com/drop-effect/
10898
 */
10899
10900
10901
var effectDrop = $.effects.effect.drop = function( o, done ) {
10902
10903
        var el = $( this ),
10904
                props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
10905
                mode = $.effects.setMode( el, o.mode || "hide" ),
10906
                show = mode === "show",
10907
                direction = o.direction || "left",
10908
                ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10909
                motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
10910
                animation = {
10911
                        opacity: show ? 1 : 0
10912
                },
10913
                distance;
10914
10915
        // Adjust
10916
        $.effects.save( el, props );
10917
        el.show();
10918
        $.effects.createWrapper( el );
10919
10920
        distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
10921
10922
        if ( show ) {
10923
                el
10924
                        .css( "opacity", 0 )
10925
                        .css( ref, motion === "pos" ? -distance : distance );
10926
        }
10927
10928
        // Animation
10929
        animation[ ref ] = ( show ?
10930
                ( motion === "pos" ? "+=" : "-=" ) :
10931
                ( motion === "pos" ? "-=" : "+=" ) ) +
10932
                distance;
10933
10934
        // Animate
10935
        el.animate( animation, {
10936
                queue: false,
10937
                duration: o.duration,
10938
                easing: o.easing,
10939
                complete: function() {
10940
                        if ( mode === "hide" ) {
10941
                                el.hide();
10942
                        }
10943
                        $.effects.restore( el, props );
10944
                        $.effects.removeWrapper( el );
10945
                        done();
10946
                }
10947
        });
10948
};
10949
10950
10951
/*!
10952
 * jQuery UI Effects Explode 1.11.4
10953
 * http://jqueryui.com
10954
 *
10955
 * Copyright jQuery Foundation and other contributors
10956
 * Released under the MIT license.
10957
 * http://jquery.org/license
10958
 *
10959
 * http://api.jqueryui.com/explode-effect/
10960
 */
10961
10962
10963
var effectExplode = $.effects.effect.explode = function( o, done ) {
10964
10965
        var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
10966
                cells = rows,
10967
                el = $( this ),
10968
                mode = $.effects.setMode( el, o.mode || "hide" ),
10969
                show = mode === "show",
10970
10971
                // show and then visibility:hidden the element before calculating offset
10972
                offset = el.show().css( "visibility", "hidden" ).offset(),
10973
10974
                // width and height of a piece
10975
                width = Math.ceil( el.outerWidth() / cells ),
10976
                height = Math.ceil( el.outerHeight() / rows ),
10977
                pieces = [],
10978
10979
                // loop
10980
                i, j, left, top, mx, my;
10981
10982
        // children animate complete:
10983
        function childComplete() {
10984
                pieces.push( this );
10985
                if ( pieces.length === rows * cells ) {
10986
                        animComplete();
10987
                }
10988
        }
10989
10990
        // clone the element for each row and cell.
10991
        for ( i = 0; i < rows ; i++ ) { // ===>
10992
                top = offset.top + i * height;
10993
                my = i - ( rows - 1 ) / 2 ;
10994
10995
                for ( j = 0; j < cells ; j++ ) { // |||
10996
                        left = offset.left + j * width;
10997
                        mx = j - ( cells - 1 ) / 2 ;
10998
10999
                        // Create a clone of the now hidden main element that will be absolute positioned
11000
                        // within a wrapper div off the -left and -top equal to size of our pieces
11001
                        el
11002
                                .clone()
11003
                                .appendTo( "body" )
11004
                                .wrap( "<div></div>" )
11005
                                .css({
11006
                                        position: "absolute",
11007
                                        visibility: "visible",
11008
                                        left: -j * width,
11009
                                        top: -i * height
11010
                                })
11011
11012
                        // select the wrapper - make it overflow: hidden and absolute positioned based on
11013
                        // where the original was located +left and +top equal to the size of pieces
11014
                                .parent()
11015
                                .addClass( "ui-effects-explode" )
11016
                                .css({
11017
                                        position: "absolute",
11018
                                        overflow: "hidden",
11019
                                        width: width,
11020
                                        height: height,
11021
                                        left: left + ( show ? mx * width : 0 ),
11022
                                        top: top + ( show ? my * height : 0 ),
11023
                                        opacity: show ? 0 : 1
11024
                                }).animate({
11025
                                        left: left + ( show ? 0 : mx * width ),
11026
                                        top: top + ( show ? 0 : my * height ),
11027
                                        opacity: show ? 1 : 0
11028
                                }, o.duration || 500, o.easing, childComplete );
11029
                }
11030
        }
11031
11032
        function animComplete() {
11033
                el.css({
11034
                        visibility: "visible"
11035
                });
11036
                $( pieces ).remove();
11037
                if ( !show ) {
11038
                        el.hide();
11039
                }
11040
                done();
11041
        }
11042
};
11043
11044
11045
/*!
11046
 * jQuery UI Effects Fade 1.11.4
11047
 * http://jqueryui.com
11048
 *
11049
 * Copyright jQuery Foundation and other contributors
11050
 * Released under the MIT license.
11051
 * http://jquery.org/license
11052
 *
11053
 * http://api.jqueryui.com/fade-effect/
11054
 */
11055
11056
11057
var effectFade = $.effects.effect.fade = function( o, done ) {
11058
        var el = $( this ),
11059
                mode = $.effects.setMode( el, o.mode || "toggle" );
11060
11061
        el.animate({
11062
                opacity: mode
11063
        }, {
11064
                queue: false,
11065
                duration: o.duration,
11066
                easing: o.easing,
11067
                complete: done
11068
        });
11069
};
11070
11071
11072
/*!
11073
 * jQuery UI Effects Fold 1.11.4
11074
 * http://jqueryui.com
11075
 *
11076
 * Copyright jQuery Foundation and other contributors
11077
 * Released under the MIT license.
11078
 * http://jquery.org/license
11079
 *
11080
 * http://api.jqueryui.com/fold-effect/
11081
 */
11082
11083
11084
var effectFold = $.effects.effect.fold = function( o, done ) {
11085
11086
        // Create element
11087
        var el = $( this ),
11088
                props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
11089
                mode = $.effects.setMode( el, o.mode || "hide" ),
11090
                show = mode === "show",
11091
                hide = mode === "hide",
11092
                size = o.size || 15,
11093
                percent = /([0-9]+)%/.exec( size ),
11094
                horizFirst = !!o.horizFirst,
11095
                widthFirst = show !== horizFirst,
11096
                ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
11097
                duration = o.duration / 2,
11098
                wrapper, distance,
11099
                animation1 = {},
11100
                animation2 = {};
11101
11102
        $.effects.save( el, props );
11103
        el.show();
11104
11105
        // Create Wrapper
11106
        wrapper = $.effects.createWrapper( el ).css({
11107
                overflow: "hidden"
11108
        });
11109
        distance = widthFirst ?
11110
                [ wrapper.width(), wrapper.height() ] :
11111
                [ wrapper.height(), wrapper.width() ];
11112
11113
        if ( percent ) {
11114
                size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
11115
        }
11116
        if ( show ) {
11117
                wrapper.css( horizFirst ? {
11118
                        height: 0,
11119
                        width: size
11120
                } : {
11121
                        height: size,
11122
                        width: 0
11123
                });
11124
        }
11125
11126
        // Animation
11127
        animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
11128
        animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
11129
11130
        // Animate
11131
        wrapper
11132
                .animate( animation1, duration, o.easing )
11133
                .animate( animation2, duration, o.easing, function() {
11134
                        if ( hide ) {
11135
                                el.hide();
11136
                        }
11137
                        $.effects.restore( el, props );
11138
                        $.effects.removeWrapper( el );
11139
                        done();
11140
                });
11141
11142
};
11143
11144
11145
/*!
11146
 * jQuery UI Effects Highlight 1.11.4
11147
 * http://jqueryui.com
11148
 *
11149
 * Copyright jQuery Foundation and other contributors
11150
 * Released under the MIT license.
11151
 * http://jquery.org/license
11152
 *
11153
 * http://api.jqueryui.com/highlight-effect/
11154
 */
11155
11156
11157
var effectHighlight = $.effects.effect.highlight = function( o, done ) {
11158
        var elem = $( this ),
11159
                props = [ "backgroundImage", "backgroundColor", "opacity" ],
11160
                mode = $.effects.setMode( elem, o.mode || "show" ),
11161
                animation = {
11162
                        backgroundColor: elem.css( "backgroundColor" )
11163
                };
11164
11165
        if (mode === "hide") {
11166
                animation.opacity = 0;
11167
        }
11168
11169
        $.effects.save( elem, props );
11170
11171
        elem
11172
                .show()
11173
                .css({
11174
                        backgroundImage: "none",
11175
                        backgroundColor: o.color || "#ffff99"
11176
                })
11177
                .animate( animation, {
11178
                        queue: false,
11179
                        duration: o.duration,
11180
                        easing: o.easing,
11181
                        complete: function() {
11182
                                if ( mode === "hide" ) {
11183
                                        elem.hide();
11184
                                }
11185
                                $.effects.restore( elem, props );
11186
                                done();
11187
                        }
11188
                });
11189
};
11190
11191
11192
/*!
11193
 * jQuery UI Effects Size 1.11.4
11194
 * http://jqueryui.com
11195
 *
11196
 * Copyright jQuery Foundation and other contributors
11197
 * Released under the MIT license.
11198
 * http://jquery.org/license
11199
 *
11200
 * http://api.jqueryui.com/size-effect/
11201
 */
11202
11203
11204
var effectSize = $.effects.effect.size = function( o, done ) {
11205
11206
        // Create element
11207
        var original, baseline, factor,
11208
                el = $( this ),
11209
                props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
11210
11211
                // Always restore
11212
                props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
11213
11214
                // Copy for children
11215
                props2 = [ "width", "height", "overflow" ],
11216
                cProps = [ "fontSize" ],
11217
                vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
11218
                hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
11219
11220
                // Set options
11221
                mode = $.effects.setMode( el, o.mode || "effect" ),
11222
                restore = o.restore || mode !== "effect",
11223
                scale = o.scale || "both",
11224
                origin = o.origin || [ "middle", "center" ],
11225
                position = el.css( "position" ),
11226
                props = restore ? props0 : props1,
11227
                zero = {
11228
                        height: 0,
11229
                        width: 0,
11230
                        outerHeight: 0,
11231
                        outerWidth: 0
11232
                };
11233
11234
        if ( mode === "show" ) {
11235
                el.show();
11236
        }
11237
        original = {
11238
                height: el.height(),
11239
                width: el.width(),
11240
                outerHeight: el.outerHeight(),
11241
                outerWidth: el.outerWidth()
11242
        };
11243
11244
        if ( o.mode === "toggle" && mode === "show" ) {
11245
                el.from = o.to || zero;
11246
                el.to = o.from || original;
11247
        } else {
11248
                el.from = o.from || ( mode === "show" ? zero : original );
11249
                el.to = o.to || ( mode === "hide" ? zero : original );
11250
        }
11251
11252
        // Set scaling factor
11253
        factor = {
11254
                from: {
11255
                        y: el.from.height / original.height,
11256
                        x: el.from.width / original.width
11257
                },
11258
                to: {
11259
                        y: el.to.height / original.height,
11260
                        x: el.to.width / original.width
11261
                }
11262
        };
11263
11264
        // Scale the css box
11265
        if ( scale === "box" || scale === "both" ) {
11266
11267
                // Vertical props scaling
11268
                if ( factor.from.y !== factor.to.y ) {
11269
                        props = props.concat( vProps );
11270
                        el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
11271
                        el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
11272
                }
11273
11274
                // Horizontal props scaling
11275
                if ( factor.from.x !== factor.to.x ) {
11276
                        props = props.concat( hProps );
11277
                        el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
11278
                        el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
11279
                }
11280
        }
11281
11282
        // Scale the content
11283
        if ( scale === "content" || scale === "both" ) {
11284
11285
                // Vertical props scaling
11286
                if ( factor.from.y !== factor.to.y ) {
11287
                        props = props.concat( cProps ).concat( props2 );
11288
                        el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
11289
                        el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
11290
                }
11291
        }
11292
11293
        $.effects.save( el, props );
11294
        el.show();
11295
        $.effects.createWrapper( el );
11296
        el.css( "overflow", "hidden" ).css( el.from );
11297
11298
        // Adjust
11299
        if (origin) { // Calculate baseline shifts
11300
                baseline = $.effects.getBaseline( origin, original );
11301
                el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
11302
                el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
11303
                el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
11304
                el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
11305
        }
11306
        el.css( el.from ); // set top & left
11307
11308
        // Animate
11309
        if ( scale === "content" || scale === "both" ) { // Scale the children
11310
11311
                // Add margins/font-size
11312
                vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
11313
                hProps = hProps.concat([ "marginLeft", "marginRight" ]);
11314
                props2 = props0.concat(vProps).concat(hProps);
11315
11316
                el.find( "*[width]" ).each( function() {
11317
                        var child = $( this ),
11318
                                c_original = {
11319
                                        height: child.height(),
11320
                                        width: child.width(),
11321
                                        outerHeight: child.outerHeight(),
11322
                                        outerWidth: child.outerWidth()
11323
                                };
11324
                        if (restore) {
11325
                                $.effects.save(child, props2);
11326
                        }
11327
11328
                        child.from = {
11329
                                height: c_original.height * factor.from.y,
11330
                                width: c_original.width * factor.from.x,
11331
                                outerHeight: c_original.outerHeight * factor.from.y,
11332
                                outerWidth: c_original.outerWidth * factor.from.x
11333
                        };
11334
                        child.to = {
11335
                                height: c_original.height * factor.to.y,
11336
                                width: c_original.width * factor.to.x,
11337
                                outerHeight: c_original.height * factor.to.y,
11338
                                outerWidth: c_original.width * factor.to.x
11339
                        };
11340
11341
                        // Vertical props scaling
11342
                        if ( factor.from.y !== factor.to.y ) {
11343
                                child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
11344
                                child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
11345
                        }
11346
11347
                        // Horizontal props scaling
11348
                        if ( factor.from.x !== factor.to.x ) {
11349
                                child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
11350
                                child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
11351
                        }
11352
11353
                        // Animate children
11354
                        child.css( child.from );
11355
                        child.animate( child.to, o.duration, o.easing, function() {
11356
11357
                                // Restore children
11358
                                if ( restore ) {
11359
                                        $.effects.restore( child, props2 );
11360
                                }
11361
                        });
11362
                });
11363
        }
11364
11365
        // Animate
11366
        el.animate( el.to, {
11367
                queue: false,
11368
                duration: o.duration,
11369
                easing: o.easing,
11370
                complete: function() {
11371
                        if ( el.to.opacity === 0 ) {
11372
                                el.css( "opacity", el.from.opacity );
11373
                        }
11374
                        if ( mode === "hide" ) {
11375
                                el.hide();
11376
                        }
11377
                        $.effects.restore( el, props );
11378
                        if ( !restore ) {
11379
11380
                                // we need to calculate our new positioning based on the scaling
11381
                                if ( position === "static" ) {
11382
                                        el.css({
11383
                                                position: "relative",
11384
                                                top: el.to.top,
11385
                                                left: el.to.left
11386
                                        });
11387
                                } else {
11388
                                        $.each([ "top", "left" ], function( idx, pos ) {
11389
                                                el.css( pos, function( _, str ) {
11390
                                                        var val = parseInt( str, 10 ),
11391
                                                                toRef = idx ? el.to.left : el.to.top;
11392
11393
                                                        // if original was "auto", recalculate the new value from wrapper
11394
                                                        if ( str === "auto" ) {
11395
                                                                return toRef + "px";
11396
                                                        }
11397
11398
                                                        return val + toRef + "px";
11399
                                                });
11400
                                        });
11401
                                }
11402
                        }
11403
11404
                        $.effects.removeWrapper( el );
11405
                        done();
11406
                }
11407
        });
11408
11409
};
11410
11411
11412
/*!
11413
 * jQuery UI Effects Scale 1.11.4
11414
 * http://jqueryui.com
11415
 *
11416
 * Copyright jQuery Foundation and other contributors
11417
 * Released under the MIT license.
11418
 * http://jquery.org/license
11419
 *
11420
 * http://api.jqueryui.com/scale-effect/
11421
 */
11422
11423
11424
var effectScale = $.effects.effect.scale = function( o, done ) {
11425
11426
        // Create element
11427
        var el = $( this ),
11428
                options = $.extend( true, {}, o ),
11429
                mode = $.effects.setMode( el, o.mode || "effect" ),
11430
                percent = parseInt( o.percent, 10 ) ||
11431
                        ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
11432
                direction = o.direction || "both",
11433
                origin = o.origin,
11434
                original = {
11435
                        height: el.height(),
11436
                        width: el.width(),
11437
                        outerHeight: el.outerHeight(),
11438
                        outerWidth: el.outerWidth()
11439
                },
11440
                factor = {
11441
                        y: direction !== "horizontal" ? (percent / 100) : 1,
11442
                        x: direction !== "vertical" ? (percent / 100) : 1
11443
                };
11444
11445
        // We are going to pass this effect to the size effect:
11446
        options.effect = "size";
11447
        options.queue = false;
11448
        options.complete = done;
11449
11450
        // Set default origin and restore for show/hide
11451
        if ( mode !== "effect" ) {
11452
                options.origin = origin || [ "middle", "center" ];
11453
                options.restore = true;
11454
        }
11455
11456
        options.from = o.from || ( mode === "show" ? {
11457
                height: 0,
11458
                width: 0,
11459
                outerHeight: 0,
11460
                outerWidth: 0
11461
        } : original );
11462
        options.to = {
11463
                height: original.height * factor.y,
11464
                width: original.width * factor.x,
11465
                outerHeight: original.outerHeight * factor.y,
11466
                outerWidth: original.outerWidth * factor.x
11467
        };
11468
11469
        // Fade option to support puff
11470
        if ( options.fade ) {
11471
                if ( mode === "show" ) {
11472
                        options.from.opacity = 0;
11473
                        options.to.opacity = 1;
11474
                }
11475
                if ( mode === "hide" ) {
11476
                        options.from.opacity = 1;
11477
                        options.to.opacity = 0;
11478
                }
11479
        }
11480
11481
        // Animate
11482
        el.effect( options );
11483
11484
};
11485
11486
11487
/*!
11488
 * jQuery UI Effects Puff 1.11.4
11489
 * http://jqueryui.com
11490
 *
11491
 * Copyright jQuery Foundation and other contributors
11492
 * Released under the MIT license.
11493
 * http://jquery.org/license
11494
 *
11495
 * http://api.jqueryui.com/puff-effect/
11496
 */
11497
11498
11499
var effectPuff = $.effects.effect.puff = function( o, done ) {
11500
        var elem = $( this ),
11501
                mode = $.effects.setMode( elem, o.mode || "hide" ),
11502
                hide = mode === "hide",
11503
                percent = parseInt( o.percent, 10 ) || 150,
11504
                factor = percent / 100,
11505
                original = {
11506
                        height: elem.height(),
11507
                        width: elem.width(),
11508
                        outerHeight: elem.outerHeight(),
11509
                        outerWidth: elem.outerWidth()
11510
                };
11511
11512
        $.extend( o, {
11513
                effect: "scale",
11514
                queue: false,
11515
                fade: true,
11516
                mode: mode,
11517
                complete: done,
11518
                percent: hide ? percent : 100,
11519
                from: hide ?
11520
                        original :
11521
                        {
11522
                                height: original.height * factor,
11523
                                width: original.width * factor,
11524
                                outerHeight: original.outerHeight * factor,
11525
                                outerWidth: original.outerWidth * factor
11526
                        }
11527
        });
11528
11529
        elem.effect( o );
11530
};
11531
11532
11533
/*!
11534
 * jQuery UI Effects Pulsate 1.11.4
11535
 * http://jqueryui.com
11536
 *
11537
 * Copyright jQuery Foundation and other contributors
11538
 * Released under the MIT license.
11539
 * http://jquery.org/license
11540
 *
11541
 * http://api.jqueryui.com/pulsate-effect/
11542
 */
11543
11544
11545
var effectPulsate = $.effects.effect.pulsate = function( o, done ) {
11546
        var elem = $( this ),
11547
                mode = $.effects.setMode( elem, o.mode || "show" ),
11548
                show = mode === "show",
11549
                hide = mode === "hide",
11550
                showhide = ( show || mode === "hide" ),
11551
11552
                // showing or hiding leaves of the "last" animation
11553
                anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
11554
                duration = o.duration / anims,
11555
                animateTo = 0,
11556
                queue = elem.queue(),
11557
                queuelen = queue.length,
11558
                i;
11559
11560
        if ( show || !elem.is(":visible")) {
11561
                elem.css( "opacity", 0 ).show();
11562
                animateTo = 1;
11563
        }
11564
11565
        // anims - 1 opacity "toggles"
11566
        for ( i = 1; i < anims; i++ ) {
11567
                elem.animate({
11568
                        opacity: animateTo
11569
                }, duration, o.easing );
11570
                animateTo = 1 - animateTo;
11571
        }
11572
11573
        elem.animate({
11574
                opacity: animateTo
11575
        }, duration, o.easing);
11576
11577
        elem.queue(function() {
11578
                if ( hide ) {
11579
                        elem.hide();
11580
                }
11581
                done();
11582
        });
11583
11584
        // We just queued up "anims" animations, we need to put them next in the queue
11585
        if ( queuelen > 1 ) {
11586
                queue.splice.apply( queue,
11587
                        [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
11588
        }
11589
        elem.dequeue();
11590
};
11591
11592
11593
/*!
11594
 * jQuery UI Effects Shake 1.11.4
11595
 * http://jqueryui.com
11596
 *
11597
 * Copyright jQuery Foundation and other contributors
11598
 * Released under the MIT license.
11599
 * http://jquery.org/license
11600
 *
11601
 * http://api.jqueryui.com/shake-effect/
11602
 */
11603
11604
11605
var effectShake = $.effects.effect.shake = function( o, done ) {
11606
11607
        var el = $( this ),
11608
                props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
11609
                mode = $.effects.setMode( el, o.mode || "effect" ),
11610
                direction = o.direction || "left",
11611
                distance = o.distance || 20,
11612
                times = o.times || 3,
11613
                anims = times * 2 + 1,
11614
                speed = Math.round( o.duration / anims ),
11615
                ref = (direction === "up" || direction === "down") ? "top" : "left",
11616
                positiveMotion = (direction === "up" || direction === "left"),
11617
                animation = {},
11618
                animation1 = {},
11619
                animation2 = {},
11620
                i,
11621
11622
                // we will need to re-assemble the queue to stack our animations in place
11623
                queue = el.queue(),
11624
                queuelen = queue.length;
11625
11626
        $.effects.save( el, props );
11627
        el.show();
11628
        $.effects.createWrapper( el );
11629
11630
        // Animation
11631
        animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
11632
        animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
11633
        animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
11634
11635
        // Animate
11636
        el.animate( animation, speed, o.easing );
11637
11638
        // Shakes
11639
        for ( i = 1; i < times; i++ ) {
11640
                el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
11641
        }
11642
        el
11643
                .animate( animation1, speed, o.easing )
11644
                .animate( animation, speed / 2, o.easing )
11645
                .queue(function() {
11646
                        if ( mode === "hide" ) {
11647
                                el.hide();
11648
                        }
11649
                        $.effects.restore( el, props );
11650
                        $.effects.removeWrapper( el );
11651
                        done();
11652
                });
11653
11654
        // inject all the animations we just queued to be first in line (after "inprogress")
11655
        if ( queuelen > 1) {
11656
                queue.splice.apply( queue,
11657
                        [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
11658
        }
11659
        el.dequeue();
11660
11661
};
11662
11663
11664
/*!
11665
 * jQuery UI Effects Slide 1.11.4
11666
 * http://jqueryui.com
11667
 *
11668
 * Copyright jQuery Foundation and other contributors
11669
 * Released under the MIT license.
11670
 * http://jquery.org/license
11671
 *
11672
 * http://api.jqueryui.com/slide-effect/
11673
 */
11674
11675
11676
var effectSlide = $.effects.effect.slide = function( o, done ) {
11677
11678
        // Create element
11679
        var el = $( this ),
11680
                props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
11681
                mode = $.effects.setMode( el, o.mode || "show" ),
11682
                show = mode === "show",
11683
                direction = o.direction || "left",
11684
                ref = (direction === "up" || direction === "down") ? "top" : "left",
11685
                positiveMotion = (direction === "up" || direction === "left"),
11686
                distance,
11687
                animation = {};
11688
11689
        // Adjust
11690
        $.effects.save( el, props );
11691
        el.show();
11692
        distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
11693
11694
        $.effects.createWrapper( el ).css({
11695
                overflow: "hidden"
11696
        });
11697
11698
        if ( show ) {
11699
                el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
11700
        }
11701
11702
        // Animation
11703
        animation[ ref ] = ( show ?
11704
                ( positiveMotion ? "+=" : "-=") :
11705
                ( positiveMotion ? "-=" : "+=")) +
11706
                distance;
11707
11708
        // Animate
11709
        el.animate( animation, {
11710
                queue: false,
11711
                duration: o.duration,
11712
                easing: o.easing,
11713
                complete: function() {
11714
                        if ( mode === "hide" ) {
11715
                                el.hide();
11716
                        }
11717
                        $.effects.restore( el, props );
11718
                        $.effects.removeWrapper( el );
11719
                        done();
11720
                }
11721
        });
11722
};
11723
11724
11725
/*!
11726
 * jQuery UI Effects Transfer 1.11.4
11727
 * http://jqueryui.com
11728
 *
11729
 * Copyright jQuery Foundation and other contributors
11730
 * Released under the MIT license.
11731
 * http://jquery.org/license
11732
 *
11733
 * http://api.jqueryui.com/transfer-effect/
11734
 */
11735
11736
11737
var effectTransfer = $.effects.effect.transfer = function( o, done ) {
11738
        var elem = $( this ),
11739
                target = $( o.to ),
11740
                targetFixed = target.css( "position" ) === "fixed",
11741
                body = $("body"),
11742
                fixTop = targetFixed ? body.scrollTop() : 0,
11743
                fixLeft = targetFixed ? body.scrollLeft() : 0,
11744
                endPosition = target.offset(),
11745
                animation = {
11746
                        top: endPosition.top - fixTop,
11747
                        left: endPosition.left - fixLeft,
11748
                        height: target.innerHeight(),
11749
                        width: target.innerWidth()
11750
                },
11751
                startPosition = elem.offset(),
11752
                transfer = $( "<div class='ui-effects-transfer'></div>" )
11753
                        .appendTo( document.body )
11754
                        .addClass( o.className )
11755
                        .css({
11756
                                top: startPosition.top - fixTop,
11757
                                left: startPosition.left - fixLeft,
11758
                                height: elem.innerHeight(),
11759
                                width: elem.innerWidth(),
11760
                                position: targetFixed ? "fixed" : "absolute"
11761
                        })
11762
                        .animate( animation, o.duration, o.easing, function() {
11763
                                transfer.remove();
11764
                                done();
11765
                        });
11766
};
11767
11768
11769
/*!
11770
 * jQuery UI Progressbar 1.11.4
11771
 * http://jqueryui.com
11772
 *
11773
 * Copyright jQuery Foundation and other contributors
11774
 * Released under the MIT license.
11775
 * http://jquery.org/license
11776
 *
11777
 * http://api.jqueryui.com/progressbar/
11778
 */
11779
11780
11781
var progressbar = $.widget( "ui.progressbar", {
11782
        version: "1.11.4",
11783
        options: {
11784
                max: 100,
11785
                value: 0,
11786
11787
                change: null,
11788
                complete: null
11789
        },
11790
11791
        min: 0,
11792
11793
        _create: function() {
11794
                // Constrain initial value
11795
                this.oldValue = this.options.value = this._constrainedValue();
11796
11797
                this.element
11798
                        .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
11799
                        .attr({
11800
                                // Only set static values, aria-valuenow and aria-valuemax are
11801
                                // set inside _refreshValue()
11802
                                role: "progressbar",
11803
                                "aria-valuemin": this.min
11804
                        });
11805
11806
                this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
11807
                        .appendTo( this.element );
11808
11809
                this._refreshValue();
11810
        },
11811
11812
        _destroy: function() {
11813
                this.element
11814
                        .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
11815
                        .removeAttr( "role" )
11816
                        .removeAttr( "aria-valuemin" )
11817
                        .removeAttr( "aria-valuemax" )
11818
                        .removeAttr( "aria-valuenow" );
11819
11820
                this.valueDiv.remove();
11821
        },
11822
11823
        value: function( newValue ) {
11824
                if ( newValue === undefined ) {
11825
                        return this.options.value;
11826
                }
11827
11828
                this.options.value = this._constrainedValue( newValue );
11829
                this._refreshValue();
11830
        },
11831
11832
        _constrainedValue: function( newValue ) {
11833
                if ( newValue === undefined ) {
11834
                        newValue = this.options.value;
11835
                }
11836
11837
                this.indeterminate = newValue === false;
11838
11839
                // sanitize value
11840
                if ( typeof newValue !== "number" ) {
11841
                        newValue = 0;
11842
                }
11843
11844
                return this.indeterminate ? false :
11845
                        Math.min( this.options.max, Math.max( this.min, newValue ) );
11846
        },
11847
11848
        _setOptions: function( options ) {
11849
                // Ensure "value" option is set after other values (like max)
11850
                var value = options.value;
11851
                delete options.value;
11852
11853
                this._super( options );
11854
11855
                this.options.value = this._constrainedValue( value );
11856
                this._refreshValue();
11857
        },
11858
11859
        _setOption: function( key, value ) {
11860
                if ( key === "max" ) {
11861
                        // Don't allow a max less than min
11862
                        value = Math.max( this.min, value );
11863
                }
11864
                if ( key === "disabled" ) {
11865
                        this.element
11866
                                .toggleClass( "ui-state-disabled", !!value )
11867
                                .attr( "aria-disabled", value );
11868
                }
11869
                this._super( key, value );
11870
        },
11871
11872
        _percentage: function() {
11873
                return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
11874
        },
11875
11876
        _refreshValue: function() {
11877
                var value = this.options.value,
11878
                        percentage = this._percentage();
11879
11880
                this.valueDiv
11881
                        .toggle( this.indeterminate || value > this.min )
11882
                        .toggleClass( "ui-corner-right", value === this.options.max )
11883
                        .width( percentage.toFixed(0) + "%" );
11884
11885
                this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
11886
11887
                if ( this.indeterminate ) {
11888
                        this.element.removeAttr( "aria-valuenow" );
11889
                        if ( !this.overlayDiv ) {
11890
                                this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
11891
                        }
11892
                } else {
11893
                        this.element.attr({
11894
                                "aria-valuemax": this.options.max,
11895
                                "aria-valuenow": value
11896
                        });
11897
                        if ( this.overlayDiv ) {
11898
                                this.overlayDiv.remove();
11899
                                this.overlayDiv = null;
11900
                        }
11901
                }
11902
11903
                if ( this.oldValue !== value ) {
11904
                        this.oldValue = value;
11905
                        this._trigger( "change" );
11906
                }
11907
                if ( value === this.options.max ) {
11908
                        this._trigger( "complete" );
11909
                }
11910
        }
11911
});
11912
11913
11914
/*!
11915
 * jQuery UI Selectable 1.11.4
11916
 * http://jqueryui.com
11917
 *
11918
 * Copyright jQuery Foundation and other contributors
11919
 * Released under the MIT license.
11920
 * http://jquery.org/license
11921
 *
11922
 * http://api.jqueryui.com/selectable/
11923
 */
11924
11925
11926
var selectable = $.widget("ui.selectable", $.ui.mouse, {
11927
        version: "1.11.4",
11928
        options: {
11929
                appendTo: "body",
11930
                autoRefresh: true,
11931
                distance: 0,
11932
                filter: "*",
11933
                tolerance: "touch",
11934
11935
                // callbacks
11936
                selected: null,
11937
                selecting: null,
11938
                start: null,
11939
                stop: null,
11940
                unselected: null,
11941
                unselecting: null
11942
        },
11943
        _create: function() {
11944
                var selectees,
11945
                        that = this;
11946
11947
                this.element.addClass("ui-selectable");
11948
11949
                this.dragged = false;
11950
11951
                // cache selectee children based on filter
11952
                this.refresh = function() {
11953
                        selectees = $(that.options.filter, that.element[0]);
11954
                        selectees.addClass("ui-selectee");
11955
                        selectees.each(function() {
11956
                                var $this = $(this),
11957
                                        pos = $this.offset();
11958
                                $.data(this, "selectable-item", {
11959
                                        element: this,
11960
                                        $element: $this,
11961
                                        left: pos.left,
11962
                                        top: pos.top,
11963
                                        right: pos.left + $this.outerWidth(),
11964
                                        bottom: pos.top + $this.outerHeight(),
11965
                                        startselected: false,
11966
                                        selected: $this.hasClass("ui-selected"),
11967
                                        selecting: $this.hasClass("ui-selecting"),
11968
                                        unselecting: $this.hasClass("ui-unselecting")
11969
                                });
11970
                        });
11971
                };
11972
                this.refresh();
11973
11974
                this.selectees = selectees.addClass("ui-selectee");
11975
11976
                this._mouseInit();
11977
11978
                this.helper = $("<div class='ui-selectable-helper'></div>");
11979
        },
11980
11981
        _destroy: function() {
11982
                this.selectees
11983
                        .removeClass("ui-selectee")
11984
                        .removeData("selectable-item");
11985
                this.element
11986
                        .removeClass("ui-selectable ui-selectable-disabled");
11987
                this._mouseDestroy();
11988
        },
11989
11990
        _mouseStart: function(event) {
11991
                var that = this,
11992
                        options = this.options;
11993
11994
                this.opos = [ event.pageX, event.pageY ];
11995
11996
                if (this.options.disabled) {
11997
                        return;
11998
                }
11999
12000
                this.selectees = $(options.filter, this.element[0]);
12001
12002
                this._trigger("start", event);
12003
12004
                $(options.appendTo).append(this.helper);
12005
                // position helper (lasso)
12006
                this.helper.css({
12007
                        "left": event.pageX,
12008
                        "top": event.pageY,
12009
                        "width": 0,
12010
                        "height": 0
12011
                });
12012
12013
                if (options.autoRefresh) {
12014
                        this.refresh();
12015
                }
12016
12017
                this.selectees.filter(".ui-selected").each(function() {
12018
                        var selectee = $.data(this, "selectable-item");
12019
                        selectee.startselected = true;
12020
                        if (!event.metaKey && !event.ctrlKey) {
12021
                                selectee.$element.removeClass("ui-selected");
12022
                                selectee.selected = false;
12023
                                selectee.$element.addClass("ui-unselecting");
12024
                                selectee.unselecting = true;
12025
                                // selectable UNSELECTING callback
12026
                                that._trigger("unselecting", event, {
12027
                                        unselecting: selectee.element
12028
                                });
12029
                        }
12030
                });
12031
12032
                $(event.target).parents().addBack().each(function() {
12033
                        var doSelect,
12034
                                selectee = $.data(this, "selectable-item");
12035
                        if (selectee) {
12036
                                doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
12037
                                selectee.$element
12038
                                        .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
12039
                                        .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
12040
                                selectee.unselecting = !doSelect;
12041
                                selectee.selecting = doSelect;
12042
                                selectee.selected = doSelect;
12043
                                // selectable (UN)SELECTING callback
12044
                                if (doSelect) {
12045
                                        that._trigger("selecting", event, {
12046
                                                selecting: selectee.element
12047
                                        });
12048
                                } else {
12049
                                        that._trigger("unselecting", event, {
12050
                                                unselecting: selectee.element
12051
                                        });
12052
                                }
12053
                                return false;
12054
                        }
12055
                });
12056
12057
        },
12058
12059
        _mouseDrag: function(event) {
12060
12061
                this.dragged = true;
12062
12063
                if (this.options.disabled) {
12064
                        return;
12065
                }
12066
12067
                var tmp,
12068
                        that = this,
12069
                        options = this.options,
12070
                        x1 = this.opos[0],
12071
                        y1 = this.opos[1],
12072
                        x2 = event.pageX,
12073
                        y2 = event.pageY;
12074
12075
                if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
12076
                if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
12077
                this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 });
12078
12079
                this.selectees.each(function() {
12080
                        var selectee = $.data(this, "selectable-item"),
12081
                                hit = false;
12082
12083
                        //prevent helper from being selected if appendTo: selectable
12084
                        if (!selectee || selectee.element === that.element[0]) {
12085
                                return;
12086
                        }
12087
12088
                        if (options.tolerance === "touch") {
12089
                                hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
12090
                        } else if (options.tolerance === "fit") {
12091
                                hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
12092
                        }
12093
12094
                        if (hit) {
12095
                                // SELECT
12096
                                if (selectee.selected) {
12097
                                        selectee.$element.removeClass("ui-selected");
12098
                                        selectee.selected = false;
12099
                                }
12100
                                if (selectee.unselecting) {
12101
                                        selectee.$element.removeClass("ui-unselecting");
12102
                                        selectee.unselecting = false;
12103
                                }
12104
                                if (!selectee.selecting) {
12105
                                        selectee.$element.addClass("ui-selecting");
12106
                                        selectee.selecting = true;
12107
                                        // selectable SELECTING callback
12108
                                        that._trigger("selecting", event, {
12109
                                                selecting: selectee.element
12110
                                        });
12111
                                }
12112
                        } else {
12113
                                // UNSELECT
12114
                                if (selectee.selecting) {
12115
                                        if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
12116
                                                selectee.$element.removeClass("ui-selecting");
12117
                                                selectee.selecting = false;
12118
                                                selectee.$element.addClass("ui-selected");
12119
                                                selectee.selected = true;
12120
                                        } else {
12121
                                                selectee.$element.removeClass("ui-selecting");
12122
                                                selectee.selecting = false;
12123
                                                if (selectee.startselected) {
12124
                                                        selectee.$element.addClass("ui-unselecting");
12125
                                                        selectee.unselecting = true;
12126
                                                }
12127
                                                // selectable UNSELECTING callback
12128
                                                that._trigger("unselecting", event, {
12129
                                                        unselecting: selectee.element
12130
                                                });
12131
                                        }
12132
                                }
12133
                                if (selectee.selected) {
12134
                                        if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
12135
                                                selectee.$element.removeClass("ui-selected");
12136
                                                selectee.selected = false;
12137
12138
                                                selectee.$element.addClass("ui-unselecting");
12139
                                                selectee.unselecting = true;
12140
                                                // selectable UNSELECTING callback
12141
                                                that._trigger("unselecting", event, {
12142
                                                        unselecting: selectee.element
12143
                                                });
12144
                                        }
12145
                                }
12146
                        }
12147
                });
12148
12149
                return false;
12150
        },
12151
12152
        _mouseStop: function(event) {
12153
                var that = this;
12154
12155
                this.dragged = false;
12156
12157
                $(".ui-unselecting", this.element[0]).each(function() {
12158
                        var selectee = $.data(this, "selectable-item");
12159
                        selectee.$element.removeClass("ui-unselecting");
12160
                        selectee.unselecting = false;
12161
                        selectee.startselected = false;
12162
                        that._trigger("unselected", event, {
12163
                                unselected: selectee.element
12164
                        });
12165
                });
12166
                $(".ui-selecting", this.element[0]).each(function() {
12167
                        var selectee = $.data(this, "selectable-item");
12168
                        selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
12169
                        selectee.selecting = false;
12170
                        selectee.selected = true;
12171
                        selectee.startselected = true;
12172
                        that._trigger("selected", event, {
12173
                                selected: selectee.element
12174
                        });
12175
                });
12176
                this._trigger("stop", event);
12177
12178
                this.helper.remove();
12179
12180
                return false;
12181
        }
12182
12183
});
12184
12185
12186
/*!
12187
 * jQuery UI Selectmenu 1.11.4
12188
 * http://jqueryui.com
12189
 *
12190
 * Copyright jQuery Foundation and other contributors
12191
 * Released under the MIT license.
12192
 * http://jquery.org/license
12193
 *
12194
 * http://api.jqueryui.com/selectmenu
12195
 */
12196
12197
12198
var selectmenu = $.widget( "ui.selectmenu", {
12199
        version: "1.11.4",
12200
        defaultElement: "<select>",
12201
        options: {
12202
                appendTo: null,
12203
                disabled: null,
12204
                icons: {
12205
                        button: "ui-icon-triangle-1-s"
12206
                },
12207
                position: {
12208
                        my: "left top",
12209
                        at: "left bottom",
12210
                        collision: "none"
12211
                },
12212
                width: null,
12213
12214
                // callbacks
12215
                change: null,
12216
                close: null,
12217
                focus: null,
12218
                open: null,
12219
                select: null
12220
        },
12221
12222
        _create: function() {
12223
                var selectmenuId = this.element.uniqueId().attr( "id" );
12224
                this.ids = {
12225
                        element: selectmenuId,
12226
                        button: selectmenuId + "-button",
12227
                        menu: selectmenuId + "-menu"
12228
                };
12229
12230
                this._drawButton();
12231
                this._drawMenu();
12232
12233
                if ( this.options.disabled ) {
12234
                        this.disable();
12235
                }
12236
        },
12237
12238
        _drawButton: function() {
12239
                var that = this;
12240
12241
                // Associate existing label with the new button
12242
                this.label = $( "label[for='" + this.ids.element + "']" ).attr( "for", this.ids.button );
12243
                this._on( this.label, {
12244
                        click: function( event ) {
12245
                                this.button.focus();
12246
                                event.preventDefault();
12247
                        }
12248
                });
12249
12250
                // Hide original select element
12251
                this.element.hide();
12252
12253
                // Create button
12254
                this.button = $( "<span>", {
12255
                        "class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all",
12256
                        tabindex: this.options.disabled ? -1 : 0,
12257
                        id: this.ids.button,
12258
                        role: "combobox",
12259
                        "aria-expanded": "false",
12260
                        "aria-autocomplete": "list",
12261
                        "aria-owns": this.ids.menu,
12262
                        "aria-haspopup": "true"
12263
                })
12264
                        .insertAfter( this.element );
12265
12266
                $( "<span>", {
12267
                        "class": "ui-icon " + this.options.icons.button
12268
                })
12269
                        .prependTo( this.button );
12270
12271
                this.buttonText = $( "<span>", {
12272
                        "class": "ui-selectmenu-text"
12273
                })
12274
                        .appendTo( this.button );
12275
12276
                this._setText( this.buttonText, this.element.find( "option:selected" ).text() );
12277
                this._resizeButton();
12278
12279
                this._on( this.button, this._buttonEvents );
12280
                this.button.one( "focusin", function() {
12281
12282
                        // Delay rendering the menu items until the button receives focus.
12283
                        // The menu may have already been rendered via a programmatic open.
12284
                        if ( !that.menuItems ) {
12285
                                that._refreshMenu();
12286
                        }
12287
                });
12288
                this._hoverable( this.button );
12289
                this._focusable( this.button );
12290
        },
12291
12292
        _drawMenu: function() {
12293
                var that = this;
12294
12295
                // Create menu
12296
                this.menu = $( "<ul>", {
12297
                        "aria-hidden": "true",
12298
                        "aria-labelledby": this.ids.button,
12299
                        id: this.ids.menu
12300
                });
12301
12302
                // Wrap menu
12303
                this.menuWrap = $( "<div>", {
12304
                        "class": "ui-selectmenu-menu ui-front"
12305
                })
12306
                        .append( this.menu )
12307
                        .appendTo( this._appendTo() );
12308
12309
                // Initialize menu widget
12310
                this.menuInstance = this.menu
12311
                        .menu({
12312
                                role: "listbox",
12313
                                select: function( event, ui ) {
12314
                                        event.preventDefault();
12315
12316
                                        // support: IE8
12317
                                        // If the item was selected via a click, the text selection
12318
                                        // will be destroyed in IE
12319
                                        that._setSelection();
12320
12321
                                        that._select( ui.item.data( "ui-selectmenu-item" ), event );
12322
                                },
12323
                                focus: function( event, ui ) {
12324
                                        var item = ui.item.data( "ui-selectmenu-item" );
12325
12326
                                        // Prevent inital focus from firing and check if its a newly focused item
12327
                                        if ( that.focusIndex != null && item.index !== that.focusIndex ) {
12328
                                                that._trigger( "focus", event, { item: item } );
12329
                                                if ( !that.isOpen ) {
12330
                                                        that._select( item, event );
12331
                                                }
12332
                                        }
12333
                                        that.focusIndex = item.index;
12334
12335
                                        that.button.attr( "aria-activedescendant",
12336
                                                that.menuItems.eq( item.index ).attr( "id" ) );
12337
                                }
12338
                        })
12339
                        .menu( "instance" );
12340
12341
                // Adjust menu styles to dropdown
12342
                this.menu
12343
                        .addClass( "ui-corner-bottom" )
12344
                        .removeClass( "ui-corner-all" );
12345
12346
                // Don't close the menu on mouseleave
12347
                this.menuInstance._off( this.menu, "mouseleave" );
12348
12349
                // Cancel the menu's collapseAll on document click
12350
                this.menuInstance._closeOnDocumentClick = function() {
12351
                        return false;
12352
                };
12353
12354
                // Selects often contain empty items, but never contain dividers
12355
                this.menuInstance._isDivider = function() {
12356
                        return false;
12357
                };
12358
        },
12359
12360
        refresh: function() {
12361
                this._refreshMenu();
12362
                this._setText( this.buttonText, this._getSelectedItem().text() );
12363
                if ( !this.options.width ) {
12364
                        this._resizeButton();
12365
                }
12366
        },
12367
12368
        _refreshMenu: function() {
12369
                this.menu.empty();
12370
12371
                var item,
12372
                        options = this.element.find( "option" );
12373
12374
                if ( !options.length ) {
12375
                        return;
12376
                }
12377
12378
                this._parseOptions( options );
12379
                this._renderMenu( this.menu, this.items );
12380
12381
                this.menuInstance.refresh();
12382
                this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" );
12383
12384
                item = this._getSelectedItem();
12385
12386
                // Update the menu to have the correct item focused
12387
                this.menuInstance.focus( null, item );
12388
                this._setAria( item.data( "ui-selectmenu-item" ) );
12389
12390
                // Set disabled state
12391
                this._setOption( "disabled", this.element.prop( "disabled" ) );
12392
        },
12393
12394
        open: function( event ) {
12395
                if ( this.options.disabled ) {
12396
                        return;
12397
                }
12398
12399
                // If this is the first time the menu is being opened, render the items
12400
                if ( !this.menuItems ) {
12401
                        this._refreshMenu();
12402
                } else {
12403
12404
                        // Menu clears focus on close, reset focus to selected item
12405
                        this.menu.find( ".ui-state-focus" ).removeClass( "ui-state-focus" );
12406
                        this.menuInstance.focus( null, this._getSelectedItem() );
12407
                }
12408
12409
                this.isOpen = true;
12410
                this._toggleAttr();
12411
                this._resizeMenu();
12412
                this._position();
12413
12414
                this._on( this.document, this._documentClick );
12415
12416
                this._trigger( "open", event );
12417
        },
12418
12419
        _position: function() {
12420
                this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
12421
        },
12422
12423
        close: function( event ) {
12424
                if ( !this.isOpen ) {
12425
                        return;
12426
                }
12427
12428
                this.isOpen = false;
12429
                this._toggleAttr();
12430
12431
                this.range = null;
12432
                this._off( this.document );
12433
12434
                this._trigger( "close", event );
12435
        },
12436
12437
        widget: function() {
12438
                return this.button;
12439
        },
12440
12441
        menuWidget: function() {
12442
                return this.menu;
12443
        },
12444
12445
        _renderMenu: function( ul, items ) {
12446
                var that = this,
12447
                        currentOptgroup = "";
12448
12449
                $.each( items, function( index, item ) {
12450
                        if ( item.optgroup !== currentOptgroup ) {
12451
                                $( "<li>", {
12452
                                        "class": "ui-selectmenu-optgroup ui-menu-divider" +
12453
                                                ( item.element.parent( "optgroup" ).prop( "disabled" ) ?
12454
                                                        " ui-state-disabled" :
12455
                                                        "" ),
12456
                                        text: item.optgroup
12457
                                })
12458
                                        .appendTo( ul );
12459
12460
                                currentOptgroup = item.optgroup;
12461
                        }
12462
12463
                        that._renderItemData( ul, item );
12464
                });
12465
        },
12466
12467
        _renderItemData: function( ul, item ) {
12468
                return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
12469
        },
12470
12471
        _renderItem: function( ul, item ) {
12472
                var li = $( "<li>" );
12473
12474
                if ( item.disabled ) {
12475
                        li.addClass( "ui-state-disabled" );
12476
                }
12477
                this._setText( li, item.label );
12478
12479
                return li.appendTo( ul );
12480
        },
12481
12482
        _setText: function( element, value ) {
12483
                if ( value ) {
12484
                        element.text( value );
12485
                } else {
12486
                        element.html( "&#160;" );
12487
                }
12488
        },
12489
12490
        _move: function( direction, event ) {
12491
                var item, next,
12492
                        filter = ".ui-menu-item";
12493
12494
                if ( this.isOpen ) {
12495
                        item = this.menuItems.eq( this.focusIndex );
12496
                } else {
12497
                        item = this.menuItems.eq( this.element[ 0 ].selectedIndex );
12498
                        filter += ":not(.ui-state-disabled)";
12499
                }
12500
12501
                if ( direction === "first" || direction === "last" ) {
12502
                        next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
12503
                } else {
12504
                        next = item[ direction + "All" ]( filter ).eq( 0 );
12505
                }
12506
12507
                if ( next.length ) {
12508
                        this.menuInstance.focus( event, next );
12509
                }
12510
        },
12511
12512
        _getSelectedItem: function() {
12513
                return this.menuItems.eq( this.element[ 0 ].selectedIndex );
12514
        },
12515
12516
        _toggle: function( event ) {
12517
                this[ this.isOpen ? "close" : "open" ]( event );
12518
        },
12519
12520
        _setSelection: function() {
12521
                var selection;
12522
12523
                if ( !this.range ) {
12524
                        return;
12525
                }
12526
12527
                if ( window.getSelection ) {
12528
                        selection = window.getSelection();
12529
                        selection.removeAllRanges();
12530
                        selection.addRange( this.range );
12531
12532
                // support: IE8
12533
                } else {
12534
                        this.range.select();
12535
                }
12536
12537
                // support: IE
12538
                // Setting the text selection kills the button focus in IE, but
12539
                // restoring the focus doesn't kill the selection.
12540
                this.button.focus();
12541
        },
12542
12543
        _documentClick: {
12544
                mousedown: function( event ) {
12545
                        if ( !this.isOpen ) {
12546
                                return;
12547
                        }
12548
12549
                        if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + this.ids.button ).length ) {
12550
                                this.close( event );
12551
                        }
12552
                }
12553
        },
12554
12555
        _buttonEvents: {
12556
12557
                // Prevent text selection from being reset when interacting with the selectmenu (#10144)
12558
                mousedown: function() {
12559
                        var selection;
12560
12561
                        if ( window.getSelection ) {
12562
                                selection = window.getSelection();
12563
                                if ( selection.rangeCount ) {
12564
                                        this.range = selection.getRangeAt( 0 );
12565
                                }
12566
12567
                        // support: IE8
12568
                        } else {
12569
                                this.range = document.selection.createRange();
12570
                        }
12571
                },
12572
12573
                click: function( event ) {
12574
                        this._setSelection();
12575
                        this._toggle( event );
12576
                },
12577
12578
                keydown: function( event ) {
12579
                        var preventDefault = true;
12580
                        switch ( event.keyCode ) {
12581
                                case $.ui.keyCode.TAB:
12582
                                case $.ui.keyCode.ESCAPE:
12583
                                        this.close( event );
12584
                                        preventDefault = false;
12585
                                        break;
12586
                                case $.ui.keyCode.ENTER:
12587
                                        if ( this.isOpen ) {
12588
                                                this._selectFocusedItem( event );
12589
                                        }
12590
                                        break;
12591
                                case $.ui.keyCode.UP:
12592
                                        if ( event.altKey ) {
12593
                                                this._toggle( event );
12594
                                        } else {
12595
                                                this._move( "prev", event );
12596
                                        }
12597
                                        break;
12598
                                case $.ui.keyCode.DOWN:
12599
                                        if ( event.altKey ) {
12600
                                                this._toggle( event );
12601
                                        } else {
12602
                                                this._move( "next", event );
12603
                                        }
12604
                                        break;
12605
                                case $.ui.keyCode.SPACE:
12606
                                        if ( this.isOpen ) {
12607
                                                this._selectFocusedItem( event );
12608
                                        } else {
12609
                                                this._toggle( event );
12610
                                        }
12611
                                        break;
12612
                                case $.ui.keyCode.LEFT:
12613
                                        this._move( "prev", event );
12614
                                        break;
12615
                                case $.ui.keyCode.RIGHT:
12616
                                        this._move( "next", event );
12617
                                        break;
12618
                                case $.ui.keyCode.HOME:
12619
                                case $.ui.keyCode.PAGE_UP:
12620
                                        this._move( "first", event );
12621
                                        break;
12622
                                case $.ui.keyCode.END:
12623
                                case $.ui.keyCode.PAGE_DOWN:
12624
                                        this._move( "last", event );
12625
                                        break;
12626
                                default:
12627
                                        this.menu.trigger( event );
12628
                                        preventDefault = false;
12629
                        }
12630
12631
                        if ( preventDefault ) {
12632
                                event.preventDefault();
12633
                        }
12634
                }
12635
        },
12636
12637
        _selectFocusedItem: function( event ) {
12638
                var item = this.menuItems.eq( this.focusIndex );
12639
                if ( !item.hasClass( "ui-state-disabled" ) ) {
12640
                        this._select( item.data( "ui-selectmenu-item" ), event );
12641
                }
12642
        },
12643
12644
        _select: function( item, event ) {
12645
                var oldIndex = this.element[ 0 ].selectedIndex;
12646
12647
                // Change native select element
12648
                this.element[ 0 ].selectedIndex = item.index;
12649
                this._setText( this.buttonText, item.label );
12650
                this._setAria( item );
12651
                this._trigger( "select", event, { item: item } );
12652
12653
                if ( item.index !== oldIndex ) {
12654
                        this._trigger( "change", event, { item: item } );
12655
                }
12656
12657
                this.close( event );
12658
        },
12659
12660
        _setAria: function( item ) {
12661
                var id = this.menuItems.eq( item.index ).attr( "id" );
12662
12663
                this.button.attr({
12664
                        "aria-labelledby": id,
12665
                        "aria-activedescendant": id
12666
                });
12667
                this.menu.attr( "aria-activedescendant", id );
12668
        },
12669
12670
        _setOption: function( key, value ) {
12671
                if ( key === "icons" ) {
12672
                        this.button.find( "span.ui-icon" )
12673
                                .removeClass( this.options.icons.button )
12674
                                .addClass( value.button );
12675
                }
12676
12677
                this._super( key, value );
12678
12679
                if ( key === "appendTo" ) {
12680
                        this.menuWrap.appendTo( this._appendTo() );
12681
                }
12682
12683
                if ( key === "disabled" ) {
12684
                        this.menuInstance.option( "disabled", value );
12685
                        this.button
12686
                                .toggleClass( "ui-state-disabled", value )
12687
                                .attr( "aria-disabled", value );
12688
12689
                        this.element.prop( "disabled", value );
12690
                        if ( value ) {
12691
                                this.button.attr( "tabindex", -1 );
12692
                                this.close();
12693
                        } else {
12694
                                this.button.attr( "tabindex", 0 );
12695
                        }
12696
                }
12697
12698
                if ( key === "width" ) {
12699
                        this._resizeButton();
12700
                }
12701
        },
12702
12703
        _appendTo: function() {
12704
                var element = this.options.appendTo;
12705
12706
                if ( element ) {
12707
                        element = element.jquery || element.nodeType ?
12708
                                $( element ) :
12709
                                this.document.find( element ).eq( 0 );
12710
                }
12711
12712
                if ( !element || !element[ 0 ] ) {
12713
                        element = this.element.closest( ".ui-front" );
12714
                }
12715
12716
                if ( !element.length ) {
12717
                        element = this.document[ 0 ].body;
12718
                }
12719
12720
                return element;
12721
        },
12722
12723
        _toggleAttr: function() {
12724
                this.button
12725
                        .toggleClass( "ui-corner-top", this.isOpen )
12726
                        .toggleClass( "ui-corner-all", !this.isOpen )
12727
                        .attr( "aria-expanded", this.isOpen );
12728
                this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen );
12729
                this.menu.attr( "aria-hidden", !this.isOpen );
12730
        },
12731
12732
        _resizeButton: function() {
12733
                var width = this.options.width;
12734
12735
                if ( !width ) {
12736
                        width = this.element.show().outerWidth();
12737
                        this.element.hide();
12738
                }
12739
12740
                this.button.outerWidth( width );
12741
        },
12742
12743
        _resizeMenu: function() {
12744
                this.menu.outerWidth( Math.max(
12745
                        this.button.outerWidth(),
12746
12747
                        // support: IE10
12748
                        // IE10 wraps long text (possibly a rounding bug)
12749
                        // so we add 1px to avoid the wrapping
12750
                        this.menu.width( "" ).outerWidth() + 1
12751
                ) );
12752
        },
12753
12754
        _getCreateOptions: function() {
12755
                return { disabled: this.element.prop( "disabled" ) };
12756
        },
12757
12758
        _parseOptions: function( options ) {
12759
                var data = [];
12760
                options.each(function( index, item ) {
12761
                        var option = $( item ),
12762
                                optgroup = option.parent( "optgroup" );
12763
                        data.push({
12764
                                element: option,
12765
                                index: index,
12766
                                value: option.val(),
12767
                                label: option.text(),
12768
                                optgroup: optgroup.attr( "label" ) || "",
12769
                                disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
12770
                        });
12771
                });
12772
                this.items = data;
12773
        },
12774
12775
        _destroy: function() {
12776
                this.menuWrap.remove();
12777
                this.button.remove();
12778
                this.element.show();
12779
                this.element.removeUniqueId();
12780
                this.label.attr( "for", this.ids.element );
12781
        }
12782
});
12783
12784
12785
/*!
12786
 * jQuery UI Slider 1.11.4
12787
 * http://jqueryui.com
12788
 *
12789
 * Copyright jQuery Foundation and other contributors
12790
 * Released under the MIT license.
12791
 * http://jquery.org/license
12792
 *
12793
 * http://api.jqueryui.com/slider/
12794
 */
12795
12796
12797
var slider = $.widget( "ui.slider", $.ui.mouse, {
12798
        version: "1.11.4",
12799
        widgetEventPrefix: "slide",
12800
12801
        options: {
12802
                animate: false,
12803
                distance: 0,
12804
                max: 100,
12805
                min: 0,
12806
                orientation: "horizontal",
12807
                range: false,
12808
                step: 1,
12809
                value: 0,
12810
                values: null,
12811
12812
                // callbacks
12813
                change: null,
12814
                slide: null,
12815
                start: null,
12816
                stop: null
12817
        },
12818
12819
        // number of pages in a slider
12820
        // (how many times can you page up/down to go through the whole range)
12821
        numPages: 5,
12822
12823
        _create: function() {
12824
                this._keySliding = false;
12825
                this._mouseSliding = false;
12826
                this._animateOff = true;
12827
                this._handleIndex = null;
12828
                this._detectOrientation();
12829
                this._mouseInit();
12830
                this._calculateNewMax();
12831
12832
                this.element
12833
                        .addClass( "ui-slider" +
12834
                                " ui-slider-" + this.orientation +
12835
                                " ui-widget" +
12836
                                " ui-widget-content" +
12837
                                " ui-corner-all");
12838
12839
                this._refresh();
12840
                this._setOption( "disabled", this.options.disabled );
12841
12842
                this._animateOff = false;
12843
        },
12844
12845
        _refresh: function() {
12846
                this._createRange();
12847
                this._createHandles();
12848
                this._setupEvents();
12849
                this._refreshValue();
12850
        },
12851
12852
        _createHandles: function() {
12853
                var i, handleCount,
12854
                        options = this.options,
12855
                        existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
12856
                        handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>",
12857
                        handles = [];
12858
12859
                handleCount = ( options.values && options.values.length ) || 1;
12860
12861
                if ( existingHandles.length > handleCount ) {
12862
                        existingHandles.slice( handleCount ).remove();
12863
                        existingHandles = existingHandles.slice( 0, handleCount );
12864
                }
12865
12866
                for ( i = existingHandles.length; i < handleCount; i++ ) {
12867
                        handles.push( handle );
12868
                }
12869
12870
                this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
12871
12872
                this.handle = this.handles.eq( 0 );
12873
12874
                this.handles.each(function( i ) {
12875
                        $( this ).data( "ui-slider-handle-index", i );
12876
                });
12877
        },
12878
12879
        _createRange: function() {
12880
                var options = this.options,
12881
                        classes = "";
12882
12883
                if ( options.range ) {
12884
                        if ( options.range === true ) {
12885
                                if ( !options.values ) {
12886
                                        options.values = [ this._valueMin(), this._valueMin() ];
12887
                                } else if ( options.values.length && options.values.length !== 2 ) {
12888
                                        options.values = [ options.values[0], options.values[0] ];
12889
                                } else if ( $.isArray( options.values ) ) {
12890
                                        options.values = options.values.slice(0);
12891
                                }
12892
                        }
12893
12894
                        if ( !this.range || !this.range.length ) {
12895
                                this.range = $( "<div></div>" )
12896
                                        .appendTo( this.element );
12897
12898
                                classes = "ui-slider-range" +
12899
                                // note: this isn't the most fittingly semantic framework class for this element,
12900
                                // but worked best visually with a variety of themes
12901
                                " ui-widget-header ui-corner-all";
12902
                        } else {
12903
                                this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
12904
                                        // Handle range switching from true to min/max
12905
                                        .css({
12906
                                                "left": "",
12907
                                                "bottom": ""
12908
                                        });
12909
                        }
12910
12911
                        this.range.addClass( classes +
12912
                                ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
12913
                } else {
12914
                        if ( this.range ) {
12915
                                this.range.remove();
12916
                        }
12917
                        this.range = null;
12918
                }
12919
        },
12920
12921
        _setupEvents: function() {
12922
                this._off( this.handles );
12923
                this._on( this.handles, this._handleEvents );
12924
                this._hoverable( this.handles );
12925
                this._focusable( this.handles );
12926
        },
12927
12928
        _destroy: function() {
12929
                this.handles.remove();
12930
                if ( this.range ) {
12931
                        this.range.remove();
12932
                }
12933
12934
                this.element
12935
                        .removeClass( "ui-slider" +
12936
                                " ui-slider-horizontal" +
12937
                                " ui-slider-vertical" +
12938
                                " ui-widget" +
12939
                                " ui-widget-content" +
12940
                                " ui-corner-all" );
12941
12942
                this._mouseDestroy();
12943
        },
12944
12945
        _mouseCapture: function( event ) {
12946
                var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
12947
                        that = this,
12948
                        o = this.options;
12949
12950
                if ( o.disabled ) {
12951
                        return false;
12952
                }
12953
12954
                this.elementSize = {
12955
                        width: this.element.outerWidth(),
12956
                        height: this.element.outerHeight()
12957
                };
12958
                this.elementOffset = this.element.offset();
12959
12960
                position = { x: event.pageX, y: event.pageY };
12961
                normValue = this._normValueFromMouse( position );
12962
                distance = this._valueMax() - this._valueMin() + 1;
12963
                this.handles.each(function( i ) {
12964
                        var thisDistance = Math.abs( normValue - that.values(i) );
12965
                        if (( distance > thisDistance ) ||
12966
                                ( distance === thisDistance &&
12967
                                        (i === that._lastChangedValue || that.values(i) === o.min ))) {
12968
                                distance = thisDistance;
12969
                                closestHandle = $( this );
12970
                                index = i;
12971
                        }
12972
                });
12973
12974
                allowed = this._start( event, index );
12975
                if ( allowed === false ) {
12976
                        return false;
12977
                }
12978
                this._mouseSliding = true;
12979
12980
                this._handleIndex = index;
12981
12982
                closestHandle
12983
                        .addClass( "ui-state-active" )
12984
                        .focus();
12985
12986
                offset = closestHandle.offset();
12987
                mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
12988
                this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
12989
                        left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
12990
                        top: event.pageY - offset.top -
12991
                                ( closestHandle.height() / 2 ) -
12992
                                ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
12993
                                ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
12994
                                ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
12995
                };
12996
12997
                if ( !this.handles.hasClass( "ui-state-hover" ) ) {
12998
                        this._slide( event, index, normValue );
12999
                }
13000
                this._animateOff = true;
13001
                return true;
13002
        },
13003
13004
        _mouseStart: function() {
13005
                return true;
13006
        },
13007
13008
        _mouseDrag: function( event ) {
13009
                var position = { x: event.pageX, y: event.pageY },
13010
                        normValue = this._normValueFromMouse( position );
13011
13012
                this._slide( event, this._handleIndex, normValue );
13013
13014
                return false;
13015
        },
13016
13017
        _mouseStop: function( event ) {
13018
                this.handles.removeClass( "ui-state-active" );
13019
                this._mouseSliding = false;
13020
13021
                this._stop( event, this._handleIndex );
13022
                this._change( event, this._handleIndex );
13023
13024
                this._handleIndex = null;
13025
                this._clickOffset = null;
13026
                this._animateOff = false;
13027
13028
                return false;
13029
        },
13030
13031
        _detectOrientation: function() {
13032
                this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
13033
        },
13034
13035
        _normValueFromMouse: function( position ) {
13036
                var pixelTotal,
13037
                        pixelMouse,
13038
                        percentMouse,
13039
                        valueTotal,
13040
                        valueMouse;
13041
13042
                if ( this.orientation === "horizontal" ) {
13043
                        pixelTotal = this.elementSize.width;
13044
                        pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
13045
                } else {
13046
                        pixelTotal = this.elementSize.height;
13047
                        pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
13048
                }
13049
13050
                percentMouse = ( pixelMouse / pixelTotal );
13051
                if ( percentMouse > 1 ) {
13052
                        percentMouse = 1;
13053
                }
13054
                if ( percentMouse < 0 ) {
13055
                        percentMouse = 0;
13056
                }
13057
                if ( this.orientation === "vertical" ) {
13058
                        percentMouse = 1 - percentMouse;
13059
                }
13060
13061
                valueTotal = this._valueMax() - this._valueMin();
13062
                valueMouse = this._valueMin() + percentMouse * valueTotal;
13063
13064
                return this._trimAlignValue( valueMouse );
13065
        },
13066
13067
        _start: function( event, index ) {
13068
                var uiHash = {
13069
                        handle: this.handles[ index ],
13070
                        value: this.value()
13071
                };
13072
                if ( this.options.values && this.options.values.length ) {
13073
                        uiHash.value = this.values( index );
13074
                        uiHash.values = this.values();
13075
                }
13076
                return this._trigger( "start", event, uiHash );
13077
        },
13078
13079
        _slide: function( event, index, newVal ) {
13080
                var otherVal,
13081
                        newValues,
13082
                        allowed;
13083
13084
                if ( this.options.values && this.options.values.length ) {
13085
                        otherVal = this.values( index ? 0 : 1 );
13086
13087
                        if ( ( this.options.values.length === 2 && this.options.range === true ) &&
13088
                                        ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
13089
                                ) {
13090
                                newVal = otherVal;
13091
                        }
13092
13093
                        if ( newVal !== this.values( index ) ) {
13094
                                newValues = this.values();
13095
                                newValues[ index ] = newVal;
13096
                                // A slide can be canceled by returning false from the slide callback
13097
                                allowed = this._trigger( "slide", event, {
13098
                                        handle: this.handles[ index ],
13099
                                        value: newVal,
13100
                                        values: newValues
13101
                                } );
13102
                                otherVal = this.values( index ? 0 : 1 );
13103
                                if ( allowed !== false ) {
13104
                                        this.values( index, newVal );
13105
                                }
13106
                        }
13107
                } else {
13108
                        if ( newVal !== this.value() ) {
13109
                                // A slide can be canceled by returning false from the slide callback
13110
                                allowed = this._trigger( "slide", event, {
13111
                                        handle: this.handles[ index ],
13112
                                        value: newVal
13113
                                } );
13114
                                if ( allowed !== false ) {
13115
                                        this.value( newVal );
13116
                                }
13117
                        }
13118
                }
13119
        },
13120
13121
        _stop: function( event, index ) {
13122
                var uiHash = {
13123
                        handle: this.handles[ index ],
13124
                        value: this.value()
13125
                };
13126
                if ( this.options.values && this.options.values.length ) {
13127
                        uiHash.value = this.values( index );
13128
                        uiHash.values = this.values();
13129
                }
13130
13131
                this._trigger( "stop", event, uiHash );
13132
        },
13133
13134
        _change: function( event, index ) {
13135
                if ( !this._keySliding && !this._mouseSliding ) {
13136
                        var uiHash = {
13137
                                handle: this.handles[ index ],
13138
                                value: this.value()
13139
                        };
13140
                        if ( this.options.values && this.options.values.length ) {
13141
                                uiHash.value = this.values( index );
13142
                                uiHash.values = this.values();
13143
                        }
13144
13145
                        //store the last changed value index for reference when handles overlap
13146
                        this._lastChangedValue = index;
13147
13148
                        this._trigger( "change", event, uiHash );
13149
                }
13150
        },
13151
13152
        value: function( newValue ) {
13153
                if ( arguments.length ) {
13154
                        this.options.value = this._trimAlignValue( newValue );
13155
                        this._refreshValue();
13156
                        this._change( null, 0 );
13157
                        return;
13158
                }
13159
13160
                return this._value();
13161
        },
13162
13163
        values: function( index, newValue ) {
13164
                var vals,
13165
                        newValues,
13166
                        i;
13167
13168
                if ( arguments.length > 1 ) {
13169
                        this.options.values[ index ] = this._trimAlignValue( newValue );
13170
                        this._refreshValue();
13171
                        this._change( null, index );
13172
                        return;
13173
                }
13174
13175
                if ( arguments.length ) {
13176
                        if ( $.isArray( arguments[ 0 ] ) ) {
13177
                                vals = this.options.values;
13178
                                newValues = arguments[ 0 ];
13179
                                for ( i = 0; i < vals.length; i += 1 ) {
13180
                                        vals[ i ] = this._trimAlignValue( newValues[ i ] );
13181
                                        this._change( null, i );
13182
                                }
13183
                                this._refreshValue();
13184
                        } else {
13185
                                if ( this.options.values && this.options.values.length ) {
13186
                                        return this._values( index );
13187
                                } else {
13188
                                        return this.value();
13189
                                }
13190
                        }
13191
                } else {
13192
                        return this._values();
13193
                }
13194
        },
13195
13196
        _setOption: function( key, value ) {
13197
                var i,
13198
                        valsLength = 0;
13199
13200
                if ( key === "range" && this.options.range === true ) {
13201
                        if ( value === "min" ) {
13202
                                this.options.value = this._values( 0 );
13203
                                this.options.values = null;
13204
                        } else if ( value === "max" ) {
13205
                                this.options.value = this._values( this.options.values.length - 1 );
13206
                                this.options.values = null;
13207
                        }
13208
                }
13209
13210
                if ( $.isArray( this.options.values ) ) {
13211
                        valsLength = this.options.values.length;
13212
                }
13213
13214
                if ( key === "disabled" ) {
13215
                        this.element.toggleClass( "ui-state-disabled", !!value );
13216
                }
13217
13218
                this._super( key, value );
13219
13220
                switch ( key ) {
13221
                        case "orientation":
13222
                                this._detectOrientation();
13223
                                this.element
13224
                                        .removeClass( "ui-slider-horizontal ui-slider-vertical" )
13225
                                        .addClass( "ui-slider-" + this.orientation );
13226
                                this._refreshValue();
13227
13228
                                // Reset positioning from previous orientation
13229
                                this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
13230
                                break;
13231
                        case "value":
13232
                                this._animateOff = true;
13233
                                this._refreshValue();
13234
                                this._change( null, 0 );
13235
                                this._animateOff = false;
13236
                                break;
13237
                        case "values":
13238
                                this._animateOff = true;
13239
                                this._refreshValue();
13240
                                for ( i = 0; i < valsLength; i += 1 ) {
13241
                                        this._change( null, i );
13242
                                }
13243
                                this._animateOff = false;
13244
                                break;
13245
                        case "step":
13246
                        case "min":
13247
                        case "max":
13248
                                this._animateOff = true;
13249
                                this._calculateNewMax();
13250
                                this._refreshValue();
13251
                                this._animateOff = false;
13252
                                break;
13253
                        case "range":
13254
                                this._animateOff = true;
13255
                                this._refresh();
13256
                                this._animateOff = false;
13257
                                break;
13258
                }
13259
        },
13260
13261
        //internal value getter
13262
        // _value() returns value trimmed by min and max, aligned by step
13263
        _value: function() {
13264
                var val = this.options.value;
13265
                val = this._trimAlignValue( val );
13266
13267
                return val;
13268
        },
13269
13270
        //internal values getter
13271
        // _values() returns array of values trimmed by min and max, aligned by step
13272
        // _values( index ) returns single value trimmed by min and max, aligned by step
13273
        _values: function( index ) {
13274
                var val,
13275
                        vals,
13276
                        i;
13277
13278
                if ( arguments.length ) {
13279
                        val = this.options.values[ index ];
13280
                        val = this._trimAlignValue( val );
13281
13282
                        return val;
13283
                } else if ( this.options.values && this.options.values.length ) {
13284
                        // .slice() creates a copy of the array
13285
                        // this copy gets trimmed by min and max and then returned
13286
                        vals = this.options.values.slice();
13287
                        for ( i = 0; i < vals.length; i += 1) {
13288
                                vals[ i ] = this._trimAlignValue( vals[ i ] );
13289
                        }
13290
13291
                        return vals;
13292
                } else {
13293
                        return [];
13294
                }
13295
        },
13296
13297
        // returns the step-aligned value that val is closest to, between (inclusive) min and max
13298
        _trimAlignValue: function( val ) {
13299
                if ( val <= this._valueMin() ) {
13300
                        return this._valueMin();
13301
                }
13302
                if ( val >= this._valueMax() ) {
13303
                        return this._valueMax();
13304
                }
13305
                var step = ( this.options.step > 0 ) ? this.options.step : 1,
13306
                        valModStep = (val - this._valueMin()) % step,
13307
                        alignValue = val - valModStep;
13308
13309
                if ( Math.abs(valModStep) * 2 >= step ) {
13310
                        alignValue += ( valModStep > 0 ) ? step : ( -step );
13311
                }
13312
13313
                // Since JavaScript has problems with large floats, round
13314
                // the final value to 5 digits after the decimal point (see #4124)
13315
                return parseFloat( alignValue.toFixed(5) );
13316
        },
13317
13318
        _calculateNewMax: function() {
13319
                var max = this.options.max,
13320
                        min = this._valueMin(),
13321
                        step = this.options.step,
13322
                        aboveMin = Math.floor( ( +( max - min ).toFixed( this._precision() ) ) / step ) * step;
13323
                max = aboveMin + min;
13324
                this.max = parseFloat( max.toFixed( this._precision() ) );
13325
        },
13326
13327
        _precision: function() {
13328
                var precision = this._precisionOf( this.options.step );
13329
                if ( this.options.min !== null ) {
13330
                        precision = Math.max( precision, this._precisionOf( this.options.min ) );
13331
                }
13332
                return precision;
13333
        },
13334
13335
        _precisionOf: function( num ) {
13336
                var str = num.toString(),
13337
                        decimal = str.indexOf( "." );
13338
                return decimal === -1 ? 0 : str.length - decimal - 1;
13339
        },
13340
13341
        _valueMin: function() {
13342
                return this.options.min;
13343
        },
13344
13345
        _valueMax: function() {
13346
                return this.max;
13347
        },
13348
13349
        _refreshValue: function() {
13350
                var lastValPercent, valPercent, value, valueMin, valueMax,
13351
                        oRange = this.options.range,
13352
                        o = this.options,
13353
                        that = this,
13354
                        animate = ( !this._animateOff ) ? o.animate : false,
13355
                        _set = {};
13356
13357
                if ( this.options.values && this.options.values.length ) {
13358
                        this.handles.each(function( i ) {
13359
                                valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
13360
                                _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13361
                                $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13362
                                if ( that.options.range === true ) {
13363
                                        if ( that.orientation === "horizontal" ) {
13364
                                                if ( i === 0 ) {
13365
                                                        that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
13366
                                                }
13367
                                                if ( i === 1 ) {
13368
                                                        that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13369
                                                }
13370
                                        } else {
13371
                                                if ( i === 0 ) {
13372
                                                        that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
13373
                                                }
13374
                                                if ( i === 1 ) {
13375
                                                        that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13376
                                                }
13377
                                        }
13378
                                }
13379
                                lastValPercent = valPercent;
13380
                        });
13381
                } else {
13382
                        value = this.value();
13383
                        valueMin = this._valueMin();
13384
                        valueMax = this._valueMax();
13385
                        valPercent = ( valueMax !== valueMin ) ?
13386
                                        ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
13387
                                        0;
13388
                        _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13389
                        this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13390
13391
                        if ( oRange === "min" && this.orientation === "horizontal" ) {
13392
                                this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
13393
                        }
13394
                        if ( oRange === "max" && this.orientation === "horizontal" ) {
13395
                                this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13396
                        }
13397
                        if ( oRange === "min" && this.orientation === "vertical" ) {
13398
                                this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
13399
                        }
13400
                        if ( oRange === "max" && this.orientation === "vertical" ) {
13401
                                this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13402
                        }
13403
                }
13404
        },
13405
13406
        _handleEvents: {
13407
                keydown: function( event ) {
13408
                        var allowed, curVal, newVal, step,
13409
                                index = $( event.target ).data( "ui-slider-handle-index" );
13410
13411
                        switch ( event.keyCode ) {
13412
                                case $.ui.keyCode.HOME:
13413
                                case $.ui.keyCode.END:
13414
                                case $.ui.keyCode.PAGE_UP:
13415
                                case $.ui.keyCode.PAGE_DOWN:
13416
                                case $.ui.keyCode.UP:
13417
                                case $.ui.keyCode.RIGHT:
13418
                                case $.ui.keyCode.DOWN:
13419
                                case $.ui.keyCode.LEFT:
13420
                                        event.preventDefault();
13421
                                        if ( !this._keySliding ) {
13422
                                                this._keySliding = true;
13423
                                                $( event.target ).addClass( "ui-state-active" );
13424
                                                allowed = this._start( event, index );
13425
                                                if ( allowed === false ) {
13426
                                                        return;
13427
                                                }
13428
                                        }
13429
                                        break;
13430
                        }
13431
13432
                        step = this.options.step;
13433
                        if ( this.options.values && this.options.values.length ) {
13434
                                curVal = newVal = this.values( index );
13435
                        } else {
13436
                                curVal = newVal = this.value();
13437
                        }
13438
13439
                        switch ( event.keyCode ) {
13440
                                case $.ui.keyCode.HOME:
13441
                                        newVal = this._valueMin();
13442
                                        break;
13443
                                case $.ui.keyCode.END:
13444
                                        newVal = this._valueMax();
13445
                                        break;
13446
                                case $.ui.keyCode.PAGE_UP:
13447
                                        newVal = this._trimAlignValue(
13448
                                                curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
13449
                                        );
13450
                                        break;
13451
                                case $.ui.keyCode.PAGE_DOWN:
13452
                                        newVal = this._trimAlignValue(
13453
                                                curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) );
13454
                                        break;
13455
                                case $.ui.keyCode.UP:
13456
                                case $.ui.keyCode.RIGHT:
13457
                                        if ( curVal === this._valueMax() ) {
13458
                                                return;
13459
                                        }
13460
                                        newVal = this._trimAlignValue( curVal + step );
13461
                                        break;
13462
                                case $.ui.keyCode.DOWN:
13463
                                case $.ui.keyCode.LEFT:
13464
                                        if ( curVal === this._valueMin() ) {
13465
                                                return;
13466
                                        }
13467
                                        newVal = this._trimAlignValue( curVal - step );
13468
                                        break;
13469
                        }
13470
13471
                        this._slide( event, index, newVal );
13472
                },
13473
                keyup: function( event ) {
13474
                        var index = $( event.target ).data( "ui-slider-handle-index" );
13475
13476
                        if ( this._keySliding ) {
13477
                                this._keySliding = false;
13478
                                this._stop( event, index );
13479
                                this._change( event, index );
13480
                                $( event.target ).removeClass( "ui-state-active" );
13481
                        }
13482
                }
13483
        }
13484
});
13485
13486
13487
/*!
13488
 * jQuery UI Sortable 1.11.4
13489
 * http://jqueryui.com
13490
 *
13491
 * Copyright jQuery Foundation and other contributors
13492
 * Released under the MIT license.
13493
 * http://jquery.org/license
13494
 *
13495
 * http://api.jqueryui.com/sortable/
13496
 */
13497
13498
13499
var sortable = $.widget("ui.sortable", $.ui.mouse, {
13500
        version: "1.11.4",
13501
        widgetEventPrefix: "sort",
13502
        ready: false,
13503
        options: {
13504
                appendTo: "parent",
13505
                axis: false,
13506
                connectWith: false,
13507
                containment: false,
13508
                cursor: "auto",
13509
                cursorAt: false,
13510
                dropOnEmpty: true,
13511
                forcePlaceholderSize: false,
13512
                forceHelperSize: false,
13513
                grid: false,
13514
                handle: false,
13515
                helper: "original",
13516
                items: "> *",
13517
                opacity: false,
13518
                placeholder: false,
13519
                revert: false,
13520
                scroll: true,
13521
                scrollSensitivity: 20,
13522
                scrollSpeed: 20,
13523
                scope: "default",
13524
                tolerance: "intersect",
13525
                zIndex: 1000,
13526
13527
                // callbacks
13528
                activate: null,
13529
                beforeStop: null,
13530
                change: null,
13531
                deactivate: null,
13532
                out: null,
13533
                over: null,
13534
                receive: null,
13535
                remove: null,
13536
                sort: null,
13537
                start: null,
13538
                stop: null,
13539
                update: null
13540
        },
13541
13542
        _isOverAxis: function( x, reference, size ) {
13543
                return ( x >= reference ) && ( x < ( reference + size ) );
13544
        },
13545
13546
        _isFloating: function( item ) {
13547
                return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
13548
        },
13549
13550
        _create: function() {
13551
                this.containerCache = {};
13552
                this.element.addClass("ui-sortable");
13553
13554
                //Get the items
13555
                this.refresh();
13556
13557
                //Let's determine the parent's offset
13558
                this.offset = this.element.offset();
13559
13560
                //Initialize mouse events for interaction
13561
                this._mouseInit();
13562
13563
                this._setHandleClassName();
13564
13565
                //We're ready to go
13566
                this.ready = true;
13567
13568
        },
13569
13570
        _setOption: function( key, value ) {
13571
                this._super( key, value );
13572
13573
                if ( key === "handle" ) {
13574
                        this._setHandleClassName();
13575
                }
13576
        },
13577
13578
        _setHandleClassName: function() {
13579
                this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" );
13580
                $.each( this.items, function() {
13581
                        ( this.instance.options.handle ?
13582
                                this.item.find( this.instance.options.handle ) : this.item )
13583
                                .addClass( "ui-sortable-handle" );
13584
                });
13585
        },
13586
13587
        _destroy: function() {
13588
                this.element
13589
                        .removeClass( "ui-sortable ui-sortable-disabled" )
13590
                        .find( ".ui-sortable-handle" )
13591
                                .removeClass( "ui-sortable-handle" );
13592
                this._mouseDestroy();
13593
13594
                for ( var i = this.items.length - 1; i >= 0; i-- ) {
13595
                        this.items[i].item.removeData(this.widgetName + "-item");
13596
                }
13597
13598
                return this;
13599
        },
13600
13601
        _mouseCapture: function(event, overrideHandle) {
13602
                var currentItem = null,
13603
                        validHandle = false,
13604
                        that = this;
13605
13606
                if (this.reverting) {
13607
                        return false;
13608
                }
13609
13610
                if(this.options.disabled || this.options.type === "static") {
13611
                        return false;
13612
                }
13613
13614
                //We have to refresh the items data once first
13615
                this._refreshItems(event);
13616
13617
                //Find out if the clicked node (or one of its parents) is a actual item in this.items
13618
                $(event.target).parents().each(function() {
13619
                        if($.data(this, that.widgetName + "-item") === that) {
13620
                                currentItem = $(this);
13621
                                return false;
13622
                        }
13623
                });
13624
                if($.data(event.target, that.widgetName + "-item") === that) {
13625
                        currentItem = $(event.target);
13626
                }
13627
13628
                if(!currentItem) {
13629
                        return false;
13630
                }
13631
                if(this.options.handle && !overrideHandle) {
13632
                        $(this.options.handle, currentItem).find("*").addBack().each(function() {
13633
                                if(this === event.target) {
13634
                                        validHandle = true;
13635
                                }
13636
                        });
13637
                        if(!validHandle) {
13638
                                return false;
13639
                        }
13640
                }
13641
13642
                this.currentItem = currentItem;
13643
                this._removeCurrentsFromItems();
13644
                return true;
13645
13646
        },
13647
13648
        _mouseStart: function(event, overrideHandle, noActivation) {
13649
13650
                var i, body,
13651
                        o = this.options;
13652
13653
                this.currentContainer = this;
13654
13655
                //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
13656
                this.refreshPositions();
13657
13658
                //Create and append the visible helper
13659
                this.helper = this._createHelper(event);
13660
13661
                //Cache the helper size
13662
                this._cacheHelperProportions();
13663
13664
                /*
13665
                 * - Position generation -
13666
                 * This block generates everything position related - it's the core of draggables.
13667
                 */
13668
13669
                //Cache the margins of the original element
13670
                this._cacheMargins();
13671
13672
                //Get the next scrolling parent
13673
                this.scrollParent = this.helper.scrollParent();
13674
13675
                //The element's absolute position on the page minus margins
13676
                this.offset = this.currentItem.offset();
13677
                this.offset = {
13678
                        top: this.offset.top - this.margins.top,
13679
                        left: this.offset.left - this.margins.left
13680
                };
13681
13682
                $.extend(this.offset, {
13683
                        click: { //Where the click happened, relative to the element
13684
                                left: event.pageX - this.offset.left,
13685
                                top: event.pageY - this.offset.top
13686
                        },
13687
                        parent: this._getParentOffset(),
13688
                        relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
13689
                });
13690
13691
                // Only after we got the offset, we can change the helper's position to absolute
13692
                // TODO: Still need to figure out a way to make relative sorting possible
13693
                this.helper.css("position", "absolute");
13694
                this.cssPosition = this.helper.css("position");
13695
13696
                //Generate the original position
13697
                this.originalPosition = this._generatePosition(event);
13698
                this.originalPageX = event.pageX;
13699
                this.originalPageY = event.pageY;
13700
13701
                //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
13702
                (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
13703
13704
                //Cache the former DOM position
13705
                this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
13706
13707
                //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
13708
                if(this.helper[0] !== this.currentItem[0]) {
13709
                        this.currentItem.hide();
13710
                }
13711
13712
                //Create the placeholder
13713
                this._createPlaceholder();
13714
13715
                //Set a containment if given in the options
13716
                if(o.containment) {
13717
                        this._setContainment();
13718
                }
13719
13720
                if( o.cursor && o.cursor !== "auto" ) { // cursor option
13721
                        body = this.document.find( "body" );
13722
13723
                        // support: IE
13724
                        this.storedCursor = body.css( "cursor" );
13725
                        body.css( "cursor", o.cursor );
13726
13727
                        this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
13728
                }
13729
13730
                if(o.opacity) { // opacity option
13731
                        if (this.helper.css("opacity")) {
13732
                                this._storedOpacity = this.helper.css("opacity");
13733
                        }
13734
                        this.helper.css("opacity", o.opacity);
13735
                }
13736
13737
                if(o.zIndex) { // zIndex option
13738
                        if (this.helper.css("zIndex")) {
13739
                                this._storedZIndex = this.helper.css("zIndex");
13740
                        }
13741
                        this.helper.css("zIndex", o.zIndex);
13742
                }
13743
13744
                //Prepare scrolling
13745
                if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
13746
                        this.overflowOffset = this.scrollParent.offset();
13747
                }
13748
13749
                //Call callbacks
13750
                this._trigger("start", event, this._uiHash());
13751
13752
                //Recache the helper size
13753
                if(!this._preserveHelperProportions) {
13754
                        this._cacheHelperProportions();
13755
                }
13756
13757
13758
                //Post "activate" events to possible containers
13759
                if( !noActivation ) {
13760
                        for ( i = this.containers.length - 1; i >= 0; i-- ) {
13761
                                this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
13762
                        }
13763
                }
13764
13765
                //Prepare possible droppables
13766
                if($.ui.ddmanager) {
13767
                        $.ui.ddmanager.current = this;
13768
                }
13769
13770
                if ($.ui.ddmanager && !o.dropBehaviour) {
13771
                        $.ui.ddmanager.prepareOffsets(this, event);
13772
                }
13773
13774
                this.dragging = true;
13775
13776
                this.helper.addClass("ui-sortable-helper");
13777
                this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
13778
                return true;
13779
13780
        },
13781
13782
        _mouseDrag: function(event) {
13783
                var i, item, itemElement, intersection,
13784
                        o = this.options,
13785
                        scrolled = false;
13786
13787
                //Compute the helpers position
13788
                this.position = this._generatePosition(event);
13789
                this.positionAbs = this._convertPositionTo("absolute");
13790
13791
                if (!this.lastPositionAbs) {
13792
                        this.lastPositionAbs = this.positionAbs;
13793
                }
13794
13795
                //Do scrolling
13796
                if(this.options.scroll) {
13797
                        if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
13798
13799
                                if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
13800
                                        this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
13801
                                } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
13802
                                        this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
13803
                                }
13804
13805
                                if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
13806
                                        this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
13807
                                } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
13808
                                        this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
13809
                                }
13810
13811
                        } else {
13812
13813
                                if(event.pageY - this.document.scrollTop() < o.scrollSensitivity) {
13814
                                        scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed);
13815
                                } else if(this.window.height() - (event.pageY - this.document.scrollTop()) < o.scrollSensitivity) {
13816
                                        scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed);
13817
                                }
13818
13819
                                if(event.pageX - this.document.scrollLeft() < o.scrollSensitivity) {
13820
                                        scrolled = this.document.scrollLeft(this.document.scrollLeft() - o.scrollSpeed);
13821
                                } else if(this.window.width() - (event.pageX - this.document.scrollLeft()) < o.scrollSensitivity) {
13822
                                        scrolled = this.document.scrollLeft(this.document.scrollLeft() + o.scrollSpeed);
13823
                                }
13824
13825
                        }
13826
13827
                        if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
13828
                                $.ui.ddmanager.prepareOffsets(this, event);
13829
                        }
13830
                }
13831
13832
                //Regenerate the absolute position used for position checks
13833
                this.positionAbs = this._convertPositionTo("absolute");
13834
13835
                //Set the helper position
13836
                if(!this.options.axis || this.options.axis !== "y") {
13837
                        this.helper[0].style.left = this.position.left+"px";
13838
                }
13839
                if(!this.options.axis || this.options.axis !== "x") {
13840
                        this.helper[0].style.top = this.position.top+"px";
13841
                }
13842
13843
                //Rearrange
13844
                for (i = this.items.length - 1; i >= 0; i--) {
13845
13846
                        //Cache variables and intersection, continue if no intersection
13847
                        item = this.items[i];
13848
                        itemElement = item.item[0];
13849
                        intersection = this._intersectsWithPointer(item);
13850
                        if (!intersection) {
13851
                                continue;
13852
                        }
13853
13854
                        // Only put the placeholder inside the current Container, skip all
13855
                        // items from other containers. This works because when moving
13856
                        // an item from one container to another the
13857
                        // currentContainer is switched before the placeholder is moved.
13858
                        //
13859
                        // Without this, moving items in "sub-sortables" can cause
13860
                        // the placeholder to jitter between the outer and inner container.
13861
                        if (item.instance !== this.currentContainer) {
13862
                                continue;
13863
                        }
13864
13865
                        // cannot intersect with itself
13866
                        // no useless actions that have been done before
13867
                        // no action if the item moved is the parent of the item checked
13868
                        if (itemElement !== this.currentItem[0] &&
13869
                                this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
13870
                                !$.contains(this.placeholder[0], itemElement) &&
13871
                                (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
13872
                        ) {
13873
13874
                                this.direction = intersection === 1 ? "down" : "up";
13875
13876
                                if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
13877
                                        this._rearrange(event, item);
13878
                                } else {
13879
                                        break;
13880
                                }
13881
13882
                                this._trigger("change", event, this._uiHash());
13883
                                break;
13884
                        }
13885
                }
13886
13887
                //Post events to containers
13888
                this._contactContainers(event);
13889
13890
                //Interconnect with droppables
13891
                if($.ui.ddmanager) {
13892
                        $.ui.ddmanager.drag(this, event);
13893
                }
13894
13895
                //Call callbacks
13896
                this._trigger("sort", event, this._uiHash());
13897
13898
                this.lastPositionAbs = this.positionAbs;
13899
                return false;
13900
13901
        },
13902
13903
        _mouseStop: function(event, noPropagation) {
13904
13905
                if(!event) {
13906
                        return;
13907
                }
13908
13909
                //If we are using droppables, inform the manager about the drop
13910
                if ($.ui.ddmanager && !this.options.dropBehaviour) {
13911
                        $.ui.ddmanager.drop(this, event);
13912
                }
13913
13914
                if(this.options.revert) {
13915
                        var that = this,
13916
                                cur = this.placeholder.offset(),
13917
                                axis = this.options.axis,
13918
                                animation = {};
13919
13920
                        if ( !axis || axis === "x" ) {
13921
                                animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollLeft);
13922
                        }
13923
                        if ( !axis || axis === "y" ) {
13924
                                animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollTop);
13925
                        }
13926
                        this.reverting = true;
13927
                        $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
13928
                                that._clear(event);
13929
                        });
13930
                } else {
13931
                        this._clear(event, noPropagation);
13932
                }
13933
13934
                return false;
13935
13936
        },
13937
13938
        cancel: function() {
13939
13940
                if(this.dragging) {
13941
13942
                        this._mouseUp({ target: null });
13943
13944
                        if(this.options.helper === "original") {
13945
                                this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
13946
                        } else {
13947
                                this.currentItem.show();
13948
                        }
13949
13950
                        //Post deactivating events to containers
13951
                        for (var i = this.containers.length - 1; i >= 0; i--){
13952
                                this.containers[i]._trigger("deactivate", null, this._uiHash(this));
13953
                                if(this.containers[i].containerCache.over) {
13954
                                        this.containers[i]._trigger("out", null, this._uiHash(this));
13955
                                        this.containers[i].containerCache.over = 0;
13956
                                }
13957
                        }
13958
13959
                }
13960
13961
                if (this.placeholder) {
13962
                        //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
13963
                        if(this.placeholder[0].parentNode) {
13964
                                this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
13965
                        }
13966
                        if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
13967
                                this.helper.remove();
13968
                        }
13969
13970
                        $.extend(this, {
13971
                                helper: null,
13972
                                dragging: false,
13973
                                reverting: false,
13974
                                _noFinalSort: null
13975
                        });
13976
13977
                        if(this.domPosition.prev) {
13978
                                $(this.domPosition.prev).after(this.currentItem);
13979
                        } else {
13980
                                $(this.domPosition.parent).prepend(this.currentItem);
13981
                        }
13982
                }
13983
13984
                return this;
13985
13986
        },
13987
13988
        serialize: function(o) {
13989
13990
                var items = this._getItemsAsjQuery(o && o.connected),
13991
                        str = [];
13992
                o = o || {};
13993
13994
                $(items).each(function() {
13995
                        var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
13996
                        if (res) {
13997
                                str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
13998
                        }
13999
                });
14000
14001
                if(!str.length && o.key) {
14002
                        str.push(o.key + "=");
14003
                }
14004
14005
                return str.join("&");
14006
14007
        },
14008
14009
        toArray: function(o) {
14010
14011
                var items = this._getItemsAsjQuery(o && o.connected),
14012
                        ret = [];
14013
14014
                o = o || {};
14015
14016
                items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
14017
                return ret;
14018
14019
        },
14020
14021
        /* Be careful with the following core functions */
14022
        _intersectsWith: function(item) {
14023
14024
                var x1 = this.positionAbs.left,
14025
                        x2 = x1 + this.helperProportions.width,
14026
                        y1 = this.positionAbs.top,
14027
                        y2 = y1 + this.helperProportions.height,
14028
                        l = item.left,
14029
                        r = l + item.width,
14030
                        t = item.top,
14031
                        b = t + item.height,
14032
                        dyClick = this.offset.click.top,
14033
                        dxClick = this.offset.click.left,
14034
                        isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
14035
                        isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
14036
                        isOverElement = isOverElementHeight && isOverElementWidth;
14037
14038
                if ( this.options.tolerance === "pointer" ||
14039
                        this.options.forcePointerForContainers ||
14040
                        (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
14041
                ) {
14042
                        return isOverElement;
14043
                } else {
14044
14045
                        return (l < x1 + (this.helperProportions.width / 2) && // Right Half
14046
                                x2 - (this.helperProportions.width / 2) < r && // Left Half
14047
                                t < y1 + (this.helperProportions.height / 2) && // Bottom Half
14048
                                y2 - (this.helperProportions.height / 2) < b ); // Top Half
14049
14050
                }
14051
        },
14052
14053
        _intersectsWithPointer: function(item) {
14054
14055
                var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
14056
                        isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
14057
                        isOverElement = isOverElementHeight && isOverElementWidth,
14058
                        verticalDirection = this._getDragVerticalDirection(),
14059
                        horizontalDirection = this._getDragHorizontalDirection();
14060
14061
                if (!isOverElement) {
14062
                        return false;
14063
                }
14064
14065
                return this.floating ?
14066
                        ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
14067
                        : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
14068
14069
        },
14070
14071
        _intersectsWithSides: function(item) {
14072
14073
                var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
14074
                        isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
14075
                        verticalDirection = this._getDragVerticalDirection(),
14076
                        horizontalDirection = this._getDragHorizontalDirection();
14077
14078
                if (this.floating && horizontalDirection) {
14079
                        return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
14080
                } else {
14081
                        return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
14082
                }
14083
14084
        },
14085
14086
        _getDragVerticalDirection: function() {
14087
                var delta = this.positionAbs.top - this.lastPositionAbs.top;
14088
                return delta !== 0 && (delta > 0 ? "down" : "up");
14089
        },
14090
14091
        _getDragHorizontalDirection: function() {
14092
                var delta = this.positionAbs.left - this.lastPositionAbs.left;
14093
                return delta !== 0 && (delta > 0 ? "right" : "left");
14094
        },
14095
14096
        refresh: function(event) {
14097
                this._refreshItems(event);
14098
                this._setHandleClassName();
14099
                this.refreshPositions();
14100
                return this;
14101
        },
14102
14103
        _connectWith: function() {
14104
                var options = this.options;
14105
                return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
14106
        },
14107
14108
        _getItemsAsjQuery: function(connected) {
14109
14110
                var i, j, cur, inst,
14111
                        items = [],
14112
                        queries = [],
14113
                        connectWith = this._connectWith();
14114
14115
                if(connectWith && connected) {
14116
                        for (i = connectWith.length - 1; i >= 0; i--){
14117
                                cur = $(connectWith[i], this.document[0]);
14118
                                for ( j = cur.length - 1; j >= 0; j--){
14119
                                        inst = $.data(cur[j], this.widgetFullName);
14120
                                        if(inst && inst !== this && !inst.options.disabled) {
14121
                                                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]);
14122
                                        }
14123
                                }
14124
                        }
14125
                }
14126
14127
                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]);
14128
14129
                function addItems() {
14130
                        items.push( this );
14131
                }
14132
                for (i = queries.length - 1; i >= 0; i--){
14133
                        queries[i][0].each( addItems );
14134
                }
14135
14136
                return $(items);
14137
14138
        },
14139
14140
        _removeCurrentsFromItems: function() {
14141
14142
                var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
14143
14144
                this.items = $.grep(this.items, function (item) {
14145
                        for (var j=0; j < list.length; j++) {
14146
                                if(list[j] === item.item[0]) {
14147
                                        return false;
14148
                                }
14149
                        }
14150
                        return true;
14151
                });
14152
14153
        },
14154
14155
        _refreshItems: function(event) {
14156
14157
                this.items = [];
14158
                this.containers = [this];
14159
14160
                var i, j, cur, inst, targetData, _queries, item, queriesLength,
14161
                        items = this.items,
14162
                        queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
14163
                        connectWith = this._connectWith();
14164
14165
                if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
14166
                        for (i = connectWith.length - 1; i >= 0; i--){
14167
                                cur = $(connectWith[i], this.document[0]);
14168
                                for (j = cur.length - 1; j >= 0; j--){
14169
                                        inst = $.data(cur[j], this.widgetFullName);
14170
                                        if(inst && inst !== this && !inst.options.disabled) {
14171
                                                queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
14172
                                                this.containers.push(inst);
14173
                                        }
14174
                                }
14175
                        }
14176
                }
14177
14178
                for (i = queries.length - 1; i >= 0; i--) {
14179
                        targetData = queries[i][1];
14180
                        _queries = queries[i][0];
14181
14182
                        for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
14183
                                item = $(_queries[j]);
14184
14185
                                item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
14186
14187
                                items.push({
14188
                                        item: item,
14189
                                        instance: targetData,
14190
                                        width: 0, height: 0,
14191
                                        left: 0, top: 0
14192
                                });
14193
                        }
14194
                }
14195
14196
        },
14197
14198
        refreshPositions: function(fast) {
14199
14200
                // Determine whether items are being displayed horizontally
14201
                this.floating = this.items.length ?
14202
                        this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
14203
                        false;
14204
14205
                //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
14206
                if(this.offsetParent && this.helper) {
14207
                        this.offset.parent = this._getParentOffset();
14208
                }
14209
14210
                var i, item, t, p;
14211
14212
                for (i = this.items.length - 1; i >= 0; i--){
14213
                        item = this.items[i];
14214
14215
                        //We ignore calculating positions of all connected containers when we're not over them
14216
                        if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
14217
                                continue;
14218
                        }
14219
14220
                        t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
14221
14222
                        if (!fast) {
14223
                                item.width = t.outerWidth();
14224
                                item.height = t.outerHeight();
14225
                        }
14226
14227
                        p = t.offset();
14228
                        item.left = p.left;
14229
                        item.top = p.top;
14230
                }
14231
14232
                if(this.options.custom && this.options.custom.refreshContainers) {
14233
                        this.options.custom.refreshContainers.call(this);
14234
                } else {
14235
                        for (i = this.containers.length - 1; i >= 0; i--){
14236
                                p = this.containers[i].element.offset();
14237
                                this.containers[i].containerCache.left = p.left;
14238
                                this.containers[i].containerCache.top = p.top;
14239
                                this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
14240
                                this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
14241
                        }
14242
                }
14243
14244
                return this;
14245
        },
14246
14247
        _createPlaceholder: function(that) {
14248
                that = that || this;
14249
                var className,
14250
                        o = that.options;
14251
14252
                if(!o.placeholder || o.placeholder.constructor === String) {
14253
                        className = o.placeholder;
14254
                        o.placeholder = {
14255
                                element: function() {
14256
14257
                                        var nodeName = that.currentItem[0].nodeName.toLowerCase(),
14258
                                                element = $( "<" + nodeName + ">", that.document[0] )
14259
                                                        .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
14260
                                                        .removeClass("ui-sortable-helper");
14261
14262
                                        if ( nodeName === "tbody" ) {
14263
                                                that._createTrPlaceholder(
14264
                                                        that.currentItem.find( "tr" ).eq( 0 ),
14265
                                                        $( "<tr>", that.document[ 0 ] ).appendTo( element )
14266
                                                );
14267
                                        } else if ( nodeName === "tr" ) {
14268
                                                that._createTrPlaceholder( that.currentItem, element );
14269
                                        } else if ( nodeName === "img" ) {
14270
                                                element.attr( "src", that.currentItem.attr( "src" ) );
14271
                                        }
14272
14273
                                        if ( !className ) {
14274
                                                element.css( "visibility", "hidden" );
14275
                                        }
14276
14277
                                        return element;
14278
                                },
14279
                                update: function(container, p) {
14280
14281
                                        // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
14282
                                        // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
14283
                                        if(className && !o.forcePlaceholderSize) {
14284
                                                return;
14285
                                        }
14286
14287
                                        //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
14288
                                        if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
14289
                                        if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
14290
                                }
14291
                        };
14292
                }
14293
14294
                //Create the placeholder
14295
                that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
14296
14297
                //Append it after the actual current item
14298
                that.currentItem.after(that.placeholder);
14299
14300
                //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
14301
                o.placeholder.update(that, that.placeholder);
14302
14303
        },
14304
14305
        _createTrPlaceholder: function( sourceTr, targetTr ) {
14306
                var that = this;
14307
14308
                sourceTr.children().each(function() {
14309
                        $( "<td>&#160;</td>", that.document[ 0 ] )
14310
                                .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
14311
                                .appendTo( targetTr );
14312
                });
14313
        },
14314
14315
        _contactContainers: function(event) {
14316
                var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis,
14317
                        innermostContainer = null,
14318
                        innermostIndex = null;
14319
14320
                // get innermost container that intersects with item
14321
                for (i = this.containers.length - 1; i >= 0; i--) {
14322
14323
                        // never consider a container that's located within the item itself
14324
                        if($.contains(this.currentItem[0], this.containers[i].element[0])) {
14325
                                continue;
14326
                        }
14327
14328
                        if(this._intersectsWith(this.containers[i].containerCache)) {
14329
14330
                                // if we've already found a container and it's more "inner" than this, then continue
14331
                                if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
14332
                                        continue;
14333
                                }
14334
14335
                                innermostContainer = this.containers[i];
14336
                                innermostIndex = i;
14337
14338
                        } else {
14339
                                // container doesn't intersect. trigger "out" event if necessary
14340
                                if(this.containers[i].containerCache.over) {
14341
                                        this.containers[i]._trigger("out", event, this._uiHash(this));
14342
                                        this.containers[i].containerCache.over = 0;
14343
                                }
14344
                        }
14345
14346
                }
14347
14348
                // if no intersecting containers found, return
14349
                if(!innermostContainer) {
14350
                        return;
14351
                }
14352
14353
                // move the item into the container if it's not there already
14354
                if(this.containers.length === 1) {
14355
                        if (!this.containers[innermostIndex].containerCache.over) {
14356
                                this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
14357
                                this.containers[innermostIndex].containerCache.over = 1;
14358
                        }
14359
                } else {
14360
14361
                        //When entering a new container, we will find the item with the least distance and append our item near it
14362
                        dist = 10000;
14363
                        itemWithLeastDistance = null;
14364
                        floating = innermostContainer.floating || this._isFloating(this.currentItem);
14365
                        posProperty = floating ? "left" : "top";
14366
                        sizeProperty = floating ? "width" : "height";
14367
                        axis = floating ? "clientX" : "clientY";
14368
14369
                        for (j = this.items.length - 1; j >= 0; j--) {
14370
                                if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
14371
                                        continue;
14372
                                }
14373
                                if(this.items[j].item[0] === this.currentItem[0]) {
14374
                                        continue;
14375
                                }
14376
14377
                                cur = this.items[j].item.offset()[posProperty];
14378
                                nearBottom = false;
14379
                                if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
14380
                                        nearBottom = true;
14381
                                }
14382
14383
                                if ( Math.abs( event[ axis ] - cur ) < dist ) {
14384
                                        dist = Math.abs( event[ axis ] - cur );
14385
                                        itemWithLeastDistance = this.items[ j ];
14386
                                        this.direction = nearBottom ? "up": "down";
14387
                                }
14388
                        }
14389
14390
                        //Check if dropOnEmpty is enabled
14391
                        if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
14392
                                return;
14393
                        }
14394
14395
                        if(this.currentContainer === this.containers[innermostIndex]) {
14396
                                if ( !this.currentContainer.containerCache.over ) {
14397
                                        this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
14398
                                        this.currentContainer.containerCache.over = 1;
14399
                                }
14400
                                return;
14401
                        }
14402
14403
                        itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
14404
                        this._trigger("change", event, this._uiHash());
14405
                        this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
14406
                        this.currentContainer = this.containers[innermostIndex];
14407
14408
                        //Update the placeholder
14409
                        this.options.placeholder.update(this.currentContainer, this.placeholder);
14410
14411
                        this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
14412
                        this.containers[innermostIndex].containerCache.over = 1;
14413
                }
14414
14415
14416
        },
14417
14418
        _createHelper: function(event) {
14419
14420
                var o = this.options,
14421
                        helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
14422
14423
                //Add the helper to the DOM if that didn't happen already
14424
                if(!helper.parents("body").length) {
14425
                        $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
14426
                }
14427
14428
                if(helper[0] === this.currentItem[0]) {
14429
                        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") };
14430
                }
14431
14432
                if(!helper[0].style.width || o.forceHelperSize) {
14433
                        helper.width(this.currentItem.width());
14434
                }
14435
                if(!helper[0].style.height || o.forceHelperSize) {
14436
                        helper.height(this.currentItem.height());
14437
                }
14438
14439
                return helper;
14440
14441
        },
14442
14443
        _adjustOffsetFromHelper: function(obj) {
14444
                if (typeof obj === "string") {
14445
                        obj = obj.split(" ");
14446
                }
14447
                if ($.isArray(obj)) {
14448
                        obj = {left: +obj[0], top: +obj[1] || 0};
14449
                }
14450
                if ("left" in obj) {
14451
                        this.offset.click.left = obj.left + this.margins.left;
14452
                }
14453
                if ("right" in obj) {
14454
                        this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
14455
                }
14456
                if ("top" in obj) {
14457
                        this.offset.click.top = obj.top + this.margins.top;
14458
                }
14459
                if ("bottom" in obj) {
14460
                        this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
14461
                }
14462
        },
14463
14464
        _getParentOffset: function() {
14465
14466
14467
                //Get the offsetParent and cache its position
14468
                this.offsetParent = this.helper.offsetParent();
14469
                var po = this.offsetParent.offset();
14470
14471
                // This is a special case where we need to modify a offset calculated on start, since the following happened:
14472
                // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
14473
                // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
14474
                //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
14475
                if(this.cssPosition === "absolute" && this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) {
14476
                        po.left += this.scrollParent.scrollLeft();
14477
                        po.top += this.scrollParent.scrollTop();
14478
                }
14479
14480
                // This needs to be actually done for all browsers, since pageX/pageY includes this information
14481
                // with an ugly IE fix
14482
                if( this.offsetParent[0] === this.document[0].body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
14483
                        po = { top: 0, left: 0 };
14484
                }
14485
14486
                return {
14487
                        top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
14488
                        left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
14489
                };
14490
14491
        },
14492
14493
        _getRelativeOffset: function() {
14494
14495
                if(this.cssPosition === "relative") {
14496
                        var p = this.currentItem.position();
14497
                        return {
14498
                                top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
14499
                                left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
14500
                        };
14501
                } else {
14502
                        return { top: 0, left: 0 };
14503
                }
14504
14505
        },
14506
14507
        _cacheMargins: function() {
14508
                this.margins = {
14509
                        left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
14510
                        top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
14511
                };
14512
        },
14513
14514
        _cacheHelperProportions: function() {
14515
                this.helperProportions = {
14516
                        width: this.helper.outerWidth(),
14517
                        height: this.helper.outerHeight()
14518
                };
14519
        },
14520
14521
        _setContainment: function() {
14522
14523
                var ce, co, over,
14524
                        o = this.options;
14525
                if(o.containment === "parent") {
14526
                        o.containment = this.helper[0].parentNode;
14527
                }
14528
                if(o.containment === "document" || o.containment === "window") {
14529
                        this.containment = [
14530
                                0 - this.offset.relative.left - this.offset.parent.left,
14531
                                0 - this.offset.relative.top - this.offset.parent.top,
14532
                                o.containment === "document" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left,
14533
                                (o.containment === "document" ? this.document.width() : this.window.height() || this.document[0].body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
14534
                        ];
14535
                }
14536
14537
                if(!(/^(document|window|parent)$/).test(o.containment)) {
14538
                        ce = $(o.containment)[0];
14539
                        co = $(o.containment).offset();
14540
                        over = ($(ce).css("overflow") !== "hidden");
14541
14542
                        this.containment = [
14543
                                co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
14544
                                co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
14545
                                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,
14546
                                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
14547
                        ];
14548
                }
14549
14550
        },
14551
14552
        _convertPositionTo: function(d, pos) {
14553
14554
                if(!pos) {
14555
                        pos = this.position;
14556
                }
14557
                var mod = d === "absolute" ? 1 : -1,
14558
                        scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
14559
                        scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
14560
14561
                return {
14562
                        top: (
14563
                                pos.top        +                                                                                                                                // The absolute mouse position
14564
                                this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
14565
                                this.offset.parent.top * mod -                                                                                        // The offsetParent's offset without borders (offset + border)
14566
                                ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
14567
                        ),
14568
                        left: (
14569
                                pos.left +                                                                                                                                // The absolute mouse position
14570
                                this.offset.relative.left * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
14571
                                this.offset.parent.left * mod        -                                                                                // The offsetParent's offset without borders (offset + border)
14572
                                ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
14573
                        )
14574
                };
14575
14576
        },
14577
14578
        _generatePosition: function(event) {
14579
14580
                var top, left,
14581
                        o = this.options,
14582
                        pageX = event.pageX,
14583
                        pageY = event.pageY,
14584
                        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);
14585
14586
                // This is another very weird special case that only happens for relative elements:
14587
                // 1. If the css position is relative
14588
                // 2. and the scroll parent is the document or similar to the offset parent
14589
                // we have to refresh the relative offset during the scroll so there are no jumps
14590
                if(this.cssPosition === "relative" && !(this.scrollParent[0] !== this.document[0] && this.scrollParent[0] !== this.offsetParent[0])) {
14591
                        this.offset.relative = this._getRelativeOffset();
14592
                }
14593
14594
                /*
14595
                 * - Position constraining -
14596
                 * Constrain the position to a mix of grid, containment.
14597
                 */
14598
14599
                if(this.originalPosition) { //If we are not dragging yet, we won't check for options
14600
14601
                        if(this.containment) {
14602
                                if(event.pageX - this.offset.click.left < this.containment[0]) {
14603
                                        pageX = this.containment[0] + this.offset.click.left;
14604
                                }
14605
                                if(event.pageY - this.offset.click.top < this.containment[1]) {
14606
                                        pageY = this.containment[1] + this.offset.click.top;
14607
                                }
14608
                                if(event.pageX - this.offset.click.left > this.containment[2]) {
14609
                                        pageX = this.containment[2] + this.offset.click.left;
14610
                                }
14611
                                if(event.pageY - this.offset.click.top > this.containment[3]) {
14612
                                        pageY = this.containment[3] + this.offset.click.top;
14613
                                }
14614
                        }
14615
14616
                        if(o.grid) {
14617
                                top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
14618
                                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;
14619
14620
                                left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
14621
                                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;
14622
                        }
14623
14624
                }
14625
14626
                return {
14627
                        top: (
14628
                                pageY -                                                                                                                                // The absolute mouse position
14629
                                this.offset.click.top -                                                                                                        // Click offset (relative to the element)
14630
                                this.offset.relative.top        -                                                                                        // Only for relative positioned nodes: Relative offset from element to offset parent
14631
                                this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
14632
                                ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
14633
                        ),
14634
                        left: (
14635
                                pageX -                                                                                                                                // The absolute mouse position
14636
                                this.offset.click.left -                                                                                                // Click offset (relative to the element)
14637
                                this.offset.relative.left        -                                                                                        // Only for relative positioned nodes: Relative offset from element to offset parent
14638
                                this.offset.parent.left +                                                                                                // The offsetParent's offset without borders (offset + border)
14639
                                ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
14640
                        )
14641
                };
14642
14643
        },
14644
14645
        _rearrange: function(event, i, a, hardRefresh) {
14646
14647
                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));
14648
14649
                //Various things done here to improve the performance:
14650
                // 1. we create a setTimeout, that calls refreshPositions
14651
                // 2. on the instance, we have a counter variable, that get's higher after every append
14652
                // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
14653
                // 4. this lets only the last addition to the timeout stack through
14654
                this.counter = this.counter ? ++this.counter : 1;
14655
                var counter = this.counter;
14656
14657
                this._delay(function() {
14658
                        if(counter === this.counter) {
14659
                                this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
14660
                        }
14661
                });
14662
14663
        },
14664
14665
        _clear: function(event, noPropagation) {
14666
14667
                this.reverting = false;
14668
                // We delay all events that have to be triggered to after the point where the placeholder has been removed and
14669
                // everything else normalized again
14670
                var i,
14671
                        delayedTriggers = [];
14672
14673
                // We first have to update the dom position of the actual currentItem
14674
                // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
14675
                if(!this._noFinalSort && this.currentItem.parent().length) {
14676
                        this.placeholder.before(this.currentItem);
14677
                }
14678
                this._noFinalSort = null;
14679
14680
                if(this.helper[0] === this.currentItem[0]) {
14681
                        for(i in this._storedCSS) {
14682
                                if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
14683
                                        this._storedCSS[i] = "";
14684
                                }
14685
                        }
14686
                        this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
14687
                } else {
14688
                        this.currentItem.show();
14689
                }
14690
14691
                if(this.fromOutside && !noPropagation) {
14692
                        delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
14693
                }
14694
                if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
14695
                        delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
14696
                }
14697
14698
                // Check if the items Container has Changed and trigger appropriate
14699
                // events.
14700
                if (this !== this.currentContainer) {
14701
                        if(!noPropagation) {
14702
                                delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
14703
                                delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
14704
                                delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
14705
                        }
14706
                }
14707
14708
14709
                //Post events to containers
14710
                function delayEvent( type, instance, container ) {
14711
                        return function( event ) {
14712
                                container._trigger( type, event, instance._uiHash( instance ) );
14713
                        };
14714
                }
14715
                for (i = this.containers.length - 1; i >= 0; i--){
14716
                        if (!noPropagation) {
14717
                                delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
14718
                        }
14719
                        if(this.containers[i].containerCache.over) {
14720
                                delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
14721
                                this.containers[i].containerCache.over = 0;
14722
                        }
14723
                }
14724
14725
                //Do what was originally in plugins
14726
                if ( this.storedCursor ) {
14727
                        this.document.find( "body" ).css( "cursor", this.storedCursor );
14728
                        this.storedStylesheet.remove();
14729
                }
14730
                if(this._storedOpacity) {
14731
                        this.helper.css("opacity", this._storedOpacity);
14732
                }
14733
                if(this._storedZIndex) {
14734
                        this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
14735
                }
14736
14737
                this.dragging = false;
14738
14739
                if(!noPropagation) {
14740
                        this._trigger("beforeStop", event, this._uiHash());
14741
                }
14742
14743
                //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
14744
                this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
14745
14746
                if ( !this.cancelHelperRemoval ) {
14747
                        if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
14748
                                this.helper.remove();
14749
                        }
14750
                        this.helper = null;
14751
                }
14752
14753
                if(!noPropagation) {
14754
                        for (i=0; i < delayedTriggers.length; i++) {
14755
                                delayedTriggers[i].call(this, event);
14756
                        } //Trigger all delayed events
14757
                        this._trigger("stop", event, this._uiHash());
14758
                }
14759
14760
                this.fromOutside = false;
14761
                return !this.cancelHelperRemoval;
14762
14763
        },
14764
14765
        _trigger: function() {
14766
                if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
14767
                        this.cancel();
14768
                }
14769
        },
14770
14771
        _uiHash: function(_inst) {
14772
                var inst = _inst || this;
14773
                return {
14774
                        helper: inst.helper,
14775
                        placeholder: inst.placeholder || $([]),
14776
                        position: inst.position,
14777
                        originalPosition: inst.originalPosition,
14778
                        offset: inst.positionAbs,
14779
                        item: inst.currentItem,
14780
                        sender: _inst ? _inst.element : null
14781
                };
14782
        }
14783
14784
});
14785
14786
14787
/*!
14788
 * jQuery UI Spinner 1.11.4
14789
 * http://jqueryui.com
14790
 *
14791
 * Copyright jQuery Foundation and other contributors
14792
 * Released under the MIT license.
14793
 * http://jquery.org/license
14794
 *
14795
 * http://api.jqueryui.com/spinner/
14796
 */
14797
14798
14799
function spinner_modifier( fn ) {
14800
        return function() {
14801
                var previous = this.element.val();
14802
                fn.apply( this, arguments );
14803
                this._refresh();
14804
                if ( previous !== this.element.val() ) {
14805
                        this._trigger( "change" );
14806
                }
14807
        };
14808
}
14809
14810
var spinner = $.widget( "ui.spinner", {
14811
        version: "1.11.4",
14812
        defaultElement: "<input>",
14813
        widgetEventPrefix: "spin",
14814
        options: {
14815
                culture: null,
14816
                icons: {
14817
                        down: "ui-icon-triangle-1-s",
14818
                        up: "ui-icon-triangle-1-n"
14819
                },
14820
                incremental: true,
14821
                max: null,
14822
                min: null,
14823
                numberFormat: null,
14824
                page: 10,
14825
                step: 1,
14826
14827
                change: null,
14828
                spin: null,
14829
                start: null,
14830
                stop: null
14831
        },
14832
14833
        _create: function() {
14834
                // handle string values that need to be parsed
14835
                this._setOption( "max", this.options.max );
14836
                this._setOption( "min", this.options.min );
14837
                this._setOption( "step", this.options.step );
14838
14839
                // Only format if there is a value, prevents the field from being marked
14840
                // as invalid in Firefox, see #9573.
14841
                if ( this.value() !== "" ) {
14842
                        // Format the value, but don't constrain.
14843
                        this._value( this.element.val(), true );
14844
                }
14845
14846
                this._draw();
14847
                this._on( this._events );
14848
                this._refresh();
14849
14850
                // turning off autocomplete prevents the browser from remembering the
14851
                // value when navigating through history, so we re-enable autocomplete
14852
                // if the page is unloaded before the widget is destroyed. #7790
14853
                this._on( this.window, {
14854
                        beforeunload: function() {
14855
                                this.element.removeAttr( "autocomplete" );
14856
                        }
14857
                });
14858
        },
14859
14860
        _getCreateOptions: function() {
14861
                var options = {},
14862
                        element = this.element;
14863
14864
                $.each( [ "min", "max", "step" ], function( i, option ) {
14865
                        var value = element.attr( option );
14866
                        if ( value !== undefined && value.length ) {
14867
                                options[ option ] = value;
14868
                        }
14869
                });
14870
14871
                return options;
14872
        },
14873
14874
        _events: {
14875
                keydown: function( event ) {
14876
                        if ( this._start( event ) && this._keydown( event ) ) {
14877
                                event.preventDefault();
14878
                        }
14879
                },
14880
                keyup: "_stop",
14881
                focus: function() {
14882
                        this.previous = this.element.val();
14883
                },
14884
                blur: function( event ) {
14885
                        if ( this.cancelBlur ) {
14886
                                delete this.cancelBlur;
14887
                                return;
14888
                        }
14889
14890
                        this._stop();
14891
                        this._refresh();
14892
                        if ( this.previous !== this.element.val() ) {
14893
                                this._trigger( "change", event );
14894
                        }
14895
                },
14896
                mousewheel: function( event, delta ) {
14897
                        if ( !delta ) {
14898
                                return;
14899
                        }
14900
                        if ( !this.spinning && !this._start( event ) ) {
14901
                                return false;
14902
                        }
14903
14904
                        this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
14905
                        clearTimeout( this.mousewheelTimer );
14906
                        this.mousewheelTimer = this._delay(function() {
14907
                                if ( this.spinning ) {
14908
                                        this._stop( event );
14909
                                }
14910
                        }, 100 );
14911
                        event.preventDefault();
14912
                },
14913
                "mousedown .ui-spinner-button": function( event ) {
14914
                        var previous;
14915
14916
                        // We never want the buttons to have focus; whenever the user is
14917
                        // interacting with the spinner, the focus should be on the input.
14918
                        // If the input is focused then this.previous is properly set from
14919
                        // when the input first received focus. If the input is not focused
14920
                        // then we need to set this.previous based on the value before spinning.
14921
                        previous = this.element[0] === this.document[0].activeElement ?
14922
                                this.previous : this.element.val();
14923
                        function checkFocus() {
14924
                                var isActive = this.element[0] === this.document[0].activeElement;
14925
                                if ( !isActive ) {
14926
                                        this.element.focus();
14927
                                        this.previous = previous;
14928
                                        // support: IE
14929
                                        // IE sets focus asynchronously, so we need to check if focus
14930
                                        // moved off of the input because the user clicked on the button.
14931
                                        this._delay(function() {
14932
                                                this.previous = previous;
14933
                                        });
14934
                                }
14935
                        }
14936
14937
                        // ensure focus is on (or stays on) the text field
14938
                        event.preventDefault();
14939
                        checkFocus.call( this );
14940
14941
                        // support: IE
14942
                        // IE doesn't prevent moving focus even with event.preventDefault()
14943
                        // so we set a flag to know when we should ignore the blur event
14944
                        // and check (again) if focus moved off of the input.
14945
                        this.cancelBlur = true;
14946
                        this._delay(function() {
14947
                                delete this.cancelBlur;
14948
                                checkFocus.call( this );
14949
                        });
14950
14951
                        if ( this._start( event ) === false ) {
14952
                                return;
14953
                        }
14954
14955
                        this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
14956
                },
14957
                "mouseup .ui-spinner-button": "_stop",
14958
                "mouseenter .ui-spinner-button": function( event ) {
14959
                        // button will add ui-state-active if mouse was down while mouseleave and kept down
14960
                        if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
14961
                                return;
14962
                        }
14963
14964
                        if ( this._start( event ) === false ) {
14965
                                return false;
14966
                        }
14967
                        this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
14968
                },
14969
                // TODO: do we really want to consider this a stop?
14970
                // shouldn't we just stop the repeater and wait until mouseup before
14971
                // we trigger the stop event?
14972
                "mouseleave .ui-spinner-button": "_stop"
14973
        },
14974
14975
        _draw: function() {
14976
                var uiSpinner = this.uiSpinner = this.element
14977
                        .addClass( "ui-spinner-input" )
14978
                        .attr( "autocomplete", "off" )
14979
                        .wrap( this._uiSpinnerHtml() )
14980
                        .parent()
14981
                                // add buttons
14982
                                .append( this._buttonHtml() );
14983
14984
                this.element.attr( "role", "spinbutton" );
14985
14986
                // button bindings
14987
                this.buttons = uiSpinner.find( ".ui-spinner-button" )
14988
                        .attr( "tabIndex", -1 )
14989
                        .button()
14990
                        .removeClass( "ui-corner-all" );
14991
14992
                // IE 6 doesn't understand height: 50% for the buttons
14993
                // unless the wrapper has an explicit height
14994
                if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
14995
                                uiSpinner.height() > 0 ) {
14996
                        uiSpinner.height( uiSpinner.height() );
14997
                }
14998
14999
                // disable spinner if element was already disabled
15000
                if ( this.options.disabled ) {
15001
                        this.disable();
15002
                }
15003
        },
15004
15005
        _keydown: function( event ) {
15006
                var options = this.options,
15007
                        keyCode = $.ui.keyCode;
15008
15009
                switch ( event.keyCode ) {
15010
                case keyCode.UP:
15011
                        this._repeat( null, 1, event );
15012
                        return true;
15013
                case keyCode.DOWN:
15014
                        this._repeat( null, -1, event );
15015
                        return true;
15016
                case keyCode.PAGE_UP:
15017
                        this._repeat( null, options.page, event );
15018
                        return true;
15019
                case keyCode.PAGE_DOWN:
15020
                        this._repeat( null, -options.page, event );
15021
                        return true;
15022
                }
15023
15024
                return false;
15025
        },
15026
15027
        _uiSpinnerHtml: function() {
15028
                return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
15029
        },
15030
15031
        _buttonHtml: function() {
15032
                return "" +
15033
                        "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
15034
                                "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
15035
                        "</a>" +
15036
                        "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
15037
                                "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
15038
                        "</a>";
15039
        },
15040
15041
        _start: function( event ) {
15042
                if ( !this.spinning && this._trigger( "start", event ) === false ) {
15043
                        return false;
15044
                }
15045
15046
                if ( !this.counter ) {
15047
                        this.counter = 1;
15048
                }
15049
                this.spinning = true;
15050
                return true;
15051
        },
15052
15053
        _repeat: function( i, steps, event ) {
15054
                i = i || 500;
15055
15056
                clearTimeout( this.timer );
15057
                this.timer = this._delay(function() {
15058
                        this._repeat( 40, steps, event );
15059
                }, i );
15060
15061
                this._spin( steps * this.options.step, event );
15062
        },
15063
15064
        _spin: function( step, event ) {
15065
                var value = this.value() || 0;
15066
15067
                if ( !this.counter ) {
15068
                        this.counter = 1;
15069
                }
15070
15071
                value = this._adjustValue( value + step * this._increment( this.counter ) );
15072
15073
                if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
15074
                        this._value( value );
15075
                        this.counter++;
15076
                }
15077
        },
15078
15079
        _increment: function( i ) {
15080
                var incremental = this.options.incremental;
15081
15082
                if ( incremental ) {
15083
                        return $.isFunction( incremental ) ?
15084
                                incremental( i ) :
15085
                                Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
15086
                }
15087
15088
                return 1;
15089
        },
15090
15091
        _precision: function() {
15092
                var precision = this._precisionOf( this.options.step );
15093
                if ( this.options.min !== null ) {
15094
                        precision = Math.max( precision, this._precisionOf( this.options.min ) );
15095
                }
15096
                return precision;
15097
        },
15098
15099
        _precisionOf: function( num ) {
15100
                var str = num.toString(),
15101
                        decimal = str.indexOf( "." );
15102
                return decimal === -1 ? 0 : str.length - decimal - 1;
15103
        },
15104
15105
        _adjustValue: function( value ) {
15106
                var base, aboveMin,
15107
                        options = this.options;
15108
15109
                // make sure we're at a valid step
15110
                // - find out where we are relative to the base (min or 0)
15111
                base = options.min !== null ? options.min : 0;
15112
                aboveMin = value - base;
15113
                // - round to the nearest step
15114
                aboveMin = Math.round(aboveMin / options.step) * options.step;
15115
                // - rounding is based on 0, so adjust back to our base
15116
                value = base + aboveMin;
15117
15118
                // fix precision from bad JS floating point math
15119
                value = parseFloat( value.toFixed( this._precision() ) );
15120
15121
                // clamp the value
15122
                if ( options.max !== null && value > options.max) {
15123
                        return options.max;
15124
                }
15125
                if ( options.min !== null && value < options.min ) {
15126
                        return options.min;
15127
                }
15128
15129
                return value;
15130
        },
15131
15132
        _stop: function( event ) {
15133
                if ( !this.spinning ) {
15134
                        return;
15135
                }
15136
15137
                clearTimeout( this.timer );
15138
                clearTimeout( this.mousewheelTimer );
15139
                this.counter = 0;
15140
                this.spinning = false;
15141
                this._trigger( "stop", event );
15142
        },
15143
15144
        _setOption: function( key, value ) {
15145
                if ( key === "culture" || key === "numberFormat" ) {
15146
                        var prevValue = this._parse( this.element.val() );
15147
                        this.options[ key ] = value;
15148
                        this.element.val( this._format( prevValue ) );
15149
                        return;
15150
                }
15151
15152
                if ( key === "max" || key === "min" || key === "step" ) {
15153
                        if ( typeof value === "string" ) {
15154
                                value = this._parse( value );
15155
                        }
15156
                }
15157
                if ( key === "icons" ) {
15158
                        this.buttons.first().find( ".ui-icon" )
15159
                                .removeClass( this.options.icons.up )
15160
                                .addClass( value.up );
15161
                        this.buttons.last().find( ".ui-icon" )
15162
                                .removeClass( this.options.icons.down )
15163
                                .addClass( value.down );
15164
                }
15165
15166
                this._super( key, value );
15167
15168
                if ( key === "disabled" ) {
15169
                        this.widget().toggleClass( "ui-state-disabled", !!value );
15170
                        this.element.prop( "disabled", !!value );
15171
                        this.buttons.button( value ? "disable" : "enable" );
15172
                }
15173
        },
15174
15175
        _setOptions: spinner_modifier(function( options ) {
15176
                this._super( options );
15177
        }),
15178
15179
        _parse: function( val ) {
15180
                if ( typeof val === "string" && val !== "" ) {
15181
                        val = window.Globalize && this.options.numberFormat ?
15182
                                Globalize.parseFloat( val, 10, this.options.culture ) : +val;
15183
                }
15184
                return val === "" || isNaN( val ) ? null : val;
15185
        },
15186
15187
        _format: function( value ) {
15188
                if ( value === "" ) {
15189
                        return "";
15190
                }
15191
                return window.Globalize && this.options.numberFormat ?
15192
                        Globalize.format( value, this.options.numberFormat, this.options.culture ) :
15193
                        value;
15194
        },
15195
15196
        _refresh: function() {
15197
                this.element.attr({
15198
                        "aria-valuemin": this.options.min,
15199
                        "aria-valuemax": this.options.max,
15200
                        // TODO: what should we do with values that can't be parsed?
15201
                        "aria-valuenow": this._parse( this.element.val() )
15202
                });
15203
        },
15204
15205
        isValid: function() {
15206
                var value = this.value();
15207
15208
                // null is invalid
15209
                if ( value === null ) {
15210
                        return false;
15211
                }
15212
15213
                // if value gets adjusted, it's invalid
15214
                return value === this._adjustValue( value );
15215
        },
15216
15217
        // update the value without triggering change
15218
        _value: function( value, allowAny ) {
15219
                var parsed;
15220
                if ( value !== "" ) {
15221
                        parsed = this._parse( value );
15222
                        if ( parsed !== null ) {
15223
                                if ( !allowAny ) {
15224
                                        parsed = this._adjustValue( parsed );
15225
                                }
15226
                                value = this._format( parsed );
15227
                        }
15228
                }
15229
                this.element.val( value );
15230
                this._refresh();
15231
        },
15232
15233
        _destroy: function() {
15234
                this.element
15235
                        .removeClass( "ui-spinner-input" )
15236
                        .prop( "disabled", false )
15237
                        .removeAttr( "autocomplete" )
15238
                        .removeAttr( "role" )
15239
                        .removeAttr( "aria-valuemin" )
15240
                        .removeAttr( "aria-valuemax" )
15241
                        .removeAttr( "aria-valuenow" );
15242
                this.uiSpinner.replaceWith( this.element );
15243
        },
15244
15245
        stepUp: spinner_modifier(function( steps ) {
15246
                this._stepUp( steps );
15247
        }),
15248
        _stepUp: function( steps ) {
15249
                if ( this._start() ) {
15250
                        this._spin( (steps || 1) * this.options.step );
15251
                        this._stop();
15252
                }
15253
        },
15254
15255
        stepDown: spinner_modifier(function( steps ) {
15256
                this._stepDown( steps );
15257
        }),
15258
        _stepDown: function( steps ) {
15259
                if ( this._start() ) {
15260
                        this._spin( (steps || 1) * -this.options.step );
15261
                        this._stop();
15262
                }
15263
        },
15264
15265
        pageUp: spinner_modifier(function( pages ) {
15266
                this._stepUp( (pages || 1) * this.options.page );
15267
        }),
15268
15269
        pageDown: spinner_modifier(function( pages ) {
15270
                this._stepDown( (pages || 1) * this.options.page );
15271
        }),
15272
15273
        value: function( newVal ) {
15274
                if ( !arguments.length ) {
15275
                        return this._parse( this.element.val() );
15276
                }
15277
                spinner_modifier( this._value ).call( this, newVal );
15278
        },
15279
15280
        widget: function() {
15281
                return this.uiSpinner;
15282
        }
15283
});
15284
15285
15286
/*!
15287
 * jQuery UI Tabs 1.11.4
15288
 * http://jqueryui.com
15289
 *
15290
 * Copyright jQuery Foundation and other contributors
15291
 * Released under the MIT license.
15292
 * http://jquery.org/license
15293
 *
15294
 * http://api.jqueryui.com/tabs/
15295
 */
15296
15297
15298
var tabs = $.widget( "ui.tabs", {
15299
        version: "1.11.4",
15300
        delay: 300,
15301
        options: {
15302
                active: null,
15303
                collapsible: false,
15304
                event: "click",
15305
                heightStyle: "content",
15306
                hide: null,
15307
                show: null,
15308
15309
                // callbacks
15310
                activate: null,
15311
                beforeActivate: null,
15312
                beforeLoad: null,
15313
                load: null
15314
        },
15315
15316
        _isLocal: (function() {
15317
                var rhash = /#.*$/;
15318
15319
                return function( anchor ) {
15320
                        var anchorUrl, locationUrl;
15321
15322
                        // support: IE7
15323
                        // IE7 doesn't normalize the href property when set via script (#9317)
15324
                        anchor = anchor.cloneNode( false );
15325
15326
                        anchorUrl = anchor.href.replace( rhash, "" );
15327
                        locationUrl = location.href.replace( rhash, "" );
15328
15329
                        // decoding may throw an error if the URL isn't UTF-8 (#9518)
15330
                        try {
15331
                                anchorUrl = decodeURIComponent( anchorUrl );
15332
                        } catch ( error ) {}
15333
                        try {
15334
                                locationUrl = decodeURIComponent( locationUrl );
15335
                        } catch ( error ) {}
15336
15337
                        return anchor.hash.length > 1 && anchorUrl === locationUrl;
15338
                };
15339
        })(),
15340
15341
        _create: function() {
15342
                var that = this,
15343
                        options = this.options;
15344
15345
                this.running = false;
15346
15347
                this.element
15348
                        .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
15349
                        .toggleClass( "ui-tabs-collapsible", options.collapsible );
15350
15351
                this._processTabs();
15352
                options.active = this._initialActive();
15353
15354
                // Take disabling tabs via class attribute from HTML
15355
                // into account and update option properly.
15356
                if ( $.isArray( options.disabled ) ) {
15357
                        options.disabled = $.unique( options.disabled.concat(
15358
                                $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
15359
                                        return that.tabs.index( li );
15360
                                })
15361
                        ) ).sort();
15362
                }
15363
15364
                // check for length avoids error when initializing empty list
15365
                if ( this.options.active !== false && this.anchors.length ) {
15366
                        this.active = this._findActive( options.active );
15367
                } else {
15368
                        this.active = $();
15369
                }
15370
15371
                this._refresh();
15372
15373
                if ( this.active.length ) {
15374
                        this.load( options.active );
15375
                }
15376
        },
15377
15378
        _initialActive: function() {
15379
                var active = this.options.active,
15380
                        collapsible = this.options.collapsible,
15381
                        locationHash = location.hash.substring( 1 );
15382
15383
                if ( active === null ) {
15384
                        // check the fragment identifier in the URL
15385
                        if ( locationHash ) {
15386
                                this.tabs.each(function( i, tab ) {
15387
                                        if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
15388
                                                active = i;
15389
                                                return false;
15390
                                        }
15391
                                });
15392
                        }
15393
15394
                        // check for a tab marked active via a class
15395
                        if ( active === null ) {
15396
                                active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
15397
                        }
15398
15399
                        // no active tab, set to false
15400
                        if ( active === null || active === -1 ) {
15401
                                active = this.tabs.length ? 0 : false;
15402
                        }
15403
                }
15404
15405
                // handle numbers: negative, out of range
15406
                if ( active !== false ) {
15407
                        active = this.tabs.index( this.tabs.eq( active ) );
15408
                        if ( active === -1 ) {
15409
                                active = collapsible ? false : 0;
15410
                        }
15411
                }
15412
15413
                // don't allow collapsible: false and active: false
15414
                if ( !collapsible && active === false && this.anchors.length ) {
15415
                        active = 0;
15416
                }
15417
15418
                return active;
15419
        },
15420
15421
        _getCreateEventData: function() {
15422
                return {
15423
                        tab: this.active,
15424
                        panel: !this.active.length ? $() : this._getPanelForTab( this.active )
15425
                };
15426
        },
15427
15428
        _tabKeydown: function( event ) {
15429
                var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
15430
                        selectedIndex = this.tabs.index( focusedTab ),
15431
                        goingForward = true;
15432
15433
                if ( this._handlePageNav( event ) ) {
15434
                        return;
15435
                }
15436
15437
                switch ( event.keyCode ) {
15438
                        case $.ui.keyCode.RIGHT:
15439
                        case $.ui.keyCode.DOWN:
15440
                                selectedIndex++;
15441
                                break;
15442
                        case $.ui.keyCode.UP:
15443
                        case $.ui.keyCode.LEFT:
15444
                                goingForward = false;
15445
                                selectedIndex--;
15446
                                break;
15447
                        case $.ui.keyCode.END:
15448
                                selectedIndex = this.anchors.length - 1;
15449
                                break;
15450
                        case $.ui.keyCode.HOME:
15451
                                selectedIndex = 0;
15452
                                break;
15453
                        case $.ui.keyCode.SPACE:
15454
                                // Activate only, no collapsing
15455
                                event.preventDefault();
15456
                                clearTimeout( this.activating );
15457
                                this._activate( selectedIndex );
15458
                                return;
15459
                        case $.ui.keyCode.ENTER:
15460
                                // Toggle (cancel delayed activation, allow collapsing)
15461
                                event.preventDefault();
15462
                                clearTimeout( this.activating );
15463
                                // Determine if we should collapse or activate
15464
                                this._activate( selectedIndex === this.options.active ? false : selectedIndex );
15465
                                return;
15466
                        default:
15467
                                return;
15468
                }
15469
15470
                // Focus the appropriate tab, based on which key was pressed
15471
                event.preventDefault();
15472
                clearTimeout( this.activating );
15473
                selectedIndex = this._focusNextTab( selectedIndex, goingForward );
15474
15475
                // Navigating with control/command key will prevent automatic activation
15476
                if ( !event.ctrlKey && !event.metaKey ) {
15477
15478
                        // Update aria-selected immediately so that AT think the tab is already selected.
15479
                        // Otherwise AT may confuse the user by stating that they need to activate the tab,
15480
                        // but the tab will already be activated by the time the announcement finishes.
15481
                        focusedTab.attr( "aria-selected", "false" );
15482
                        this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
15483
15484
                        this.activating = this._delay(function() {
15485
                                this.option( "active", selectedIndex );
15486
                        }, this.delay );
15487
                }
15488
        },
15489
15490
        _panelKeydown: function( event ) {
15491
                if ( this._handlePageNav( event ) ) {
15492
                        return;
15493
                }
15494
15495
                // Ctrl+up moves focus to the current tab
15496
                if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
15497
                        event.preventDefault();
15498
                        this.active.focus();
15499
                }
15500
        },
15501
15502
        // Alt+page up/down moves focus to the previous/next tab (and activates)
15503
        _handlePageNav: function( event ) {
15504
                if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
15505
                        this._activate( this._focusNextTab( this.options.active - 1, false ) );
15506
                        return true;
15507
                }
15508
                if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
15509
                        this._activate( this._focusNextTab( this.options.active + 1, true ) );
15510
                        return true;
15511
                }
15512
        },
15513
15514
        _findNextTab: function( index, goingForward ) {
15515
                var lastTabIndex = this.tabs.length - 1;
15516
15517
                function constrain() {
15518
                        if ( index > lastTabIndex ) {
15519
                                index = 0;
15520
                        }
15521
                        if ( index < 0 ) {
15522
                                index = lastTabIndex;
15523
                        }
15524
                        return index;
15525
                }
15526
15527
                while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
15528
                        index = goingForward ? index + 1 : index - 1;
15529
                }
15530
15531
                return index;
15532
        },
15533
15534
        _focusNextTab: function( index, goingForward ) {
15535
                index = this._findNextTab( index, goingForward );
15536
                this.tabs.eq( index ).focus();
15537
                return index;
15538
        },
15539
15540
        _setOption: function( key, value ) {
15541
                if ( key === "active" ) {
15542
                        // _activate() will handle invalid values and update this.options
15543
                        this._activate( value );
15544
                        return;
15545
                }
15546
15547
                if ( key === "disabled" ) {
15548
                        // don't use the widget factory's disabled handling
15549
                        this._setupDisabled( value );
15550
                        return;
15551
                }
15552
15553
                this._super( key, value);
15554
15555
                if ( key === "collapsible" ) {
15556
                        this.element.toggleClass( "ui-tabs-collapsible", value );
15557
                        // Setting collapsible: false while collapsed; open first panel
15558
                        if ( !value && this.options.active === false ) {
15559
                                this._activate( 0 );
15560
                        }
15561
                }
15562
15563
                if ( key === "event" ) {
15564
                        this._setupEvents( value );
15565
                }
15566
15567
                if ( key === "heightStyle" ) {
15568
                        this._setupHeightStyle( value );
15569
                }
15570
        },
15571
15572
        _sanitizeSelector: function( hash ) {
15573
                return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
15574
        },
15575
15576
        refresh: function() {
15577
                var options = this.options,
15578
                        lis = this.tablist.children( ":has(a[href])" );
15579
15580
                // get disabled tabs from class attribute from HTML
15581
                // this will get converted to a boolean if needed in _refresh()
15582
                options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
15583
                        return lis.index( tab );
15584
                });
15585
15586
                this._processTabs();
15587
15588
                // was collapsed or no tabs
15589
                if ( options.active === false || !this.anchors.length ) {
15590
                        options.active = false;
15591
                        this.active = $();
15592
                // was active, but active tab is gone
15593
                } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
15594
                        // all remaining tabs are disabled
15595
                        if ( this.tabs.length === options.disabled.length ) {
15596
                                options.active = false;
15597
                                this.active = $();
15598
                        // activate previous tab
15599
                        } else {
15600
                                this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
15601
                        }
15602
                // was active, active tab still exists
15603
                } else {
15604
                        // make sure active index is correct
15605
                        options.active = this.tabs.index( this.active );
15606
                }
15607
15608
                this._refresh();
15609
        },
15610
15611
        _refresh: function() {
15612
                this._setupDisabled( this.options.disabled );
15613
                this._setupEvents( this.options.event );
15614
                this._setupHeightStyle( this.options.heightStyle );
15615
15616
                this.tabs.not( this.active ).attr({
15617
                        "aria-selected": "false",
15618
                        "aria-expanded": "false",
15619
                        tabIndex: -1
15620
                });
15621
                this.panels.not( this._getPanelForTab( this.active ) )
15622
                        .hide()
15623
                        .attr({
15624
                                "aria-hidden": "true"
15625
                        });
15626
15627
                // Make sure one tab is in the tab order
15628
                if ( !this.active.length ) {
15629
                        this.tabs.eq( 0 ).attr( "tabIndex", 0 );
15630
                } else {
15631
                        this.active
15632
                                .addClass( "ui-tabs-active ui-state-active" )
15633
                                .attr({
15634
                                        "aria-selected": "true",
15635
                                        "aria-expanded": "true",
15636
                                        tabIndex: 0
15637
                                });
15638
                        this._getPanelForTab( this.active )
15639
                                .show()
15640
                                .attr({
15641
                                        "aria-hidden": "false"
15642
                                });
15643
                }
15644
        },
15645
15646
        _processTabs: function() {
15647
                var that = this,
15648
                        prevTabs = this.tabs,
15649
                        prevAnchors = this.anchors,
15650
                        prevPanels = this.panels;
15651
15652
                this.tablist = this._getList()
15653
                        .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
15654
                        .attr( "role", "tablist" )
15655
15656
                        // Prevent users from focusing disabled tabs via click
15657
                        .delegate( "> li", "mousedown" + this.eventNamespace, function( event ) {
15658
                                if ( $( this ).is( ".ui-state-disabled" ) ) {
15659
                                        event.preventDefault();
15660
                                }
15661
                        })
15662
15663
                        // support: IE <9
15664
                        // Preventing the default action in mousedown doesn't prevent IE
15665
                        // from focusing the element, so if the anchor gets focused, blur.
15666
                        // We don't have to worry about focusing the previously focused
15667
                        // element since clicking on a non-focusable element should focus
15668
                        // the body anyway.
15669
                        .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
15670
                                if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
15671
                                        this.blur();
15672
                                }
15673
                        });
15674
15675
                this.tabs = this.tablist.find( "> li:has(a[href])" )
15676
                        .addClass( "ui-state-default ui-corner-top" )
15677
                        .attr({
15678
                                role: "tab",
15679
                                tabIndex: -1
15680
                        });
15681
15682
                this.anchors = this.tabs.map(function() {
15683
                                return $( "a", this )[ 0 ];
15684
                        })
15685
                        .addClass( "ui-tabs-anchor" )
15686
                        .attr({
15687
                                role: "presentation",
15688
                                tabIndex: -1
15689
                        });
15690
15691
                this.panels = $();
15692
15693
                this.anchors.each(function( i, anchor ) {
15694
                        var selector, panel, panelId,
15695
                                anchorId = $( anchor ).uniqueId().attr( "id" ),
15696
                                tab = $( anchor ).closest( "li" ),
15697
                                originalAriaControls = tab.attr( "aria-controls" );
15698
15699
                        // inline tab
15700
                        if ( that._isLocal( anchor ) ) {
15701
                                selector = anchor.hash;
15702
                                panelId = selector.substring( 1 );
15703
                                panel = that.element.find( that._sanitizeSelector( selector ) );
15704
                        // remote tab
15705
                        } else {
15706
                                // If the tab doesn't already have aria-controls,
15707
                                // generate an id by using a throw-away element
15708
                                panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
15709
                                selector = "#" + panelId;
15710
                                panel = that.element.find( selector );
15711
                                if ( !panel.length ) {
15712
                                        panel = that._createPanel( panelId );
15713
                                        panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
15714
                                }
15715
                                panel.attr( "aria-live", "polite" );
15716
                        }
15717
15718
                        if ( panel.length) {
15719
                                that.panels = that.panels.add( panel );
15720
                        }
15721
                        if ( originalAriaControls ) {
15722
                                tab.data( "ui-tabs-aria-controls", originalAriaControls );
15723
                        }
15724
                        tab.attr({
15725
                                "aria-controls": panelId,
15726
                                "aria-labelledby": anchorId
15727
                        });
15728
                        panel.attr( "aria-labelledby", anchorId );
15729
                });
15730
15731
                this.panels
15732
                        .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
15733
                        .attr( "role", "tabpanel" );
15734
15735
                // Avoid memory leaks (#10056)
15736
                if ( prevTabs ) {
15737
                        this._off( prevTabs.not( this.tabs ) );
15738
                        this._off( prevAnchors.not( this.anchors ) );
15739
                        this._off( prevPanels.not( this.panels ) );
15740
                }
15741
        },
15742
15743
        // allow overriding how to find the list for rare usage scenarios (#7715)
15744
        _getList: function() {
15745
                return this.tablist || this.element.find( "ol,ul" ).eq( 0 );
15746
        },
15747
15748
        _createPanel: function( id ) {
15749
                return $( "<div>" )
15750
                        .attr( "id", id )
15751
                        .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
15752
                        .data( "ui-tabs-destroy", true );
15753
        },
15754
15755
        _setupDisabled: function( disabled ) {
15756
                if ( $.isArray( disabled ) ) {
15757
                        if ( !disabled.length ) {
15758
                                disabled = false;
15759
                        } else if ( disabled.length === this.anchors.length ) {
15760
                                disabled = true;
15761
                        }
15762
                }
15763
15764
                // disable tabs
15765
                for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
15766
                        if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
15767
                                $( li )
15768
                                        .addClass( "ui-state-disabled" )
15769
                                        .attr( "aria-disabled", "true" );
15770
                        } else {
15771
                                $( li )
15772
                                        .removeClass( "ui-state-disabled" )
15773
                                        .removeAttr( "aria-disabled" );
15774
                        }
15775
                }
15776
15777
                this.options.disabled = disabled;
15778
        },
15779
15780
        _setupEvents: function( event ) {
15781
                var events = {};
15782
                if ( event ) {
15783
                        $.each( event.split(" "), function( index, eventName ) {
15784
                                events[ eventName ] = "_eventHandler";
15785
                        });
15786
                }
15787
15788
                this._off( this.anchors.add( this.tabs ).add( this.panels ) );
15789
                // Always prevent the default action, even when disabled
15790
                this._on( true, this.anchors, {
15791
                        click: function( event ) {
15792
                                event.preventDefault();
15793
                        }
15794
                });
15795
                this._on( this.anchors, events );
15796
                this._on( this.tabs, { keydown: "_tabKeydown" } );
15797
                this._on( this.panels, { keydown: "_panelKeydown" } );
15798
15799
                this._focusable( this.tabs );
15800
                this._hoverable( this.tabs );
15801
        },
15802
15803
        _setupHeightStyle: function( heightStyle ) {
15804
                var maxHeight,
15805
                        parent = this.element.parent();
15806
15807
                if ( heightStyle === "fill" ) {
15808
                        maxHeight = parent.height();
15809
                        maxHeight -= this.element.outerHeight() - this.element.height();
15810
15811
                        this.element.siblings( ":visible" ).each(function() {
15812
                                var elem = $( this ),
15813
                                        position = elem.css( "position" );
15814
15815
                                if ( position === "absolute" || position === "fixed" ) {
15816
                                        return;
15817
                                }
15818
                                maxHeight -= elem.outerHeight( true );
15819
                        });
15820
15821
                        this.element.children().not( this.panels ).each(function() {
15822
                                maxHeight -= $( this ).outerHeight( true );
15823
                        });
15824
15825
                        this.panels.each(function() {
15826
                                $( this ).height( Math.max( 0, maxHeight -
15827
                                        $( this ).innerHeight() + $( this ).height() ) );
15828
                        })
15829
                        .css( "overflow", "auto" );
15830
                } else if ( heightStyle === "auto" ) {
15831
                        maxHeight = 0;
15832
                        this.panels.each(function() {
15833
                                maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
15834
                        }).height( maxHeight );
15835
                }
15836
        },
15837
15838
        _eventHandler: function( event ) {
15839
                var options = this.options,
15840
                        active = this.active,
15841
                        anchor = $( event.currentTarget ),
15842
                        tab = anchor.closest( "li" ),
15843
                        clickedIsActive = tab[ 0 ] === active[ 0 ],
15844
                        collapsing = clickedIsActive && options.collapsible,
15845
                        toShow = collapsing ? $() : this._getPanelForTab( tab ),
15846
                        toHide = !active.length ? $() : this._getPanelForTab( active ),
15847
                        eventData = {
15848
                                oldTab: active,
15849
                                oldPanel: toHide,
15850
                                newTab: collapsing ? $() : tab,
15851
                                newPanel: toShow
15852
                        };
15853
15854
                event.preventDefault();
15855
15856
                if ( tab.hasClass( "ui-state-disabled" ) ||
15857
                                // tab is already loading
15858
                                tab.hasClass( "ui-tabs-loading" ) ||
15859
                                // can't switch durning an animation
15860
                                this.running ||
15861
                                // click on active header, but not collapsible
15862
                                ( clickedIsActive && !options.collapsible ) ||
15863
                                // allow canceling activation
15864
                                ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
15865
                        return;
15866
                }
15867
15868
                options.active = collapsing ? false : this.tabs.index( tab );
15869
15870
                this.active = clickedIsActive ? $() : tab;
15871
                if ( this.xhr ) {
15872
                        this.xhr.abort();
15873
                }
15874
15875
                if ( !toHide.length && !toShow.length ) {
15876
                        $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
15877
                }
15878
15879
                if ( toShow.length ) {
15880
                        this.load( this.tabs.index( tab ), event );
15881
                }
15882
                this._toggle( event, eventData );
15883
        },
15884
15885
        // handles show/hide for selecting tabs
15886
        _toggle: function( event, eventData ) {
15887
                var that = this,
15888
                        toShow = eventData.newPanel,
15889
                        toHide = eventData.oldPanel;
15890
15891
                this.running = true;
15892
15893
                function complete() {
15894
                        that.running = false;
15895
                        that._trigger( "activate", event, eventData );
15896
                }
15897
15898
                function show() {
15899
                        eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
15900
15901
                        if ( toShow.length && that.options.show ) {
15902
                                that._show( toShow, that.options.show, complete );
15903
                        } else {
15904
                                toShow.show();
15905
                                complete();
15906
                        }
15907
                }
15908
15909
                // start out by hiding, then showing, then completing
15910
                if ( toHide.length && this.options.hide ) {
15911
                        this._hide( toHide, this.options.hide, function() {
15912
                                eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
15913
                                show();
15914
                        });
15915
                } else {
15916
                        eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
15917
                        toHide.hide();
15918
                        show();
15919
                }
15920
15921
                toHide.attr( "aria-hidden", "true" );
15922
                eventData.oldTab.attr({
15923
                        "aria-selected": "false",
15924
                        "aria-expanded": "false"
15925
                });
15926
                // If we're switching tabs, remove the old tab from the tab order.
15927
                // If we're opening from collapsed state, remove the previous tab from the tab order.
15928
                // If we're collapsing, then keep the collapsing tab in the tab order.
15929
                if ( toShow.length && toHide.length ) {
15930
                        eventData.oldTab.attr( "tabIndex", -1 );
15931
                } else if ( toShow.length ) {
15932
                        this.tabs.filter(function() {
15933
                                return $( this ).attr( "tabIndex" ) === 0;
15934
                        })
15935
                        .attr( "tabIndex", -1 );
15936
                }
15937
15938
                toShow.attr( "aria-hidden", "false" );
15939
                eventData.newTab.attr({
15940
                        "aria-selected": "true",
15941
                        "aria-expanded": "true",
15942
                        tabIndex: 0
15943
                });
15944
        },
15945
15946
        _activate: function( index ) {
15947
                var anchor,
15948
                        active = this._findActive( index );
15949
15950
                // trying to activate the already active panel
15951
                if ( active[ 0 ] === this.active[ 0 ] ) {
15952
                        return;
15953
                }
15954
15955
                // trying to collapse, simulate a click on the current active header
15956
                if ( !active.length ) {
15957
                        active = this.active;
15958
                }
15959
15960
                anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
15961
                this._eventHandler({
15962
                        target: anchor,
15963
                        currentTarget: anchor,
15964
                        preventDefault: $.noop
15965
                });
15966
        },
15967
15968
        _findActive: function( index ) {
15969
                return index === false ? $() : this.tabs.eq( index );
15970
        },
15971
15972
        _getIndex: function( index ) {
15973
                // meta-function to give users option to provide a href string instead of a numerical index.
15974
                if ( typeof index === "string" ) {
15975
                        index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
15976
                }
15977
15978
                return index;
15979
        },
15980
15981
        _destroy: function() {
15982
                if ( this.xhr ) {
15983
                        this.xhr.abort();
15984
                }
15985
15986
                this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
15987
15988
                this.tablist
15989
                        .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
15990
                        .removeAttr( "role" );
15991
15992
                this.anchors
15993
                        .removeClass( "ui-tabs-anchor" )
15994
                        .removeAttr( "role" )
15995
                        .removeAttr( "tabIndex" )
15996
                        .removeUniqueId();
15997
15998
                this.tablist.unbind( this.eventNamespace );
15999
16000
                this.tabs.add( this.panels ).each(function() {
16001
                        if ( $.data( this, "ui-tabs-destroy" ) ) {
16002
                                $( this ).remove();
16003
                        } else {
16004
                                $( this )
16005
                                        .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
16006
                                                "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
16007
                                        .removeAttr( "tabIndex" )
16008
                                        .removeAttr( "aria-live" )
16009
                                        .removeAttr( "aria-busy" )
16010
                                        .removeAttr( "aria-selected" )
16011
                                        .removeAttr( "aria-labelledby" )
16012
                                        .removeAttr( "aria-hidden" )
16013
                                        .removeAttr( "aria-expanded" )
16014
                                        .removeAttr( "role" );
16015
                        }
16016
                });
16017
16018
                this.tabs.each(function() {
16019
                        var li = $( this ),
16020
                                prev = li.data( "ui-tabs-aria-controls" );
16021
                        if ( prev ) {
16022
                                li
16023
                                        .attr( "aria-controls", prev )
16024
                                        .removeData( "ui-tabs-aria-controls" );
16025
                        } else {
16026
                                li.removeAttr( "aria-controls" );
16027
                        }
16028
                });
16029
16030
                this.panels.show();
16031
16032
                if ( this.options.heightStyle !== "content" ) {
16033
                        this.panels.css( "height", "" );
16034
                }
16035
        },
16036
16037
        enable: function( index ) {
16038
                var disabled = this.options.disabled;
16039
                if ( disabled === false ) {
16040
                        return;
16041
                }
16042
16043
                if ( index === undefined ) {
16044
                        disabled = false;
16045
                } else {
16046
                        index = this._getIndex( index );
16047
                        if ( $.isArray( disabled ) ) {
16048
                                disabled = $.map( disabled, function( num ) {
16049
                                        return num !== index ? num : null;
16050
                                });
16051
                        } else {
16052
                                disabled = $.map( this.tabs, function( li, num ) {
16053
                                        return num !== index ? num : null;
16054
                                });
16055
                        }
16056
                }
16057
                this._setupDisabled( disabled );
16058
        },
16059
16060
        disable: function( index ) {
16061
                var disabled = this.options.disabled;
16062
                if ( disabled === true ) {
16063
                        return;
16064
                }
16065
16066
                if ( index === undefined ) {
16067
                        disabled = true;
16068
                } else {
16069
                        index = this._getIndex( index );
16070
                        if ( $.inArray( index, disabled ) !== -1 ) {
16071
                                return;
16072
                        }
16073
                        if ( $.isArray( disabled ) ) {
16074
                                disabled = $.merge( [ index ], disabled ).sort();
16075
                        } else {
16076
                                disabled = [ index ];
16077
                        }
16078
                }
16079
                this._setupDisabled( disabled );
16080
        },
16081
16082
        load: function( index, event ) {
16083
                index = this._getIndex( index );
16084
                var that = this,
16085
                        tab = this.tabs.eq( index ),
16086
                        anchor = tab.find( ".ui-tabs-anchor" ),
16087
                        panel = this._getPanelForTab( tab ),
16088
                        eventData = {
16089
                                tab: tab,
16090
                                panel: panel
16091
                        },
16092
                        complete = function( jqXHR, status ) {
16093
                                if ( status === "abort" ) {
16094
                                        that.panels.stop( false, true );
16095
                                }
16096
16097
                                tab.removeClass( "ui-tabs-loading" );
16098
                                panel.removeAttr( "aria-busy" );
16099
16100
                                if ( jqXHR === that.xhr ) {
16101
                                        delete that.xhr;
16102
                                }
16103
                        };
16104
16105
                // not remote
16106
                if ( this._isLocal( anchor[ 0 ] ) ) {
16107
                        return;
16108
                }
16109
16110
                this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
16111
16112
                // support: jQuery <1.8
16113
                // jQuery <1.8 returns false if the request is canceled in beforeSend,
16114
                // but as of 1.8, $.ajax() always returns a jqXHR object.
16115
                if ( this.xhr && this.xhr.statusText !== "canceled" ) {
16116
                        tab.addClass( "ui-tabs-loading" );
16117
                        panel.attr( "aria-busy", "true" );
16118
16119
                        this.xhr
16120
                                .done(function( response, status, jqXHR ) {
16121
                                        // support: jQuery <1.8
16122
                                        // http://bugs.jquery.com/ticket/11778
16123
                                        setTimeout(function() {
16124
                                                panel.html( response );
16125
                                                that._trigger( "load", event, eventData );
16126
16127
                                                complete( jqXHR, status );
16128
                                        }, 1 );
16129
                                })
16130
                                .fail(function( jqXHR, status ) {
16131
                                        // support: jQuery <1.8
16132
                                        // http://bugs.jquery.com/ticket/11778
16133
                                        setTimeout(function() {
16134
                                                complete( jqXHR, status );
16135
                                        }, 1 );
16136
                                });
16137
                }
16138
        },
16139
16140
        _ajaxSettings: function( anchor, event, eventData ) {
16141
                var that = this;
16142
                return {
16143
                        url: anchor.attr( "href" ),
16144
                        beforeSend: function( jqXHR, settings ) {
16145
                                return that._trigger( "beforeLoad", event,
16146
                                        $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
16147
                        }
16148
                };
16149
        },
16150
16151
        _getPanelForTab: function( tab ) {
16152
                var id = $( tab ).attr( "aria-controls" );
16153
                return this.element.find( this._sanitizeSelector( "#" + id ) );
16154
        }
16155
});
16156
16157
16158
/*!
16159
 * jQuery UI Tooltip 1.11.4
16160
 * http://jqueryui.com
16161
 *
16162
 * Copyright jQuery Foundation and other contributors
16163
 * Released under the MIT license.
16164
 * http://jquery.org/license
16165
 *
16166
 * http://api.jqueryui.com/tooltip/
16167
 */
16168
16169
16170
var tooltip = $.widget( "ui.tooltip", {
16171
        version: "1.11.4",
16172
        options: {
16173
                content: function() {
16174
                        // support: IE<9, Opera in jQuery <1.7
16175
                        // .text() can't accept undefined, so coerce to a string
16176
                        var title = $( this ).attr( "title" ) || "";
16177
                        // Escape title, since we're going from an attribute to raw HTML
16178
                        return $( "<a>" ).text( title ).html();
16179
                },
16180
                hide: true,
16181
                // Disabled elements have inconsistent behavior across browsers (#8661)
16182
                items: "[title]:not([disabled])",
16183
                position: {
16184
                        my: "left top+15",
16185
                        at: "left bottom",
16186
                        collision: "flipfit flip"
16187
                },
16188
                show: true,
16189
                tooltipClass: null,
16190
                track: false,
16191
16192
                // callbacks
16193
                close: null,
16194
                open: null
16195
        },
16196
16197
        _addDescribedBy: function( elem, id ) {
16198
                var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
16199
                describedby.push( id );
16200
                elem
16201
                        .data( "ui-tooltip-id", id )
16202
                        .attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
16203
        },
16204
16205
        _removeDescribedBy: function( elem ) {
16206
                var id = elem.data( "ui-tooltip-id" ),
16207
                        describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
16208
                        index = $.inArray( id, describedby );
16209
16210
                if ( index !== -1 ) {
16211
                        describedby.splice( index, 1 );
16212
                }
16213
16214
                elem.removeData( "ui-tooltip-id" );
16215
                describedby = $.trim( describedby.join( " " ) );
16216
                if ( describedby ) {
16217
                        elem.attr( "aria-describedby", describedby );
16218
                } else {
16219
                        elem.removeAttr( "aria-describedby" );
16220
                }
16221
        },
16222
16223
        _create: function() {
16224
                this._on({
16225
                        mouseover: "open",
16226
                        focusin: "open"
16227
                });
16228
16229
                // IDs of generated tooltips, needed for destroy
16230
                this.tooltips = {};
16231
16232
                // IDs of parent tooltips where we removed the title attribute
16233
                this.parents = {};
16234
16235
                if ( this.options.disabled ) {
16236
                        this._disable();
16237
                }
16238
16239
                // Append the aria-live region so tooltips announce correctly
16240
                this.liveRegion = $( "<div>" )
16241
                        .attr({
16242
                                role: "log",
16243
                                "aria-live": "assertive",
16244
                                "aria-relevant": "additions"
16245
                        })
16246
                        .addClass( "ui-helper-hidden-accessible" )
16247
                        .appendTo( this.document[ 0 ].body );
16248
        },
16249
16250
        _setOption: function( key, value ) {
16251
                var that = this;
16252
16253
                if ( key === "disabled" ) {
16254
                        this[ value ? "_disable" : "_enable" ]();
16255
                        this.options[ key ] = value;
16256
                        // disable element style changes
16257
                        return;
16258
                }
16259
16260
                this._super( key, value );
16261
16262
                if ( key === "content" ) {
16263
                        $.each( this.tooltips, function( id, tooltipData ) {
16264
                                that._updateContent( tooltipData.element );
16265
                        });
16266
                }
16267
        },
16268
16269
        _disable: function() {
16270
                var that = this;
16271
16272
                // close open tooltips
16273
                $.each( this.tooltips, function( id, tooltipData ) {
16274
                        var event = $.Event( "blur" );
16275
                        event.target = event.currentTarget = tooltipData.element[ 0 ];
16276
                        that.close( event, true );
16277
                });
16278
16279
                // remove title attributes to prevent native tooltips
16280
                this.element.find( this.options.items ).addBack().each(function() {
16281
                        var element = $( this );
16282
                        if ( element.is( "[title]" ) ) {
16283
                                element
16284
                                        .data( "ui-tooltip-title", element.attr( "title" ) )
16285
                                        .removeAttr( "title" );
16286
                        }
16287
                });
16288
        },
16289
16290
        _enable: function() {
16291
                // restore title attributes
16292
                this.element.find( this.options.items ).addBack().each(function() {
16293
                        var element = $( this );
16294
                        if ( element.data( "ui-tooltip-title" ) ) {
16295
                                element.attr( "title", element.data( "ui-tooltip-title" ) );
16296
                        }
16297
                });
16298
        },
16299
16300
        open: function( event ) {
16301
                var that = this,
16302
                        target = $( event ? event.target : this.element )
16303
                                // we need closest here due to mouseover bubbling,
16304
                                // but always pointing at the same event target
16305
                                .closest( this.options.items );
16306
16307
                // No element to show a tooltip for or the tooltip is already open
16308
                if ( !target.length || target.data( "ui-tooltip-id" ) ) {
16309
                        return;
16310
                }
16311
16312
                if ( target.attr( "title" ) ) {
16313
                        target.data( "ui-tooltip-title", target.attr( "title" ) );
16314
                }
16315
16316
                target.data( "ui-tooltip-open", true );
16317
16318
                // kill parent tooltips, custom or native, for hover
16319
                if ( event && event.type === "mouseover" ) {
16320
                        target.parents().each(function() {
16321
                                var parent = $( this ),
16322
                                        blurEvent;
16323
                                if ( parent.data( "ui-tooltip-open" ) ) {
16324
                                        blurEvent = $.Event( "blur" );
16325
                                        blurEvent.target = blurEvent.currentTarget = this;
16326
                                        that.close( blurEvent, true );
16327
                                }
16328
                                if ( parent.attr( "title" ) ) {
16329
                                        parent.uniqueId();
16330
                                        that.parents[ this.id ] = {
16331
                                                element: this,
16332
                                                title: parent.attr( "title" )
16333
                                        };
16334
                                        parent.attr( "title", "" );
16335
                                }
16336
                        });
16337
                }
16338
16339
                this._registerCloseHandlers( event, target );
16340
                this._updateContent( target, event );
16341
        },
16342
16343
        _updateContent: function( target, event ) {
16344
                var content,
16345
                        contentOption = this.options.content,
16346
                        that = this,
16347
                        eventType = event ? event.type : null;
16348
16349
                if ( typeof contentOption === "string" ) {
16350
                        return this._open( event, target, contentOption );
16351
                }
16352
16353
                content = contentOption.call( target[0], function( response ) {
16354
16355
                        // IE may instantly serve a cached response for ajax requests
16356
                        // delay this call to _open so the other call to _open runs first
16357
                        that._delay(function() {
16358
16359
                                // Ignore async response if tooltip was closed already
16360
                                if ( !target.data( "ui-tooltip-open" ) ) {
16361
                                        return;
16362
                                }
16363
16364
                                // jQuery creates a special event for focusin when it doesn't
16365
                                // exist natively. To improve performance, the native event
16366
                                // object is reused and the type is changed. Therefore, we can't
16367
                                // rely on the type being correct after the event finished
16368
                                // bubbling, so we set it back to the previous value. (#8740)
16369
                                if ( event ) {
16370
                                        event.type = eventType;
16371
                                }
16372
                                this._open( event, target, response );
16373
                        });
16374
                });
16375
                if ( content ) {
16376
                        this._open( event, target, content );
16377
                }
16378
        },
16379
16380
        _open: function( event, target, content ) {
16381
                var tooltipData, tooltip, delayedShow, a11yContent,
16382
                        positionOption = $.extend( {}, this.options.position );
16383
16384
                if ( !content ) {
16385
                        return;
16386
                }
16387
16388
                // Content can be updated multiple times. If the tooltip already
16389
                // exists, then just update the content and bail.
16390
                tooltipData = this._find( target );
16391
                if ( tooltipData ) {
16392
                        tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
16393
                        return;
16394
                }
16395
16396
                // if we have a title, clear it to prevent the native tooltip
16397
                // we have to check first to avoid defining a title if none exists
16398
                // (we don't want to cause an element to start matching [title])
16399
                //
16400
                // We use removeAttr only for key events, to allow IE to export the correct
16401
                // accessible attributes. For mouse events, set to empty string to avoid
16402
                // native tooltip showing up (happens only when removing inside mouseover).
16403
                if ( target.is( "[title]" ) ) {
16404
                        if ( event && event.type === "mouseover" ) {
16405
                                target.attr( "title", "" );
16406
                        } else {
16407
                                target.removeAttr( "title" );
16408
                        }
16409
                }
16410
16411
                tooltipData = this._tooltip( target );
16412
                tooltip = tooltipData.tooltip;
16413
                this._addDescribedBy( target, tooltip.attr( "id" ) );
16414
                tooltip.find( ".ui-tooltip-content" ).html( content );
16415
16416
                // Support: Voiceover on OS X, JAWS on IE <= 9
16417
                // JAWS announces deletions even when aria-relevant="additions"
16418
                // Voiceover will sometimes re-read the entire log region's contents from the beginning
16419
                this.liveRegion.children().hide();
16420
                if ( content.clone ) {
16421
                        a11yContent = content.clone();
16422
                        a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
16423
                } else {
16424
                        a11yContent = content;
16425
                }
16426
                $( "<div>" ).html( a11yContent ).appendTo( this.liveRegion );
16427
16428
                function position( event ) {
16429
                        positionOption.of = event;
16430
                        if ( tooltip.is( ":hidden" ) ) {
16431
                                return;
16432
                        }
16433
                        tooltip.position( positionOption );
16434
                }
16435
                if ( this.options.track && event && /^mouse/.test( event.type ) ) {
16436
                        this._on( this.document, {
16437
                                mousemove: position
16438
                        });
16439
                        // trigger once to override element-relative positioning
16440
                        position( event );
16441
                } else {
16442
                        tooltip.position( $.extend({
16443
                                of: target
16444
                        }, this.options.position ) );
16445
                }
16446
16447
                tooltip.hide();
16448
16449
                this._show( tooltip, this.options.show );
16450
                // Handle tracking tooltips that are shown with a delay (#8644). As soon
16451
                // as the tooltip is visible, position the tooltip using the most recent
16452
                // event.
16453
                if ( this.options.show && this.options.show.delay ) {
16454
                        delayedShow = this.delayedShow = setInterval(function() {
16455
                                if ( tooltip.is( ":visible" ) ) {
16456
                                        position( positionOption.of );
16457
                                        clearInterval( delayedShow );
16458
                                }
16459
                        }, $.fx.interval );
16460
                }
16461
16462
                this._trigger( "open", event, { tooltip: tooltip } );
16463
        },
16464
16465
        _registerCloseHandlers: function( event, target ) {
16466
                var events = {
16467
                        keyup: function( event ) {
16468
                                if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
16469
                                        var fakeEvent = $.Event(event);
16470
                                        fakeEvent.currentTarget = target[0];
16471
                                        this.close( fakeEvent, true );
16472
                                }
16473
                        }
16474
                };
16475
16476
                // Only bind remove handler for delegated targets. Non-delegated
16477
                // tooltips will handle this in destroy.
16478
                if ( target[ 0 ] !== this.element[ 0 ] ) {
16479
                        events.remove = function() {
16480
                                this._removeTooltip( this._find( target ).tooltip );
16481
                        };
16482
                }
16483
16484
                if ( !event || event.type === "mouseover" ) {
16485
                        events.mouseleave = "close";
16486
                }
16487
                if ( !event || event.type === "focusin" ) {
16488
                        events.focusout = "close";
16489
                }
16490
                this._on( true, target, events );
16491
        },
16492
16493
        close: function( event ) {
16494
                var tooltip,
16495
                        that = this,
16496
                        target = $( event ? event.currentTarget : this.element ),
16497
                        tooltipData = this._find( target );
16498
16499
                // The tooltip may already be closed
16500
                if ( !tooltipData ) {
16501
16502
                        // We set ui-tooltip-open immediately upon open (in open()), but only set the
16503
                        // additional data once there's actually content to show (in _open()). So even if the
16504
                        // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
16505
                        // the period between open() and _open().
16506
                        target.removeData( "ui-tooltip-open" );
16507
                        return;
16508
                }
16509
16510
                tooltip = tooltipData.tooltip;
16511
16512
                // disabling closes the tooltip, so we need to track when we're closing
16513
                // to avoid an infinite loop in case the tooltip becomes disabled on close
16514
                if ( tooltipData.closing ) {
16515
                        return;
16516
                }
16517
16518
                // Clear the interval for delayed tracking tooltips
16519
                clearInterval( this.delayedShow );
16520
16521
                // only set title if we had one before (see comment in _open())
16522
                // If the title attribute has changed since open(), don't restore
16523
                if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
16524
                        target.attr( "title", target.data( "ui-tooltip-title" ) );
16525
                }
16526
16527
                this._removeDescribedBy( target );
16528
16529
                tooltipData.hiding = true;
16530
                tooltip.stop( true );
16531
                this._hide( tooltip, this.options.hide, function() {
16532
                        that._removeTooltip( $( this ) );
16533
                });
16534
16535
                target.removeData( "ui-tooltip-open" );
16536
                this._off( target, "mouseleave focusout keyup" );
16537
16538
                // Remove 'remove' binding only on delegated targets
16539
                if ( target[ 0 ] !== this.element[ 0 ] ) {
16540
                        this._off( target, "remove" );
16541
                }
16542
                this._off( this.document, "mousemove" );
16543
16544
                if ( event && event.type === "mouseleave" ) {
16545
                        $.each( this.parents, function( id, parent ) {
16546
                                $( parent.element ).attr( "title", parent.title );
16547
                                delete that.parents[ id ];
16548
                        });
16549
                }
16550
16551
                tooltipData.closing = true;
16552
                this._trigger( "close", event, { tooltip: tooltip } );
16553
                if ( !tooltipData.hiding ) {
16554
                        tooltipData.closing = false;
16555
                }
16556
        },
16557
16558
        _tooltip: function( element ) {
16559
                var tooltip = $( "<div>" )
16560
                                .attr( "role", "tooltip" )
16561
                                .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
16562
                                        ( this.options.tooltipClass || "" ) ),
16563
                        id = tooltip.uniqueId().attr( "id" );
16564
16565
                $( "<div>" )
16566
                        .addClass( "ui-tooltip-content" )
16567
                        .appendTo( tooltip );
16568
16569
                tooltip.appendTo( this.document[0].body );
16570
16571
                return this.tooltips[ id ] = {
16572
                        element: element,
16573
                        tooltip: tooltip
16574
                };
16575
        },
16576
16577
        _find: function( target ) {
16578
                var id = target.data( "ui-tooltip-id" );
16579
                return id ? this.tooltips[ id ] : null;
16580
        },
16581
16582
        _removeTooltip: function( tooltip ) {
16583
                tooltip.remove();
16584
                delete this.tooltips[ tooltip.attr( "id" ) ];
16585
        },
16586
16587
        _destroy: function() {
16588
                var that = this;
16589
16590
                // close open tooltips
16591
                $.each( this.tooltips, function( id, tooltipData ) {
16592
                        // Delegate to close method to handle common cleanup
16593
                        var event = $.Event( "blur" ),
16594
                                element = tooltipData.element;
16595
                        event.target = event.currentTarget = element[ 0 ];
16596
                        that.close( event, true );
16597
16598
                        // Remove immediately; destroying an open tooltip doesn't use the
16599
                        // hide animation
16600
                        $( "#" + id ).remove();
16601
16602
                        // Restore the title
16603
                        if ( element.data( "ui-tooltip-title" ) ) {
16604
                                // If the title attribute has changed since open(), don't restore
16605
                                if ( !element.attr( "title" ) ) {
16606
                                        element.attr( "title", element.data( "ui-tooltip-title" ) );
16607
                                }
16608
                                element.removeData( "ui-tooltip-title" );
16609
                        }
16610
                });
16611
                this.liveRegion.remove();
16612
        }
16613
});
16614
16615
16616
16617
}));