UNPKG

470 kBJavaScriptView Raw
1/*! jQuery UI - v1.11.3 - 2015-02-22
2* http://jqueryui.com
3* Includes: core.js, widget.js, mouse.js, position.js, draggable.js, droppable.js, resizable.js, selectable.js, sortable.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, menu.js, progressbar.js, selectmenu.js, slider.js, spinner.js, tabs.js, tooltip.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js
4* Copyright 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.3
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.3",
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
94function 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
115function 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
146if ( !$( "<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
193if ( !$.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)
202if ( $( "<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.3
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
323var 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
856var widget = $.widget;
857
858
859/*!
860 * jQuery UI Mouse 1.11.3
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
871var mouseHandled = false;
872$( document ).mouseup( function() {
873 mouseHandled = false;
874});
875
876var mouse = $.widget("ui.mouse", {
877 version: "1.11.3",
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.3
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
1060var 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
1071function 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
1078function parseCss( element, property ) {
1079 return parseInt( $.css( element, property ), 10 ) || 0;
1080}
1081
1082function 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
1549var position = $.ui.position;
1550
1551
1552/*!
1553 * jQuery UI Draggable 1.11.3
1554 * http://jqueryui.com
1555 *
1556 * Copyright jQuery Foundation and other contributors
1557 * Released under the MIT license.
1558 * http://jquery.org/license
1559 *
1560 * http://api.jqueryui.com/draggable/
1561 */
1562
1563
1564$.widget("ui.draggable", $.ui.mouse, {
1565 version: "1.11.3",
1566 widgetEventPrefix: "drag",
1567 options: {
1568 addClasses: true,
1569 appendTo: "parent",
1570 axis: false,
1571 connectToSortable: false,
1572 containment: false,
1573 cursor: "auto",
1574 cursorAt: false,
1575 grid: false,
1576 handle: false,
1577 helper: "original",
1578 iframeFix: false,
1579 opacity: false,
1580 refreshPositions: false,
1581 revert: false,
1582 revertDuration: 500,
1583 scope: "default",
1584 scroll: true,
1585 scrollSensitivity: 20,
1586 scrollSpeed: 20,
1587 snap: false,
1588 snapMode: "both",
1589 snapTolerance: 20,
1590 stack: false,
1591 zIndex: false,
1592
1593 // callbacks
1594 drag: null,
1595 start: null,
1596 stop: null
1597 },
1598 _create: function() {
1599
1600 if ( this.options.helper === "original" ) {
1601 this._setPositionRelative();
1602 }
1603 if (this.options.addClasses){
1604 this.element.addClass("ui-draggable");
1605 }
1606 if (this.options.disabled){
1607 this.element.addClass("ui-draggable-disabled");
1608 }
1609 this._setHandleClassName();
1610
1611 this._mouseInit();
1612 },
1613
1614 _setOption: function( key, value ) {
1615 this._super( key, value );
1616 if ( key === "handle" ) {
1617 this._removeHandleClassName();
1618 this._setHandleClassName();
1619 }
1620 },
1621
1622 _destroy: function() {
1623 if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
1624 this.destroyOnClear = true;
1625 return;
1626 }
1627 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1628 this._removeHandleClassName();
1629 this._mouseDestroy();
1630 },
1631
1632 _mouseCapture: function(event) {
1633 var o = this.options;
1634
1635 this._blurActiveElement( event );
1636
1637 // among others, prevent a drag on a resizable-handle
1638 if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
1639 return false;
1640 }
1641
1642 //Quit if we're not on a valid handle
1643 this.handle = this._getHandle(event);
1644 if (!this.handle) {
1645 return false;
1646 }
1647
1648 this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
1649
1650 return true;
1651
1652 },
1653
1654 _blockFrames: function( selector ) {
1655 this.iframeBlocks = this.document.find( selector ).map(function() {
1656 var iframe = $( this );
1657
1658 return $( "<div>" )
1659 .css( "position", "absolute" )
1660 .appendTo( iframe.parent() )
1661 .outerWidth( iframe.outerWidth() )
1662 .outerHeight( iframe.outerHeight() )
1663 .offset( iframe.offset() )[ 0 ];
1664 });
1665 },
1666
1667 _unblockFrames: function() {
1668 if ( this.iframeBlocks ) {
1669 this.iframeBlocks.remove();
1670 delete this.iframeBlocks;
1671 }
1672 },
1673
1674 _blurActiveElement: function( event ) {
1675 var document = this.document[ 0 ];
1676
1677 // Only need to blur if the event occurred on the draggable itself, see #10527
1678 if ( !this.handleElement.is( event.target ) ) {
1679 return;
1680 }
1681
1682 // support: IE9
1683 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
1684 try {
1685
1686 // Support: IE9, IE10
1687 // If the <body> is blurred, IE will switch windows, see #9520
1688 if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) {
1689
1690 // Blur any element that currently has focus, see #4261
1691 $( document.activeElement ).blur();
1692 }
1693 } catch ( error ) {}
1694 },
1695
1696 _mouseStart: function(event) {
1697
1698 var o = this.options;
1699
1700 //Create and append the visible helper
1701 this.helper = this._createHelper(event);
1702
1703 this.helper.addClass("ui-draggable-dragging");
1704
1705 //Cache the helper size
1706 this._cacheHelperProportions();
1707
1708 //If ddmanager is used for droppables, set the global draggable
1709 if ($.ui.ddmanager) {
1710 $.ui.ddmanager.current = this;
1711 }
1712
1713 /*
1714 * - Position generation -
1715 * This block generates everything position related - it's the core of draggables.
1716 */
1717
1718 //Cache the margins of the original element
1719 this._cacheMargins();
1720
1721 //Store the helper's css position
1722 this.cssPosition = this.helper.css( "position" );
1723 this.scrollParent = this.helper.scrollParent( true );
1724 this.offsetParent = this.helper.offsetParent();
1725 this.hasFixedAncestor = this.helper.parents().filter(function() {
1726 return $( this ).css( "position" ) === "fixed";
1727 }).length > 0;
1728
1729 //The element's absolute position on the page minus margins
1730 this.positionAbs = this.element.offset();
1731 this._refreshOffsets( event );
1732
1733 //Generate the original position
1734 this.originalPosition = this.position = this._generatePosition( event, false );
1735 this.originalPageX = event.pageX;
1736 this.originalPageY = event.pageY;
1737
1738 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
1739 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1740
1741 //Set a containment if given in the options
1742 this._setContainment();
1743
1744 //Trigger event + callbacks
1745 if (this._trigger("start", event) === false) {
1746 this._clear();
1747 return false;
1748 }
1749
1750 //Recache the helper size
1751 this._cacheHelperProportions();
1752
1753 //Prepare the droppable offsets
1754 if ($.ui.ddmanager && !o.dropBehaviour) {
1755 $.ui.ddmanager.prepareOffsets(this, event);
1756 }
1757
1758 // Reset helper's right/bottom css if they're set and set explicit width/height instead
1759 // as this prevents resizing of elements with right/bottom set (see #7772)
1760 this._normalizeRightBottom();
1761
1762 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1763
1764 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1765 if ( $.ui.ddmanager ) {
1766 $.ui.ddmanager.dragStart(this, event);
1767 }
1768
1769 return true;
1770 },
1771
1772 _refreshOffsets: function( event ) {
1773 this.offset = {
1774 top: this.positionAbs.top - this.margins.top,
1775 left: this.positionAbs.left - this.margins.left,
1776 scroll: false,
1777 parent: this._getParentOffset(),
1778 relative: this._getRelativeOffset()
1779 };
1780
1781 this.offset.click = {
1782 left: event.pageX - this.offset.left,
1783 top: event.pageY - this.offset.top
1784 };
1785 },
1786
1787 _mouseDrag: function(event, noPropagation) {
1788 // reset any necessary cached properties (see #5009)
1789 if ( this.hasFixedAncestor ) {
1790 this.offset.parent = this._getParentOffset();
1791 }
1792
1793 //Compute the helpers position
1794 this.position = this._generatePosition( event, true );
1795 this.positionAbs = this._convertPositionTo("absolute");
1796
1797 //Call plugins and callbacks and use the resulting position if something is returned
1798 if (!noPropagation) {
1799 var ui = this._uiHash();
1800 if (this._trigger("drag", event, ui) === false) {
1801 this._mouseUp({});
1802 return false;
1803 }
1804 this.position = ui.position;
1805 }
1806
1807 this.helper[ 0 ].style.left = this.position.left + "px";
1808 this.helper[ 0 ].style.top = this.position.top + "px";
1809
1810 if ($.ui.ddmanager) {
1811 $.ui.ddmanager.drag(this, event);
1812 }
1813
1814 return false;
1815 },
1816
1817 _mouseStop: function(event) {
1818
1819 //If we are using droppables, inform the manager about the drop
1820 var that = this,
1821 dropped = false;
1822 if ($.ui.ddmanager && !this.options.dropBehaviour) {
1823 dropped = $.ui.ddmanager.drop(this, event);
1824 }
1825
1826 //if a drop comes from outside (a sortable)
1827 if (this.dropped) {
1828 dropped = this.dropped;
1829 this.dropped = false;
1830 }
1831
1832 if ((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
1833 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1834 if (that._trigger("stop", event) !== false) {
1835 that._clear();
1836 }
1837 });
1838 } else {
1839 if (this._trigger("stop", event) !== false) {
1840 this._clear();
1841 }
1842 }
1843
1844 return false;
1845 },
1846
1847 _mouseUp: function( event ) {
1848 this._unblockFrames();
1849
1850 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1851 if ( $.ui.ddmanager ) {
1852 $.ui.ddmanager.dragStop(this, event);
1853 }
1854
1855 // Only need to focus if the event occurred on the draggable itself, see #10527
1856 if ( this.handleElement.is( event.target ) ) {
1857 // The interaction is over; whether or not the click resulted in a drag, focus the element
1858 this.element.focus();
1859 }
1860
1861 return $.ui.mouse.prototype._mouseUp.call(this, event);
1862 },
1863
1864 cancel: function() {
1865
1866 if (this.helper.is(".ui-draggable-dragging")) {
1867 this._mouseUp({});
1868 } else {
1869 this._clear();
1870 }
1871
1872 return this;
1873
1874 },
1875
1876 _getHandle: function(event) {
1877 return this.options.handle ?
1878 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
1879 true;
1880 },
1881
1882 _setHandleClassName: function() {
1883 this.handleElement = this.options.handle ?
1884 this.element.find( this.options.handle ) : this.element;
1885 this.handleElement.addClass( "ui-draggable-handle" );
1886 },
1887
1888 _removeHandleClassName: function() {
1889 this.handleElement.removeClass( "ui-draggable-handle" );
1890 },
1891
1892 _createHelper: function(event) {
1893
1894 var o = this.options,
1895 helperIsFunction = $.isFunction( o.helper ),
1896 helper = helperIsFunction ?
1897 $( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
1898 ( o.helper === "clone" ?
1899 this.element.clone().removeAttr( "id" ) :
1900 this.element );
1901
1902 if (!helper.parents("body").length) {
1903 helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
1904 }
1905
1906 // http://bugs.jqueryui.com/ticket/9446
1907 // a helper function can return the original element
1908 // which wouldn't have been set to relative in _create
1909 if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
1910 this._setPositionRelative();
1911 }
1912
1913 if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
1914 helper.css("position", "absolute");
1915 }
1916
1917 return helper;
1918
1919 },
1920
1921 _setPositionRelative: function() {
1922 if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
1923 this.element[ 0 ].style.position = "relative";
1924 }
1925 },
1926
1927 _adjustOffsetFromHelper: function(obj) {
1928 if (typeof obj === "string") {
1929 obj = obj.split(" ");
1930 }
1931 if ($.isArray(obj)) {
1932 obj = { left: +obj[0], top: +obj[1] || 0 };
1933 }
1934 if ("left" in obj) {
1935 this.offset.click.left = obj.left + this.margins.left;
1936 }
1937 if ("right" in obj) {
1938 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1939 }
1940 if ("top" in obj) {
1941 this.offset.click.top = obj.top + this.margins.top;
1942 }
1943 if ("bottom" in obj) {
1944 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1945 }
1946 },
1947
1948 _isRootNode: function( element ) {
1949 return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
1950 },
1951
1952 _getParentOffset: function() {
1953
1954 //Get the offsetParent and cache its position
1955 var po = this.offsetParent.offset(),
1956 document = this.document[ 0 ];
1957
1958 // This is a special case where we need to modify a offset calculated on start, since the following happened:
1959 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1960 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1961 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1962 if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1963 po.left += this.scrollParent.scrollLeft();
1964 po.top += this.scrollParent.scrollTop();
1965 }
1966
1967 if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
1968 po = { top: 0, left: 0 };
1969 }
1970
1971 return {
1972 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0),
1973 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0)
1974 };
1975
1976 },
1977
1978 _getRelativeOffset: function() {
1979 if ( this.cssPosition !== "relative" ) {
1980 return { top: 0, left: 0 };
1981 }
1982
1983 var p = this.element.position(),
1984 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
1985
1986 return {
1987 top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
1988 left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
1989 };
1990
1991 },
1992
1993 _cacheMargins: function() {
1994 this.margins = {
1995 left: (parseInt(this.element.css("marginLeft"), 10) || 0),
1996 top: (parseInt(this.element.css("marginTop"), 10) || 0),
1997 right: (parseInt(this.element.css("marginRight"), 10) || 0),
1998 bottom: (parseInt(this.element.css("marginBottom"), 10) || 0)
1999 };
2000 },
2001
2002 _cacheHelperProportions: function() {
2003 this.helperProportions = {
2004 width: this.helper.outerWidth(),
2005 height: this.helper.outerHeight()
2006 };
2007 },
2008
2009 _setContainment: function() {
2010
2011 var isUserScrollable, c, ce,
2012 o = this.options,
2013 document = this.document[ 0 ];
2014
2015 this.relativeContainer = null;
2016
2017 if ( !o.containment ) {
2018 this.containment = null;
2019 return;
2020 }
2021
2022 if ( o.containment === "window" ) {
2023 this.containment = [
2024 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
2025 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
2026 $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
2027 $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
2028 ];
2029 return;
2030 }
2031
2032 if ( o.containment === "document") {
2033 this.containment = [
2034 0,
2035 0,
2036 $( document ).width() - this.helperProportions.width - this.margins.left,
2037 ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
2038 ];
2039 return;
2040 }
2041
2042 if ( o.containment.constructor === Array ) {
2043 this.containment = o.containment;
2044 return;
2045 }
2046
2047 if ( o.containment === "parent" ) {
2048 o.containment = this.helper[ 0 ].parentNode;
2049 }
2050
2051 c = $( o.containment );
2052 ce = c[ 0 ];
2053
2054 if ( !ce ) {
2055 return;
2056 }
2057
2058 isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
2059
2060 this.containment = [
2061 ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
2062 ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
2063 ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
2064 ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
2065 ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
2066 this.helperProportions.width -
2067 this.margins.left -
2068 this.margins.right,
2069 ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
2070 ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
2071 ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
2072 this.helperProportions.height -
2073 this.margins.top -
2074 this.margins.bottom
2075 ];
2076 this.relativeContainer = c;
2077 },
2078
2079 _convertPositionTo: function(d, pos) {
2080
2081 if (!pos) {
2082 pos = this.position;
2083 }
2084
2085 var mod = d === "absolute" ? 1 : -1,
2086 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
2087
2088 return {
2089 top: (
2090 pos.top + // The absolute mouse position
2091 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
2092 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border)
2093 ( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)
2094 ),
2095 left: (
2096 pos.left + // The absolute mouse position
2097 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
2098 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border)
2099 ( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod)
2100 )
2101 };
2102
2103 },
2104
2105 _generatePosition: function( event, constrainPosition ) {
2106
2107 var containment, co, top, left,
2108 o = this.options,
2109 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
2110 pageX = event.pageX,
2111 pageY = event.pageY;
2112
2113 // Cache the scroll
2114 if ( !scrollIsRootNode || !this.offset.scroll ) {
2115 this.offset.scroll = {
2116 top: this.scrollParent.scrollTop(),
2117 left: this.scrollParent.scrollLeft()
2118 };
2119 }
2120
2121 /*
2122 * - Position constraining -
2123 * Constrain the position to a mix of grid, containment.
2124 */
2125
2126 // If we are not dragging yet, we won't check for options
2127 if ( constrainPosition ) {
2128 if ( this.containment ) {
2129 if ( this.relativeContainer ){
2130 co = this.relativeContainer.offset();
2131 containment = [
2132 this.containment[ 0 ] + co.left,
2133 this.containment[ 1 ] + co.top,
2134 this.containment[ 2 ] + co.left,
2135 this.containment[ 3 ] + co.top
2136 ];
2137 } else {
2138 containment = this.containment;
2139 }
2140
2141 if (event.pageX - this.offset.click.left < containment[0]) {
2142 pageX = containment[0] + this.offset.click.left;
2143 }
2144 if (event.pageY - this.offset.click.top < containment[1]) {
2145 pageY = containment[1] + this.offset.click.top;
2146 }
2147 if (event.pageX - this.offset.click.left > containment[2]) {
2148 pageX = containment[2] + this.offset.click.left;
2149 }
2150 if (event.pageY - this.offset.click.top > containment[3]) {
2151 pageY = containment[3] + this.offset.click.top;
2152 }
2153 }
2154
2155 if (o.grid) {
2156 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
2157 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
2158 pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
2159
2160 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
2161 pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
2162 }
2163
2164 if ( o.axis === "y" ) {
2165 pageX = this.originalPageX;
2166 }
2167
2168 if ( o.axis === "x" ) {
2169 pageY = this.originalPageY;
2170 }
2171 }
2172
2173 return {
2174 top: (
2175 pageY - // The absolute mouse position
2176 this.offset.click.top - // Click offset (relative to the element)
2177 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent
2178 this.offset.parent.top + // The offsetParent's offset without borders (offset + border)
2179 ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
2180 ),
2181 left: (
2182 pageX - // The absolute mouse position
2183 this.offset.click.left - // Click offset (relative to the element)
2184 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent
2185 this.offset.parent.left + // The offsetParent's offset without borders (offset + border)
2186 ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
2187 )
2188 };
2189
2190 },
2191
2192 _clear: function() {
2193 this.helper.removeClass("ui-draggable-dragging");
2194 if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
2195 this.helper.remove();
2196 }
2197 this.helper = null;
2198 this.cancelHelperRemoval = false;
2199 if ( this.destroyOnClear ) {
2200 this.destroy();
2201 }
2202 },
2203
2204 _normalizeRightBottom: function() {
2205 if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) {
2206 this.helper.width( this.helper.width() );
2207 this.helper.css( "right", "auto" );
2208 }
2209 if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) {
2210 this.helper.height( this.helper.height() );
2211 this.helper.css( "bottom", "auto" );
2212 }
2213 },
2214
2215 // From now on bulk stuff - mainly helpers
2216
2217 _trigger: function( type, event, ui ) {
2218 ui = ui || this._uiHash();
2219 $.ui.plugin.call( this, type, [ event, ui, this ], true );
2220
2221 // Absolute position and offset (see #6884 ) have to be recalculated after plugins
2222 if ( /^(drag|start|stop)/.test( type ) ) {
2223 this.positionAbs = this._convertPositionTo( "absolute" );
2224 ui.offset = this.positionAbs;
2225 }
2226 return $.Widget.prototype._trigger.call( this, type, event, ui );
2227 },
2228
2229 plugins: {},
2230
2231 _uiHash: function() {
2232 return {
2233 helper: this.helper,
2234 position: this.position,
2235 originalPosition: this.originalPosition,
2236 offset: this.positionAbs
2237 };
2238 }
2239
2240});
2241
2242$.ui.plugin.add( "draggable", "connectToSortable", {
2243 start: function( event, ui, draggable ) {
2244 var uiSortable = $.extend( {}, ui, {
2245 item: draggable.element
2246 });
2247
2248 draggable.sortables = [];
2249 $( draggable.options.connectToSortable ).each(function() {
2250 var sortable = $( this ).sortable( "instance" );
2251
2252 if ( sortable && !sortable.options.disabled ) {
2253 draggable.sortables.push( sortable );
2254
2255 // refreshPositions is called at drag start to refresh the containerCache
2256 // which is used in drag. This ensures it's initialized and synchronized
2257 // with any changes that might have happened on the page since initialization.
2258 sortable.refreshPositions();
2259 sortable._trigger("activate", event, uiSortable);
2260 }
2261 });
2262 },
2263 stop: function( event, ui, draggable ) {
2264 var uiSortable = $.extend( {}, ui, {
2265 item: draggable.element
2266 });
2267
2268 draggable.cancelHelperRemoval = false;
2269
2270 $.each( draggable.sortables, function() {
2271 var sortable = this;
2272
2273 if ( sortable.isOver ) {
2274 sortable.isOver = 0;
2275
2276 // Allow this sortable to handle removing the helper
2277 draggable.cancelHelperRemoval = true;
2278 sortable.cancelHelperRemoval = false;
2279
2280 // Use _storedCSS To restore properties in the sortable,
2281 // as this also handles revert (#9675) since the draggable
2282 // may have modified them in unexpected ways (#8809)
2283 sortable._storedCSS = {
2284 position: sortable.placeholder.css( "position" ),
2285 top: sortable.placeholder.css( "top" ),
2286 left: sortable.placeholder.css( "left" )
2287 };
2288
2289 sortable._mouseStop(event);
2290
2291 // Once drag has ended, the sortable should return to using
2292 // its original helper, not the shared helper from draggable
2293 sortable.options.helper = sortable.options._helper;
2294 } else {
2295 // Prevent this Sortable from removing the helper.
2296 // However, don't set the draggable to remove the helper
2297 // either as another connected Sortable may yet handle the removal.
2298 sortable.cancelHelperRemoval = true;
2299
2300 sortable._trigger( "deactivate", event, uiSortable );
2301 }
2302 });
2303 },
2304 drag: function( event, ui, draggable ) {
2305 $.each( draggable.sortables, function() {
2306 var innermostIntersecting = false,
2307 sortable = this;
2308
2309 // Copy over variables that sortable's _intersectsWith uses
2310 sortable.positionAbs = draggable.positionAbs;
2311 sortable.helperProportions = draggable.helperProportions;
2312 sortable.offset.click = draggable.offset.click;
2313
2314 if ( sortable._intersectsWith( sortable.containerCache ) ) {
2315 innermostIntersecting = true;
2316
2317 $.each( draggable.sortables, function() {
2318 // Copy over variables that sortable's _intersectsWith uses
2319 this.positionAbs = draggable.positionAbs;
2320 this.helperProportions = draggable.helperProportions;
2321 this.offset.click = draggable.offset.click;
2322
2323 if ( this !== sortable &&
2324 this._intersectsWith( this.containerCache ) &&
2325 $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
2326 innermostIntersecting = false;
2327 }
2328
2329 return innermostIntersecting;
2330 });
2331 }
2332
2333 if ( innermostIntersecting ) {
2334 // If it intersects, we use a little isOver variable and set it once,
2335 // so that the move-in stuff gets fired only once.
2336 if ( !sortable.isOver ) {
2337 sortable.isOver = 1;
2338
2339 sortable.currentItem = ui.helper
2340 .appendTo( sortable.element )
2341 .data( "ui-sortable-item", true );
2342
2343 // Store helper option to later restore it
2344 sortable.options._helper = sortable.options.helper;
2345
2346 sortable.options.helper = function() {
2347 return ui.helper[ 0 ];
2348 };
2349
2350 // Fire the start events of the sortable with our passed browser event,
2351 // and our own helper (so it doesn't create a new one)
2352 event.target = sortable.currentItem[ 0 ];
2353 sortable._mouseCapture( event, true );
2354 sortable._mouseStart( event, true, true );
2355
2356 // Because the browser event is way off the new appended portlet,
2357 // modify necessary variables to reflect the changes
2358 sortable.offset.click.top = draggable.offset.click.top;
2359 sortable.offset.click.left = draggable.offset.click.left;
2360 sortable.offset.parent.left -= draggable.offset.parent.left -
2361 sortable.offset.parent.left;
2362 sortable.offset.parent.top -= draggable.offset.parent.top -
2363 sortable.offset.parent.top;
2364
2365 draggable._trigger( "toSortable", event );
2366
2367 // Inform draggable that the helper is in a valid drop zone,
2368 // used solely in the revert option to handle "valid/invalid".
2369 draggable.dropped = sortable.element;
2370
2371 // Need to refreshPositions of all sortables in the case that
2372 // adding to one sortable changes the location of the other sortables (#9675)
2373 $.each( draggable.sortables, function() {
2374 this.refreshPositions();
2375 });
2376
2377 // hack so receive/update callbacks work (mostly)
2378 draggable.currentItem = draggable.element;
2379 sortable.fromOutside = draggable;
2380 }
2381
2382 if ( sortable.currentItem ) {
2383 sortable._mouseDrag( event );
2384 // Copy the sortable's position because the draggable's can potentially reflect
2385 // a relative position, while sortable is always absolute, which the dragged
2386 // element has now become. (#8809)
2387 ui.position = sortable.position;
2388 }
2389 } else {
2390 // If it doesn't intersect with the sortable, and it intersected before,
2391 // we fake the drag stop of the sortable, but make sure it doesn't remove
2392 // the helper by using cancelHelperRemoval.
2393 if ( sortable.isOver ) {
2394
2395 sortable.isOver = 0;
2396 sortable.cancelHelperRemoval = true;
2397
2398 // Calling sortable's mouseStop would trigger a revert,
2399 // so revert must be temporarily false until after mouseStop is called.
2400 sortable.options._revert = sortable.options.revert;
2401 sortable.options.revert = false;
2402
2403 sortable._trigger( "out", event, sortable._uiHash( sortable ) );
2404 sortable._mouseStop( event, true );
2405
2406 // restore sortable behaviors that were modfied
2407 // when the draggable entered the sortable area (#9481)
2408 sortable.options.revert = sortable.options._revert;
2409 sortable.options.helper = sortable.options._helper;
2410
2411 if ( sortable.placeholder ) {
2412 sortable.placeholder.remove();
2413 }
2414
2415 // Recalculate the draggable's offset considering the sortable
2416 // may have modified them in unexpected ways (#8809)
2417 draggable._refreshOffsets( event );
2418 ui.position = draggable._generatePosition( event, true );
2419
2420 draggable._trigger( "fromSortable", event );
2421
2422 // Inform draggable that the helper is no longer in a valid drop zone
2423 draggable.dropped = false;
2424
2425 // Need to refreshPositions of all sortables just in case removing
2426 // from one sortable changes the location of other sortables (#9675)
2427 $.each( draggable.sortables, function() {
2428 this.refreshPositions();
2429 });
2430 }
2431 }
2432 });
2433 }
2434});
2435
2436$.ui.plugin.add("draggable", "cursor", {
2437 start: function( event, ui, instance ) {
2438 var t = $( "body" ),
2439 o = instance.options;
2440
2441 if (t.css("cursor")) {
2442 o._cursor = t.css("cursor");
2443 }
2444 t.css("cursor", o.cursor);
2445 },
2446 stop: function( event, ui, instance ) {
2447 var o = instance.options;
2448 if (o._cursor) {
2449 $("body").css("cursor", o._cursor);
2450 }
2451 }
2452});
2453
2454$.ui.plugin.add("draggable", "opacity", {
2455 start: function( event, ui, instance ) {
2456 var t = $( ui.helper ),
2457 o = instance.options;
2458 if (t.css("opacity")) {
2459 o._opacity = t.css("opacity");
2460 }
2461 t.css("opacity", o.opacity);
2462 },
2463 stop: function( event, ui, instance ) {
2464 var o = instance.options;
2465 if (o._opacity) {
2466 $(ui.helper).css("opacity", o._opacity);
2467 }
2468 }
2469});
2470
2471$.ui.plugin.add("draggable", "scroll", {
2472 start: function( event, ui, i ) {
2473 if ( !i.scrollParentNotHidden ) {
2474 i.scrollParentNotHidden = i.helper.scrollParent( false );
2475 }
2476
2477 if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
2478 i.overflowOffset = i.scrollParentNotHidden.offset();
2479 }
2480 },
2481 drag: function( event, ui, i ) {
2482
2483 var o = i.options,
2484 scrolled = false,
2485 scrollParent = i.scrollParentNotHidden[ 0 ],
2486 document = i.document[ 0 ];
2487
2488 if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
2489 if ( !o.axis || o.axis !== "x" ) {
2490 if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) {
2491 scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
2492 } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
2493 scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
2494 }
2495 }
2496
2497 if ( !o.axis || o.axis !== "y" ) {
2498 if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) {
2499 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
2500 } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
2501 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
2502 }
2503 }
2504
2505 } else {
2506
2507 if (!o.axis || o.axis !== "x") {
2508 if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
2509 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
2510 } else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
2511 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
2512 }
2513 }
2514
2515 if (!o.axis || o.axis !== "y") {
2516 if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
2517 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
2518 } else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
2519 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
2520 }
2521 }
2522
2523 }
2524
2525 if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
2526 $.ui.ddmanager.prepareOffsets(i, event);
2527 }
2528
2529 }
2530});
2531
2532$.ui.plugin.add("draggable", "snap", {
2533 start: function( event, ui, i ) {
2534
2535 var o = i.options;
2536
2537 i.snapElements = [];
2538
2539 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
2540 var $t = $(this),
2541 $o = $t.offset();
2542 if (this !== i.element[0]) {
2543 i.snapElements.push({
2544 item: this,
2545 width: $t.outerWidth(), height: $t.outerHeight(),
2546 top: $o.top, left: $o.left
2547 });
2548 }
2549 });
2550
2551 },
2552 drag: function( event, ui, inst ) {
2553
2554 var ts, bs, ls, rs, l, r, t, b, i, first,
2555 o = inst.options,
2556 d = o.snapTolerance,
2557 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
2558 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
2559
2560 for (i = inst.snapElements.length - 1; i >= 0; i--){
2561
2562 l = inst.snapElements[i].left - inst.margins.left;
2563 r = l + inst.snapElements[i].width;
2564 t = inst.snapElements[i].top - inst.margins.top;
2565 b = t + inst.snapElements[i].height;
2566
2567 if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
2568 if (inst.snapElements[i].snapping) {
2569 (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2570 }
2571 inst.snapElements[i].snapping = false;
2572 continue;
2573 }
2574
2575 if (o.snapMode !== "inner") {
2576 ts = Math.abs(t - y2) <= d;
2577 bs = Math.abs(b - y1) <= d;
2578 ls = Math.abs(l - x2) <= d;
2579 rs = Math.abs(r - x1) <= d;
2580 if (ts) {
2581 ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top;
2582 }
2583 if (bs) {
2584 ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top;
2585 }
2586 if (ls) {
2587 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left;
2588 }
2589 if (rs) {
2590 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left;
2591 }
2592 }
2593
2594 first = (ts || bs || ls || rs);
2595
2596 if (o.snapMode !== "outer") {
2597 ts = Math.abs(t - y1) <= d;
2598 bs = Math.abs(b - y2) <= d;
2599 ls = Math.abs(l - x1) <= d;
2600 rs = Math.abs(r - x2) <= d;
2601 if (ts) {
2602 ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top;
2603 }
2604 if (bs) {
2605 ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top;
2606 }
2607 if (ls) {
2608 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left;
2609 }
2610 if (rs) {
2611 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left;
2612 }
2613 }
2614
2615 if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
2616 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2617 }
2618 inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
2619
2620 }
2621
2622 }
2623});
2624
2625$.ui.plugin.add("draggable", "stack", {
2626 start: function( event, ui, instance ) {
2627 var min,
2628 o = instance.options,
2629 group = $.makeArray($(o.stack)).sort(function(a, b) {
2630 return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0);
2631 });
2632
2633 if (!group.length) { return; }
2634
2635 min = parseInt($(group[0]).css("zIndex"), 10) || 0;
2636 $(group).each(function(i) {
2637 $(this).css("zIndex", min + i);
2638 });
2639 this.css("zIndex", (min + group.length));
2640 }
2641});
2642
2643$.ui.plugin.add("draggable", "zIndex", {
2644 start: function( event, ui, instance ) {
2645 var t = $( ui.helper ),
2646 o = instance.options;
2647
2648 if (t.css("zIndex")) {
2649 o._zIndex = t.css("zIndex");
2650 }
2651 t.css("zIndex", o.zIndex);
2652 },
2653 stop: function( event, ui, instance ) {
2654 var o = instance.options;
2655
2656 if (o._zIndex) {
2657 $(ui.helper).css("zIndex", o._zIndex);
2658 }
2659 }
2660});
2661
2662var draggable = $.ui.draggable;
2663
2664
2665/*!
2666 * jQuery UI Droppable 1.11.3
2667 * http://jqueryui.com
2668 *
2669 * Copyright jQuery Foundation and other contributors
2670 * Released under the MIT license.
2671 * http://jquery.org/license
2672 *
2673 * http://api.jqueryui.com/droppable/
2674 */
2675
2676
2677$.widget( "ui.droppable", {
2678 version: "1.11.3",
2679 widgetEventPrefix: "drop",
2680 options: {
2681 accept: "*",
2682 activeClass: false,
2683 addClasses: true,
2684 greedy: false,
2685 hoverClass: false,
2686 scope: "default",
2687 tolerance: "intersect",
2688
2689 // callbacks
2690 activate: null,
2691 deactivate: null,
2692 drop: null,
2693 out: null,
2694 over: null
2695 },
2696 _create: function() {
2697
2698 var proportions,
2699 o = this.options,
2700 accept = o.accept;
2701
2702 this.isover = false;
2703 this.isout = true;
2704
2705 this.accept = $.isFunction( accept ) ? accept : function( d ) {
2706 return d.is( accept );
2707 };
2708
2709 this.proportions = function( /* valueToWrite */ ) {
2710 if ( arguments.length ) {
2711 // Store the droppable's proportions
2712 proportions = arguments[ 0 ];
2713 } else {
2714 // Retrieve or derive the droppable's proportions
2715 return proportions ?
2716 proportions :
2717 proportions = {
2718 width: this.element[ 0 ].offsetWidth,
2719 height: this.element[ 0 ].offsetHeight
2720 };
2721 }
2722 };
2723
2724 this._addToManager( o.scope );
2725
2726 o.addClasses && this.element.addClass( "ui-droppable" );
2727
2728 },
2729
2730 _addToManager: function( scope ) {
2731 // Add the reference and positions to the manager
2732 $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
2733 $.ui.ddmanager.droppables[ scope ].push( this );
2734 },
2735
2736 _splice: function( drop ) {
2737 var i = 0;
2738 for ( ; i < drop.length; i++ ) {
2739 if ( drop[ i ] === this ) {
2740 drop.splice( i, 1 );
2741 }
2742 }
2743 },
2744
2745 _destroy: function() {
2746 var drop = $.ui.ddmanager.droppables[ this.options.scope ];
2747
2748 this._splice( drop );
2749
2750 this.element.removeClass( "ui-droppable ui-droppable-disabled" );
2751 },
2752
2753 _setOption: function( key, value ) {
2754
2755 if ( key === "accept" ) {
2756 this.accept = $.isFunction( value ) ? value : function( d ) {
2757 return d.is( value );
2758 };
2759 } else if ( key === "scope" ) {
2760 var drop = $.ui.ddmanager.droppables[ this.options.scope ];
2761
2762 this._splice( drop );
2763 this._addToManager( value );
2764 }
2765
2766 this._super( key, value );
2767 },
2768
2769 _activate: function( event ) {
2770 var draggable = $.ui.ddmanager.current;
2771 if ( this.options.activeClass ) {
2772 this.element.addClass( this.options.activeClass );
2773 }
2774 if ( draggable ){
2775 this._trigger( "activate", event, this.ui( draggable ) );
2776 }
2777 },
2778
2779 _deactivate: function( event ) {
2780 var draggable = $.ui.ddmanager.current;
2781 if ( this.options.activeClass ) {
2782 this.element.removeClass( this.options.activeClass );
2783 }
2784 if ( draggable ){
2785 this._trigger( "deactivate", event, this.ui( draggable ) );
2786 }
2787 },
2788
2789 _over: function( event ) {
2790
2791 var draggable = $.ui.ddmanager.current;
2792
2793 // Bail if draggable and droppable are same element
2794 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2795 return;
2796 }
2797
2798 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2799 if ( this.options.hoverClass ) {
2800 this.element.addClass( this.options.hoverClass );
2801 }
2802 this._trigger( "over", event, this.ui( draggable ) );
2803 }
2804
2805 },
2806
2807 _out: function( event ) {
2808
2809 var draggable = $.ui.ddmanager.current;
2810
2811 // Bail if draggable and droppable are same element
2812 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2813 return;
2814 }
2815
2816 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2817 if ( this.options.hoverClass ) {
2818 this.element.removeClass( this.options.hoverClass );
2819 }
2820 this._trigger( "out", event, this.ui( draggable ) );
2821 }
2822
2823 },
2824
2825 _drop: function( event, custom ) {
2826
2827 var draggable = custom || $.ui.ddmanager.current,
2828 childrenIntersection = false;
2829
2830 // Bail if draggable and droppable are same element
2831 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2832 return false;
2833 }
2834
2835 this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() {
2836 var inst = $( this ).droppable( "instance" );
2837 if (
2838 inst.options.greedy &&
2839 !inst.options.disabled &&
2840 inst.options.scope === draggable.options.scope &&
2841 inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) &&
2842 $.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event )
2843 ) { childrenIntersection = true; return false; }
2844 });
2845 if ( childrenIntersection ) {
2846 return false;
2847 }
2848
2849 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2850 if ( this.options.activeClass ) {
2851 this.element.removeClass( this.options.activeClass );
2852 }
2853 if ( this.options.hoverClass ) {
2854 this.element.removeClass( this.options.hoverClass );
2855 }
2856 this._trigger( "drop", event, this.ui( draggable ) );
2857 return this.element;
2858 }
2859
2860 return false;
2861
2862 },
2863
2864 ui: function( c ) {
2865 return {
2866 draggable: ( c.currentItem || c.element ),
2867 helper: c.helper,
2868 position: c.position,
2869 offset: c.positionAbs
2870 };
2871 }
2872
2873});
2874
2875$.ui.intersect = (function() {
2876 function isOverAxis( x, reference, size ) {
2877 return ( x >= reference ) && ( x < ( reference + size ) );
2878 }
2879
2880 return function( draggable, droppable, toleranceMode, event ) {
2881
2882 if ( !droppable.offset ) {
2883 return false;
2884 }
2885
2886 var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left,
2887 y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top,
2888 x2 = x1 + draggable.helperProportions.width,
2889 y2 = y1 + draggable.helperProportions.height,
2890 l = droppable.offset.left,
2891 t = droppable.offset.top,
2892 r = l + droppable.proportions().width,
2893 b = t + droppable.proportions().height;
2894
2895 switch ( toleranceMode ) {
2896 case "fit":
2897 return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
2898 case "intersect":
2899 return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
2900 x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
2901 t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
2902 y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
2903 case "pointer":
2904 return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width );
2905 case "touch":
2906 return (
2907 ( y1 >= t && y1 <= b ) || // Top edge touching
2908 ( y2 >= t && y2 <= b ) || // Bottom edge touching
2909 ( y1 < t && y2 > b ) // Surrounded vertically
2910 ) && (
2911 ( x1 >= l && x1 <= r ) || // Left edge touching
2912 ( x2 >= l && x2 <= r ) || // Right edge touching
2913 ( x1 < l && x2 > r ) // Surrounded horizontally
2914 );
2915 default:
2916 return false;
2917 }
2918 };
2919})();
2920
2921/*
2922 This manager tracks offsets of draggables and droppables
2923*/
2924$.ui.ddmanager = {
2925 current: null,
2926 droppables: { "default": [] },
2927 prepareOffsets: function( t, event ) {
2928
2929 var i, j,
2930 m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
2931 type = event ? event.type : null, // workaround for #2317
2932 list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
2933
2934 droppablesLoop: for ( i = 0; i < m.length; i++ ) {
2935
2936 // No disabled and non-accepted
2937 if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) {
2938 continue;
2939 }
2940
2941 // Filter out elements in the current dragged item
2942 for ( j = 0; j < list.length; j++ ) {
2943 if ( list[ j ] === m[ i ].element[ 0 ] ) {
2944 m[ i ].proportions().height = 0;
2945 continue droppablesLoop;
2946 }
2947 }
2948
2949 m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
2950 if ( !m[ i ].visible ) {
2951 continue;
2952 }
2953
2954 // Activate the droppable if used directly from draggables
2955 if ( type === "mousedown" ) {
2956 m[ i ]._activate.call( m[ i ], event );
2957 }
2958
2959 m[ i ].offset = m[ i ].element.offset();
2960 m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
2961
2962 }
2963
2964 },
2965 drop: function( draggable, event ) {
2966
2967 var dropped = false;
2968 // Create a copy of the droppables in case the list changes during the drop (#9116)
2969 $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
2970
2971 if ( !this.options ) {
2972 return;
2973 }
2974 if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
2975 dropped = this._drop.call( this, event ) || dropped;
2976 }
2977
2978 if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2979 this.isout = true;
2980 this.isover = false;
2981 this._deactivate.call( this, event );
2982 }
2983
2984 });
2985 return dropped;
2986
2987 },
2988 dragStart: function( draggable, event ) {
2989 // Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2990 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2991 if ( !draggable.options.refreshPositions ) {
2992 $.ui.ddmanager.prepareOffsets( draggable, event );
2993 }
2994 });
2995 },
2996 drag: function( draggable, event ) {
2997
2998 // If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2999 if ( draggable.options.refreshPositions ) {
3000 $.ui.ddmanager.prepareOffsets( draggable, event );
3001 }
3002
3003 // Run through all droppables and check their positions based on specific tolerance options
3004 $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
3005
3006 if ( this.options.disabled || this.greedyChild || !this.visible ) {
3007 return;
3008 }
3009
3010 var parentInstance, scope, parent,
3011 intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
3012 c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null );
3013 if ( !c ) {
3014 return;
3015 }
3016
3017 if ( this.options.greedy ) {
3018 // find droppable parents with same scope
3019 scope = this.options.scope;
3020 parent = this.element.parents( ":data(ui-droppable)" ).filter(function() {
3021 return $( this ).droppable( "instance" ).options.scope === scope;
3022 });
3023
3024 if ( parent.length ) {
3025 parentInstance = $( parent[ 0 ] ).droppable( "instance" );
3026 parentInstance.greedyChild = ( c === "isover" );
3027 }
3028 }
3029
3030 // we just moved into a greedy child
3031 if ( parentInstance && c === "isover" ) {
3032 parentInstance.isover = false;
3033 parentInstance.isout = true;
3034 parentInstance._out.call( parentInstance, event );
3035 }
3036
3037 this[ c ] = true;
3038 this[c === "isout" ? "isover" : "isout"] = false;
3039 this[c === "isover" ? "_over" : "_out"].call( this, event );
3040
3041 // we just moved out of a greedy child
3042 if ( parentInstance && c === "isout" ) {
3043 parentInstance.isout = false;
3044 parentInstance.isover = true;
3045 parentInstance._over.call( parentInstance, event );
3046 }
3047 });
3048
3049 },
3050 dragStop: function( draggable, event ) {
3051 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
3052 // Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
3053 if ( !draggable.options.refreshPositions ) {
3054 $.ui.ddmanager.prepareOffsets( draggable, event );
3055 }
3056 }
3057};
3058
3059var droppable = $.ui.droppable;
3060
3061
3062/*!
3063 * jQuery UI Resizable 1.11.3
3064 * http://jqueryui.com
3065 *
3066 * Copyright jQuery Foundation and other contributors
3067 * Released under the MIT license.
3068 * http://jquery.org/license
3069 *
3070 * http://api.jqueryui.com/resizable/
3071 */
3072
3073
3074$.widget("ui.resizable", $.ui.mouse, {
3075 version: "1.11.3",
3076 widgetEventPrefix: "resize",
3077 options: {
3078 alsoResize: false,
3079 animate: false,
3080 animateDuration: "slow",
3081 animateEasing: "swing",
3082 aspectRatio: false,
3083 autoHide: false,
3084 containment: false,
3085 ghost: false,
3086 grid: false,
3087 handles: "e,s,se",
3088 helper: false,
3089 maxHeight: null,
3090 maxWidth: null,
3091 minHeight: 10,
3092 minWidth: 10,
3093 // See #7960
3094 zIndex: 90,
3095
3096 // callbacks
3097 resize: null,
3098 start: null,
3099 stop: null
3100 },
3101
3102 _num: function( value ) {
3103 return parseInt( value, 10 ) || 0;
3104 },
3105
3106 _isNumber: function( value ) {
3107 return !isNaN( parseInt( value, 10 ) );
3108 },
3109
3110 _hasScroll: function( el, a ) {
3111
3112 if ( $( el ).css( "overflow" ) === "hidden") {
3113 return false;
3114 }
3115
3116 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
3117 has = false;
3118
3119 if ( el[ scroll ] > 0 ) {
3120 return true;
3121 }
3122
3123 // TODO: determine which cases actually cause this to happen
3124 // if the element doesn't have the scroll set, see if it's possible to
3125 // set the scroll
3126 el[ scroll ] = 1;
3127 has = ( el[ scroll ] > 0 );
3128 el[ scroll ] = 0;
3129 return has;
3130 },
3131
3132 _create: function() {
3133
3134 var n, i, handle, axis, hname,
3135 that = this,
3136 o = this.options;
3137 this.element.addClass("ui-resizable");
3138
3139 $.extend(this, {
3140 _aspectRatio: !!(o.aspectRatio),
3141 aspectRatio: o.aspectRatio,
3142 originalElement: this.element,
3143 _proportionallyResizeElements: [],
3144 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
3145 });
3146
3147 // Wrap the element if it cannot hold child nodes
3148 if (this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)) {
3149
3150 this.element.wrap(
3151 $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
3152 position: this.element.css("position"),
3153 width: this.element.outerWidth(),
3154 height: this.element.outerHeight(),
3155 top: this.element.css("top"),
3156 left: this.element.css("left")
3157 })
3158 );
3159
3160 this.element = this.element.parent().data(
3161 "ui-resizable", this.element.resizable( "instance" )
3162 );
3163
3164 this.elementIsWrapper = true;
3165
3166 this.element.css({
3167 marginLeft: this.originalElement.css("marginLeft"),
3168 marginTop: this.originalElement.css("marginTop"),
3169 marginRight: this.originalElement.css("marginRight"),
3170 marginBottom: this.originalElement.css("marginBottom")
3171 });
3172 this.originalElement.css({
3173 marginLeft: 0,
3174 marginTop: 0,
3175 marginRight: 0,
3176 marginBottom: 0
3177 });
3178 // support: Safari
3179 // Prevent Safari textarea resize
3180 this.originalResizeStyle = this.originalElement.css("resize");
3181 this.originalElement.css("resize", "none");
3182
3183 this._proportionallyResizeElements.push( this.originalElement.css({
3184 position: "static",
3185 zoom: 1,
3186 display: "block"
3187 }) );
3188
3189 // support: IE9
3190 // avoid IE jump (hard set the margin)
3191 this.originalElement.css({ margin: this.originalElement.css("margin") });
3192
3193 this._proportionallyResize();
3194 }
3195
3196 this.handles = o.handles ||
3197 ( !$(".ui-resizable-handle", this.element).length ?
3198 "e,s,se" : {
3199 n: ".ui-resizable-n",
3200 e: ".ui-resizable-e",
3201 s: ".ui-resizable-s",
3202 w: ".ui-resizable-w",
3203 se: ".ui-resizable-se",
3204 sw: ".ui-resizable-sw",
3205 ne: ".ui-resizable-ne",
3206 nw: ".ui-resizable-nw"
3207 } );
3208
3209 if (this.handles.constructor === String) {
3210
3211 if ( this.handles === "all") {
3212 this.handles = "n,e,s,w,se,sw,ne,nw";
3213 }
3214
3215 n = this.handles.split(",");
3216 this.handles = {};
3217
3218 for (i = 0; i < n.length; i++) {
3219
3220 handle = $.trim(n[i]);
3221 hname = "ui-resizable-" + handle;
3222 axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
3223
3224 axis.css({ zIndex: o.zIndex });
3225
3226 // TODO : What's going on here?
3227 if ("se" === handle) {
3228 axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
3229 }
3230
3231 this.handles[handle] = ".ui-resizable-" + handle;
3232 this.element.append(axis);
3233 }
3234
3235 }
3236
3237 this._renderAxis = function(target) {
3238
3239 var i, axis, padPos, padWrapper;
3240
3241 target = target || this.element;
3242
3243 for (i in this.handles) {
3244
3245 if (this.handles[i].constructor === String) {
3246 this.handles[i] = this.element.children( this.handles[ i ] ).first().show();
3247 }
3248
3249 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)) {
3250
3251 axis = $(this.handles[i], this.element);
3252
3253 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
3254
3255 padPos = [ "padding",
3256 /ne|nw|n/.test(i) ? "Top" :
3257 /se|sw|s/.test(i) ? "Bottom" :
3258 /^e$/.test(i) ? "Right" : "Left" ].join("");
3259
3260 target.css(padPos, padWrapper);
3261
3262 this._proportionallyResize();
3263
3264 }
3265
3266 // TODO: What's that good for? There's not anything to be executed left
3267 if (!$(this.handles[i]).length) {
3268 continue;
3269 }
3270 }
3271 };
3272
3273 // TODO: make renderAxis a prototype function
3274 this._renderAxis(this.element);
3275
3276 this._handles = $(".ui-resizable-handle", this.element)
3277 .disableSelection();
3278
3279 this._handles.mouseover(function() {
3280 if (!that.resizing) {
3281 if (this.className) {
3282 axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
3283 }
3284 that.axis = axis && axis[1] ? axis[1] : "se";
3285 }
3286 });
3287
3288 if (o.autoHide) {
3289 this._handles.hide();
3290 $(this.element)
3291 .addClass("ui-resizable-autohide")
3292 .mouseenter(function() {
3293 if (o.disabled) {
3294 return;
3295 }
3296 $(this).removeClass("ui-resizable-autohide");
3297 that._handles.show();
3298 })
3299 .mouseleave(function() {
3300 if (o.disabled) {
3301 return;
3302 }
3303 if (!that.resizing) {
3304 $(this).addClass("ui-resizable-autohide");
3305 that._handles.hide();
3306 }
3307 });
3308 }
3309
3310 this._mouseInit();
3311
3312 },
3313
3314 _destroy: function() {
3315
3316 this._mouseDestroy();
3317
3318 var wrapper,
3319 _destroy = function(exp) {
3320 $(exp)
3321 .removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
3322 .removeData("resizable")
3323 .removeData("ui-resizable")
3324 .unbind(".resizable")
3325 .find(".ui-resizable-handle")
3326 .remove();
3327 };
3328
3329 // TODO: Unwrap at same DOM position
3330 if (this.elementIsWrapper) {
3331 _destroy(this.element);
3332 wrapper = this.element;
3333 this.originalElement.css({
3334 position: wrapper.css("position"),
3335 width: wrapper.outerWidth(),
3336 height: wrapper.outerHeight(),
3337 top: wrapper.css("top"),
3338 left: wrapper.css("left")
3339 }).insertAfter( wrapper );
3340 wrapper.remove();
3341 }
3342
3343 this.originalElement.css("resize", this.originalResizeStyle);
3344 _destroy(this.originalElement);
3345
3346 return this;
3347 },
3348
3349 _mouseCapture: function(event) {
3350 var i, handle,
3351 capture = false;
3352
3353 for (i in this.handles) {
3354 handle = $(this.handles[i])[0];
3355 if (handle === event.target || $.contains(handle, event.target)) {
3356 capture = true;
3357 }
3358 }
3359
3360 return !this.options.disabled && capture;
3361 },
3362
3363 _mouseStart: function(event) {
3364
3365 var curleft, curtop, cursor,
3366 o = this.options,
3367 el = this.element;
3368
3369 this.resizing = true;
3370
3371 this._renderProxy();
3372
3373 curleft = this._num(this.helper.css("left"));
3374 curtop = this._num(this.helper.css("top"));
3375
3376 if (o.containment) {
3377 curleft += $(o.containment).scrollLeft() || 0;
3378 curtop += $(o.containment).scrollTop() || 0;
3379 }
3380
3381 this.offset = this.helper.offset();
3382 this.position = { left: curleft, top: curtop };
3383
3384 this.size = this._helper ? {
3385 width: this.helper.width(),
3386 height: this.helper.height()
3387 } : {
3388 width: el.width(),
3389 height: el.height()
3390 };
3391
3392 this.originalSize = this._helper ? {
3393 width: el.outerWidth(),
3394 height: el.outerHeight()
3395 } : {
3396 width: el.width(),
3397 height: el.height()
3398 };
3399
3400 this.sizeDiff = {
3401 width: el.outerWidth() - el.width(),
3402 height: el.outerHeight() - el.height()
3403 };
3404
3405 this.originalPosition = { left: curleft, top: curtop };
3406 this.originalMousePosition = { left: event.pageX, top: event.pageY };
3407
3408 this.aspectRatio = (typeof o.aspectRatio === "number") ?
3409 o.aspectRatio :
3410 ((this.originalSize.width / this.originalSize.height) || 1);
3411
3412 cursor = $(".ui-resizable-" + this.axis).css("cursor");
3413 $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
3414
3415 el.addClass("ui-resizable-resizing");
3416 this._propagate("start", event);
3417 return true;
3418 },
3419
3420 _mouseDrag: function(event) {
3421
3422 var data, props,
3423 smp = this.originalMousePosition,
3424 a = this.axis,
3425 dx = (event.pageX - smp.left) || 0,
3426 dy = (event.pageY - smp.top) || 0,
3427 trigger = this._change[a];
3428
3429 this._updatePrevProperties();
3430
3431 if (!trigger) {
3432 return false;
3433 }
3434
3435 data = trigger.apply(this, [ event, dx, dy ]);
3436
3437 this._updateVirtualBoundaries(event.shiftKey);
3438 if (this._aspectRatio || event.shiftKey) {
3439 data = this._updateRatio(data, event);
3440 }
3441
3442 data = this._respectSize(data, event);
3443
3444 this._updateCache(data);
3445
3446 this._propagate("resize", event);
3447
3448 props = this._applyChanges();
3449
3450 if ( !this._helper && this._proportionallyResizeElements.length ) {
3451 this._proportionallyResize();
3452 }
3453
3454 if ( !$.isEmptyObject( props ) ) {
3455 this._updatePrevProperties();
3456 this._trigger( "resize", event, this.ui() );
3457 this._applyChanges();
3458 }
3459
3460 return false;
3461 },
3462
3463 _mouseStop: function(event) {
3464
3465 this.resizing = false;
3466 var pr, ista, soffseth, soffsetw, s, left, top,
3467 o = this.options, that = this;
3468
3469 if (this._helper) {
3470
3471 pr = this._proportionallyResizeElements;
3472 ista = pr.length && (/textarea/i).test(pr[0].nodeName);
3473 soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height;
3474 soffsetw = ista ? 0 : that.sizeDiff.width;
3475
3476 s = {
3477 width: (that.helper.width() - soffsetw),
3478 height: (that.helper.height() - soffseth)
3479 };
3480 left = (parseInt(that.element.css("left"), 10) +
3481 (that.position.left - that.originalPosition.left)) || null;
3482 top = (parseInt(that.element.css("top"), 10) +
3483 (that.position.top - that.originalPosition.top)) || null;
3484
3485 if (!o.animate) {
3486 this.element.css($.extend(s, { top: top, left: left }));
3487 }
3488
3489 that.helper.height(that.size.height);
3490 that.helper.width(that.size.width);
3491
3492 if (this._helper && !o.animate) {
3493 this._proportionallyResize();
3494 }
3495 }
3496
3497 $("body").css("cursor", "auto");
3498
3499 this.element.removeClass("ui-resizable-resizing");
3500
3501 this._propagate("stop", event);
3502
3503 if (this._helper) {
3504 this.helper.remove();
3505 }
3506
3507 return false;
3508
3509 },
3510
3511 _updatePrevProperties: function() {
3512 this.prevPosition = {
3513 top: this.position.top,
3514 left: this.position.left
3515 };
3516 this.prevSize = {
3517 width: this.size.width,
3518 height: this.size.height
3519 };
3520 },
3521
3522 _applyChanges: function() {
3523 var props = {};
3524
3525 if ( this.position.top !== this.prevPosition.top ) {
3526 props.top = this.position.top + "px";
3527 }
3528 if ( this.position.left !== this.prevPosition.left ) {
3529 props.left = this.position.left + "px";
3530 }
3531 if ( this.size.width !== this.prevSize.width ) {
3532 props.width = this.size.width + "px";
3533 }
3534 if ( this.size.height !== this.prevSize.height ) {
3535 props.height = this.size.height + "px";
3536 }
3537
3538 this.helper.css( props );
3539
3540 return props;
3541 },
3542
3543 _updateVirtualBoundaries: function(forceAspectRatio) {
3544 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
3545 o = this.options;
3546
3547 b = {
3548 minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0,
3549 maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity,
3550 minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0,
3551 maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity
3552 };
3553
3554 if (this._aspectRatio || forceAspectRatio) {
3555 pMinWidth = b.minHeight * this.aspectRatio;
3556 pMinHeight = b.minWidth / this.aspectRatio;
3557 pMaxWidth = b.maxHeight * this.aspectRatio;
3558 pMaxHeight = b.maxWidth / this.aspectRatio;
3559
3560 if (pMinWidth > b.minWidth) {
3561 b.minWidth = pMinWidth;
3562 }
3563 if (pMinHeight > b.minHeight) {
3564 b.minHeight = pMinHeight;
3565 }
3566 if (pMaxWidth < b.maxWidth) {
3567 b.maxWidth = pMaxWidth;
3568 }
3569 if (pMaxHeight < b.maxHeight) {
3570 b.maxHeight = pMaxHeight;
3571 }
3572 }
3573 this._vBoundaries = b;
3574 },
3575
3576 _updateCache: function(data) {
3577 this.offset = this.helper.offset();
3578 if (this._isNumber(data.left)) {
3579 this.position.left = data.left;
3580 }
3581 if (this._isNumber(data.top)) {
3582 this.position.top = data.top;
3583 }
3584 if (this._isNumber(data.height)) {
3585 this.size.height = data.height;
3586 }
3587 if (this._isNumber(data.width)) {
3588 this.size.width = data.width;
3589 }
3590 },
3591
3592 _updateRatio: function( data ) {
3593
3594 var cpos = this.position,
3595 csize = this.size,
3596 a = this.axis;
3597
3598 if (this._isNumber(data.height)) {
3599 data.width = (data.height * this.aspectRatio);
3600 } else if (this._isNumber(data.width)) {
3601 data.height = (data.width / this.aspectRatio);
3602 }
3603
3604 if (a === "sw") {
3605 data.left = cpos.left + (csize.width - data.width);
3606 data.top = null;
3607 }
3608 if (a === "nw") {
3609 data.top = cpos.top + (csize.height - data.height);
3610 data.left = cpos.left + (csize.width - data.width);
3611 }
3612
3613 return data;
3614 },
3615
3616 _respectSize: function( data ) {
3617
3618 var o = this._vBoundaries,
3619 a = this.axis,
3620 ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width),
3621 ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
3622 isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width),
3623 isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
3624 dw = this.originalPosition.left + this.originalSize.width,
3625 dh = this.position.top + this.size.height,
3626 cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
3627 if (isminw) {
3628 data.width = o.minWidth;
3629 }
3630 if (isminh) {
3631 data.height = o.minHeight;
3632 }
3633 if (ismaxw) {
3634 data.width = o.maxWidth;
3635 }
3636 if (ismaxh) {
3637 data.height = o.maxHeight;
3638 }
3639
3640 if (isminw && cw) {
3641 data.left = dw - o.minWidth;
3642 }
3643 if (ismaxw && cw) {
3644 data.left = dw - o.maxWidth;
3645 }
3646 if (isminh && ch) {
3647 data.top = dh - o.minHeight;
3648 }
3649 if (ismaxh && ch) {
3650 data.top = dh - o.maxHeight;
3651 }
3652
3653 // Fixing jump error on top/left - bug #2330
3654 if (!data.width && !data.height && !data.left && data.top) {
3655 data.top = null;
3656 } else if (!data.width && !data.height && !data.top && data.left) {
3657 data.left = null;
3658 }
3659
3660 return data;
3661 },
3662
3663 _getPaddingPlusBorderDimensions: function( element ) {
3664 var i = 0,
3665 widths = [],
3666 borders = [
3667 element.css( "borderTopWidth" ),
3668 element.css( "borderRightWidth" ),
3669 element.css( "borderBottomWidth" ),
3670 element.css( "borderLeftWidth" )
3671 ],
3672 paddings = [
3673 element.css( "paddingTop" ),
3674 element.css( "paddingRight" ),
3675 element.css( "paddingBottom" ),
3676 element.css( "paddingLeft" )
3677 ];
3678
3679 for ( ; i < 4; i++ ) {
3680 widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 );
3681 widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 );
3682 }
3683
3684 return {
3685 height: widths[ 0 ] + widths[ 2 ],
3686 width: widths[ 1 ] + widths[ 3 ]
3687 };
3688 },
3689
3690 _proportionallyResize: function() {
3691
3692 if (!this._proportionallyResizeElements.length) {
3693 return;
3694 }
3695
3696 var prel,
3697 i = 0,
3698 element = this.helper || this.element;
3699
3700 for ( ; i < this._proportionallyResizeElements.length; i++) {
3701
3702 prel = this._proportionallyResizeElements[i];
3703
3704 // TODO: Seems like a bug to cache this.outerDimensions
3705 // considering that we are in a loop.
3706 if (!this.outerDimensions) {
3707 this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
3708 }
3709
3710 prel.css({
3711 height: (element.height() - this.outerDimensions.height) || 0,
3712 width: (element.width() - this.outerDimensions.width) || 0
3713 });
3714
3715 }
3716
3717 },
3718
3719 _renderProxy: function() {
3720
3721 var el = this.element, o = this.options;
3722 this.elementOffset = el.offset();
3723
3724 if (this._helper) {
3725
3726 this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
3727
3728 this.helper.addClass(this._helper).css({
3729 width: this.element.outerWidth() - 1,
3730 height: this.element.outerHeight() - 1,
3731 position: "absolute",
3732 left: this.elementOffset.left + "px",
3733 top: this.elementOffset.top + "px",
3734 zIndex: ++o.zIndex //TODO: Don't modify option
3735 });
3736
3737 this.helper
3738 .appendTo("body")
3739 .disableSelection();
3740
3741 } else {
3742 this.helper = this.element;
3743 }
3744
3745 },
3746
3747 _change: {
3748 e: function(event, dx) {
3749 return { width: this.originalSize.width + dx };
3750 },
3751 w: function(event, dx) {
3752 var cs = this.originalSize, sp = this.originalPosition;
3753 return { left: sp.left + dx, width: cs.width - dx };
3754 },
3755 n: function(event, dx, dy) {
3756 var cs = this.originalSize, sp = this.originalPosition;
3757 return { top: sp.top + dy, height: cs.height - dy };
3758 },
3759 s: function(event, dx, dy) {
3760 return { height: this.originalSize.height + dy };
3761 },
3762 se: function(event, dx, dy) {
3763 return $.extend(this._change.s.apply(this, arguments),
3764 this._change.e.apply(this, [ event, dx, dy ]));
3765 },
3766 sw: function(event, dx, dy) {
3767 return $.extend(this._change.s.apply(this, arguments),
3768 this._change.w.apply(this, [ event, dx, dy ]));
3769 },
3770 ne: function(event, dx, dy) {
3771 return $.extend(this._change.n.apply(this, arguments),
3772 this._change.e.apply(this, [ event, dx, dy ]));
3773 },
3774 nw: function(event, dx, dy) {
3775 return $.extend(this._change.n.apply(this, arguments),
3776 this._change.w.apply(this, [ event, dx, dy ]));
3777 }
3778 },
3779
3780 _propagate: function(n, event) {
3781 $.ui.plugin.call(this, n, [ event, this.ui() ]);
3782 (n !== "resize" && this._trigger(n, event, this.ui()));
3783 },
3784
3785 plugins: {},
3786
3787 ui: function() {
3788 return {
3789 originalElement: this.originalElement,
3790 element: this.element,
3791 helper: this.helper,
3792 position: this.position,
3793 size: this.size,
3794 originalSize: this.originalSize,
3795 originalPosition: this.originalPosition
3796 };
3797 }
3798
3799});
3800
3801/*
3802 * Resizable Extensions
3803 */
3804
3805$.ui.plugin.add("resizable", "animate", {
3806
3807 stop: function( event ) {
3808 var that = $(this).resizable( "instance" ),
3809 o = that.options,
3810 pr = that._proportionallyResizeElements,
3811 ista = pr.length && (/textarea/i).test(pr[0].nodeName),
3812 soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height,
3813 soffsetw = ista ? 0 : that.sizeDiff.width,
3814 style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
3815 left = (parseInt(that.element.css("left"), 10) +
3816 (that.position.left - that.originalPosition.left)) || null,
3817 top = (parseInt(that.element.css("top"), 10) +
3818 (that.position.top - that.originalPosition.top)) || null;
3819
3820 that.element.animate(
3821 $.extend(style, top && left ? { top: top, left: left } : {}), {
3822 duration: o.animateDuration,
3823 easing: o.animateEasing,
3824 step: function() {
3825
3826 var data = {
3827 width: parseInt(that.element.css("width"), 10),
3828 height: parseInt(that.element.css("height"), 10),
3829 top: parseInt(that.element.css("top"), 10),
3830 left: parseInt(that.element.css("left"), 10)
3831 };
3832
3833 if (pr && pr.length) {
3834 $(pr[0]).css({ width: data.width, height: data.height });
3835 }
3836
3837 // propagating resize, and updating values for each animation step
3838 that._updateCache(data);
3839 that._propagate("resize", event);
3840
3841 }
3842 }
3843 );
3844 }
3845
3846});
3847
3848$.ui.plugin.add( "resizable", "containment", {
3849
3850 start: function() {
3851 var element, p, co, ch, cw, width, height,
3852 that = $( this ).resizable( "instance" ),
3853 o = that.options,
3854 el = that.element,
3855 oc = o.containment,
3856 ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
3857
3858 if ( !ce ) {
3859 return;
3860 }
3861
3862 that.containerElement = $( ce );
3863
3864 if ( /document/.test( oc ) || oc === document ) {
3865 that.containerOffset = {
3866 left: 0,
3867 top: 0
3868 };
3869 that.containerPosition = {
3870 left: 0,
3871 top: 0
3872 };
3873
3874 that.parentData = {
3875 element: $( document ),
3876 left: 0,
3877 top: 0,
3878 width: $( document ).width(),
3879 height: $( document ).height() || document.body.parentNode.scrollHeight
3880 };
3881 } else {
3882 element = $( ce );
3883 p = [];
3884 $([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) {
3885 p[ i ] = that._num( element.css( "padding" + name ) );
3886 });
3887
3888 that.containerOffset = element.offset();
3889 that.containerPosition = element.position();
3890 that.containerSize = {
3891 height: ( element.innerHeight() - p[ 3 ] ),
3892 width: ( element.innerWidth() - p[ 1 ] )
3893 };
3894
3895 co = that.containerOffset;
3896 ch = that.containerSize.height;
3897 cw = that.containerSize.width;
3898 width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
3899 height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
3900
3901 that.parentData = {
3902 element: ce,
3903 left: co.left,
3904 top: co.top,
3905 width: width,
3906 height: height
3907 };
3908 }
3909 },
3910
3911 resize: function( event ) {
3912 var woset, hoset, isParent, isOffsetRelative,
3913 that = $( this ).resizable( "instance" ),
3914 o = that.options,
3915 co = that.containerOffset,
3916 cp = that.position,
3917 pRatio = that._aspectRatio || event.shiftKey,
3918 cop = {
3919 top: 0,
3920 left: 0
3921 },
3922 ce = that.containerElement,
3923 continueResize = true;
3924
3925 if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
3926 cop = co;
3927 }
3928
3929 if ( cp.left < ( that._helper ? co.left : 0 ) ) {
3930 that.size.width = that.size.width +
3931 ( that._helper ?
3932 ( that.position.left - co.left ) :
3933 ( that.position.left - cop.left ) );
3934
3935 if ( pRatio ) {
3936 that.size.height = that.size.width / that.aspectRatio;
3937 continueResize = false;
3938 }
3939 that.position.left = o.helper ? co.left : 0;
3940 }
3941
3942 if ( cp.top < ( that._helper ? co.top : 0 ) ) {
3943 that.size.height = that.size.height +
3944 ( that._helper ?
3945 ( that.position.top - co.top ) :
3946 that.position.top );
3947
3948 if ( pRatio ) {
3949 that.size.width = that.size.height * that.aspectRatio;
3950 continueResize = false;
3951 }
3952 that.position.top = that._helper ? co.top : 0;
3953 }
3954
3955 isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
3956 isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
3957
3958 if ( isParent && isOffsetRelative ) {
3959 that.offset.left = that.parentData.left + that.position.left;
3960 that.offset.top = that.parentData.top + that.position.top;
3961 } else {
3962 that.offset.left = that.element.offset().left;
3963 that.offset.top = that.element.offset().top;
3964 }
3965
3966 woset = Math.abs( that.sizeDiff.width +
3967 (that._helper ?
3968 that.offset.left - cop.left :
3969 (that.offset.left - co.left)) );
3970
3971 hoset = Math.abs( that.sizeDiff.height +
3972 (that._helper ?
3973 that.offset.top - cop.top :
3974 (that.offset.top - co.top)) );
3975
3976 if ( woset + that.size.width >= that.parentData.width ) {
3977 that.size.width = that.parentData.width - woset;
3978 if ( pRatio ) {
3979 that.size.height = that.size.width / that.aspectRatio;
3980 continueResize = false;
3981 }
3982 }
3983
3984 if ( hoset + that.size.height >= that.parentData.height ) {
3985 that.size.height = that.parentData.height - hoset;
3986 if ( pRatio ) {
3987 that.size.width = that.size.height * that.aspectRatio;
3988 continueResize = false;
3989 }
3990 }
3991
3992 if ( !continueResize ) {
3993 that.position.left = that.prevPosition.left;
3994 that.position.top = that.prevPosition.top;
3995 that.size.width = that.prevSize.width;
3996 that.size.height = that.prevSize.height;
3997 }
3998 },
3999
4000 stop: function() {
4001 var that = $( this ).resizable( "instance" ),
4002 o = that.options,
4003 co = that.containerOffset,
4004 cop = that.containerPosition,
4005 ce = that.containerElement,
4006 helper = $( that.helper ),
4007 ho = helper.offset(),
4008 w = helper.outerWidth() - that.sizeDiff.width,
4009 h = helper.outerHeight() - that.sizeDiff.height;
4010
4011 if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
4012 $( this ).css({
4013 left: ho.left - cop.left - co.left,
4014 width: w,
4015 height: h
4016 });
4017 }
4018
4019 if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
4020 $( this ).css({
4021 left: ho.left - cop.left - co.left,
4022 width: w,
4023 height: h
4024 });
4025 }
4026 }
4027});
4028
4029$.ui.plugin.add("resizable", "alsoResize", {
4030
4031 start: function() {
4032 var that = $(this).resizable( "instance" ),
4033 o = that.options,
4034 _store = function(exp) {
4035 $(exp).each(function() {
4036 var el = $(this);
4037 el.data("ui-resizable-alsoresize", {
4038 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
4039 left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
4040 });
4041 });
4042 };
4043
4044 if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) {
4045 if (o.alsoResize.length) {
4046 o.alsoResize = o.alsoResize[0];
4047 _store(o.alsoResize);
4048 } else {
4049 $.each(o.alsoResize, function(exp) {
4050 _store(exp);
4051 });
4052 }
4053 } else {
4054 _store(o.alsoResize);
4055 }
4056 },
4057
4058 resize: function(event, ui) {
4059 var that = $(this).resizable( "instance" ),
4060 o = that.options,
4061 os = that.originalSize,
4062 op = that.originalPosition,
4063 delta = {
4064 height: (that.size.height - os.height) || 0,
4065 width: (that.size.width - os.width) || 0,
4066 top: (that.position.top - op.top) || 0,
4067 left: (that.position.left - op.left) || 0
4068 },
4069
4070 _alsoResize = function(exp, c) {
4071 $(exp).each(function() {
4072 var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
4073 css = c && c.length ?
4074 c :
4075 el.parents(ui.originalElement[0]).length ?
4076 [ "width", "height" ] :
4077 [ "width", "height", "top", "left" ];
4078
4079 $.each(css, function(i, prop) {
4080 var sum = (start[prop] || 0) + (delta[prop] || 0);
4081 if (sum && sum >= 0) {
4082 style[prop] = sum || null;
4083 }
4084 });
4085
4086 el.css(style);
4087 });
4088 };
4089
4090 if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) {
4091 $.each(o.alsoResize, function(exp, c) {
4092 _alsoResize(exp, c);
4093 });
4094 } else {
4095 _alsoResize(o.alsoResize);
4096 }
4097 },
4098
4099 stop: function() {
4100 $(this).removeData("resizable-alsoresize");
4101 }
4102});
4103
4104$.ui.plugin.add("resizable", "ghost", {
4105
4106 start: function() {
4107
4108 var that = $(this).resizable( "instance" ), o = that.options, cs = that.size;
4109
4110 that.ghost = that.originalElement.clone();
4111 that.ghost
4112 .css({
4113 opacity: 0.25,
4114 display: "block",
4115 position: "relative",
4116 height: cs.height,
4117 width: cs.width,
4118 margin: 0,
4119 left: 0,
4120 top: 0
4121 })
4122 .addClass("ui-resizable-ghost")
4123 .addClass(typeof o.ghost === "string" ? o.ghost : "");
4124
4125 that.ghost.appendTo(that.helper);
4126
4127 },
4128
4129 resize: function() {
4130 var that = $(this).resizable( "instance" );
4131 if (that.ghost) {
4132 that.ghost.css({
4133 position: "relative",
4134 height: that.size.height,
4135 width: that.size.width
4136 });
4137 }
4138 },
4139
4140 stop: function() {
4141 var that = $(this).resizable( "instance" );
4142 if (that.ghost && that.helper) {
4143 that.helper.get(0).removeChild(that.ghost.get(0));
4144 }
4145 }
4146
4147});
4148
4149$.ui.plugin.add("resizable", "grid", {
4150
4151 resize: function() {
4152 var outerDimensions,
4153 that = $(this).resizable( "instance" ),
4154 o = that.options,
4155 cs = that.size,
4156 os = that.originalSize,
4157 op = that.originalPosition,
4158 a = that.axis,
4159 grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
4160 gridX = (grid[0] || 1),
4161 gridY = (grid[1] || 1),
4162 ox = Math.round((cs.width - os.width) / gridX) * gridX,
4163 oy = Math.round((cs.height - os.height) / gridY) * gridY,
4164 newWidth = os.width + ox,
4165 newHeight = os.height + oy,
4166 isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
4167 isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
4168 isMinWidth = o.minWidth && (o.minWidth > newWidth),
4169 isMinHeight = o.minHeight && (o.minHeight > newHeight);
4170
4171 o.grid = grid;
4172
4173 if (isMinWidth) {
4174 newWidth += gridX;
4175 }
4176 if (isMinHeight) {
4177 newHeight += gridY;
4178 }
4179 if (isMaxWidth) {
4180 newWidth -= gridX;
4181 }
4182 if (isMaxHeight) {
4183 newHeight -= gridY;
4184 }
4185
4186 if (/^(se|s|e)$/.test(a)) {
4187 that.size.width = newWidth;
4188 that.size.height = newHeight;
4189 } else if (/^(ne)$/.test(a)) {
4190 that.size.width = newWidth;
4191 that.size.height = newHeight;
4192 that.position.top = op.top - oy;
4193 } else if (/^(sw)$/.test(a)) {
4194 that.size.width = newWidth;
4195 that.size.height = newHeight;
4196 that.position.left = op.left - ox;
4197 } else {
4198 if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) {
4199 outerDimensions = that._getPaddingPlusBorderDimensions( this );
4200 }
4201
4202 if ( newHeight - gridY > 0 ) {
4203 that.size.height = newHeight;
4204 that.position.top = op.top - oy;
4205 } else {
4206 newHeight = gridY - outerDimensions.height;
4207 that.size.height = newHeight;
4208 that.position.top = op.top + os.height - newHeight;
4209 }
4210 if ( newWidth - gridX > 0 ) {
4211 that.size.width = newWidth;
4212 that.position.left = op.left - ox;
4213 } else {
4214 newWidth = gridX - outerDimensions.width;
4215 that.size.width = newWidth;
4216 that.position.left = op.left + os.width - newWidth;
4217 }
4218 }
4219 }
4220
4221});
4222
4223var resizable = $.ui.resizable;
4224
4225
4226/*!
4227 * jQuery UI Selectable 1.11.3
4228 * http://jqueryui.com
4229 *
4230 * Copyright jQuery Foundation and other contributors
4231 * Released under the MIT license.
4232 * http://jquery.org/license
4233 *
4234 * http://api.jqueryui.com/selectable/
4235 */
4236
4237
4238var selectable = $.widget("ui.selectable", $.ui.mouse, {
4239 version: "1.11.3",
4240 options: {
4241 appendTo: "body",
4242 autoRefresh: true,
4243 distance: 0,
4244 filter: "*",
4245 tolerance: "touch",
4246
4247 // callbacks
4248 selected: null,
4249 selecting: null,
4250 start: null,
4251 stop: null,
4252 unselected: null,
4253 unselecting: null
4254 },
4255 _create: function() {
4256 var selectees,
4257 that = this;
4258
4259 this.element.addClass("ui-selectable");
4260
4261 this.dragged = false;
4262
4263 // cache selectee children based on filter
4264 this.refresh = function() {
4265 selectees = $(that.options.filter, that.element[0]);
4266 selectees.addClass("ui-selectee");
4267 selectees.each(function() {
4268 var $this = $(this),
4269 pos = $this.offset();
4270 $.data(this, "selectable-item", {
4271 element: this,
4272 $element: $this,
4273 left: pos.left,
4274 top: pos.top,
4275 right: pos.left + $this.outerWidth(),
4276 bottom: pos.top + $this.outerHeight(),
4277 startselected: false,
4278 selected: $this.hasClass("ui-selected"),
4279 selecting: $this.hasClass("ui-selecting"),
4280 unselecting: $this.hasClass("ui-unselecting")
4281 });
4282 });
4283 };
4284 this.refresh();
4285
4286 this.selectees = selectees.addClass("ui-selectee");
4287
4288 this._mouseInit();
4289
4290 this.helper = $("<div class='ui-selectable-helper'></div>");
4291 },
4292
4293 _destroy: function() {
4294 this.selectees
4295 .removeClass("ui-selectee")
4296 .removeData("selectable-item");
4297 this.element
4298 .removeClass("ui-selectable ui-selectable-disabled");
4299 this._mouseDestroy();
4300 },
4301
4302 _mouseStart: function(event) {
4303 var that = this,
4304 options = this.options;
4305
4306 this.opos = [ event.pageX, event.pageY ];
4307
4308 if (this.options.disabled) {
4309 return;
4310 }
4311
4312 this.selectees = $(options.filter, this.element[0]);
4313
4314 this._trigger("start", event);
4315
4316 $(options.appendTo).append(this.helper);
4317 // position helper (lasso)
4318 this.helper.css({
4319 "left": event.pageX,
4320 "top": event.pageY,
4321 "width": 0,
4322 "height": 0
4323 });
4324
4325 if (options.autoRefresh) {
4326 this.refresh();
4327 }
4328
4329 this.selectees.filter(".ui-selected").each(function() {
4330 var selectee = $.data(this, "selectable-item");
4331 selectee.startselected = true;
4332 if (!event.metaKey && !event.ctrlKey) {
4333 selectee.$element.removeClass("ui-selected");
4334 selectee.selected = false;
4335 selectee.$element.addClass("ui-unselecting");
4336 selectee.unselecting = true;
4337 // selectable UNSELECTING callback
4338 that._trigger("unselecting", event, {
4339 unselecting: selectee.element
4340 });
4341 }
4342 });
4343
4344 $(event.target).parents().addBack().each(function() {
4345 var doSelect,
4346 selectee = $.data(this, "selectable-item");
4347 if (selectee) {
4348 doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
4349 selectee.$element
4350 .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
4351 .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
4352 selectee.unselecting = !doSelect;
4353 selectee.selecting = doSelect;
4354 selectee.selected = doSelect;
4355 // selectable (UN)SELECTING callback
4356 if (doSelect) {
4357 that._trigger("selecting", event, {
4358 selecting: selectee.element
4359 });
4360 } else {
4361 that._trigger("unselecting", event, {
4362 unselecting: selectee.element
4363 });
4364 }
4365 return false;
4366 }
4367 });
4368
4369 },
4370
4371 _mouseDrag: function(event) {
4372
4373 this.dragged = true;
4374
4375 if (this.options.disabled) {
4376 return;
4377 }
4378
4379 var tmp,
4380 that = this,
4381 options = this.options,
4382 x1 = this.opos[0],
4383 y1 = this.opos[1],
4384 x2 = event.pageX,
4385 y2 = event.pageY;
4386
4387 if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
4388 if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
4389 this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 });
4390
4391 this.selectees.each(function() {
4392 var selectee = $.data(this, "selectable-item"),
4393 hit = false;
4394
4395 //prevent helper from being selected if appendTo: selectable
4396 if (!selectee || selectee.element === that.element[0]) {
4397 return;
4398 }
4399
4400 if (options.tolerance === "touch") {
4401 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
4402 } else if (options.tolerance === "fit") {
4403 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
4404 }
4405
4406 if (hit) {
4407 // SELECT
4408 if (selectee.selected) {
4409 selectee.$element.removeClass("ui-selected");
4410 selectee.selected = false;
4411 }
4412 if (selectee.unselecting) {
4413 selectee.$element.removeClass("ui-unselecting");
4414 selectee.unselecting = false;
4415 }
4416 if (!selectee.selecting) {
4417 selectee.$element.addClass("ui-selecting");
4418 selectee.selecting = true;
4419 // selectable SELECTING callback
4420 that._trigger("selecting", event, {
4421 selecting: selectee.element
4422 });
4423 }
4424 } else {
4425 // UNSELECT
4426 if (selectee.selecting) {
4427 if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
4428 selectee.$element.removeClass("ui-selecting");
4429 selectee.selecting = false;
4430 selectee.$element.addClass("ui-selected");
4431 selectee.selected = true;
4432 } else {
4433 selectee.$element.removeClass("ui-selecting");
4434 selectee.selecting = false;
4435 if (selectee.startselected) {
4436 selectee.$element.addClass("ui-unselecting");
4437 selectee.unselecting = true;
4438 }
4439 // selectable UNSELECTING callback
4440 that._trigger("unselecting", event, {
4441 unselecting: selectee.element
4442 });
4443 }
4444 }
4445 if (selectee.selected) {
4446 if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
4447 selectee.$element.removeClass("ui-selected");
4448 selectee.selected = false;
4449
4450 selectee.$element.addClass("ui-unselecting");
4451 selectee.unselecting = true;
4452 // selectable UNSELECTING callback
4453 that._trigger("unselecting", event, {
4454 unselecting: selectee.element
4455 });
4456 }
4457 }
4458 }
4459 });
4460
4461 return false;
4462 },
4463
4464 _mouseStop: function(event) {
4465 var that = this;
4466
4467 this.dragged = false;
4468
4469 $(".ui-unselecting", this.element[0]).each(function() {
4470 var selectee = $.data(this, "selectable-item");
4471 selectee.$element.removeClass("ui-unselecting");
4472 selectee.unselecting = false;
4473 selectee.startselected = false;
4474 that._trigger("unselected", event, {
4475 unselected: selectee.element
4476 });
4477 });
4478 $(".ui-selecting", this.element[0]).each(function() {
4479 var selectee = $.data(this, "selectable-item");
4480 selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
4481 selectee.selecting = false;
4482 selectee.selected = true;
4483 selectee.startselected = true;
4484 that._trigger("selected", event, {
4485 selected: selectee.element
4486 });
4487 });
4488 this._trigger("stop", event);
4489
4490 this.helper.remove();
4491
4492 return false;
4493 }
4494
4495});
4496
4497
4498/*!
4499 * jQuery UI Sortable 1.11.3
4500 * http://jqueryui.com
4501 *
4502 * Copyright jQuery Foundation and other contributors
4503 * Released under the MIT license.
4504 * http://jquery.org/license
4505 *
4506 * http://api.jqueryui.com/sortable/
4507 */
4508
4509
4510var sortable = $.widget("ui.sortable", $.ui.mouse, {
4511 version: "1.11.3",
4512 widgetEventPrefix: "sort",
4513 ready: false,
4514 options: {
4515 appendTo: "parent",
4516 axis: false,
4517 connectWith: false,
4518 containment: false,
4519 cursor: "auto",
4520 cursorAt: false,
4521 dropOnEmpty: true,
4522 forcePlaceholderSize: false,
4523 forceHelperSize: false,
4524 grid: false,
4525 handle: false,
4526 helper: "original",
4527 items: "> *",
4528 opacity: false,
4529 placeholder: false,
4530 revert: false,
4531 scroll: true,
4532 scrollSensitivity: 20,
4533 scrollSpeed: 20,
4534 scope: "default",
4535 tolerance: "intersect",
4536 zIndex: 1000,
4537
4538 // callbacks
4539 activate: null,
4540 beforeStop: null,
4541 change: null,
4542 deactivate: null,
4543 out: null,
4544 over: null,
4545 receive: null,
4546 remove: null,
4547 sort: null,
4548 start: null,
4549 stop: null,
4550 update: null
4551 },
4552
4553 _isOverAxis: function( x, reference, size ) {
4554 return ( x >= reference ) && ( x < ( reference + size ) );
4555 },
4556
4557 _isFloating: function( item ) {
4558 return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
4559 },
4560
4561 _create: function() {
4562
4563 var o = this.options;
4564 this.containerCache = {};
4565 this.element.addClass("ui-sortable");
4566
4567 //Get the items
4568 this.refresh();
4569
4570 //Let's determine if the items are being displayed horizontally
4571 this.floating = this.items.length ? o.axis === "x" || this._isFloating(this.items[0].item) : false;
4572
4573 //Let's determine the parent's offset
4574 this.offset = this.element.offset();
4575
4576 //Initialize mouse events for interaction
4577 this._mouseInit();
4578
4579 this._setHandleClassName();
4580
4581 //We're ready to go
4582 this.ready = true;
4583
4584 },
4585
4586 _setOption: function( key, value ) {
4587 this._super( key, value );
4588
4589 if ( key === "handle" ) {
4590 this._setHandleClassName();
4591 }
4592 },
4593
4594 _setHandleClassName: function() {
4595 this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" );
4596 $.each( this.items, function() {
4597 ( this.instance.options.handle ?
4598 this.item.find( this.instance.options.handle ) : this.item )
4599 .addClass( "ui-sortable-handle" );
4600 });
4601 },
4602
4603 _destroy: function() {
4604 this.element
4605 .removeClass( "ui-sortable ui-sortable-disabled" )
4606 .find( ".ui-sortable-handle" )
4607 .removeClass( "ui-sortable-handle" );
4608 this._mouseDestroy();
4609
4610 for ( var i = this.items.length - 1; i >= 0; i-- ) {
4611 this.items[i].item.removeData(this.widgetName + "-item");
4612 }
4613
4614 return this;
4615 },
4616
4617 _mouseCapture: function(event, overrideHandle) {
4618 var currentItem = null,
4619 validHandle = false,
4620 that = this;
4621
4622 if (this.reverting) {
4623 return false;
4624 }
4625
4626 if(this.options.disabled || this.options.type === "static") {
4627 return false;
4628 }
4629
4630 //We have to refresh the items data once first
4631 this._refreshItems(event);
4632
4633 //Find out if the clicked node (or one of its parents) is a actual item in this.items
4634 $(event.target).parents().each(function() {
4635 if($.data(this, that.widgetName + "-item") === that) {
4636 currentItem = $(this);
4637 return false;
4638 }
4639 });
4640 if($.data(event.target, that.widgetName + "-item") === that) {
4641 currentItem = $(event.target);
4642 }
4643
4644 if(!currentItem) {
4645 return false;
4646 }
4647 if(this.options.handle && !overrideHandle) {
4648 $(this.options.handle, currentItem).find("*").addBack().each(function() {
4649 if(this === event.target) {
4650 validHandle = true;
4651 }
4652 });
4653 if(!validHandle) {
4654 return false;
4655 }
4656 }
4657
4658 this.currentItem = currentItem;
4659 this._removeCurrentsFromItems();
4660 return true;
4661
4662 },
4663
4664 _mouseStart: function(event, overrideHandle, noActivation) {
4665
4666 var i, body,
4667 o = this.options;
4668
4669 this.currentContainer = this;
4670
4671 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
4672 this.refreshPositions();
4673
4674 //Create and append the visible helper
4675 this.helper = this._createHelper(event);
4676
4677 //Cache the helper size
4678 this._cacheHelperProportions();
4679
4680 /*
4681 * - Position generation -
4682 * This block generates everything position related - it's the core of draggables.
4683 */
4684
4685 //Cache the margins of the original element
4686 this._cacheMargins();
4687
4688 //Get the next scrolling parent
4689 this.scrollParent = this.helper.scrollParent();
4690
4691 //The element's absolute position on the page minus margins
4692 this.offset = this.currentItem.offset();
4693 this.offset = {
4694 top: this.offset.top - this.margins.top,
4695 left: this.offset.left - this.margins.left
4696 };
4697
4698 $.extend(this.offset, {
4699 click: { //Where the click happened, relative to the element
4700 left: event.pageX - this.offset.left,
4701 top: event.pageY - this.offset.top
4702 },
4703 parent: this._getParentOffset(),
4704 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
4705 });
4706
4707 // Only after we got the offset, we can change the helper's position to absolute
4708 // TODO: Still need to figure out a way to make relative sorting possible
4709 this.helper.css("position", "absolute");
4710 this.cssPosition = this.helper.css("position");
4711
4712 //Generate the original position
4713 this.originalPosition = this._generatePosition(event);
4714 this.originalPageX = event.pageX;
4715 this.originalPageY = event.pageY;
4716
4717 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
4718 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
4719
4720 //Cache the former DOM position
4721 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
4722
4723 //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
4724 if(this.helper[0] !== this.currentItem[0]) {
4725 this.currentItem.hide();
4726 }
4727
4728 //Create the placeholder
4729 this._createPlaceholder();
4730
4731 //Set a containment if given in the options
4732 if(o.containment) {
4733 this._setContainment();
4734 }
4735
4736 if( o.cursor && o.cursor !== "auto" ) { // cursor option
4737 body = this.document.find( "body" );
4738
4739 // support: IE
4740 this.storedCursor = body.css( "cursor" );
4741 body.css( "cursor", o.cursor );
4742
4743 this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
4744 }
4745
4746 if(o.opacity) { // opacity option
4747 if (this.helper.css("opacity")) {
4748 this._storedOpacity = this.helper.css("opacity");
4749 }
4750 this.helper.css("opacity", o.opacity);
4751 }
4752
4753 if(o.zIndex) { // zIndex option
4754 if (this.helper.css("zIndex")) {
4755 this._storedZIndex = this.helper.css("zIndex");
4756 }
4757 this.helper.css("zIndex", o.zIndex);
4758 }
4759
4760 //Prepare scrolling
4761 if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
4762 this.overflowOffset = this.scrollParent.offset();
4763 }
4764
4765 //Call callbacks
4766 this._trigger("start", event, this._uiHash());
4767
4768 //Recache the helper size
4769 if(!this._preserveHelperProportions) {
4770 this._cacheHelperProportions();
4771 }
4772
4773
4774 //Post "activate" events to possible containers
4775 if( !noActivation ) {
4776 for ( i = this.containers.length - 1; i >= 0; i-- ) {
4777 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
4778 }
4779 }
4780
4781 //Prepare possible droppables
4782 if($.ui.ddmanager) {
4783 $.ui.ddmanager.current = this;
4784 }
4785
4786 if ($.ui.ddmanager && !o.dropBehaviour) {
4787 $.ui.ddmanager.prepareOffsets(this, event);
4788 }
4789
4790 this.dragging = true;
4791
4792 this.helper.addClass("ui-sortable-helper");
4793 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
4794 return true;
4795
4796 },
4797
4798 _mouseDrag: function(event) {
4799 var i, item, itemElement, intersection,
4800 o = this.options,
4801 scrolled = false;
4802
4803 //Compute the helpers position
4804 this.position = this._generatePosition(event);
4805 this.positionAbs = this._convertPositionTo("absolute");
4806
4807 if (!this.lastPositionAbs) {
4808 this.lastPositionAbs = this.positionAbs;
4809 }
4810
4811 //Do scrolling
4812 if(this.options.scroll) {
4813 if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
4814
4815 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
4816 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
4817 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
4818 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
4819 }
4820
4821 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
4822 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
4823 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
4824 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
4825 }
4826
4827 } else {
4828
4829 if(event.pageY - this.document.scrollTop() < o.scrollSensitivity) {
4830 scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed);
4831 } else if(this.window.height() - (event.pageY - this.document.scrollTop()) < o.scrollSensitivity) {
4832 scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed);
4833 }
4834
4835 if(event.pageX - this.document.scrollLeft() < o.scrollSensitivity) {
4836 scrolled = this.document.scrollLeft(this.document.scrollLeft() - o.scrollSpeed);
4837 } else if(this.window.width() - (event.pageX - this.document.scrollLeft()) < o.scrollSensitivity) {
4838 scrolled = this.document.scrollLeft(this.document.scrollLeft() + o.scrollSpeed);
4839 }
4840
4841 }
4842
4843 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
4844 $.ui.ddmanager.prepareOffsets(this, event);
4845 }
4846 }
4847
4848 //Regenerate the absolute position used for position checks
4849 this.positionAbs = this._convertPositionTo("absolute");
4850
4851 //Set the helper position
4852 if(!this.options.axis || this.options.axis !== "y") {
4853 this.helper[0].style.left = this.position.left+"px";
4854 }
4855 if(!this.options.axis || this.options.axis !== "x") {
4856 this.helper[0].style.top = this.position.top+"px";
4857 }
4858
4859 //Rearrange
4860 for (i = this.items.length - 1; i >= 0; i--) {
4861
4862 //Cache variables and intersection, continue if no intersection
4863 item = this.items[i];
4864 itemElement = item.item[0];
4865 intersection = this._intersectsWithPointer(item);
4866 if (!intersection) {
4867 continue;
4868 }
4869
4870 // Only put the placeholder inside the current Container, skip all
4871 // items from other containers. This works because when moving
4872 // an item from one container to another the
4873 // currentContainer is switched before the placeholder is moved.
4874 //
4875 // Without this, moving items in "sub-sortables" can cause
4876 // the placeholder to jitter between the outer and inner container.
4877 if (item.instance !== this.currentContainer) {
4878 continue;
4879 }
4880
4881 // cannot intersect with itself
4882 // no useless actions that have been done before
4883 // no action if the item moved is the parent of the item checked
4884 if (itemElement !== this.currentItem[0] &&
4885 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
4886 !$.contains(this.placeholder[0], itemElement) &&
4887 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
4888 ) {
4889
4890 this.direction = intersection === 1 ? "down" : "up";
4891
4892 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
4893 this._rearrange(event, item);
4894 } else {
4895 break;
4896 }
4897
4898 this._trigger("change", event, this._uiHash());
4899 break;
4900 }
4901 }
4902
4903 //Post events to containers
4904 this._contactContainers(event);
4905
4906 //Interconnect with droppables
4907 if($.ui.ddmanager) {
4908 $.ui.ddmanager.drag(this, event);
4909 }
4910
4911 //Call callbacks
4912 this._trigger("sort", event, this._uiHash());
4913
4914 this.lastPositionAbs = this.positionAbs;
4915 return false;
4916
4917 },
4918
4919 _mouseStop: function(event, noPropagation) {
4920
4921 if(!event) {
4922 return;
4923 }
4924
4925 //If we are using droppables, inform the manager about the drop
4926 if ($.ui.ddmanager && !this.options.dropBehaviour) {
4927 $.ui.ddmanager.drop(this, event);
4928 }
4929
4930 if(this.options.revert) {
4931 var that = this,
4932 cur = this.placeholder.offset(),
4933 axis = this.options.axis,
4934 animation = {};
4935
4936 if ( !axis || axis === "x" ) {
4937 animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollLeft);
4938 }
4939 if ( !axis || axis === "y" ) {
4940 animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollTop);
4941 }
4942 this.reverting = true;
4943 $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
4944 that._clear(event);
4945 });
4946 } else {
4947 this._clear(event, noPropagation);
4948 }
4949
4950 return false;
4951
4952 },
4953
4954 cancel: function() {
4955
4956 if(this.dragging) {
4957
4958 this._mouseUp({ target: null });
4959
4960 if(this.options.helper === "original") {
4961 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4962 } else {
4963 this.currentItem.show();
4964 }
4965
4966 //Post deactivating events to containers
4967 for (var i = this.containers.length - 1; i >= 0; i--){
4968 this.containers[i]._trigger("deactivate", null, this._uiHash(this));
4969 if(this.containers[i].containerCache.over) {
4970 this.containers[i]._trigger("out", null, this._uiHash(this));
4971 this.containers[i].containerCache.over = 0;
4972 }
4973 }
4974
4975 }
4976
4977 if (this.placeholder) {
4978 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4979 if(this.placeholder[0].parentNode) {
4980 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4981 }
4982 if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
4983 this.helper.remove();
4984 }
4985
4986 $.extend(this, {
4987 helper: null,
4988 dragging: false,
4989 reverting: false,
4990 _noFinalSort: null
4991 });
4992
4993 if(this.domPosition.prev) {
4994 $(this.domPosition.prev).after(this.currentItem);
4995 } else {
4996 $(this.domPosition.parent).prepend(this.currentItem);
4997 }
4998 }
4999
5000 return this;
5001
5002 },
5003
5004 serialize: function(o) {
5005
5006 var items = this._getItemsAsjQuery(o && o.connected),
5007 str = [];
5008 o = o || {};
5009
5010 $(items).each(function() {
5011 var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
5012 if (res) {
5013 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
5014 }
5015 });
5016
5017 if(!str.length && o.key) {
5018 str.push(o.key + "=");
5019 }
5020
5021 return str.join("&");
5022
5023 },
5024
5025 toArray: function(o) {
5026
5027 var items = this._getItemsAsjQuery(o && o.connected),
5028 ret = [];
5029
5030 o = o || {};
5031
5032 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
5033 return ret;
5034
5035 },
5036
5037 /* Be careful with the following core functions */
5038 _intersectsWith: function(item) {
5039
5040 var x1 = this.positionAbs.left,
5041 x2 = x1 + this.helperProportions.width,
5042 y1 = this.positionAbs.top,
5043 y2 = y1 + this.helperProportions.height,
5044 l = item.left,
5045 r = l + item.width,
5046 t = item.top,
5047 b = t + item.height,
5048 dyClick = this.offset.click.top,
5049 dxClick = this.offset.click.left,
5050 isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
5051 isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
5052 isOverElement = isOverElementHeight && isOverElementWidth;
5053
5054 if ( this.options.tolerance === "pointer" ||
5055 this.options.forcePointerForContainers ||
5056 (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
5057 ) {
5058 return isOverElement;
5059 } else {
5060
5061 return (l < x1 + (this.helperProportions.width / 2) && // Right Half
5062 x2 - (this.helperProportions.width / 2) < r && // Left Half
5063 t < y1 + (this.helperProportions.height / 2) && // Bottom Half
5064 y2 - (this.helperProportions.height / 2) < b ); // Top Half
5065
5066 }
5067 },
5068
5069 _intersectsWithPointer: function(item) {
5070
5071 var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
5072 isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
5073 isOverElement = isOverElementHeight && isOverElementWidth,
5074 verticalDirection = this._getDragVerticalDirection(),
5075 horizontalDirection = this._getDragHorizontalDirection();
5076
5077 if (!isOverElement) {
5078 return false;
5079 }
5080
5081 return this.floating ?
5082 ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
5083 : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
5084
5085 },
5086
5087 _intersectsWithSides: function(item) {
5088
5089 var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
5090 isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
5091 verticalDirection = this._getDragVerticalDirection(),
5092 horizontalDirection = this._getDragHorizontalDirection();
5093
5094 if (this.floating && horizontalDirection) {
5095 return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
5096 } else {
5097 return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
5098 }
5099
5100 },
5101
5102 _getDragVerticalDirection: function() {
5103 var delta = this.positionAbs.top - this.lastPositionAbs.top;
5104 return delta !== 0 && (delta > 0 ? "down" : "up");
5105 },
5106
5107 _getDragHorizontalDirection: function() {
5108 var delta = this.positionAbs.left - this.lastPositionAbs.left;
5109 return delta !== 0 && (delta > 0 ? "right" : "left");
5110 },
5111
5112 refresh: function(event) {
5113 this._refreshItems(event);
5114 this._setHandleClassName();
5115 this.refreshPositions();
5116 return this;
5117 },
5118
5119 _connectWith: function() {
5120 var options = this.options;
5121 return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
5122 },
5123
5124 _getItemsAsjQuery: function(connected) {
5125
5126 var i, j, cur, inst,
5127 items = [],
5128 queries = [],
5129 connectWith = this._connectWith();
5130
5131 if(connectWith && connected) {
5132 for (i = connectWith.length - 1; i >= 0; i--){
5133 cur = $(connectWith[i], this.document[0]);
5134 for ( j = cur.length - 1; j >= 0; j--){
5135 inst = $.data(cur[j], this.widgetFullName);
5136 if(inst && inst !== this && !inst.options.disabled) {
5137 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]);
5138 }
5139 }
5140 }
5141 }
5142
5143 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]);
5144
5145 function addItems() {
5146 items.push( this );
5147 }
5148 for (i = queries.length - 1; i >= 0; i--){
5149 queries[i][0].each( addItems );
5150 }
5151
5152 return $(items);
5153
5154 },
5155
5156 _removeCurrentsFromItems: function() {
5157
5158 var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
5159
5160 this.items = $.grep(this.items, function (item) {
5161 for (var j=0; j < list.length; j++) {
5162 if(list[j] === item.item[0]) {
5163 return false;
5164 }
5165 }
5166 return true;
5167 });
5168
5169 },
5170
5171 _refreshItems: function(event) {
5172
5173 this.items = [];
5174 this.containers = [this];
5175
5176 var i, j, cur, inst, targetData, _queries, item, queriesLength,
5177 items = this.items,
5178 queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
5179 connectWith = this._connectWith();
5180
5181 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
5182 for (i = connectWith.length - 1; i >= 0; i--){
5183 cur = $(connectWith[i], this.document[0]);
5184 for (j = cur.length - 1; j >= 0; j--){
5185 inst = $.data(cur[j], this.widgetFullName);
5186 if(inst && inst !== this && !inst.options.disabled) {
5187 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
5188 this.containers.push(inst);
5189 }
5190 }
5191 }
5192 }
5193
5194 for (i = queries.length - 1; i >= 0; i--) {
5195 targetData = queries[i][1];
5196 _queries = queries[i][0];
5197
5198 for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
5199 item = $(_queries[j]);
5200
5201 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
5202
5203 items.push({
5204 item: item,
5205 instance: targetData,
5206 width: 0, height: 0,
5207 left: 0, top: 0
5208 });
5209 }
5210 }
5211
5212 },
5213
5214 refreshPositions: function(fast) {
5215
5216 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
5217 if(this.offsetParent && this.helper) {
5218 this.offset.parent = this._getParentOffset();
5219 }
5220
5221 var i, item, t, p;
5222
5223 for (i = this.items.length - 1; i >= 0; i--){
5224 item = this.items[i];
5225
5226 //We ignore calculating positions of all connected containers when we're not over them
5227 if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
5228 continue;
5229 }
5230
5231 t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
5232
5233 if (!fast) {
5234 item.width = t.outerWidth();
5235 item.height = t.outerHeight();
5236 }
5237
5238 p = t.offset();
5239 item.left = p.left;
5240 item.top = p.top;
5241 }
5242
5243 if(this.options.custom && this.options.custom.refreshContainers) {
5244 this.options.custom.refreshContainers.call(this);
5245 } else {
5246 for (i = this.containers.length - 1; i >= 0; i--){
5247 p = this.containers[i].element.offset();
5248 this.containers[i].containerCache.left = p.left;
5249 this.containers[i].containerCache.top = p.top;
5250 this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
5251 this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
5252 }
5253 }
5254
5255 return this;
5256 },
5257
5258 _createPlaceholder: function(that) {
5259 that = that || this;
5260 var className,
5261 o = that.options;
5262
5263 if(!o.placeholder || o.placeholder.constructor === String) {
5264 className = o.placeholder;
5265 o.placeholder = {
5266 element: function() {
5267
5268 var nodeName = that.currentItem[0].nodeName.toLowerCase(),
5269 element = $( "<" + nodeName + ">", that.document[0] )
5270 .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
5271 .removeClass("ui-sortable-helper");
5272
5273 if ( nodeName === "tr" ) {
5274 that.currentItem.children().each(function() {
5275 $( "<td>&#160;</td>", that.document[0] )
5276 .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
5277 .appendTo( element );
5278 });
5279 } else if ( nodeName === "img" ) {
5280 element.attr( "src", that.currentItem.attr( "src" ) );
5281 }
5282
5283 if ( !className ) {
5284 element.css( "visibility", "hidden" );
5285 }
5286
5287 return element;
5288 },
5289 update: function(container, p) {
5290
5291 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
5292 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
5293 if(className && !o.forcePlaceholderSize) {
5294 return;
5295 }
5296
5297 //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
5298 if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
5299 if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
5300 }
5301 };
5302 }
5303
5304 //Create the placeholder
5305 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
5306
5307 //Append it after the actual current item
5308 that.currentItem.after(that.placeholder);
5309
5310 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
5311 o.placeholder.update(that, that.placeholder);
5312
5313 },
5314
5315 _contactContainers: function(event) {
5316 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis,
5317 innermostContainer = null,
5318 innermostIndex = null;
5319
5320 // get innermost container that intersects with item
5321 for (i = this.containers.length - 1; i >= 0; i--) {
5322
5323 // never consider a container that's located within the item itself
5324 if($.contains(this.currentItem[0], this.containers[i].element[0])) {
5325 continue;
5326 }
5327
5328 if(this._intersectsWith(this.containers[i].containerCache)) {
5329
5330 // if we've already found a container and it's more "inner" than this, then continue
5331 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
5332 continue;
5333 }
5334
5335 innermostContainer = this.containers[i];
5336 innermostIndex = i;
5337
5338 } else {
5339 // container doesn't intersect. trigger "out" event if necessary
5340 if(this.containers[i].containerCache.over) {
5341 this.containers[i]._trigger("out", event, this._uiHash(this));
5342 this.containers[i].containerCache.over = 0;
5343 }
5344 }
5345
5346 }
5347
5348 // if no intersecting containers found, return
5349 if(!innermostContainer) {
5350 return;
5351 }
5352
5353 // move the item into the container if it's not there already
5354 if(this.containers.length === 1) {
5355 if (!this.containers[innermostIndex].containerCache.over) {
5356 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
5357 this.containers[innermostIndex].containerCache.over = 1;
5358 }
5359 } else {
5360
5361 //When entering a new container, we will find the item with the least distance and append our item near it
5362 dist = 10000;
5363 itemWithLeastDistance = null;
5364 floating = innermostContainer.floating || this._isFloating(this.currentItem);
5365 posProperty = floating ? "left" : "top";
5366 sizeProperty = floating ? "width" : "height";
5367 axis = floating ? "clientX" : "clientY";
5368
5369 for (j = this.items.length - 1; j >= 0; j--) {
5370 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
5371 continue;
5372 }
5373 if(this.items[j].item[0] === this.currentItem[0]) {
5374 continue;
5375 }
5376
5377 cur = this.items[j].item.offset()[posProperty];
5378 nearBottom = false;
5379 if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
5380 nearBottom = true;
5381 }
5382
5383 if ( Math.abs( event[ axis ] - cur ) < dist ) {
5384 dist = Math.abs( event[ axis ] - cur );
5385 itemWithLeastDistance = this.items[ j ];
5386 this.direction = nearBottom ? "up": "down";
5387 }
5388 }
5389
5390 //Check if dropOnEmpty is enabled
5391 if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
5392 return;
5393 }
5394
5395 if(this.currentContainer === this.containers[innermostIndex]) {
5396 if ( !this.currentContainer.containerCache.over ) {
5397 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
5398 this.currentContainer.containerCache.over = 1;
5399 }
5400 return;
5401 }
5402
5403 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
5404 this._trigger("change", event, this._uiHash());
5405 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
5406 this.currentContainer = this.containers[innermostIndex];
5407
5408 //Update the placeholder
5409 this.options.placeholder.update(this.currentContainer, this.placeholder);
5410
5411 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
5412 this.containers[innermostIndex].containerCache.over = 1;
5413 }
5414
5415
5416 },
5417
5418 _createHelper: function(event) {
5419
5420 var o = this.options,
5421 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
5422
5423 //Add the helper to the DOM if that didn't happen already
5424 if(!helper.parents("body").length) {
5425 $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
5426 }
5427
5428 if(helper[0] === this.currentItem[0]) {
5429 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") };
5430 }
5431
5432 if(!helper[0].style.width || o.forceHelperSize) {
5433 helper.width(this.currentItem.width());
5434 }
5435 if(!helper[0].style.height || o.forceHelperSize) {
5436 helper.height(this.currentItem.height());
5437 }
5438
5439 return helper;
5440
5441 },
5442
5443 _adjustOffsetFromHelper: function(obj) {
5444 if (typeof obj === "string") {
5445 obj = obj.split(" ");
5446 }
5447 if ($.isArray(obj)) {
5448 obj = {left: +obj[0], top: +obj[1] || 0};
5449 }
5450 if ("left" in obj) {
5451 this.offset.click.left = obj.left + this.margins.left;
5452 }
5453 if ("right" in obj) {
5454 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
5455 }
5456 if ("top" in obj) {
5457 this.offset.click.top = obj.top + this.margins.top;
5458 }
5459 if ("bottom" in obj) {
5460 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
5461 }
5462 },
5463
5464 _getParentOffset: function() {
5465
5466
5467 //Get the offsetParent and cache its position
5468 this.offsetParent = this.helper.offsetParent();
5469 var po = this.offsetParent.offset();
5470
5471 // This is a special case where we need to modify a offset calculated on start, since the following happened:
5472 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
5473 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
5474 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
5475 if(this.cssPosition === "absolute" && this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) {
5476 po.left += this.scrollParent.scrollLeft();
5477 po.top += this.scrollParent.scrollTop();
5478 }
5479
5480 // This needs to be actually done for all browsers, since pageX/pageY includes this information
5481 // with an ugly IE fix
5482 if( this.offsetParent[0] === this.document[0].body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
5483 po = { top: 0, left: 0 };
5484 }
5485
5486 return {
5487 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
5488 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
5489 };
5490
5491 },
5492
5493 _getRelativeOffset: function() {
5494
5495 if(this.cssPosition === "relative") {
5496 var p = this.currentItem.position();
5497 return {
5498 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
5499 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
5500 };
5501 } else {
5502 return { top: 0, left: 0 };
5503 }
5504
5505 },
5506
5507 _cacheMargins: function() {
5508 this.margins = {
5509 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
5510 top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
5511 };
5512 },
5513
5514 _cacheHelperProportions: function() {
5515 this.helperProportions = {
5516 width: this.helper.outerWidth(),
5517 height: this.helper.outerHeight()
5518 };
5519 },
5520
5521 _setContainment: function() {
5522
5523 var ce, co, over,
5524 o = this.options;
5525 if(o.containment === "parent") {
5526 o.containment = this.helper[0].parentNode;
5527 }
5528 if(o.containment === "document" || o.containment === "window") {
5529 this.containment = [
5530 0 - this.offset.relative.left - this.offset.parent.left,
5531 0 - this.offset.relative.top - this.offset.parent.top,
5532 o.containment === "document" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left,
5533 (o.containment === "document" ? this.document.width() : this.window.height() || this.document[0].body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
5534 ];
5535 }
5536
5537 if(!(/^(document|window|parent)$/).test(o.containment)) {
5538 ce = $(o.containment)[0];
5539 co = $(o.containment).offset();
5540 over = ($(ce).css("overflow") !== "hidden");
5541
5542 this.containment = [
5543 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
5544 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
5545 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,
5546 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
5547 ];
5548 }
5549
5550 },
5551
5552 _convertPositionTo: function(d, pos) {
5553
5554 if(!pos) {
5555 pos = this.position;
5556 }
5557 var mod = d === "absolute" ? 1 : -1,
5558 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
5559 scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
5560
5561 return {
5562 top: (
5563 pos.top + // The absolute mouse position
5564 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
5565 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border)
5566 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
5567 ),
5568 left: (
5569 pos.left + // The absolute mouse position
5570 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
5571 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border)
5572 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
5573 )
5574 };
5575
5576 },
5577
5578 _generatePosition: function(event) {
5579
5580 var top, left,
5581 o = this.options,
5582 pageX = event.pageX,
5583 pageY = event.pageY,
5584 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);
5585
5586 // This is another very weird special case that only happens for relative elements:
5587 // 1. If the css position is relative
5588 // 2. and the scroll parent is the document or similar to the offset parent
5589 // we have to refresh the relative offset during the scroll so there are no jumps
5590 if(this.cssPosition === "relative" && !(this.scrollParent[0] !== this.document[0] && this.scrollParent[0] !== this.offsetParent[0])) {
5591 this.offset.relative = this._getRelativeOffset();
5592 }
5593
5594 /*
5595 * - Position constraining -
5596 * Constrain the position to a mix of grid, containment.
5597 */
5598
5599 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
5600
5601 if(this.containment) {
5602 if(event.pageX - this.offset.click.left < this.containment[0]) {
5603 pageX = this.containment[0] + this.offset.click.left;
5604 }
5605 if(event.pageY - this.offset.click.top < this.containment[1]) {
5606 pageY = this.containment[1] + this.offset.click.top;
5607 }
5608 if(event.pageX - this.offset.click.left > this.containment[2]) {
5609 pageX = this.containment[2] + this.offset.click.left;
5610 }
5611 if(event.pageY - this.offset.click.top > this.containment[3]) {
5612 pageY = this.containment[3] + this.offset.click.top;
5613 }
5614 }
5615
5616 if(o.grid) {
5617 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
5618 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;
5619
5620 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
5621 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;
5622 }
5623
5624 }
5625
5626 return {
5627 top: (
5628 pageY - // The absolute mouse position
5629 this.offset.click.top - // Click offset (relative to the element)
5630 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent
5631 this.offset.parent.top + // The offsetParent's offset without borders (offset + border)
5632 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
5633 ),
5634 left: (
5635 pageX - // The absolute mouse position
5636 this.offset.click.left - // Click offset (relative to the element)
5637 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent
5638 this.offset.parent.left + // The offsetParent's offset without borders (offset + border)
5639 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
5640 )
5641 };
5642
5643 },
5644
5645 _rearrange: function(event, i, a, hardRefresh) {
5646
5647 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));
5648
5649 //Various things done here to improve the performance:
5650 // 1. we create a setTimeout, that calls refreshPositions
5651 // 2. on the instance, we have a counter variable, that get's higher after every append
5652 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
5653 // 4. this lets only the last addition to the timeout stack through
5654 this.counter = this.counter ? ++this.counter : 1;
5655 var counter = this.counter;
5656
5657 this._delay(function() {
5658 if(counter === this.counter) {
5659 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
5660 }
5661 });
5662
5663 },
5664
5665 _clear: function(event, noPropagation) {
5666
5667 this.reverting = false;
5668 // We delay all events that have to be triggered to after the point where the placeholder has been removed and
5669 // everything else normalized again
5670 var i,
5671 delayedTriggers = [];
5672
5673 // We first have to update the dom position of the actual currentItem
5674 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
5675 if(!this._noFinalSort && this.currentItem.parent().length) {
5676 this.placeholder.before(this.currentItem);
5677 }
5678 this._noFinalSort = null;
5679
5680 if(this.helper[0] === this.currentItem[0]) {
5681 for(i in this._storedCSS) {
5682 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
5683 this._storedCSS[i] = "";
5684 }
5685 }
5686 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
5687 } else {
5688 this.currentItem.show();
5689 }
5690
5691 if(this.fromOutside && !noPropagation) {
5692 delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
5693 }
5694 if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
5695 delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
5696 }
5697
5698 // Check if the items Container has Changed and trigger appropriate
5699 // events.
5700 if (this !== this.currentContainer) {
5701 if(!noPropagation) {
5702 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
5703 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
5704 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
5705 }
5706 }
5707
5708
5709 //Post events to containers
5710 function delayEvent( type, instance, container ) {
5711 return function( event ) {
5712 container._trigger( type, event, instance._uiHash( instance ) );
5713 };
5714 }
5715 for (i = this.containers.length - 1; i >= 0; i--){
5716 if (!noPropagation) {
5717 delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
5718 }
5719 if(this.containers[i].containerCache.over) {
5720 delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
5721 this.containers[i].containerCache.over = 0;
5722 }
5723 }
5724
5725 //Do what was originally in plugins
5726 if ( this.storedCursor ) {
5727 this.document.find( "body" ).css( "cursor", this.storedCursor );
5728 this.storedStylesheet.remove();
5729 }
5730 if(this._storedOpacity) {
5731 this.helper.css("opacity", this._storedOpacity);
5732 }
5733 if(this._storedZIndex) {
5734 this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
5735 }
5736
5737 this.dragging = false;
5738
5739 if(!noPropagation) {
5740 this._trigger("beforeStop", event, this._uiHash());
5741 }
5742
5743 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
5744 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
5745
5746 if ( !this.cancelHelperRemoval ) {
5747 if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
5748 this.helper.remove();
5749 }
5750 this.helper = null;
5751 }
5752
5753 if(!noPropagation) {
5754 for (i=0; i < delayedTriggers.length; i++) {
5755 delayedTriggers[i].call(this, event);
5756 } //Trigger all delayed events
5757 this._trigger("stop", event, this._uiHash());
5758 }
5759
5760 this.fromOutside = false;
5761 return !this.cancelHelperRemoval;
5762
5763 },
5764
5765 _trigger: function() {
5766 if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
5767 this.cancel();
5768 }
5769 },
5770
5771 _uiHash: function(_inst) {
5772 var inst = _inst || this;
5773 return {
5774 helper: inst.helper,
5775 placeholder: inst.placeholder || $([]),
5776 position: inst.position,
5777 originalPosition: inst.originalPosition,
5778 offset: inst.positionAbs,
5779 item: inst.currentItem,
5780 sender: _inst ? _inst.element : null
5781 };
5782 }
5783
5784});
5785
5786
5787/*!
5788 * jQuery UI Accordion 1.11.3
5789 * http://jqueryui.com
5790 *
5791 * Copyright jQuery Foundation and other contributors
5792 * Released under the MIT license.
5793 * http://jquery.org/license
5794 *
5795 * http://api.jqueryui.com/accordion/
5796 */
5797
5798
5799var accordion = $.widget( "ui.accordion", {
5800 version: "1.11.3",
5801 options: {
5802 active: 0,
5803 animate: {},
5804 collapsible: false,
5805 event: "click",
5806 header: "> li > :first-child,> :not(li):even",
5807 heightStyle: "auto",
5808 icons: {
5809 activeHeader: "ui-icon-triangle-1-s",
5810 header: "ui-icon-triangle-1-e"
5811 },
5812
5813 // callbacks
5814 activate: null,
5815 beforeActivate: null
5816 },
5817
5818 hideProps: {
5819 borderTopWidth: "hide",
5820 borderBottomWidth: "hide",
5821 paddingTop: "hide",
5822 paddingBottom: "hide",
5823 height: "hide"
5824 },
5825
5826 showProps: {
5827 borderTopWidth: "show",
5828 borderBottomWidth: "show",
5829 paddingTop: "show",
5830 paddingBottom: "show",
5831 height: "show"
5832 },
5833
5834 _create: function() {
5835 var options = this.options;
5836 this.prevShow = this.prevHide = $();
5837 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
5838 // ARIA
5839 .attr( "role", "tablist" );
5840
5841 // don't allow collapsible: false and active: false / null
5842 if ( !options.collapsible && (options.active === false || options.active == null) ) {
5843 options.active = 0;
5844 }
5845
5846 this._processPanels();
5847 // handle negative values
5848 if ( options.active < 0 ) {
5849 options.active += this.headers.length;
5850 }
5851 this._refresh();
5852 },
5853
5854 _getCreateEventData: function() {
5855 return {
5856 header: this.active,
5857 panel: !this.active.length ? $() : this.active.next()
5858 };
5859 },
5860
5861 _createIcons: function() {
5862 var icons = this.options.icons;
5863 if ( icons ) {
5864 $( "<span>" )
5865 .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
5866 .prependTo( this.headers );
5867 this.active.children( ".ui-accordion-header-icon" )
5868 .removeClass( icons.header )
5869 .addClass( icons.activeHeader );
5870 this.headers.addClass( "ui-accordion-icons" );
5871 }
5872 },
5873
5874 _destroyIcons: function() {
5875 this.headers
5876 .removeClass( "ui-accordion-icons" )
5877 .children( ".ui-accordion-header-icon" )
5878 .remove();
5879 },
5880
5881 _destroy: function() {
5882 var contents;
5883
5884 // clean up main element
5885 this.element
5886 .removeClass( "ui-accordion ui-widget ui-helper-reset" )
5887 .removeAttr( "role" );
5888
5889 // clean up headers
5890 this.headers
5891 .removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " +
5892 "ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
5893 .removeAttr( "role" )
5894 .removeAttr( "aria-expanded" )
5895 .removeAttr( "aria-selected" )
5896 .removeAttr( "aria-controls" )
5897 .removeAttr( "tabIndex" )
5898 .removeUniqueId();
5899
5900 this._destroyIcons();
5901
5902 // clean up content panels
5903 contents = this.headers.next()
5904 .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " +
5905 "ui-accordion-content ui-accordion-content-active ui-state-disabled" )
5906 .css( "display", "" )
5907 .removeAttr( "role" )
5908 .removeAttr( "aria-hidden" )
5909 .removeAttr( "aria-labelledby" )
5910 .removeUniqueId();
5911
5912 if ( this.options.heightStyle !== "content" ) {
5913 contents.css( "height", "" );
5914 }
5915 },
5916
5917 _setOption: function( key, value ) {
5918 if ( key === "active" ) {
5919 // _activate() will handle invalid values and update this.options
5920 this._activate( value );
5921 return;
5922 }
5923
5924 if ( key === "event" ) {
5925 if ( this.options.event ) {
5926 this._off( this.headers, this.options.event );
5927 }
5928 this._setupEvents( value );
5929 }
5930
5931 this._super( key, value );
5932
5933 // setting collapsible: false while collapsed; open first panel
5934 if ( key === "collapsible" && !value && this.options.active === false ) {
5935 this._activate( 0 );
5936 }
5937
5938 if ( key === "icons" ) {
5939 this._destroyIcons();
5940 if ( value ) {
5941 this._createIcons();
5942 }
5943 }
5944
5945 // #5332 - opacity doesn't cascade to positioned elements in IE
5946 // so we need to add the disabled class to the headers and panels
5947 if ( key === "disabled" ) {
5948 this.element
5949 .toggleClass( "ui-state-disabled", !!value )
5950 .attr( "aria-disabled", value );
5951 this.headers.add( this.headers.next() )
5952 .toggleClass( "ui-state-disabled", !!value );
5953 }
5954 },
5955
5956 _keydown: function( event ) {
5957 if ( event.altKey || event.ctrlKey ) {
5958 return;
5959 }
5960
5961 var keyCode = $.ui.keyCode,
5962 length = this.headers.length,
5963 currentIndex = this.headers.index( event.target ),
5964 toFocus = false;
5965
5966 switch ( event.keyCode ) {
5967 case keyCode.RIGHT:
5968 case keyCode.DOWN:
5969 toFocus = this.headers[ ( currentIndex + 1 ) % length ];
5970 break;
5971 case keyCode.LEFT:
5972 case keyCode.UP:
5973 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
5974 break;
5975 case keyCode.SPACE:
5976 case keyCode.ENTER:
5977 this._eventHandler( event );
5978 break;
5979 case keyCode.HOME:
5980 toFocus = this.headers[ 0 ];
5981 break;
5982 case keyCode.END:
5983 toFocus = this.headers[ length - 1 ];
5984 break;
5985 }
5986
5987 if ( toFocus ) {
5988 $( event.target ).attr( "tabIndex", -1 );
5989 $( toFocus ).attr( "tabIndex", 0 );
5990 toFocus.focus();
5991 event.preventDefault();
5992 }
5993 },
5994
5995 _panelKeyDown: function( event ) {
5996 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
5997 $( event.currentTarget ).prev().focus();
5998 }
5999 },
6000
6001 refresh: function() {
6002 var options = this.options;
6003 this._processPanels();
6004
6005 // was collapsed or no panel
6006 if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
6007 options.active = false;
6008 this.active = $();
6009 // active false only when collapsible is true
6010 } else if ( options.active === false ) {
6011 this._activate( 0 );
6012 // was active, but active panel is gone
6013 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
6014 // all remaining panel are disabled
6015 if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
6016 options.active = false;
6017 this.active = $();
6018 // activate previous panel
6019 } else {
6020 this._activate( Math.max( 0, options.active - 1 ) );
6021 }
6022 // was active, active panel still exists
6023 } else {
6024 // make sure active index is correct
6025 options.active = this.headers.index( this.active );
6026 }
6027
6028 this._destroyIcons();
6029
6030 this._refresh();
6031 },
6032
6033 _processPanels: function() {
6034 var prevHeaders = this.headers,
6035 prevPanels = this.panels;
6036
6037 this.headers = this.element.find( this.options.header )
6038 .addClass( "ui-accordion-header ui-state-default ui-corner-all" );
6039
6040 this.panels = this.headers.next()
6041 .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
6042 .filter( ":not(.ui-accordion-content-active)" )
6043 .hide();
6044
6045 // Avoid memory leaks (#10056)
6046 if ( prevPanels ) {
6047 this._off( prevHeaders.not( this.headers ) );
6048 this._off( prevPanels.not( this.panels ) );
6049 }
6050 },
6051
6052 _refresh: function() {
6053 var maxHeight,
6054 options = this.options,
6055 heightStyle = options.heightStyle,
6056 parent = this.element.parent();
6057
6058 this.active = this._findActive( options.active )
6059 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
6060 .removeClass( "ui-corner-all" );
6061 this.active.next()
6062 .addClass( "ui-accordion-content-active" )
6063 .show();
6064
6065 this.headers
6066 .attr( "role", "tab" )
6067 .each(function() {
6068 var header = $( this ),
6069 headerId = header.uniqueId().attr( "id" ),
6070 panel = header.next(),
6071 panelId = panel.uniqueId().attr( "id" );
6072 header.attr( "aria-controls", panelId );
6073 panel.attr( "aria-labelledby", headerId );
6074 })
6075 .next()
6076 .attr( "role", "tabpanel" );
6077
6078 this.headers
6079 .not( this.active )
6080 .attr({
6081 "aria-selected": "false",
6082 "aria-expanded": "false",
6083 tabIndex: -1
6084 })
6085 .next()
6086 .attr({
6087 "aria-hidden": "true"
6088 })
6089 .hide();
6090
6091 // make sure at least one header is in the tab order
6092 if ( !this.active.length ) {
6093 this.headers.eq( 0 ).attr( "tabIndex", 0 );
6094 } else {
6095 this.active.attr({
6096 "aria-selected": "true",
6097 "aria-expanded": "true",
6098 tabIndex: 0
6099 })
6100 .next()
6101 .attr({
6102 "aria-hidden": "false"
6103 });
6104 }
6105
6106 this._createIcons();
6107
6108 this._setupEvents( options.event );
6109
6110 if ( heightStyle === "fill" ) {
6111 maxHeight = parent.height();
6112 this.element.siblings( ":visible" ).each(function() {
6113 var elem = $( this ),
6114 position = elem.css( "position" );
6115
6116 if ( position === "absolute" || position === "fixed" ) {
6117 return;
6118 }
6119 maxHeight -= elem.outerHeight( true );
6120 });
6121
6122 this.headers.each(function() {
6123 maxHeight -= $( this ).outerHeight( true );
6124 });
6125
6126 this.headers.next()
6127 .each(function() {
6128 $( this ).height( Math.max( 0, maxHeight -
6129 $( this ).innerHeight() + $( this ).height() ) );
6130 })
6131 .css( "overflow", "auto" );
6132 } else if ( heightStyle === "auto" ) {
6133 maxHeight = 0;
6134 this.headers.next()
6135 .each(function() {
6136 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
6137 })
6138 .height( maxHeight );
6139 }
6140 },
6141
6142 _activate: function( index ) {
6143 var active = this._findActive( index )[ 0 ];
6144
6145 // trying to activate the already active panel
6146 if ( active === this.active[ 0 ] ) {
6147 return;
6148 }
6149
6150 // trying to collapse, simulate a click on the currently active header
6151 active = active || this.active[ 0 ];
6152
6153 this._eventHandler({
6154 target: active,
6155 currentTarget: active,
6156 preventDefault: $.noop
6157 });
6158 },
6159
6160 _findActive: function( selector ) {
6161 return typeof selector === "number" ? this.headers.eq( selector ) : $();
6162 },
6163
6164 _setupEvents: function( event ) {
6165 var events = {
6166 keydown: "_keydown"
6167 };
6168 if ( event ) {
6169 $.each( event.split( " " ), function( index, eventName ) {
6170 events[ eventName ] = "_eventHandler";
6171 });
6172 }
6173
6174 this._off( this.headers.add( this.headers.next() ) );
6175 this._on( this.headers, events );
6176 this._on( this.headers.next(), { keydown: "_panelKeyDown" });
6177 this._hoverable( this.headers );
6178 this._focusable( this.headers );
6179 },
6180
6181 _eventHandler: function( event ) {
6182 var options = this.options,
6183 active = this.active,
6184 clicked = $( event.currentTarget ),
6185 clickedIsActive = clicked[ 0 ] === active[ 0 ],
6186 collapsing = clickedIsActive && options.collapsible,
6187 toShow = collapsing ? $() : clicked.next(),
6188 toHide = active.next(),
6189 eventData = {
6190 oldHeader: active,
6191 oldPanel: toHide,
6192 newHeader: collapsing ? $() : clicked,
6193 newPanel: toShow
6194 };
6195
6196 event.preventDefault();
6197
6198 if (
6199 // click on active header, but not collapsible
6200 ( clickedIsActive && !options.collapsible ) ||
6201 // allow canceling activation
6202 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
6203 return;
6204 }
6205
6206 options.active = collapsing ? false : this.headers.index( clicked );
6207
6208 // when the call to ._toggle() comes after the class changes
6209 // it causes a very odd bug in IE 8 (see #6720)
6210 this.active = clickedIsActive ? $() : clicked;
6211 this._toggle( eventData );
6212
6213 // switch classes
6214 // corner classes on the previously active header stay after the animation
6215 active.removeClass( "ui-accordion-header-active ui-state-active" );
6216 if ( options.icons ) {
6217 active.children( ".ui-accordion-header-icon" )
6218 .removeClass( options.icons.activeHeader )
6219 .addClass( options.icons.header );
6220 }
6221
6222 if ( !clickedIsActive ) {
6223 clicked
6224 .removeClass( "ui-corner-all" )
6225 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
6226 if ( options.icons ) {
6227 clicked.children( ".ui-accordion-header-icon" )
6228 .removeClass( options.icons.header )
6229 .addClass( options.icons.activeHeader );
6230 }
6231
6232 clicked
6233 .next()
6234 .addClass( "ui-accordion-content-active" );
6235 }
6236 },
6237
6238 _toggle: function( data ) {
6239 var toShow = data.newPanel,
6240 toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
6241
6242 // handle activating a panel during the animation for another activation
6243 this.prevShow.add( this.prevHide ).stop( true, true );
6244 this.prevShow = toShow;
6245 this.prevHide = toHide;
6246
6247 if ( this.options.animate ) {
6248 this._animate( toShow, toHide, data );
6249 } else {
6250 toHide.hide();
6251 toShow.show();
6252 this._toggleComplete( data );
6253 }
6254
6255 toHide.attr({
6256 "aria-hidden": "true"
6257 });
6258 toHide.prev().attr({
6259 "aria-selected": "false",
6260 "aria-expanded": "false"
6261 });
6262 // if we're switching panels, remove the old header from the tab order
6263 // if we're opening from collapsed state, remove the previous header from the tab order
6264 // if we're collapsing, then keep the collapsing header in the tab order
6265 if ( toShow.length && toHide.length ) {
6266 toHide.prev().attr({
6267 "tabIndex": -1,
6268 "aria-expanded": "false"
6269 });
6270 } else if ( toShow.length ) {
6271 this.headers.filter(function() {
6272 return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
6273 })
6274 .attr( "tabIndex", -1 );
6275 }
6276
6277 toShow
6278 .attr( "aria-hidden", "false" )
6279 .prev()
6280 .attr({
6281 "aria-selected": "true",
6282 "aria-expanded": "true",
6283 tabIndex: 0
6284 });
6285 },
6286
6287 _animate: function( toShow, toHide, data ) {
6288 var total, easing, duration,
6289 that = this,
6290 adjust = 0,
6291 down = toShow.length &&
6292 ( !toHide.length || ( toShow.index() < toHide.index() ) ),
6293 animate = this.options.animate || {},
6294 options = down && animate.down || animate,
6295 complete = function() {
6296 that._toggleComplete( data );
6297 };
6298
6299 if ( typeof options === "number" ) {
6300 duration = options;
6301 }
6302 if ( typeof options === "string" ) {
6303 easing = options;
6304 }
6305 // fall back from options to animation in case of partial down settings
6306 easing = easing || options.easing || animate.easing;
6307 duration = duration || options.duration || animate.duration;
6308
6309 if ( !toHide.length ) {
6310 return toShow.animate( this.showProps, duration, easing, complete );
6311 }
6312 if ( !toShow.length ) {
6313 return toHide.animate( this.hideProps, duration, easing, complete );
6314 }
6315
6316 total = toShow.show().outerHeight();
6317 toHide.animate( this.hideProps, {
6318 duration: duration,
6319 easing: easing,
6320 step: function( now, fx ) {
6321 fx.now = Math.round( now );
6322 }
6323 });
6324 toShow
6325 .hide()
6326 .animate( this.showProps, {
6327 duration: duration,
6328 easing: easing,
6329 complete: complete,
6330 step: function( now, fx ) {
6331 fx.now = Math.round( now );
6332 if ( fx.prop !== "height" ) {
6333 adjust += fx.now;
6334 } else if ( that.options.heightStyle !== "content" ) {
6335 fx.now = Math.round( total - toHide.outerHeight() - adjust );
6336 adjust = 0;
6337 }
6338 }
6339 });
6340 },
6341
6342 _toggleComplete: function( data ) {
6343 var toHide = data.oldPanel;
6344
6345 toHide
6346 .removeClass( "ui-accordion-content-active" )
6347 .prev()
6348 .removeClass( "ui-corner-top" )
6349 .addClass( "ui-corner-all" );
6350
6351 // Work around for rendering bug in IE (#5421)
6352 if ( toHide.length ) {
6353 toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
6354 }
6355 this._trigger( "activate", null, data );
6356 }
6357});
6358
6359
6360/*!
6361 * jQuery UI Menu 1.11.3
6362 * http://jqueryui.com
6363 *
6364 * Copyright jQuery Foundation and other contributors
6365 * Released under the MIT license.
6366 * http://jquery.org/license
6367 *
6368 * http://api.jqueryui.com/menu/
6369 */
6370
6371
6372var menu = $.widget( "ui.menu", {
6373 version: "1.11.3",
6374 defaultElement: "<ul>",
6375 delay: 300,
6376 options: {
6377 icons: {
6378 submenu: "ui-icon-carat-1-e"
6379 },
6380 items: "> *",
6381 menus: "ul",
6382 position: {
6383 my: "left-1 top",
6384 at: "right top"
6385 },
6386 role: "menu",
6387
6388 // callbacks
6389 blur: null,
6390 focus: null,
6391 select: null
6392 },
6393
6394 _create: function() {
6395 this.activeMenu = this.element;
6396
6397 // Flag used to prevent firing of the click handler
6398 // as the event bubbles up through nested menus
6399 this.mouseHandled = false;
6400 this.element
6401 .uniqueId()
6402 .addClass( "ui-menu ui-widget ui-widget-content" )
6403 .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
6404 .attr({
6405 role: this.options.role,
6406 tabIndex: 0
6407 });
6408
6409 if ( this.options.disabled ) {
6410 this.element
6411 .addClass( "ui-state-disabled" )
6412 .attr( "aria-disabled", "true" );
6413 }
6414
6415 this._on({
6416 // Prevent focus from sticking to links inside menu after clicking
6417 // them (focus should always stay on UL during navigation).
6418 "mousedown .ui-menu-item": function( event ) {
6419 event.preventDefault();
6420 },
6421 "click .ui-menu-item": function( event ) {
6422 var target = $( event.target );
6423 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
6424 this.select( event );
6425
6426 // Only set the mouseHandled flag if the event will bubble, see #9469.
6427 if ( !event.isPropagationStopped() ) {
6428 this.mouseHandled = true;
6429 }
6430
6431 // Open submenu on click
6432 if ( target.has( ".ui-menu" ).length ) {
6433 this.expand( event );
6434 } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
6435
6436 // Redirect focus to the menu
6437 this.element.trigger( "focus", [ true ] );
6438
6439 // If the active item is on the top level, let it stay active.
6440 // Otherwise, blur the active item since it is no longer visible.
6441 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
6442 clearTimeout( this.timer );
6443 }
6444 }
6445 }
6446 },
6447 "mouseenter .ui-menu-item": function( event ) {
6448 // Ignore mouse events while typeahead is active, see #10458.
6449 // Prevents focusing the wrong item when typeahead causes a scroll while the mouse
6450 // is over an item in the menu
6451 if ( this.previousFilter ) {
6452 return;
6453 }
6454 var target = $( event.currentTarget );
6455 // Remove ui-state-active class from siblings of the newly focused menu item
6456 // to avoid a jump caused by adjacent elements both having a class with a border
6457 target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" );
6458 this.focus( event, target );
6459 },
6460 mouseleave: "collapseAll",
6461 "mouseleave .ui-menu": "collapseAll",
6462 focus: function( event, keepActiveItem ) {
6463 // If there's already an active item, keep it active
6464 // If not, activate the first item
6465 var item = this.active || this.element.find( this.options.items ).eq( 0 );
6466
6467 if ( !keepActiveItem ) {
6468 this.focus( event, item );
6469 }
6470 },
6471 blur: function( event ) {
6472 this._delay(function() {
6473 if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
6474 this.collapseAll( event );
6475 }
6476 });
6477 },
6478 keydown: "_keydown"
6479 });
6480
6481 this.refresh();
6482
6483 // Clicks outside of a menu collapse any open menus
6484 this._on( this.document, {
6485 click: function( event ) {
6486 if ( this._closeOnDocumentClick( event ) ) {
6487 this.collapseAll( event );
6488 }
6489
6490 // Reset the mouseHandled flag
6491 this.mouseHandled = false;
6492 }
6493 });
6494 },
6495
6496 _destroy: function() {
6497 // Destroy (sub)menus
6498 this.element
6499 .removeAttr( "aria-activedescendant" )
6500 .find( ".ui-menu" ).addBack()
6501 .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" )
6502 .removeAttr( "role" )
6503 .removeAttr( "tabIndex" )
6504 .removeAttr( "aria-labelledby" )
6505 .removeAttr( "aria-expanded" )
6506 .removeAttr( "aria-hidden" )
6507 .removeAttr( "aria-disabled" )
6508 .removeUniqueId()
6509 .show();
6510
6511 // Destroy menu items
6512 this.element.find( ".ui-menu-item" )
6513 .removeClass( "ui-menu-item" )
6514 .removeAttr( "role" )
6515 .removeAttr( "aria-disabled" )
6516 .removeUniqueId()
6517 .removeClass( "ui-state-hover" )
6518 .removeAttr( "tabIndex" )
6519 .removeAttr( "role" )
6520 .removeAttr( "aria-haspopup" )
6521 .children().each( function() {
6522 var elem = $( this );
6523 if ( elem.data( "ui-menu-submenu-carat" ) ) {
6524 elem.remove();
6525 }
6526 });
6527
6528 // Destroy menu dividers
6529 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
6530 },
6531
6532 _keydown: function( event ) {
6533 var match, prev, character, skip,
6534 preventDefault = true;
6535
6536 switch ( event.keyCode ) {
6537 case $.ui.keyCode.PAGE_UP:
6538 this.previousPage( event );
6539 break;
6540 case $.ui.keyCode.PAGE_DOWN:
6541 this.nextPage( event );
6542 break;
6543 case $.ui.keyCode.HOME:
6544 this._move( "first", "first", event );
6545 break;
6546 case $.ui.keyCode.END:
6547 this._move( "last", "last", event );
6548 break;
6549 case $.ui.keyCode.UP:
6550 this.previous( event );
6551 break;
6552 case $.ui.keyCode.DOWN:
6553 this.next( event );
6554 break;
6555 case $.ui.keyCode.LEFT:
6556 this.collapse( event );
6557 break;
6558 case $.ui.keyCode.RIGHT:
6559 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
6560 this.expand( event );
6561 }
6562 break;
6563 case $.ui.keyCode.ENTER:
6564 case $.ui.keyCode.SPACE:
6565 this._activate( event );
6566 break;
6567 case $.ui.keyCode.ESCAPE:
6568 this.collapse( event );
6569 break;
6570 default:
6571 preventDefault = false;
6572 prev = this.previousFilter || "";
6573 character = String.fromCharCode( event.keyCode );
6574 skip = false;
6575
6576 clearTimeout( this.filterTimer );
6577
6578 if ( character === prev ) {
6579 skip = true;
6580 } else {
6581 character = prev + character;
6582 }
6583
6584 match = this._filterMenuItems( character );
6585 match = skip && match.index( this.active.next() ) !== -1 ?
6586 this.active.nextAll( ".ui-menu-item" ) :
6587 match;
6588
6589 // If no matches on the current filter, reset to the last character pressed
6590 // to move down the menu to the first item that starts with that character
6591 if ( !match.length ) {
6592 character = String.fromCharCode( event.keyCode );
6593 match = this._filterMenuItems( character );
6594 }
6595
6596 if ( match.length ) {
6597 this.focus( event, match );
6598 this.previousFilter = character;
6599 this.filterTimer = this._delay(function() {
6600 delete this.previousFilter;
6601 }, 1000 );
6602 } else {
6603 delete this.previousFilter;
6604 }
6605 }
6606
6607 if ( preventDefault ) {
6608 event.preventDefault();
6609 }
6610 },
6611
6612 _activate: function( event ) {
6613 if ( !this.active.is( ".ui-state-disabled" ) ) {
6614 if ( this.active.is( "[aria-haspopup='true']" ) ) {
6615 this.expand( event );
6616 } else {
6617 this.select( event );
6618 }
6619 }
6620 },
6621
6622 refresh: function() {
6623 var menus, items,
6624 that = this,
6625 icon = this.options.icons.submenu,
6626 submenus = this.element.find( this.options.menus );
6627
6628 this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
6629
6630 // Initialize nested menus
6631 submenus.filter( ":not(.ui-menu)" )
6632 .addClass( "ui-menu ui-widget ui-widget-content ui-front" )
6633 .hide()
6634 .attr({
6635 role: this.options.role,
6636 "aria-hidden": "true",
6637 "aria-expanded": "false"
6638 })
6639 .each(function() {
6640 var menu = $( this ),
6641 item = menu.parent(),
6642 submenuCarat = $( "<span>" )
6643 .addClass( "ui-menu-icon ui-icon " + icon )
6644 .data( "ui-menu-submenu-carat", true );
6645
6646 item
6647 .attr( "aria-haspopup", "true" )
6648 .prepend( submenuCarat );
6649 menu.attr( "aria-labelledby", item.attr( "id" ) );
6650 });
6651
6652 menus = submenus.add( this.element );
6653 items = menus.find( this.options.items );
6654
6655 // Initialize menu-items containing spaces and/or dashes only as dividers
6656 items.not( ".ui-menu-item" ).each(function() {
6657 var item = $( this );
6658 if ( that._isDivider( item ) ) {
6659 item.addClass( "ui-widget-content ui-menu-divider" );
6660 }
6661 });
6662
6663 // Don't refresh list items that are already adapted
6664 items.not( ".ui-menu-item, .ui-menu-divider" )
6665 .addClass( "ui-menu-item" )
6666 .uniqueId()
6667 .attr({
6668 tabIndex: -1,
6669 role: this._itemRole()
6670 });
6671
6672 // Add aria-disabled attribute to any disabled menu item
6673 items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
6674
6675 // If the active item has been removed, blur the menu
6676 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
6677 this.blur();
6678 }
6679 },
6680
6681 _itemRole: function() {
6682 return {
6683 menu: "menuitem",
6684 listbox: "option"
6685 }[ this.options.role ];
6686 },
6687
6688 _setOption: function( key, value ) {
6689 if ( key === "icons" ) {
6690 this.element.find( ".ui-menu-icon" )
6691 .removeClass( this.options.icons.submenu )
6692 .addClass( value.submenu );
6693 }
6694 if ( key === "disabled" ) {
6695 this.element
6696 .toggleClass( "ui-state-disabled", !!value )
6697 .attr( "aria-disabled", value );
6698 }
6699 this._super( key, value );
6700 },
6701
6702 focus: function( event, item ) {
6703 var nested, focused;
6704 this.blur( event, event && event.type === "focus" );
6705
6706 this._scrollIntoView( item );
6707
6708 this.active = item.first();
6709 focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" );
6710 // Only update aria-activedescendant if there's a role
6711 // otherwise we assume focus is managed elsewhere
6712 if ( this.options.role ) {
6713 this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
6714 }
6715
6716 // Highlight active parent menu item, if any
6717 this.active
6718 .parent()
6719 .closest( ".ui-menu-item" )
6720 .addClass( "ui-state-active" );
6721
6722 if ( event && event.type === "keydown" ) {
6723 this._close();
6724 } else {
6725 this.timer = this._delay(function() {
6726 this._close();
6727 }, this.delay );
6728 }
6729
6730 nested = item.children( ".ui-menu" );
6731 if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
6732 this._startOpening(nested);
6733 }
6734 this.activeMenu = item.parent();
6735
6736 this._trigger( "focus", event, { item: item } );
6737 },
6738
6739 _scrollIntoView: function( item ) {
6740 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
6741 if ( this._hasScroll() ) {
6742 borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
6743 paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
6744 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
6745 scroll = this.activeMenu.scrollTop();
6746 elementHeight = this.activeMenu.height();
6747 itemHeight = item.outerHeight();
6748
6749 if ( offset < 0 ) {
6750 this.activeMenu.scrollTop( scroll + offset );
6751 } else if ( offset + itemHeight > elementHeight ) {
6752 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
6753 }
6754 }
6755 },
6756
6757 blur: function( event, fromFocus ) {
6758 if ( !fromFocus ) {
6759 clearTimeout( this.timer );
6760 }
6761
6762 if ( !this.active ) {
6763 return;
6764 }
6765
6766 this.active.removeClass( "ui-state-focus" );
6767 this.active = null;
6768
6769 this._trigger( "blur", event, { item: this.active } );
6770 },
6771
6772 _startOpening: function( submenu ) {
6773 clearTimeout( this.timer );
6774
6775 // Don't open if already open fixes a Firefox bug that caused a .5 pixel
6776 // shift in the submenu position when mousing over the carat icon
6777 if ( submenu.attr( "aria-hidden" ) !== "true" ) {
6778 return;
6779 }
6780
6781 this.timer = this._delay(function() {
6782 this._close();
6783 this._open( submenu );
6784 }, this.delay );
6785 },
6786
6787 _open: function( submenu ) {
6788 var position = $.extend({
6789 of: this.active
6790 }, this.options.position );
6791
6792 clearTimeout( this.timer );
6793 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
6794 .hide()
6795 .attr( "aria-hidden", "true" );
6796
6797 submenu
6798 .show()
6799 .removeAttr( "aria-hidden" )
6800 .attr( "aria-expanded", "true" )
6801 .position( position );
6802 },
6803
6804 collapseAll: function( event, all ) {
6805 clearTimeout( this.timer );
6806 this.timer = this._delay(function() {
6807 // If we were passed an event, look for the submenu that contains the event
6808 var currentMenu = all ? this.element :
6809 $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
6810
6811 // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
6812 if ( !currentMenu.length ) {
6813 currentMenu = this.element;
6814 }
6815
6816 this._close( currentMenu );
6817
6818 this.blur( event );
6819 this.activeMenu = currentMenu;
6820 }, this.delay );
6821 },
6822
6823 // With no arguments, closes the currently active menu - if nothing is active
6824 // it closes all menus. If passed an argument, it will search for menus BELOW
6825 _close: function( startMenu ) {
6826 if ( !startMenu ) {
6827 startMenu = this.active ? this.active.parent() : this.element;
6828 }
6829
6830 startMenu
6831 .find( ".ui-menu" )
6832 .hide()
6833 .attr( "aria-hidden", "true" )
6834 .attr( "aria-expanded", "false" )
6835 .end()
6836 .find( ".ui-state-active" ).not( ".ui-state-focus" )
6837 .removeClass( "ui-state-active" );
6838 },
6839
6840 _closeOnDocumentClick: function( event ) {
6841 return !$( event.target ).closest( ".ui-menu" ).length;
6842 },
6843
6844 _isDivider: function( item ) {
6845
6846 // Match hyphen, em dash, en dash
6847 return !/[^\-\u2014\u2013\s]/.test( item.text() );
6848 },
6849
6850 collapse: function( event ) {
6851 var newItem = this.active &&
6852 this.active.parent().closest( ".ui-menu-item", this.element );
6853 if ( newItem && newItem.length ) {
6854 this._close();
6855 this.focus( event, newItem );
6856 }
6857 },
6858
6859 expand: function( event ) {
6860 var newItem = this.active &&
6861 this.active
6862 .children( ".ui-menu " )
6863 .find( this.options.items )
6864 .first();
6865
6866 if ( newItem && newItem.length ) {
6867 this._open( newItem.parent() );
6868
6869 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
6870 this._delay(function() {
6871 this.focus( event, newItem );
6872 });
6873 }
6874 },
6875
6876 next: function( event ) {
6877 this._move( "next", "first", event );
6878 },
6879
6880 previous: function( event ) {
6881 this._move( "prev", "last", event );
6882 },
6883
6884 isFirstItem: function() {
6885 return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
6886 },
6887
6888 isLastItem: function() {
6889 return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
6890 },
6891
6892 _move: function( direction, filter, event ) {
6893 var next;
6894 if ( this.active ) {
6895 if ( direction === "first" || direction === "last" ) {
6896 next = this.active
6897 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
6898 .eq( -1 );
6899 } else {
6900 next = this.active
6901 [ direction + "All" ]( ".ui-menu-item" )
6902 .eq( 0 );
6903 }
6904 }
6905 if ( !next || !next.length || !this.active ) {
6906 next = this.activeMenu.find( this.options.items )[ filter ]();
6907 }
6908
6909 this.focus( event, next );
6910 },
6911
6912 nextPage: function( event ) {
6913 var item, base, height;
6914
6915 if ( !this.active ) {
6916 this.next( event );
6917 return;
6918 }
6919 if ( this.isLastItem() ) {
6920 return;
6921 }
6922 if ( this._hasScroll() ) {
6923 base = this.active.offset().top;
6924 height = this.element.height();
6925 this.active.nextAll( ".ui-menu-item" ).each(function() {
6926 item = $( this );
6927 return item.offset().top - base - height < 0;
6928 });
6929
6930 this.focus( event, item );
6931 } else {
6932 this.focus( event, this.activeMenu.find( this.options.items )
6933 [ !this.active ? "first" : "last" ]() );
6934 }
6935 },
6936
6937 previousPage: function( event ) {
6938 var item, base, height;
6939 if ( !this.active ) {
6940 this.next( event );
6941 return;
6942 }
6943 if ( this.isFirstItem() ) {
6944 return;
6945 }
6946 if ( this._hasScroll() ) {
6947 base = this.active.offset().top;
6948 height = this.element.height();
6949 this.active.prevAll( ".ui-menu-item" ).each(function() {
6950 item = $( this );
6951 return item.offset().top - base + height > 0;
6952 });
6953
6954 this.focus( event, item );
6955 } else {
6956 this.focus( event, this.activeMenu.find( this.options.items ).first() );
6957 }
6958 },
6959
6960 _hasScroll: function() {
6961 return this.element.outerHeight() < this.element.prop( "scrollHeight" );
6962 },
6963
6964 select: function( event ) {
6965 // TODO: It should never be possible to not have an active item at this
6966 // point, but the tests don't trigger mouseenter before click.
6967 this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
6968 var ui = { item: this.active };
6969 if ( !this.active.has( ".ui-menu" ).length ) {
6970 this.collapseAll( event, true );
6971 }
6972 this._trigger( "select", event, ui );
6973 },
6974
6975 _filterMenuItems: function(character) {
6976 var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
6977 regex = new RegExp( "^" + escapedCharacter, "i" );
6978
6979 return this.activeMenu
6980 .find( this.options.items )
6981
6982 // Only match on items, not dividers or other content (#10571)
6983 .filter( ".ui-menu-item" )
6984 .filter(function() {
6985 return regex.test( $.trim( $( this ).text() ) );
6986 });
6987 }
6988});
6989
6990
6991/*!
6992 * jQuery UI Autocomplete 1.11.3
6993 * http://jqueryui.com
6994 *
6995 * Copyright jQuery Foundation and other contributors
6996 * Released under the MIT license.
6997 * http://jquery.org/license
6998 *
6999 * http://api.jqueryui.com/autocomplete/
7000 */
7001
7002
7003$.widget( "ui.autocomplete", {
7004 version: "1.11.3",
7005 defaultElement: "<input>",
7006 options: {
7007 appendTo: null,
7008 autoFocus: false,
7009 delay: 300,
7010 minLength: 1,
7011 position: {
7012 my: "left top",
7013 at: "left bottom",
7014 collision: "none"
7015 },
7016 source: null,
7017
7018 // callbacks
7019 change: null,
7020 close: null,
7021 focus: null,
7022 open: null,
7023 response: null,
7024 search: null,
7025 select: null
7026 },
7027
7028 requestIndex: 0,
7029 pending: 0,
7030
7031 _create: function() {
7032 // Some browsers only repeat keydown events, not keypress events,
7033 // so we use the suppressKeyPress flag to determine if we've already
7034 // handled the keydown event. #7269
7035 // Unfortunately the code for & in keypress is the same as the up arrow,
7036 // so we use the suppressKeyPressRepeat flag to avoid handling keypress
7037 // events when we know the keydown event was used to modify the
7038 // search term. #7799
7039 var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
7040 nodeName = this.element[ 0 ].nodeName.toLowerCase(),
7041 isTextarea = nodeName === "textarea",
7042 isInput = nodeName === "input";
7043
7044 this.isMultiLine =
7045 // Textareas are always multi-line
7046 isTextarea ? true :
7047 // Inputs are always single-line, even if inside a contentEditable element
7048 // IE also treats inputs as contentEditable
7049 isInput ? false :
7050 // All other element types are determined by whether or not they're contentEditable
7051 this.element.prop( "isContentEditable" );
7052
7053 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
7054 this.isNewMenu = true;
7055
7056 this.element
7057 .addClass( "ui-autocomplete-input" )
7058 .attr( "autocomplete", "off" );
7059
7060 this._on( this.element, {
7061 keydown: function( event ) {
7062 if ( this.element.prop( "readOnly" ) ) {
7063 suppressKeyPress = true;
7064 suppressInput = true;
7065 suppressKeyPressRepeat = true;
7066 return;
7067 }
7068
7069 suppressKeyPress = false;
7070 suppressInput = false;
7071 suppressKeyPressRepeat = false;
7072 var keyCode = $.ui.keyCode;
7073 switch ( event.keyCode ) {
7074 case keyCode.PAGE_UP:
7075 suppressKeyPress = true;
7076 this._move( "previousPage", event );
7077 break;
7078 case keyCode.PAGE_DOWN:
7079 suppressKeyPress = true;
7080 this._move( "nextPage", event );
7081 break;
7082 case keyCode.UP:
7083 suppressKeyPress = true;
7084 this._keyEvent( "previous", event );
7085 break;
7086 case keyCode.DOWN:
7087 suppressKeyPress = true;
7088 this._keyEvent( "next", event );
7089 break;
7090 case keyCode.ENTER:
7091 // when menu is open and has focus
7092 if ( this.menu.active ) {
7093 // #6055 - Opera still allows the keypress to occur
7094 // which causes forms to submit
7095 suppressKeyPress = true;
7096 event.preventDefault();
7097 this.menu.select( event );
7098 }
7099 break;
7100 case keyCode.TAB:
7101 if ( this.menu.active ) {
7102 this.menu.select( event );
7103 }
7104 break;
7105 case keyCode.ESCAPE:
7106 if ( this.menu.element.is( ":visible" ) ) {
7107 if ( !this.isMultiLine ) {
7108 this._value( this.term );
7109 }
7110 this.close( event );
7111 // Different browsers have different default behavior for escape
7112 // Single press can mean undo or clear
7113 // Double press in IE means clear the whole form
7114 event.preventDefault();
7115 }
7116 break;
7117 default:
7118 suppressKeyPressRepeat = true;
7119 // search timeout should be triggered before the input value is changed
7120 this._searchTimeout( event );
7121 break;
7122 }
7123 },
7124 keypress: function( event ) {
7125 if ( suppressKeyPress ) {
7126 suppressKeyPress = false;
7127 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
7128 event.preventDefault();
7129 }
7130 return;
7131 }
7132 if ( suppressKeyPressRepeat ) {
7133 return;
7134 }
7135
7136 // replicate some key handlers to allow them to repeat in Firefox and Opera
7137 var keyCode = $.ui.keyCode;
7138 switch ( event.keyCode ) {
7139 case keyCode.PAGE_UP:
7140 this._move( "previousPage", event );
7141 break;
7142 case keyCode.PAGE_DOWN:
7143 this._move( "nextPage", event );
7144 break;
7145 case keyCode.UP:
7146 this._keyEvent( "previous", event );
7147 break;
7148 case keyCode.DOWN:
7149 this._keyEvent( "next", event );
7150 break;
7151 }
7152 },
7153 input: function( event ) {
7154 if ( suppressInput ) {
7155 suppressInput = false;
7156 event.preventDefault();
7157 return;
7158 }
7159 this._searchTimeout( event );
7160 },
7161 focus: function() {
7162 this.selectedItem = null;
7163 this.previous = this._value();
7164 },
7165 blur: function( event ) {
7166 if ( this.cancelBlur ) {
7167 delete this.cancelBlur;
7168 return;
7169 }
7170
7171 clearTimeout( this.searching );
7172 this.close( event );
7173 this._change( event );
7174 }
7175 });
7176
7177 this._initSource();
7178 this.menu = $( "<ul>" )
7179 .addClass( "ui-autocomplete ui-front" )
7180 .appendTo( this._appendTo() )
7181 .menu({
7182 // disable ARIA support, the live region takes care of that
7183 role: null
7184 })
7185 .hide()
7186 .menu( "instance" );
7187
7188 this._on( this.menu.element, {
7189 mousedown: function( event ) {
7190 // prevent moving focus out of the text field
7191 event.preventDefault();
7192
7193 // IE doesn't prevent moving focus even with event.preventDefault()
7194 // so we set a flag to know when we should ignore the blur event
7195 this.cancelBlur = true;
7196 this._delay(function() {
7197 delete this.cancelBlur;
7198 });
7199
7200 // clicking on the scrollbar causes focus to shift to the body
7201 // but we can't detect a mouseup or a click immediately afterward
7202 // so we have to track the next mousedown and close the menu if
7203 // the user clicks somewhere outside of the autocomplete
7204 var menuElement = this.menu.element[ 0 ];
7205 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
7206 this._delay(function() {
7207 var that = this;
7208 this.document.one( "mousedown", function( event ) {
7209 if ( event.target !== that.element[ 0 ] &&
7210 event.target !== menuElement &&
7211 !$.contains( menuElement, event.target ) ) {
7212 that.close();
7213 }
7214 });
7215 });
7216 }
7217 },
7218 menufocus: function( event, ui ) {
7219 var label, item;
7220 // support: Firefox
7221 // Prevent accidental activation of menu items in Firefox (#7024 #9118)
7222 if ( this.isNewMenu ) {
7223 this.isNewMenu = false;
7224 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
7225 this.menu.blur();
7226
7227 this.document.one( "mousemove", function() {
7228 $( event.target ).trigger( event.originalEvent );
7229 });
7230
7231 return;
7232 }
7233 }
7234
7235 item = ui.item.data( "ui-autocomplete-item" );
7236 if ( false !== this._trigger( "focus", event, { item: item } ) ) {
7237 // use value to match what will end up in the input, if it was a key event
7238 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
7239 this._value( item.value );
7240 }
7241 }
7242
7243 // Announce the value in the liveRegion
7244 label = ui.item.attr( "aria-label" ) || item.value;
7245 if ( label && $.trim( label ).length ) {
7246 this.liveRegion.children().hide();
7247 $( "<div>" ).text( label ).appendTo( this.liveRegion );
7248 }
7249 },
7250 menuselect: function( event, ui ) {
7251 var item = ui.item.data( "ui-autocomplete-item" ),
7252 previous = this.previous;
7253
7254 // only trigger when focus was lost (click on menu)
7255 if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
7256 this.element.focus();
7257 this.previous = previous;
7258 // #6109 - IE triggers two focus events and the second
7259 // is asynchronous, so we need to reset the previous
7260 // term synchronously and asynchronously :-(
7261 this._delay(function() {
7262 this.previous = previous;
7263 this.selectedItem = item;
7264 });
7265 }
7266
7267 if ( false !== this._trigger( "select", event, { item: item } ) ) {
7268 this._value( item.value );
7269 }
7270 // reset the term after the select event
7271 // this allows custom select handling to work properly
7272 this.term = this._value();
7273
7274 this.close( event );
7275 this.selectedItem = item;
7276 }
7277 });
7278
7279 this.liveRegion = $( "<span>", {
7280 role: "status",
7281 "aria-live": "assertive",
7282 "aria-relevant": "additions"
7283 })
7284 .addClass( "ui-helper-hidden-accessible" )
7285 .appendTo( this.document[ 0 ].body );
7286
7287 // turning off autocomplete prevents the browser from remembering the
7288 // value when navigating through history, so we re-enable autocomplete
7289 // if the page is unloaded before the widget is destroyed. #7790
7290 this._on( this.window, {
7291 beforeunload: function() {
7292 this.element.removeAttr( "autocomplete" );
7293 }
7294 });
7295 },
7296
7297 _destroy: function() {
7298 clearTimeout( this.searching );
7299 this.element
7300 .removeClass( "ui-autocomplete-input" )
7301 .removeAttr( "autocomplete" );
7302 this.menu.element.remove();
7303 this.liveRegion.remove();
7304 },
7305
7306 _setOption: function( key, value ) {
7307 this._super( key, value );
7308 if ( key === "source" ) {
7309 this._initSource();
7310 }
7311 if ( key === "appendTo" ) {
7312 this.menu.element.appendTo( this._appendTo() );
7313 }
7314 if ( key === "disabled" && value && this.xhr ) {
7315 this.xhr.abort();
7316 }
7317 },
7318
7319 _appendTo: function() {
7320 var element = this.options.appendTo;
7321
7322 if ( element ) {
7323 element = element.jquery || element.nodeType ?
7324 $( element ) :
7325 this.document.find( element ).eq( 0 );
7326 }
7327
7328 if ( !element || !element[ 0 ] ) {
7329 element = this.element.closest( ".ui-front" );
7330 }
7331
7332 if ( !element.length ) {
7333 element = this.document[ 0 ].body;
7334 }
7335
7336 return element;
7337 },
7338
7339 _initSource: function() {
7340 var array, url,
7341 that = this;
7342 if ( $.isArray( this.options.source ) ) {
7343 array = this.options.source;
7344 this.source = function( request, response ) {
7345 response( $.ui.autocomplete.filter( array, request.term ) );
7346 };
7347 } else if ( typeof this.options.source === "string" ) {
7348 url = this.options.source;
7349 this.source = function( request, response ) {
7350 if ( that.xhr ) {
7351 that.xhr.abort();
7352 }
7353 that.xhr = $.ajax({
7354 url: url,
7355 data: request,
7356 dataType: "json",
7357 success: function( data ) {
7358 response( data );
7359 },
7360 error: function() {
7361 response([]);
7362 }
7363 });
7364 };
7365 } else {
7366 this.source = this.options.source;
7367 }
7368 },
7369
7370 _searchTimeout: function( event ) {
7371 clearTimeout( this.searching );
7372 this.searching = this._delay(function() {
7373
7374 // Search if the value has changed, or if the user retypes the same value (see #7434)
7375 var equalValues = this.term === this._value(),
7376 menuVisible = this.menu.element.is( ":visible" ),
7377 modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
7378
7379 if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
7380 this.selectedItem = null;
7381 this.search( null, event );
7382 }
7383 }, this.options.delay );
7384 },
7385
7386 search: function( value, event ) {
7387 value = value != null ? value : this._value();
7388
7389 // always save the actual value, not the one passed as an argument
7390 this.term = this._value();
7391
7392 if ( value.length < this.options.minLength ) {
7393 return this.close( event );
7394 }
7395
7396 if ( this._trigger( "search", event ) === false ) {
7397 return;
7398 }
7399
7400 return this._search( value );
7401 },
7402
7403 _search: function( value ) {
7404 this.pending++;
7405 this.element.addClass( "ui-autocomplete-loading" );
7406 this.cancelSearch = false;
7407
7408 this.source( { term: value }, this._response() );
7409 },
7410
7411 _response: function() {
7412 var index = ++this.requestIndex;
7413
7414 return $.proxy(function( content ) {
7415 if ( index === this.requestIndex ) {
7416 this.__response( content );
7417 }
7418
7419 this.pending--;
7420 if ( !this.pending ) {
7421 this.element.removeClass( "ui-autocomplete-loading" );
7422 }
7423 }, this );
7424 },
7425
7426 __response: function( content ) {
7427 if ( content ) {
7428 content = this._normalize( content );
7429 }
7430 this._trigger( "response", null, { content: content } );
7431 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
7432 this._suggest( content );
7433 this._trigger( "open" );
7434 } else {
7435 // use ._close() instead of .close() so we don't cancel future searches
7436 this._close();
7437 }
7438 },
7439
7440 close: function( event ) {
7441 this.cancelSearch = true;
7442 this._close( event );
7443 },
7444
7445 _close: function( event ) {
7446 if ( this.menu.element.is( ":visible" ) ) {
7447 this.menu.element.hide();
7448 this.menu.blur();
7449 this.isNewMenu = true;
7450 this._trigger( "close", event );
7451 }
7452 },
7453
7454 _change: function( event ) {
7455 if ( this.previous !== this._value() ) {
7456 this._trigger( "change", event, { item: this.selectedItem } );
7457 }
7458 },
7459
7460 _normalize: function( items ) {
7461 // assume all items have the right format when the first item is complete
7462 if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
7463 return items;
7464 }
7465 return $.map( items, function( item ) {
7466 if ( typeof item === "string" ) {
7467 return {
7468 label: item,
7469 value: item
7470 };
7471 }
7472 return $.extend( {}, item, {
7473 label: item.label || item.value,
7474 value: item.value || item.label
7475 });
7476 });
7477 },
7478
7479 _suggest: function( items ) {
7480 var ul = this.menu.element.empty();
7481 this._renderMenu( ul, items );
7482 this.isNewMenu = true;
7483 this.menu.refresh();
7484
7485 // size and position menu
7486 ul.show();
7487 this._resizeMenu();
7488 ul.position( $.extend({
7489 of: this.element
7490 }, this.options.position ) );
7491
7492 if ( this.options.autoFocus ) {
7493 this.menu.next();
7494 }
7495 },
7496
7497 _resizeMenu: function() {
7498 var ul = this.menu.element;
7499 ul.outerWidth( Math.max(
7500 // Firefox wraps long text (possibly a rounding bug)
7501 // so we add 1px to avoid the wrapping (#7513)
7502 ul.width( "" ).outerWidth() + 1,
7503 this.element.outerWidth()
7504 ) );
7505 },
7506
7507 _renderMenu: function( ul, items ) {
7508 var that = this;
7509 $.each( items, function( index, item ) {
7510 that._renderItemData( ul, item );
7511 });
7512 },
7513
7514 _renderItemData: function( ul, item ) {
7515 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
7516 },
7517
7518 _renderItem: function( ul, item ) {
7519 return $( "<li>" ).text( item.label ).appendTo( ul );
7520 },
7521
7522 _move: function( direction, event ) {
7523 if ( !this.menu.element.is( ":visible" ) ) {
7524 this.search( null, event );
7525 return;
7526 }
7527 if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
7528 this.menu.isLastItem() && /^next/.test( direction ) ) {
7529
7530 if ( !this.isMultiLine ) {
7531 this._value( this.term );
7532 }
7533
7534 this.menu.blur();
7535 return;
7536 }
7537 this.menu[ direction ]( event );
7538 },
7539
7540 widget: function() {
7541 return this.menu.element;
7542 },
7543
7544 _value: function() {
7545 return this.valueMethod.apply( this.element, arguments );
7546 },
7547
7548 _keyEvent: function( keyEvent, event ) {
7549 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
7550 this._move( keyEvent, event );
7551
7552 // prevents moving cursor to beginning/end of the text field in some browsers
7553 event.preventDefault();
7554 }
7555 }
7556});
7557
7558$.extend( $.ui.autocomplete, {
7559 escapeRegex: function( value ) {
7560 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
7561 },
7562 filter: function( array, term ) {
7563 var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
7564 return $.grep( array, function( value ) {
7565 return matcher.test( value.label || value.value || value );
7566 });
7567 }
7568});
7569
7570// live region extension, adding a `messages` option
7571// NOTE: This is an experimental API. We are still investigating
7572// a full solution for string manipulation and internationalization.
7573$.widget( "ui.autocomplete", $.ui.autocomplete, {
7574 options: {
7575 messages: {
7576 noResults: "No search results.",
7577 results: function( amount ) {
7578 return amount + ( amount > 1 ? " results are" : " result is" ) +
7579 " available, use up and down arrow keys to navigate.";
7580 }
7581 }
7582 },
7583
7584 __response: function( content ) {
7585 var message;
7586 this._superApply( arguments );
7587 if ( this.options.disabled || this.cancelSearch ) {
7588 return;
7589 }
7590 if ( content && content.length ) {
7591 message = this.options.messages.results( content.length );
7592 } else {
7593 message = this.options.messages.noResults;
7594 }
7595 this.liveRegion.children().hide();
7596 $( "<div>" ).text( message ).appendTo( this.liveRegion );
7597 }
7598});
7599
7600var autocomplete = $.ui.autocomplete;
7601
7602
7603/*!
7604 * jQuery UI Button 1.11.3
7605 * http://jqueryui.com
7606 *
7607 * Copyright jQuery Foundation and other contributors
7608 * Released under the MIT license.
7609 * http://jquery.org/license
7610 *
7611 * http://api.jqueryui.com/button/
7612 */
7613
7614
7615var lastActive,
7616 baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
7617 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",
7618 formResetHandler = function() {
7619 var form = $( this );
7620 setTimeout(function() {
7621 form.find( ":ui-button" ).button( "refresh" );
7622 }, 1 );
7623 },
7624 radioGroup = function( radio ) {
7625 var name = radio.name,
7626 form = radio.form,
7627 radios = $( [] );
7628 if ( name ) {
7629 name = name.replace( /'/g, "\\'" );
7630 if ( form ) {
7631 radios = $( form ).find( "[name='" + name + "'][type=radio]" );
7632 } else {
7633 radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument )
7634 .filter(function() {
7635 return !this.form;
7636 });
7637 }
7638 }
7639 return radios;
7640 };
7641
7642$.widget( "ui.button", {
7643 version: "1.11.3",
7644 defaultElement: "<button>",
7645 options: {
7646 disabled: null,
7647 text: true,
7648 label: null,
7649 icons: {
7650 primary: null,
7651 secondary: null
7652 }
7653 },
7654 _create: function() {
7655 this.element.closest( "form" )
7656 .unbind( "reset" + this.eventNamespace )
7657 .bind( "reset" + this.eventNamespace, formResetHandler );
7658
7659 if ( typeof this.options.disabled !== "boolean" ) {
7660 this.options.disabled = !!this.element.prop( "disabled" );
7661 } else {
7662 this.element.prop( "disabled", this.options.disabled );
7663 }
7664
7665 this._determineButtonType();
7666 this.hasTitle = !!this.buttonElement.attr( "title" );
7667
7668 var that = this,
7669 options = this.options,
7670 toggleButton = this.type === "checkbox" || this.type === "radio",
7671 activeClass = !toggleButton ? "ui-state-active" : "";
7672
7673 if ( options.label === null ) {
7674 options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
7675 }
7676
7677 this._hoverable( this.buttonElement );
7678
7679 this.buttonElement
7680 .addClass( baseClasses )
7681 .attr( "role", "button" )
7682 .bind( "mouseenter" + this.eventNamespace, function() {
7683 if ( options.disabled ) {
7684 return;
7685 }
7686 if ( this === lastActive ) {
7687 $( this ).addClass( "ui-state-active" );
7688 }
7689 })
7690 .bind( "mouseleave" + this.eventNamespace, function() {
7691 if ( options.disabled ) {
7692 return;
7693 }
7694 $( this ).removeClass( activeClass );
7695 })
7696 .bind( "click" + this.eventNamespace, function( event ) {
7697 if ( options.disabled ) {
7698 event.preventDefault();
7699 event.stopImmediatePropagation();
7700 }
7701 });
7702
7703 // Can't use _focusable() because the element that receives focus
7704 // and the element that gets the ui-state-focus class are different
7705 this._on({
7706 focus: function() {
7707 this.buttonElement.addClass( "ui-state-focus" );
7708 },
7709 blur: function() {
7710 this.buttonElement.removeClass( "ui-state-focus" );
7711 }
7712 });
7713
7714 if ( toggleButton ) {
7715 this.element.bind( "change" + this.eventNamespace, function() {
7716 that.refresh();
7717 });
7718 }
7719
7720 if ( this.type === "checkbox" ) {
7721 this.buttonElement.bind( "click" + this.eventNamespace, function() {
7722 if ( options.disabled ) {
7723 return false;
7724 }
7725 });
7726 } else if ( this.type === "radio" ) {
7727 this.buttonElement.bind( "click" + this.eventNamespace, function() {
7728 if ( options.disabled ) {
7729 return false;
7730 }
7731 $( this ).addClass( "ui-state-active" );
7732 that.buttonElement.attr( "aria-pressed", "true" );
7733
7734 var radio = that.element[ 0 ];
7735 radioGroup( radio )
7736 .not( radio )
7737 .map(function() {
7738 return $( this ).button( "widget" )[ 0 ];
7739 })
7740 .removeClass( "ui-state-active" )
7741 .attr( "aria-pressed", "false" );
7742 });
7743 } else {
7744 this.buttonElement
7745 .bind( "mousedown" + this.eventNamespace, function() {
7746 if ( options.disabled ) {
7747 return false;
7748 }
7749 $( this ).addClass( "ui-state-active" );
7750 lastActive = this;
7751 that.document.one( "mouseup", function() {
7752 lastActive = null;
7753 });
7754 })
7755 .bind( "mouseup" + this.eventNamespace, function() {
7756 if ( options.disabled ) {
7757 return false;
7758 }
7759 $( this ).removeClass( "ui-state-active" );
7760 })
7761 .bind( "keydown" + this.eventNamespace, function(event) {
7762 if ( options.disabled ) {
7763 return false;
7764 }
7765 if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
7766 $( this ).addClass( "ui-state-active" );
7767 }
7768 })
7769 // see #8559, we bind to blur here in case the button element loses
7770 // focus between keydown and keyup, it would be left in an "active" state
7771 .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
7772 $( this ).removeClass( "ui-state-active" );
7773 });
7774
7775 if ( this.buttonElement.is("a") ) {
7776 this.buttonElement.keyup(function(event) {
7777 if ( event.keyCode === $.ui.keyCode.SPACE ) {
7778 // TODO pass through original event correctly (just as 2nd argument doesn't work)
7779 $( this ).click();
7780 }
7781 });
7782 }
7783 }
7784
7785 this._setOption( "disabled", options.disabled );
7786 this._resetButton();
7787 },
7788
7789 _determineButtonType: function() {
7790 var ancestor, labelSelector, checked;
7791
7792 if ( this.element.is("[type=checkbox]") ) {
7793 this.type = "checkbox";
7794 } else if ( this.element.is("[type=radio]") ) {
7795 this.type = "radio";
7796 } else if ( this.element.is("input") ) {
7797 this.type = "input";
7798 } else {
7799 this.type = "button";
7800 }
7801
7802 if ( this.type === "checkbox" || this.type === "radio" ) {
7803 // we don't search against the document in case the element
7804 // is disconnected from the DOM
7805 ancestor = this.element.parents().last();
7806 labelSelector = "label[for='" + this.element.attr("id") + "']";
7807 this.buttonElement = ancestor.find( labelSelector );
7808 if ( !this.buttonElement.length ) {
7809 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
7810 this.buttonElement = ancestor.filter( labelSelector );
7811 if ( !this.buttonElement.length ) {
7812 this.buttonElement = ancestor.find( labelSelector );
7813 }
7814 }
7815 this.element.addClass( "ui-helper-hidden-accessible" );
7816
7817 checked = this.element.is( ":checked" );
7818 if ( checked ) {
7819 this.buttonElement.addClass( "ui-state-active" );
7820 }
7821 this.buttonElement.prop( "aria-pressed", checked );
7822 } else {
7823 this.buttonElement = this.element;
7824 }
7825 },
7826
7827 widget: function() {
7828 return this.buttonElement;
7829 },
7830
7831 _destroy: function() {
7832 this.element
7833 .removeClass( "ui-helper-hidden-accessible" );
7834 this.buttonElement
7835 .removeClass( baseClasses + " ui-state-active " + typeClasses )
7836 .removeAttr( "role" )
7837 .removeAttr( "aria-pressed" )
7838 .html( this.buttonElement.find(".ui-button-text").html() );
7839
7840 if ( !this.hasTitle ) {
7841 this.buttonElement.removeAttr( "title" );
7842 }
7843 },
7844
7845 _setOption: function( key, value ) {
7846 this._super( key, value );
7847 if ( key === "disabled" ) {
7848 this.widget().toggleClass( "ui-state-disabled", !!value );
7849 this.element.prop( "disabled", !!value );
7850 if ( value ) {
7851 if ( this.type === "checkbox" || this.type === "radio" ) {
7852 this.buttonElement.removeClass( "ui-state-focus" );
7853 } else {
7854 this.buttonElement.removeClass( "ui-state-focus ui-state-active" );
7855 }
7856 }
7857 return;
7858 }
7859 this._resetButton();
7860 },
7861
7862 refresh: function() {
7863 //See #8237 & #8828
7864 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
7865
7866 if ( isDisabled !== this.options.disabled ) {
7867 this._setOption( "disabled", isDisabled );
7868 }
7869 if ( this.type === "radio" ) {
7870 radioGroup( this.element[0] ).each(function() {
7871 if ( $( this ).is( ":checked" ) ) {
7872 $( this ).button( "widget" )
7873 .addClass( "ui-state-active" )
7874 .attr( "aria-pressed", "true" );
7875 } else {
7876 $( this ).button( "widget" )
7877 .removeClass( "ui-state-active" )
7878 .attr( "aria-pressed", "false" );
7879 }
7880 });
7881 } else if ( this.type === "checkbox" ) {
7882 if ( this.element.is( ":checked" ) ) {
7883 this.buttonElement
7884 .addClass( "ui-state-active" )
7885 .attr( "aria-pressed", "true" );
7886 } else {
7887 this.buttonElement
7888 .removeClass( "ui-state-active" )
7889 .attr( "aria-pressed", "false" );
7890 }
7891 }
7892 },
7893
7894 _resetButton: function() {
7895 if ( this.type === "input" ) {
7896 if ( this.options.label ) {
7897 this.element.val( this.options.label );
7898 }
7899 return;
7900 }
7901 var buttonElement = this.buttonElement.removeClass( typeClasses ),
7902 buttonText = $( "<span></span>", this.document[0] )
7903 .addClass( "ui-button-text" )
7904 .html( this.options.label )
7905 .appendTo( buttonElement.empty() )
7906 .text(),
7907 icons = this.options.icons,
7908 multipleIcons = icons.primary && icons.secondary,
7909 buttonClasses = [];
7910
7911 if ( icons.primary || icons.secondary ) {
7912 if ( this.options.text ) {
7913 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
7914 }
7915
7916 if ( icons.primary ) {
7917 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
7918 }
7919
7920 if ( icons.secondary ) {
7921 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
7922 }
7923
7924 if ( !this.options.text ) {
7925 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
7926
7927 if ( !this.hasTitle ) {
7928 buttonElement.attr( "title", $.trim( buttonText ) );
7929 }
7930 }
7931 } else {
7932 buttonClasses.push( "ui-button-text-only" );
7933 }
7934 buttonElement.addClass( buttonClasses.join( " " ) );
7935 }
7936});
7937
7938$.widget( "ui.buttonset", {
7939 version: "1.11.3",
7940 options: {
7941 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
7942 },
7943
7944 _create: function() {
7945 this.element.addClass( "ui-buttonset" );
7946 },
7947
7948 _init: function() {
7949 this.refresh();
7950 },
7951
7952 _setOption: function( key, value ) {
7953 if ( key === "disabled" ) {
7954 this.buttons.button( "option", key, value );
7955 }
7956
7957 this._super( key, value );
7958 },
7959
7960 refresh: function() {
7961 var rtl = this.element.css( "direction" ) === "rtl",
7962 allButtons = this.element.find( this.options.items ),
7963 existingButtons = allButtons.filter( ":ui-button" );
7964
7965 // Initialize new buttons
7966 allButtons.not( ":ui-button" ).button();
7967
7968 // Refresh existing buttons
7969 existingButtons.button( "refresh" );
7970
7971 this.buttons = allButtons
7972 .map(function() {
7973 return $( this ).button( "widget" )[ 0 ];
7974 })
7975 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
7976 .filter( ":first" )
7977 .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
7978 .end()
7979 .filter( ":last" )
7980 .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
7981 .end()
7982 .end();
7983 },
7984
7985 _destroy: function() {
7986 this.element.removeClass( "ui-buttonset" );
7987 this.buttons
7988 .map(function() {
7989 return $( this ).button( "widget" )[ 0 ];
7990 })
7991 .removeClass( "ui-corner-left ui-corner-right" )
7992 .end()
7993 .button( "destroy" );
7994 }
7995});
7996
7997var button = $.ui.button;
7998
7999
8000/*!
8001 * jQuery UI Datepicker 1.11.3
8002 * http://jqueryui.com
8003 *
8004 * Copyright jQuery Foundation and other contributors
8005 * Released under the MIT license.
8006 * http://jquery.org/license
8007 *
8008 * http://api.jqueryui.com/datepicker/
8009 */
8010
8011
8012$.extend($.ui, { datepicker: { version: "1.11.3" } });
8013
8014var datepicker_instActive;
8015
8016function datepicker_getZindex( elem ) {
8017 var position, value;
8018 while ( elem.length && elem[ 0 ] !== document ) {
8019 // Ignore z-index if position is set to a value where z-index is ignored by the browser
8020 // This makes behavior of this function consistent across browsers
8021 // WebKit always returns auto if the element is positioned
8022 position = elem.css( "position" );
8023 if ( position === "absolute" || position === "relative" || position === "fixed" ) {
8024 // IE returns 0 when zIndex is not specified
8025 // other browsers return a string
8026 // we ignore the case of nested elements with an explicit value of 0
8027 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
8028 value = parseInt( elem.css( "zIndex" ), 10 );
8029 if ( !isNaN( value ) && value !== 0 ) {
8030 return value;
8031 }
8032 }
8033 elem = elem.parent();
8034 }
8035
8036 return 0;
8037}
8038/* Date picker manager.
8039 Use the singleton instance of this class, $.datepicker, to interact with the date picker.
8040 Settings for (groups of) date pickers are maintained in an instance object,
8041 allowing multiple different settings on the same page. */
8042
8043function Datepicker() {
8044 this._curInst = null; // The current instance in use
8045 this._keyEvent = false; // If the last event was a key event
8046 this._disabledInputs = []; // List of date picker inputs that have been disabled
8047 this._datepickerShowing = false; // True if the popup picker is showing , false if not
8048 this._inDialog = false; // True if showing within a "dialog", false if not
8049 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
8050 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
8051 this._appendClass = "ui-datepicker-append"; // The name of the append marker class
8052 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
8053 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
8054 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
8055 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
8056 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
8057 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
8058 this.regional = []; // Available regional settings, indexed by language code
8059 this.regional[""] = { // Default regional settings
8060 closeText: "Done", // Display text for close link
8061 prevText: "Prev", // Display text for previous month link
8062 nextText: "Next", // Display text for next month link
8063 currentText: "Today", // Display text for current month link
8064 monthNames: ["January","February","March","April","May","June",
8065 "July","August","September","October","November","December"], // Names of months for drop-down and formatting
8066 monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
8067 dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
8068 dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
8069 dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
8070 weekHeader: "Wk", // Column header for week of the year
8071 dateFormat: "mm/dd/yy", // See format options on parseDate
8072 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
8073 isRTL: false, // True if right-to-left language, false if left-to-right
8074 showMonthAfterYear: false, // True if the year select precedes month, false for month then year
8075 yearSuffix: "" // Additional text to append to the year in the month headers
8076 };
8077 this._defaults = { // Global defaults for all the date picker instances
8078 showOn: "focus", // "focus" for popup on focus,
8079 // "button" for trigger button, or "both" for either
8080 showAnim: "fadeIn", // Name of jQuery animation for popup
8081 showOptions: {}, // Options for enhanced animations
8082 defaultDate: null, // Used when field is blank: actual date,
8083 // +/-number for offset from today, null for today
8084 appendText: "", // Display text following the input box, e.g. showing the format
8085 buttonText: "...", // Text for trigger button
8086 buttonImage: "", // URL for trigger button image
8087 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
8088 hideIfNoPrevNext: false, // True to hide next/previous month links
8089 // if not applicable, false to just disable them
8090 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
8091 gotoCurrent: false, // True if today link goes back to current selection instead
8092 changeMonth: false, // True if month can be selected directly, false if only prev/next
8093 changeYear: false, // True if year can be selected directly, false if only prev/next
8094 yearRange: "c-10:c+10", // Range of years to display in drop-down,
8095 // either relative to today's year (-nn:+nn), relative to currently displayed year
8096 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
8097 showOtherMonths: false, // True to show dates in other months, false to leave blank
8098 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
8099 showWeek: false, // True to show week of the year, false to not show it
8100 calculateWeek: this.iso8601Week, // How to calculate the week of the year,
8101 // takes a Date and returns the number of the week for it
8102 shortYearCutoff: "+10", // Short year values < this are in the current century,
8103 // > this are in the previous century,
8104 // string value starting with "+" for current year + value
8105 minDate: null, // The earliest selectable date, or null for no limit
8106 maxDate: null, // The latest selectable date, or null for no limit
8107 duration: "fast", // Duration of display/closure
8108 beforeShowDay: null, // Function that takes a date and returns an array with
8109 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
8110 // [2] = cell title (optional), e.g. $.datepicker.noWeekends
8111 beforeShow: null, // Function that takes an input field and
8112 // returns a set of custom settings for the date picker
8113 onSelect: null, // Define a callback function when a date is selected
8114 onChangeMonthYear: null, // Define a callback function when the month or year is changed
8115 onClose: null, // Define a callback function when the datepicker is closed
8116 numberOfMonths: 1, // Number of months to show at a time
8117 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
8118 stepMonths: 1, // Number of months to step back/forward
8119 stepBigMonths: 12, // Number of months to step back/forward for the big links
8120 altField: "", // Selector for an alternate field to store selected dates into
8121 altFormat: "", // The date format to use for the alternate field
8122 constrainInput: true, // The input is constrained by the current date format
8123 showButtonPanel: false, // True to show button panel, false to not show it
8124 autoSize: false, // True to size the input for the date format, false to leave as is
8125 disabled: false // The initial disabled state
8126 };
8127 $.extend(this._defaults, this.regional[""]);
8128 this.regional.en = $.extend( true, {}, this.regional[ "" ]);
8129 this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
8130 this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
8131}
8132
8133$.extend(Datepicker.prototype, {
8134 /* Class name added to elements to indicate already configured with a date picker. */
8135 markerClassName: "hasDatepicker",
8136
8137 //Keep track of the maximum number of rows displayed (see #7043)
8138 maxRows: 4,
8139
8140 // TODO rename to "widget" when switching to widget factory
8141 _widgetDatepicker: function() {
8142 return this.dpDiv;
8143 },
8144
8145 /* Override the default settings for all instances of the date picker.
8146 * @param settings object - the new settings to use as defaults (anonymous object)
8147 * @return the manager object
8148 */
8149 setDefaults: function(settings) {
8150 datepicker_extendRemove(this._defaults, settings || {});
8151 return this;
8152 },
8153
8154 /* Attach the date picker to a jQuery selection.
8155 * @param target element - the target input field or division or span
8156 * @param settings object - the new settings to use for this date picker instance (anonymous)
8157 */
8158 _attachDatepicker: function(target, settings) {
8159 var nodeName, inline, inst;
8160 nodeName = target.nodeName.toLowerCase();
8161 inline = (nodeName === "div" || nodeName === "span");
8162 if (!target.id) {
8163 this.uuid += 1;
8164 target.id = "dp" + this.uuid;
8165 }
8166 inst = this._newInst($(target), inline);
8167 inst.settings = $.extend({}, settings || {});
8168 if (nodeName === "input") {
8169 this._connectDatepicker(target, inst);
8170 } else if (inline) {
8171 this._inlineDatepicker(target, inst);
8172 }
8173 },
8174
8175 /* Create a new instance object. */
8176 _newInst: function(target, inline) {
8177 var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
8178 return {id: id, input: target, // associated target
8179 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
8180 drawMonth: 0, drawYear: 0, // month being drawn
8181 inline: inline, // is datepicker inline or not
8182 dpDiv: (!inline ? this.dpDiv : // presentation div
8183 datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
8184 },
8185
8186 /* Attach the date picker to an input field. */
8187 _connectDatepicker: function(target, inst) {
8188 var input = $(target);
8189 inst.append = $([]);
8190 inst.trigger = $([]);
8191 if (input.hasClass(this.markerClassName)) {
8192 return;
8193 }
8194 this._attachments(input, inst);
8195 input.addClass(this.markerClassName).keydown(this._doKeyDown).
8196 keypress(this._doKeyPress).keyup(this._doKeyUp);
8197 this._autoSize(inst);
8198 $.data(target, "datepicker", inst);
8199 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
8200 if( inst.settings.disabled ) {
8201 this._disableDatepicker( target );
8202 }
8203 },
8204
8205 /* Make attachments based on settings. */
8206 _attachments: function(input, inst) {
8207 var showOn, buttonText, buttonImage,
8208 appendText = this._get(inst, "appendText"),
8209 isRTL = this._get(inst, "isRTL");
8210
8211 if (inst.append) {
8212 inst.append.remove();
8213 }
8214 if (appendText) {
8215 inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
8216 input[isRTL ? "before" : "after"](inst.append);
8217 }
8218
8219 input.unbind("focus", this._showDatepicker);
8220
8221 if (inst.trigger) {
8222 inst.trigger.remove();
8223 }
8224
8225 showOn = this._get(inst, "showOn");
8226 if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
8227 input.focus(this._showDatepicker);
8228 }
8229 if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
8230 buttonText = this._get(inst, "buttonText");
8231 buttonImage = this._get(inst, "buttonImage");
8232 inst.trigger = $(this._get(inst, "buttonImageOnly") ?
8233 $("<img/>").addClass(this._triggerClass).
8234 attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
8235 $("<button type='button'></button>").addClass(this._triggerClass).
8236 html(!buttonImage ? buttonText : $("<img/>").attr(
8237 { src:buttonImage, alt:buttonText, title:buttonText })));
8238 input[isRTL ? "before" : "after"](inst.trigger);
8239 inst.trigger.click(function() {
8240 if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
8241 $.datepicker._hideDatepicker();
8242 } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
8243 $.datepicker._hideDatepicker();
8244 $.datepicker._showDatepicker(input[0]);
8245 } else {
8246 $.datepicker._showDatepicker(input[0]);
8247 }
8248 return false;
8249 });
8250 }
8251 },
8252
8253 /* Apply the maximum length for the date format. */
8254 _autoSize: function(inst) {
8255 if (this._get(inst, "autoSize") && !inst.inline) {
8256 var findMax, max, maxI, i,
8257 date = new Date(2009, 12 - 1, 20), // Ensure double digits
8258 dateFormat = this._get(inst, "dateFormat");
8259
8260 if (dateFormat.match(/[DM]/)) {
8261 findMax = function(names) {
8262 max = 0;
8263 maxI = 0;
8264 for (i = 0; i < names.length; i++) {
8265 if (names[i].length > max) {
8266 max = names[i].length;
8267 maxI = i;
8268 }
8269 }
8270 return maxI;
8271 };
8272 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
8273 "monthNames" : "monthNamesShort"))));
8274 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
8275 "dayNames" : "dayNamesShort"))) + 20 - date.getDay());
8276 }
8277 inst.input.attr("size", this._formatDate(inst, date).length);
8278 }
8279 },
8280
8281 /* Attach an inline date picker to a div. */
8282 _inlineDatepicker: function(target, inst) {
8283 var divSpan = $(target);
8284 if (divSpan.hasClass(this.markerClassName)) {
8285 return;
8286 }
8287 divSpan.addClass(this.markerClassName).append(inst.dpDiv);
8288 $.data(target, "datepicker", inst);
8289 this._setDate(inst, this._getDefaultDate(inst), true);
8290 this._updateDatepicker(inst);
8291 this._updateAlternate(inst);
8292 //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
8293 if( inst.settings.disabled ) {
8294 this._disableDatepicker( target );
8295 }
8296 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
8297 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
8298 inst.dpDiv.css( "display", "block" );
8299 },
8300
8301 /* Pop-up the date picker in a "dialog" box.
8302 * @param input element - ignored
8303 * @param date string or Date - the initial date to display
8304 * @param onSelect function - the function to call when a date is selected
8305 * @param settings object - update the dialog date picker instance's settings (anonymous object)
8306 * @param pos int[2] - coordinates for the dialog's position within the screen or
8307 * event - with x/y coordinates or
8308 * leave empty for default (screen centre)
8309 * @return the manager object
8310 */
8311 _dialogDatepicker: function(input, date, onSelect, settings, pos) {
8312 var id, browserWidth, browserHeight, scrollX, scrollY,
8313 inst = this._dialogInst; // internal instance
8314
8315 if (!inst) {
8316 this.uuid += 1;
8317 id = "dp" + this.uuid;
8318 this._dialogInput = $("<input type='text' id='" + id +
8319 "' style='position: absolute; top: -100px; width: 0px;'/>");
8320 this._dialogInput.keydown(this._doKeyDown);
8321 $("body").append(this._dialogInput);
8322 inst = this._dialogInst = this._newInst(this._dialogInput, false);
8323 inst.settings = {};
8324 $.data(this._dialogInput[0], "datepicker", inst);
8325 }
8326 datepicker_extendRemove(inst.settings, settings || {});
8327 date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
8328 this._dialogInput.val(date);
8329
8330 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
8331 if (!this._pos) {
8332 browserWidth = document.documentElement.clientWidth;
8333 browserHeight = document.documentElement.clientHeight;
8334 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
8335 scrollY = document.documentElement.scrollTop || document.body.scrollTop;
8336 this._pos = // should use actual width/height below
8337 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
8338 }
8339
8340 // move input on screen for focus, but hidden behind dialog
8341 this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
8342 inst.settings.onSelect = onSelect;
8343 this._inDialog = true;
8344 this.dpDiv.addClass(this._dialogClass);
8345 this._showDatepicker(this._dialogInput[0]);
8346 if ($.blockUI) {
8347 $.blockUI(this.dpDiv);
8348 }
8349 $.data(this._dialogInput[0], "datepicker", inst);
8350 return this;
8351 },
8352
8353 /* Detach a datepicker from its control.
8354 * @param target element - the target input field or division or span
8355 */
8356 _destroyDatepicker: function(target) {
8357 var nodeName,
8358 $target = $(target),
8359 inst = $.data(target, "datepicker");
8360
8361 if (!$target.hasClass(this.markerClassName)) {
8362 return;
8363 }
8364
8365 nodeName = target.nodeName.toLowerCase();
8366 $.removeData(target, "datepicker");
8367 if (nodeName === "input") {
8368 inst.append.remove();
8369 inst.trigger.remove();
8370 $target.removeClass(this.markerClassName).
8371 unbind("focus", this._showDatepicker).
8372 unbind("keydown", this._doKeyDown).
8373 unbind("keypress", this._doKeyPress).
8374 unbind("keyup", this._doKeyUp);
8375 } else if (nodeName === "div" || nodeName === "span") {
8376 $target.removeClass(this.markerClassName).empty();
8377 }
8378
8379 if ( datepicker_instActive === inst ) {
8380 datepicker_instActive = null;
8381 }
8382 },
8383
8384 /* Enable the date picker to a jQuery selection.
8385 * @param target element - the target input field or division or span
8386 */
8387 _enableDatepicker: function(target) {
8388 var nodeName, inline,
8389 $target = $(target),
8390 inst = $.data(target, "datepicker");
8391
8392 if (!$target.hasClass(this.markerClassName)) {
8393 return;
8394 }
8395
8396 nodeName = target.nodeName.toLowerCase();
8397 if (nodeName === "input") {
8398 target.disabled = false;
8399 inst.trigger.filter("button").
8400 each(function() { this.disabled = false; }).end().
8401 filter("img").css({opacity: "1.0", cursor: ""});
8402 } else if (nodeName === "div" || nodeName === "span") {
8403 inline = $target.children("." + this._inlineClass);
8404 inline.children().removeClass("ui-state-disabled");
8405 inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
8406 prop("disabled", false);
8407 }
8408 this._disabledInputs = $.map(this._disabledInputs,
8409 function(value) { return (value === target ? null : value); }); // delete entry
8410 },
8411
8412 /* Disable the date picker to a jQuery selection.
8413 * @param target element - the target input field or division or span
8414 */
8415 _disableDatepicker: function(target) {
8416 var nodeName, inline,
8417 $target = $(target),
8418 inst = $.data(target, "datepicker");
8419
8420 if (!$target.hasClass(this.markerClassName)) {
8421 return;
8422 }
8423
8424 nodeName = target.nodeName.toLowerCase();
8425 if (nodeName === "input") {
8426 target.disabled = true;
8427 inst.trigger.filter("button").
8428 each(function() { this.disabled = true; }).end().
8429 filter("img").css({opacity: "0.5", cursor: "default"});
8430 } else if (nodeName === "div" || nodeName === "span") {
8431 inline = $target.children("." + this._inlineClass);
8432 inline.children().addClass("ui-state-disabled");
8433 inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
8434 prop("disabled", true);
8435 }
8436 this._disabledInputs = $.map(this._disabledInputs,
8437 function(value) { return (value === target ? null : value); }); // delete entry
8438 this._disabledInputs[this._disabledInputs.length] = target;
8439 },
8440
8441 /* Is the first field in a jQuery collection disabled as a datepicker?
8442 * @param target element - the target input field or division or span
8443 * @return boolean - true if disabled, false if enabled
8444 */
8445 _isDisabledDatepicker: function(target) {
8446 if (!target) {
8447 return false;
8448 }
8449 for (var i = 0; i < this._disabledInputs.length; i++) {
8450 if (this._disabledInputs[i] === target) {
8451 return true;
8452 }
8453 }
8454 return false;
8455 },
8456
8457 /* Retrieve the instance data for the target control.
8458 * @param target element - the target input field or division or span
8459 * @return object - the associated instance data
8460 * @throws error if a jQuery problem getting data
8461 */
8462 _getInst: function(target) {
8463 try {
8464 return $.data(target, "datepicker");
8465 }
8466 catch (err) {
8467 throw "Missing instance data for this datepicker";
8468 }
8469 },
8470
8471 /* Update or retrieve the settings for a date picker attached to an input field or division.
8472 * @param target element - the target input field or division or span
8473 * @param name object - the new settings to update or
8474 * string - the name of the setting to change or retrieve,
8475 * when retrieving also "all" for all instance settings or
8476 * "defaults" for all global defaults
8477 * @param value any - the new value for the setting
8478 * (omit if above is an object or to retrieve a value)
8479 */
8480 _optionDatepicker: function(target, name, value) {
8481 var settings, date, minDate, maxDate,
8482 inst = this._getInst(target);
8483
8484 if (arguments.length === 2 && typeof name === "string") {
8485 return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
8486 (inst ? (name === "all" ? $.extend({}, inst.settings) :
8487 this._get(inst, name)) : null));
8488 }
8489
8490 settings = name || {};
8491 if (typeof name === "string") {
8492 settings = {};
8493 settings[name] = value;
8494 }
8495
8496 if (inst) {
8497 if (this._curInst === inst) {
8498 this._hideDatepicker();
8499 }
8500
8501 date = this._getDateDatepicker(target, true);
8502 minDate = this._getMinMaxDate(inst, "min");
8503 maxDate = this._getMinMaxDate(inst, "max");
8504 datepicker_extendRemove(inst.settings, settings);
8505 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
8506 if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
8507 inst.settings.minDate = this._formatDate(inst, minDate);
8508 }
8509 if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
8510 inst.settings.maxDate = this._formatDate(inst, maxDate);
8511 }
8512 if ( "disabled" in settings ) {
8513 if ( settings.disabled ) {
8514 this._disableDatepicker(target);
8515 } else {
8516 this._enableDatepicker(target);
8517 }
8518 }
8519 this._attachments($(target), inst);
8520 this._autoSize(inst);
8521 this._setDate(inst, date);
8522 this._updateAlternate(inst);
8523 this._updateDatepicker(inst);
8524 }
8525 },
8526
8527 // change method deprecated
8528 _changeDatepicker: function(target, name, value) {
8529 this._optionDatepicker(target, name, value);
8530 },
8531
8532 /* Redraw the date picker attached to an input field or division.
8533 * @param target element - the target input field or division or span
8534 */
8535 _refreshDatepicker: function(target) {
8536 var inst = this._getInst(target);
8537 if (inst) {
8538 this._updateDatepicker(inst);
8539 }
8540 },
8541
8542 /* Set the dates for a jQuery selection.
8543 * @param target element - the target input field or division or span
8544 * @param date Date - the new date
8545 */
8546 _setDateDatepicker: function(target, date) {
8547 var inst = this._getInst(target);
8548 if (inst) {
8549 this._setDate(inst, date);
8550 this._updateDatepicker(inst);
8551 this._updateAlternate(inst);
8552 }
8553 },
8554
8555 /* Get the date(s) for the first entry in a jQuery selection.
8556 * @param target element - the target input field or division or span
8557 * @param noDefault boolean - true if no default date is to be used
8558 * @return Date - the current date
8559 */
8560 _getDateDatepicker: function(target, noDefault) {
8561 var inst = this._getInst(target);
8562 if (inst && !inst.inline) {
8563 this._setDateFromField(inst, noDefault);
8564 }
8565 return (inst ? this._getDate(inst) : null);
8566 },
8567
8568 /* Handle keystrokes. */
8569 _doKeyDown: function(event) {
8570 var onSelect, dateStr, sel,
8571 inst = $.datepicker._getInst(event.target),
8572 handled = true,
8573 isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
8574
8575 inst._keyEvent = true;
8576 if ($.datepicker._datepickerShowing) {
8577 switch (event.keyCode) {
8578 case 9: $.datepicker._hideDatepicker();
8579 handled = false;
8580 break; // hide on tab out
8581 case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
8582 $.datepicker._currentClass + ")", inst.dpDiv);
8583 if (sel[0]) {
8584 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
8585 }
8586
8587 onSelect = $.datepicker._get(inst, "onSelect");
8588 if (onSelect) {
8589 dateStr = $.datepicker._formatDate(inst);
8590
8591 // trigger custom callback
8592 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
8593 } else {
8594 $.datepicker._hideDatepicker();
8595 }
8596
8597 return false; // don't submit the form
8598 case 27: $.datepicker._hideDatepicker();
8599 break; // hide on escape
8600 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8601 -$.datepicker._get(inst, "stepBigMonths") :
8602 -$.datepicker._get(inst, "stepMonths")), "M");
8603 break; // previous month/year on page up/+ ctrl
8604 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8605 +$.datepicker._get(inst, "stepBigMonths") :
8606 +$.datepicker._get(inst, "stepMonths")), "M");
8607 break; // next month/year on page down/+ ctrl
8608 case 35: if (event.ctrlKey || event.metaKey) {
8609 $.datepicker._clearDate(event.target);
8610 }
8611 handled = event.ctrlKey || event.metaKey;
8612 break; // clear on ctrl or command +end
8613 case 36: if (event.ctrlKey || event.metaKey) {
8614 $.datepicker._gotoToday(event.target);
8615 }
8616 handled = event.ctrlKey || event.metaKey;
8617 break; // current on ctrl or command +home
8618 case 37: if (event.ctrlKey || event.metaKey) {
8619 $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
8620 }
8621 handled = event.ctrlKey || event.metaKey;
8622 // -1 day on ctrl or command +left
8623 if (event.originalEvent.altKey) {
8624 $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8625 -$.datepicker._get(inst, "stepBigMonths") :
8626 -$.datepicker._get(inst, "stepMonths")), "M");
8627 }
8628 // next month/year on alt +left on Mac
8629 break;
8630 case 38: if (event.ctrlKey || event.metaKey) {
8631 $.datepicker._adjustDate(event.target, -7, "D");
8632 }
8633 handled = event.ctrlKey || event.metaKey;
8634 break; // -1 week on ctrl or command +up
8635 case 39: if (event.ctrlKey || event.metaKey) {
8636 $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
8637 }
8638 handled = event.ctrlKey || event.metaKey;
8639 // +1 day on ctrl or command +right
8640 if (event.originalEvent.altKey) {
8641 $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8642 +$.datepicker._get(inst, "stepBigMonths") :
8643 +$.datepicker._get(inst, "stepMonths")), "M");
8644 }
8645 // next month/year on alt +right
8646 break;
8647 case 40: if (event.ctrlKey || event.metaKey) {
8648 $.datepicker._adjustDate(event.target, +7, "D");
8649 }
8650 handled = event.ctrlKey || event.metaKey;
8651 break; // +1 week on ctrl or command +down
8652 default: handled = false;
8653 }
8654 } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
8655 $.datepicker._showDatepicker(this);
8656 } else {
8657 handled = false;
8658 }
8659
8660 if (handled) {
8661 event.preventDefault();
8662 event.stopPropagation();
8663 }
8664 },
8665
8666 /* Filter entered characters - based on date format. */
8667 _doKeyPress: function(event) {
8668 var chars, chr,
8669 inst = $.datepicker._getInst(event.target);
8670
8671 if ($.datepicker._get(inst, "constrainInput")) {
8672 chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
8673 chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
8674 return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
8675 }
8676 },
8677
8678 /* Synchronise manual entry and field/alternate field. */
8679 _doKeyUp: function(event) {
8680 var date,
8681 inst = $.datepicker._getInst(event.target);
8682
8683 if (inst.input.val() !== inst.lastVal) {
8684 try {
8685 date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
8686 (inst.input ? inst.input.val() : null),
8687 $.datepicker._getFormatConfig(inst));
8688
8689 if (date) { // only if valid
8690 $.datepicker._setDateFromField(inst);
8691 $.datepicker._updateAlternate(inst);
8692 $.datepicker._updateDatepicker(inst);
8693 }
8694 }
8695 catch (err) {
8696 }
8697 }
8698 return true;
8699 },
8700
8701 /* Pop-up the date picker for a given input field.
8702 * If false returned from beforeShow event handler do not show.
8703 * @param input element - the input field attached to the date picker or
8704 * event - if triggered by focus
8705 */
8706 _showDatepicker: function(input) {
8707 input = input.target || input;
8708 if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
8709 input = $("input", input.parentNode)[0];
8710 }
8711
8712 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
8713 return;
8714 }
8715
8716 var inst, beforeShow, beforeShowSettings, isFixed,
8717 offset, showAnim, duration;
8718
8719 inst = $.datepicker._getInst(input);
8720 if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
8721 $.datepicker._curInst.dpDiv.stop(true, true);
8722 if ( inst && $.datepicker._datepickerShowing ) {
8723 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
8724 }
8725 }
8726
8727 beforeShow = $.datepicker._get(inst, "beforeShow");
8728 beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
8729 if(beforeShowSettings === false){
8730 return;
8731 }
8732 datepicker_extendRemove(inst.settings, beforeShowSettings);
8733
8734 inst.lastVal = null;
8735 $.datepicker._lastInput = input;
8736 $.datepicker._setDateFromField(inst);
8737
8738 if ($.datepicker._inDialog) { // hide cursor
8739 input.value = "";
8740 }
8741 if (!$.datepicker._pos) { // position below input
8742 $.datepicker._pos = $.datepicker._findPos(input);
8743 $.datepicker._pos[1] += input.offsetHeight; // add the height
8744 }
8745
8746 isFixed = false;
8747 $(input).parents().each(function() {
8748 isFixed |= $(this).css("position") === "fixed";
8749 return !isFixed;
8750 });
8751
8752 offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
8753 $.datepicker._pos = null;
8754 //to avoid flashes on Firefox
8755 inst.dpDiv.empty();
8756 // determine sizing offscreen
8757 inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
8758 $.datepicker._updateDatepicker(inst);
8759 // fix width for dynamic number of date pickers
8760 // and adjust position before showing
8761 offset = $.datepicker._checkOffset(inst, offset, isFixed);
8762 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
8763 "static" : (isFixed ? "fixed" : "absolute")), display: "none",
8764 left: offset.left + "px", top: offset.top + "px"});
8765
8766 if (!inst.inline) {
8767 showAnim = $.datepicker._get(inst, "showAnim");
8768 duration = $.datepicker._get(inst, "duration");
8769 inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
8770 $.datepicker._datepickerShowing = true;
8771
8772 if ( $.effects && $.effects.effect[ showAnim ] ) {
8773 inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
8774 } else {
8775 inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
8776 }
8777
8778 if ( $.datepicker._shouldFocusInput( inst ) ) {
8779 inst.input.focus();
8780 }
8781
8782 $.datepicker._curInst = inst;
8783 }
8784 },
8785
8786 /* Generate the date picker content. */
8787 _updateDatepicker: function(inst) {
8788 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
8789 datepicker_instActive = inst; // for delegate hover events
8790 inst.dpDiv.empty().append(this._generateHTML(inst));
8791 this._attachHandlers(inst);
8792
8793 var origyearshtml,
8794 numMonths = this._getNumberOfMonths(inst),
8795 cols = numMonths[1],
8796 width = 17,
8797 activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
8798
8799 if ( activeCell.length > 0 ) {
8800 datepicker_handleMouseover.apply( activeCell.get( 0 ) );
8801 }
8802
8803 inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
8804 if (cols > 1) {
8805 inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
8806 }
8807 inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
8808 "Class"]("ui-datepicker-multi");
8809 inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
8810 "Class"]("ui-datepicker-rtl");
8811
8812 if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
8813 inst.input.focus();
8814 }
8815
8816 // deffered render of the years select (to avoid flashes on Firefox)
8817 if( inst.yearshtml ){
8818 origyearshtml = inst.yearshtml;
8819 setTimeout(function(){
8820 //assure that inst.yearshtml didn't change.
8821 if( origyearshtml === inst.yearshtml && inst.yearshtml ){
8822 inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
8823 }
8824 origyearshtml = inst.yearshtml = null;
8825 }, 0);
8826 }
8827 },
8828
8829 // #6694 - don't focus the input if it's already focused
8830 // this breaks the change event in IE
8831 // Support: IE and jQuery <1.9
8832 _shouldFocusInput: function( inst ) {
8833 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
8834 },
8835
8836 /* Check positioning to remain on screen. */
8837 _checkOffset: function(inst, offset, isFixed) {
8838 var dpWidth = inst.dpDiv.outerWidth(),
8839 dpHeight = inst.dpDiv.outerHeight(),
8840 inputWidth = inst.input ? inst.input.outerWidth() : 0,
8841 inputHeight = inst.input ? inst.input.outerHeight() : 0,
8842 viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
8843 viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
8844
8845 offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
8846 offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
8847 offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
8848
8849 // now check if datepicker is showing outside window viewport - move to a better place if so.
8850 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
8851 Math.abs(offset.left + dpWidth - viewWidth) : 0);
8852 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
8853 Math.abs(dpHeight + inputHeight) : 0);
8854
8855 return offset;
8856 },
8857
8858 /* Find an object's position on the screen. */
8859 _findPos: function(obj) {
8860 var position,
8861 inst = this._getInst(obj),
8862 isRTL = this._get(inst, "isRTL");
8863
8864 while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
8865 obj = obj[isRTL ? "previousSibling" : "nextSibling"];
8866 }
8867
8868 position = $(obj).offset();
8869 return [position.left, position.top];
8870 },
8871
8872 /* Hide the date picker from view.
8873 * @param input element - the input field attached to the date picker
8874 */
8875 _hideDatepicker: function(input) {
8876 var showAnim, duration, postProcess, onClose,
8877 inst = this._curInst;
8878
8879 if (!inst || (input && inst !== $.data(input, "datepicker"))) {
8880 return;
8881 }
8882
8883 if (this._datepickerShowing) {
8884 showAnim = this._get(inst, "showAnim");
8885 duration = this._get(inst, "duration");
8886 postProcess = function() {
8887 $.datepicker._tidyDialog(inst);
8888 };
8889
8890 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
8891 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
8892 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
8893 } else {
8894 inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
8895 (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
8896 }
8897
8898 if (!showAnim) {
8899 postProcess();
8900 }
8901 this._datepickerShowing = false;
8902
8903 onClose = this._get(inst, "onClose");
8904 if (onClose) {
8905 onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
8906 }
8907
8908 this._lastInput = null;
8909 if (this._inDialog) {
8910 this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
8911 if ($.blockUI) {
8912 $.unblockUI();
8913 $("body").append(this.dpDiv);
8914 }
8915 }
8916 this._inDialog = false;
8917 }
8918 },
8919
8920 /* Tidy up after a dialog display. */
8921 _tidyDialog: function(inst) {
8922 inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
8923 },
8924
8925 /* Close date picker if clicked elsewhere. */
8926 _checkExternalClick: function(event) {
8927 if (!$.datepicker._curInst) {
8928 return;
8929 }
8930
8931 var $target = $(event.target),
8932 inst = $.datepicker._getInst($target[0]);
8933
8934 if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
8935 $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
8936 !$target.hasClass($.datepicker.markerClassName) &&
8937 !$target.closest("." + $.datepicker._triggerClass).length &&
8938 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
8939 ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
8940 $.datepicker._hideDatepicker();
8941 }
8942 },
8943
8944 /* Adjust one of the date sub-fields. */
8945 _adjustDate: function(id, offset, period) {
8946 var target = $(id),
8947 inst = this._getInst(target[0]);
8948
8949 if (this._isDisabledDatepicker(target[0])) {
8950 return;
8951 }
8952 this._adjustInstDate(inst, offset +
8953 (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
8954 period);
8955 this._updateDatepicker(inst);
8956 },
8957
8958 /* Action for current link. */
8959 _gotoToday: function(id) {
8960 var date,
8961 target = $(id),
8962 inst = this._getInst(target[0]);
8963
8964 if (this._get(inst, "gotoCurrent") && inst.currentDay) {
8965 inst.selectedDay = inst.currentDay;
8966 inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8967 inst.drawYear = inst.selectedYear = inst.currentYear;
8968 } else {
8969 date = new Date();
8970 inst.selectedDay = date.getDate();
8971 inst.drawMonth = inst.selectedMonth = date.getMonth();
8972 inst.drawYear = inst.selectedYear = date.getFullYear();
8973 }
8974 this._notifyChange(inst);
8975 this._adjustDate(target);
8976 },
8977
8978 /* Action for selecting a new month/year. */
8979 _selectMonthYear: function(id, select, period) {
8980 var target = $(id),
8981 inst = this._getInst(target[0]);
8982
8983 inst["selected" + (period === "M" ? "Month" : "Year")] =
8984 inst["draw" + (period === "M" ? "Month" : "Year")] =
8985 parseInt(select.options[select.selectedIndex].value,10);
8986
8987 this._notifyChange(inst);
8988 this._adjustDate(target);
8989 },
8990
8991 /* Action for selecting a day. */
8992 _selectDay: function(id, month, year, td) {
8993 var inst,
8994 target = $(id);
8995
8996 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
8997 return;
8998 }
8999
9000 inst = this._getInst(target[0]);
9001 inst.selectedDay = inst.currentDay = $("a", td).html();
9002 inst.selectedMonth = inst.currentMonth = month;
9003 inst.selectedYear = inst.currentYear = year;
9004 this._selectDate(id, this._formatDate(inst,
9005 inst.currentDay, inst.currentMonth, inst.currentYear));
9006 },
9007
9008 /* Erase the input field and hide the date picker. */
9009 _clearDate: function(id) {
9010 var target = $(id);
9011 this._selectDate(target, "");
9012 },
9013
9014 /* Update the input field with the selected date. */
9015 _selectDate: function(id, dateStr) {
9016 var onSelect,
9017 target = $(id),
9018 inst = this._getInst(target[0]);
9019
9020 dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
9021 if (inst.input) {
9022 inst.input.val(dateStr);
9023 }
9024 this._updateAlternate(inst);
9025
9026 onSelect = this._get(inst, "onSelect");
9027 if (onSelect) {
9028 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback
9029 } else if (inst.input) {
9030 inst.input.trigger("change"); // fire the change event
9031 }
9032
9033 if (inst.inline){
9034 this._updateDatepicker(inst);
9035 } else {
9036 this._hideDatepicker();
9037 this._lastInput = inst.input[0];
9038 if (typeof(inst.input[0]) !== "object") {
9039 inst.input.focus(); // restore focus
9040 }
9041 this._lastInput = null;
9042 }
9043 },
9044
9045 /* Update any alternate field to synchronise with the main field. */
9046 _updateAlternate: function(inst) {
9047 var altFormat, date, dateStr,
9048 altField = this._get(inst, "altField");
9049
9050 if (altField) { // update alternate field too
9051 altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
9052 date = this._getDate(inst);
9053 dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
9054 $(altField).each(function() { $(this).val(dateStr); });
9055 }
9056 },
9057
9058 /* Set as beforeShowDay function to prevent selection of weekends.
9059 * @param date Date - the date to customise
9060 * @return [boolean, string] - is this date selectable?, what is its CSS class?
9061 */
9062 noWeekends: function(date) {
9063 var day = date.getDay();
9064 return [(day > 0 && day < 6), ""];
9065 },
9066
9067 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
9068 * @param date Date - the date to get the week for
9069 * @return number - the number of the week within the year that contains this date
9070 */
9071 iso8601Week: function(date) {
9072 var time,
9073 checkDate = new Date(date.getTime());
9074
9075 // Find Thursday of this week starting on Monday
9076 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
9077
9078 time = checkDate.getTime();
9079 checkDate.setMonth(0); // Compare with Jan 1
9080 checkDate.setDate(1);
9081 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
9082 },
9083
9084 /* Parse a string value into a date object.
9085 * See formatDate below for the possible formats.
9086 *
9087 * @param format string - the expected format of the date
9088 * @param value string - the date in the above format
9089 * @param settings Object - attributes include:
9090 * shortYearCutoff number - the cutoff year for determining the century (optional)
9091 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
9092 * dayNames string[7] - names of the days from Sunday (optional)
9093 * monthNamesShort string[12] - abbreviated names of the months (optional)
9094 * monthNames string[12] - names of the months (optional)
9095 * @return Date - the extracted date value or null if value is blank
9096 */
9097 parseDate: function (format, value, settings) {
9098 if (format == null || value == null) {
9099 throw "Invalid arguments";
9100 }
9101
9102 value = (typeof value === "object" ? value.toString() : value + "");
9103 if (value === "") {
9104 return null;
9105 }
9106
9107 var iFormat, dim, extra,
9108 iValue = 0,
9109 shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
9110 shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
9111 new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
9112 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
9113 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
9114 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
9115 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
9116 year = -1,
9117 month = -1,
9118 day = -1,
9119 doy = -1,
9120 literal = false,
9121 date,
9122 // Check whether a format character is doubled
9123 lookAhead = function(match) {
9124 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
9125 if (matches) {
9126 iFormat++;
9127 }
9128 return matches;
9129 },
9130 // Extract a number from the string value
9131 getNumber = function(match) {
9132 var isDoubled = lookAhead(match),
9133 size = (match === "@" ? 14 : (match === "!" ? 20 :
9134 (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
9135 minSize = (match === "y" ? size : 1),
9136 digits = new RegExp("^\\d{" + minSize + "," + size + "}"),
9137 num = value.substring(iValue).match(digits);
9138 if (!num) {
9139 throw "Missing number at position " + iValue;
9140 }
9141 iValue += num[0].length;
9142 return parseInt(num[0], 10);
9143 },
9144 // Extract a name from the string value and convert to an index
9145 getName = function(match, shortNames, longNames) {
9146 var index = -1,
9147 names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
9148 return [ [k, v] ];
9149 }).sort(function (a, b) {
9150 return -(a[1].length - b[1].length);
9151 });
9152
9153 $.each(names, function (i, pair) {
9154 var name = pair[1];
9155 if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
9156 index = pair[0];
9157 iValue += name.length;
9158 return false;
9159 }
9160 });
9161 if (index !== -1) {
9162 return index + 1;
9163 } else {
9164 throw "Unknown name at position " + iValue;
9165 }
9166 },
9167 // Confirm that a literal character matches the string value
9168 checkLiteral = function() {
9169 if (value.charAt(iValue) !== format.charAt(iFormat)) {
9170 throw "Unexpected literal at position " + iValue;
9171 }
9172 iValue++;
9173 };
9174
9175 for (iFormat = 0; iFormat < format.length; iFormat++) {
9176 if (literal) {
9177 if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
9178 literal = false;
9179 } else {
9180 checkLiteral();
9181 }
9182 } else {
9183 switch (format.charAt(iFormat)) {
9184 case "d":
9185 day = getNumber("d");
9186 break;
9187 case "D":
9188 getName("D", dayNamesShort, dayNames);
9189 break;
9190 case "o":
9191 doy = getNumber("o");
9192 break;
9193 case "m":
9194 month = getNumber("m");
9195 break;
9196 case "M":
9197 month = getName("M", monthNamesShort, monthNames);
9198 break;
9199 case "y":
9200 year = getNumber("y");
9201 break;
9202 case "@":
9203 date = new Date(getNumber("@"));
9204 year = date.getFullYear();
9205 month = date.getMonth() + 1;
9206 day = date.getDate();
9207 break;
9208 case "!":
9209 date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
9210 year = date.getFullYear();
9211 month = date.getMonth() + 1;
9212 day = date.getDate();
9213 break;
9214 case "'":
9215 if (lookAhead("'")){
9216 checkLiteral();
9217 } else {
9218 literal = true;
9219 }
9220 break;
9221 default:
9222 checkLiteral();
9223 }
9224 }
9225 }
9226
9227 if (iValue < value.length){
9228 extra = value.substr(iValue);
9229 if (!/^\s+/.test(extra)) {
9230 throw "Extra/unparsed characters found in date: " + extra;
9231 }
9232 }
9233
9234 if (year === -1) {
9235 year = new Date().getFullYear();
9236 } else if (year < 100) {
9237 year += new Date().getFullYear() - new Date().getFullYear() % 100 +
9238 (year <= shortYearCutoff ? 0 : -100);
9239 }
9240
9241 if (doy > -1) {
9242 month = 1;
9243 day = doy;
9244 do {
9245 dim = this._getDaysInMonth(year, month - 1);
9246 if (day <= dim) {
9247 break;
9248 }
9249 month++;
9250 day -= dim;
9251 } while (true);
9252 }
9253
9254 date = this._daylightSavingAdjust(new Date(year, month - 1, day));
9255 if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
9256 throw "Invalid date"; // E.g. 31/02/00
9257 }
9258 return date;
9259 },
9260
9261 /* Standard date formats. */
9262 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
9263 COOKIE: "D, dd M yy",
9264 ISO_8601: "yy-mm-dd",
9265 RFC_822: "D, d M y",
9266 RFC_850: "DD, dd-M-y",
9267 RFC_1036: "D, d M y",
9268 RFC_1123: "D, d M yy",
9269 RFC_2822: "D, d M yy",
9270 RSS: "D, d M y", // RFC 822
9271 TICKS: "!",
9272 TIMESTAMP: "@",
9273 W3C: "yy-mm-dd", // ISO 8601
9274
9275 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
9276 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
9277
9278 /* Format a date object into a string value.
9279 * The format can be combinations of the following:
9280 * d - day of month (no leading zero)
9281 * dd - day of month (two digit)
9282 * o - day of year (no leading zeros)
9283 * oo - day of year (three digit)
9284 * D - day name short
9285 * DD - day name long
9286 * m - month of year (no leading zero)
9287 * mm - month of year (two digit)
9288 * M - month name short
9289 * MM - month name long
9290 * y - year (two digit)
9291 * yy - year (four digit)
9292 * @ - Unix timestamp (ms since 01/01/1970)
9293 * ! - Windows ticks (100ns since 01/01/0001)
9294 * "..." - literal text
9295 * '' - single quote
9296 *
9297 * @param format string - the desired format of the date
9298 * @param date Date - the date value to format
9299 * @param settings Object - attributes include:
9300 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
9301 * dayNames string[7] - names of the days from Sunday (optional)
9302 * monthNamesShort string[12] - abbreviated names of the months (optional)
9303 * monthNames string[12] - names of the months (optional)
9304 * @return string - the date in the above format
9305 */
9306 formatDate: function (format, date, settings) {
9307 if (!date) {
9308 return "";
9309 }
9310
9311 var iFormat,
9312 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
9313 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
9314 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
9315 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
9316 // Check whether a format character is doubled
9317 lookAhead = function(match) {
9318 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
9319 if (matches) {
9320 iFormat++;
9321 }
9322 return matches;
9323 },
9324 // Format a number, with leading zero if necessary
9325 formatNumber = function(match, value, len) {
9326 var num = "" + value;
9327 if (lookAhead(match)) {
9328 while (num.length < len) {
9329 num = "0" + num;
9330 }
9331 }
9332 return num;
9333 },
9334 // Format a name, short or long as requested
9335 formatName = function(match, value, shortNames, longNames) {
9336 return (lookAhead(match) ? longNames[value] : shortNames[value]);
9337 },
9338 output = "",
9339 literal = false;
9340
9341 if (date) {
9342 for (iFormat = 0; iFormat < format.length; iFormat++) {
9343 if (literal) {
9344 if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
9345 literal = false;
9346 } else {
9347 output += format.charAt(iFormat);
9348 }
9349 } else {
9350 switch (format.charAt(iFormat)) {
9351 case "d":
9352 output += formatNumber("d", date.getDate(), 2);
9353 break;
9354 case "D":
9355 output += formatName("D", date.getDay(), dayNamesShort, dayNames);
9356 break;
9357 case "o":
9358 output += formatNumber("o",
9359 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
9360 break;
9361 case "m":
9362 output += formatNumber("m", date.getMonth() + 1, 2);
9363 break;
9364 case "M":
9365 output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
9366 break;
9367 case "y":
9368 output += (lookAhead("y") ? date.getFullYear() :
9369 (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
9370 break;
9371 case "@":
9372 output += date.getTime();
9373 break;
9374 case "!":
9375 output += date.getTime() * 10000 + this._ticksTo1970;
9376 break;
9377 case "'":
9378 if (lookAhead("'")) {
9379 output += "'";
9380 } else {
9381 literal = true;
9382 }
9383 break;
9384 default:
9385 output += format.charAt(iFormat);
9386 }
9387 }
9388 }
9389 }
9390 return output;
9391 },
9392
9393 /* Extract all possible characters from the date format. */
9394 _possibleChars: function (format) {
9395 var iFormat,
9396 chars = "",
9397 literal = false,
9398 // Check whether a format character is doubled
9399 lookAhead = function(match) {
9400 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
9401 if (matches) {
9402 iFormat++;
9403 }
9404 return matches;
9405 };
9406
9407 for (iFormat = 0; iFormat < format.length; iFormat++) {
9408 if (literal) {
9409 if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
9410 literal = false;
9411 } else {
9412 chars += format.charAt(iFormat);
9413 }
9414 } else {
9415 switch (format.charAt(iFormat)) {
9416 case "d": case "m": case "y": case "@":
9417 chars += "0123456789";
9418 break;
9419 case "D": case "M":
9420 return null; // Accept anything
9421 case "'":
9422 if (lookAhead("'")) {
9423 chars += "'";
9424 } else {
9425 literal = true;
9426 }
9427 break;
9428 default:
9429 chars += format.charAt(iFormat);
9430 }
9431 }
9432 }
9433 return chars;
9434 },
9435
9436 /* Get a setting value, defaulting if necessary. */
9437 _get: function(inst, name) {
9438 return inst.settings[name] !== undefined ?
9439 inst.settings[name] : this._defaults[name];
9440 },
9441
9442 /* Parse existing date and initialise date picker. */
9443 _setDateFromField: function(inst, noDefault) {
9444 if (inst.input.val() === inst.lastVal) {
9445 return;
9446 }
9447
9448 var dateFormat = this._get(inst, "dateFormat"),
9449 dates = inst.lastVal = inst.input ? inst.input.val() : null,
9450 defaultDate = this._getDefaultDate(inst),
9451 date = defaultDate,
9452 settings = this._getFormatConfig(inst);
9453
9454 try {
9455 date = this.parseDate(dateFormat, dates, settings) || defaultDate;
9456 } catch (event) {
9457 dates = (noDefault ? "" : dates);
9458 }
9459 inst.selectedDay = date.getDate();
9460 inst.drawMonth = inst.selectedMonth = date.getMonth();
9461 inst.drawYear = inst.selectedYear = date.getFullYear();
9462 inst.currentDay = (dates ? date.getDate() : 0);
9463 inst.currentMonth = (dates ? date.getMonth() : 0);
9464 inst.currentYear = (dates ? date.getFullYear() : 0);
9465 this._adjustInstDate(inst);
9466 },
9467
9468 /* Retrieve the default date shown on opening. */
9469 _getDefaultDate: function(inst) {
9470 return this._restrictMinMax(inst,
9471 this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
9472 },
9473
9474 /* A date may be specified as an exact value or a relative one. */
9475 _determineDate: function(inst, date, defaultDate) {
9476 var offsetNumeric = function(offset) {
9477 var date = new Date();
9478 date.setDate(date.getDate() + offset);
9479 return date;
9480 },
9481 offsetString = function(offset) {
9482 try {
9483 return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
9484 offset, $.datepicker._getFormatConfig(inst));
9485 }
9486 catch (e) {
9487 // Ignore
9488 }
9489
9490 var date = (offset.toLowerCase().match(/^c/) ?
9491 $.datepicker._getDate(inst) : null) || new Date(),
9492 year = date.getFullYear(),
9493 month = date.getMonth(),
9494 day = date.getDate(),
9495 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
9496 matches = pattern.exec(offset);
9497
9498 while (matches) {
9499 switch (matches[2] || "d") {
9500 case "d" : case "D" :
9501 day += parseInt(matches[1],10); break;
9502 case "w" : case "W" :
9503 day += parseInt(matches[1],10) * 7; break;
9504 case "m" : case "M" :
9505 month += parseInt(matches[1],10);
9506 day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9507 break;
9508 case "y": case "Y" :
9509 year += parseInt(matches[1],10);
9510 day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9511 break;
9512 }
9513 matches = pattern.exec(offset);
9514 }
9515 return new Date(year, month, day);
9516 },
9517 newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
9518 (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
9519
9520 newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
9521 if (newDate) {
9522 newDate.setHours(0);
9523 newDate.setMinutes(0);
9524 newDate.setSeconds(0);
9525 newDate.setMilliseconds(0);
9526 }
9527 return this._daylightSavingAdjust(newDate);
9528 },
9529
9530 /* Handle switch to/from daylight saving.
9531 * Hours may be non-zero on daylight saving cut-over:
9532 * > 12 when midnight changeover, but then cannot generate
9533 * midnight datetime, so jump to 1AM, otherwise reset.
9534 * @param date (Date) the date to check
9535 * @return (Date) the corrected date
9536 */
9537 _daylightSavingAdjust: function(date) {
9538 if (!date) {
9539 return null;
9540 }
9541 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
9542 return date;
9543 },
9544
9545 /* Set the date(s) directly. */
9546 _setDate: function(inst, date, noChange) {
9547 var clear = !date,
9548 origMonth = inst.selectedMonth,
9549 origYear = inst.selectedYear,
9550 newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
9551
9552 inst.selectedDay = inst.currentDay = newDate.getDate();
9553 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
9554 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
9555 if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
9556 this._notifyChange(inst);
9557 }
9558 this._adjustInstDate(inst);
9559 if (inst.input) {
9560 inst.input.val(clear ? "" : this._formatDate(inst));
9561 }
9562 },
9563
9564 /* Retrieve the date(s) directly. */
9565 _getDate: function(inst) {
9566 var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
9567 this._daylightSavingAdjust(new Date(
9568 inst.currentYear, inst.currentMonth, inst.currentDay)));
9569 return startDate;
9570 },
9571
9572 /* Attach the onxxx handlers. These are declared statically so
9573 * they work with static code transformers like Caja.
9574 */
9575 _attachHandlers: function(inst) {
9576 var stepMonths = this._get(inst, "stepMonths"),
9577 id = "#" + inst.id.replace( /\\\\/g, "\\" );
9578 inst.dpDiv.find("[data-handler]").map(function () {
9579 var handler = {
9580 prev: function () {
9581 $.datepicker._adjustDate(id, -stepMonths, "M");
9582 },
9583 next: function () {
9584 $.datepicker._adjustDate(id, +stepMonths, "M");
9585 },
9586 hide: function () {
9587 $.datepicker._hideDatepicker();
9588 },
9589 today: function () {
9590 $.datepicker._gotoToday(id);
9591 },
9592 selectDay: function () {
9593 $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
9594 return false;
9595 },
9596 selectMonth: function () {
9597 $.datepicker._selectMonthYear(id, this, "M");
9598 return false;
9599 },
9600 selectYear: function () {
9601 $.datepicker._selectMonthYear(id, this, "Y");
9602 return false;
9603 }
9604 };
9605 $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
9606 });
9607 },
9608
9609 /* Generate the HTML for the current state of the date picker. */
9610 _generateHTML: function(inst) {
9611 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
9612 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
9613 monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
9614 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
9615 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
9616 printDate, dRow, tbody, daySettings, otherMonth, unselectable,
9617 tempDate = new Date(),
9618 today = this._daylightSavingAdjust(
9619 new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
9620 isRTL = this._get(inst, "isRTL"),
9621 showButtonPanel = this._get(inst, "showButtonPanel"),
9622 hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
9623 navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
9624 numMonths = this._getNumberOfMonths(inst),
9625 showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
9626 stepMonths = this._get(inst, "stepMonths"),
9627 isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
9628 currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
9629 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
9630 minDate = this._getMinMaxDate(inst, "min"),
9631 maxDate = this._getMinMaxDate(inst, "max"),
9632 drawMonth = inst.drawMonth - showCurrentAtPos,
9633 drawYear = inst.drawYear;
9634
9635 if (drawMonth < 0) {
9636 drawMonth += 12;
9637 drawYear--;
9638 }
9639 if (maxDate) {
9640 maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
9641 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
9642 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
9643 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
9644 drawMonth--;
9645 if (drawMonth < 0) {
9646 drawMonth = 11;
9647 drawYear--;
9648 }
9649 }
9650 }
9651 inst.drawMonth = drawMonth;
9652 inst.drawYear = drawYear;
9653
9654 prevText = this._get(inst, "prevText");
9655 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
9656 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
9657 this._getFormatConfig(inst)));
9658
9659 prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
9660 "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
9661 " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
9662 (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>"));
9663
9664 nextText = this._get(inst, "nextText");
9665 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
9666 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
9667 this._getFormatConfig(inst)));
9668
9669 next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
9670 "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
9671 " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
9672 (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>"));
9673
9674 currentText = this._get(inst, "currentText");
9675 gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
9676 currentText = (!navigationAsDateFormat ? currentText :
9677 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
9678
9679 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'>" +
9680 this._get(inst, "closeText") + "</button>" : "");
9681
9682 buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
9683 (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'" +
9684 ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
9685
9686 firstDay = parseInt(this._get(inst, "firstDay"),10);
9687 firstDay = (isNaN(firstDay) ? 0 : firstDay);
9688
9689 showWeek = this._get(inst, "showWeek");
9690 dayNames = this._get(inst, "dayNames");
9691 dayNamesMin = this._get(inst, "dayNamesMin");
9692 monthNames = this._get(inst, "monthNames");
9693 monthNamesShort = this._get(inst, "monthNamesShort");
9694 beforeShowDay = this._get(inst, "beforeShowDay");
9695 showOtherMonths = this._get(inst, "showOtherMonths");
9696 selectOtherMonths = this._get(inst, "selectOtherMonths");
9697 defaultDate = this._getDefaultDate(inst);
9698 html = "";
9699 dow;
9700 for (row = 0; row < numMonths[0]; row++) {
9701 group = "";
9702 this.maxRows = 4;
9703 for (col = 0; col < numMonths[1]; col++) {
9704 selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
9705 cornerClass = " ui-corner-all";
9706 calender = "";
9707 if (isMultiMonth) {
9708 calender += "<div class='ui-datepicker-group";
9709 if (numMonths[1] > 1) {
9710 switch (col) {
9711 case 0: calender += " ui-datepicker-group-first";
9712 cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
9713 case numMonths[1]-1: calender += " ui-datepicker-group-last";
9714 cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
9715 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
9716 }
9717 }
9718 calender += "'>";
9719 }
9720 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
9721 (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
9722 (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
9723 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
9724 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
9725 "</div><table class='ui-datepicker-calendar'><thead>" +
9726 "<tr>";
9727 thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
9728 for (dow = 0; dow < 7; dow++) { // days of the week
9729 day = (dow + firstDay) % 7;
9730 thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
9731 "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
9732 }
9733 calender += thead + "</tr></thead><tbody>";
9734 daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
9735 if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
9736 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
9737 }
9738 leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
9739 curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
9740 numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
9741 this.maxRows = numRows;
9742 printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
9743 for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
9744 calender += "<tr>";
9745 tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
9746 this._get(inst, "calculateWeek")(printDate) + "</td>");
9747 for (dow = 0; dow < 7; dow++) { // create date picker days
9748 daySettings = (beforeShowDay ?
9749 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
9750 otherMonth = (printDate.getMonth() !== drawMonth);
9751 unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
9752 (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
9753 tbody += "<td class='" +
9754 ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
9755 (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
9756 ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
9757 (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
9758 // or defaultDate is current printedDate and defaultDate is selectedDate
9759 " " + this._dayOverClass : "") + // highlight selected day
9760 (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days
9761 (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
9762 (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
9763 (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
9764 ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
9765 (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
9766 (otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
9767 (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
9768 (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
9769 (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
9770 (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
9771 "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
9772 printDate.setDate(printDate.getDate() + 1);
9773 printDate = this._daylightSavingAdjust(printDate);
9774 }
9775 calender += tbody + "</tr>";
9776 }
9777 drawMonth++;
9778 if (drawMonth > 11) {
9779 drawMonth = 0;
9780 drawYear++;
9781 }
9782 calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
9783 ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
9784 group += calender;
9785 }
9786 html += group;
9787 }
9788 html += buttonPanel;
9789 inst._keyEvent = false;
9790 return html;
9791 },
9792
9793 /* Generate the month and year header. */
9794 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
9795 secondary, monthNames, monthNamesShort) {
9796
9797 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
9798 changeMonth = this._get(inst, "changeMonth"),
9799 changeYear = this._get(inst, "changeYear"),
9800 showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
9801 html = "<div class='ui-datepicker-title'>",
9802 monthHtml = "";
9803
9804 // month selection
9805 if (secondary || !changeMonth) {
9806 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
9807 } else {
9808 inMinYear = (minDate && minDate.getFullYear() === drawYear);
9809 inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
9810 monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
9811 for ( month = 0; month < 12; month++) {
9812 if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
9813 monthHtml += "<option value='" + month + "'" +
9814 (month === drawMonth ? " selected='selected'" : "") +
9815 ">" + monthNamesShort[month] + "</option>";
9816 }
9817 }
9818 monthHtml += "</select>";
9819 }
9820
9821 if (!showMonthAfterYear) {
9822 html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
9823 }
9824
9825 // year selection
9826 if ( !inst.yearshtml ) {
9827 inst.yearshtml = "";
9828 if (secondary || !changeYear) {
9829 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
9830 } else {
9831 // determine range of years to display
9832 years = this._get(inst, "yearRange").split(":");
9833 thisYear = new Date().getFullYear();
9834 determineYear = function(value) {
9835 var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
9836 (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
9837 parseInt(value, 10)));
9838 return (isNaN(year) ? thisYear : year);
9839 };
9840 year = determineYear(years[0]);
9841 endYear = Math.max(year, determineYear(years[1] || ""));
9842 year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
9843 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
9844 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
9845 for (; year <= endYear; year++) {
9846 inst.yearshtml += "<option value='" + year + "'" +
9847 (year === drawYear ? " selected='selected'" : "") +
9848 ">" + year + "</option>";
9849 }
9850 inst.yearshtml += "</select>";
9851
9852 html += inst.yearshtml;
9853 inst.yearshtml = null;
9854 }
9855 }
9856
9857 html += this._get(inst, "yearSuffix");
9858 if (showMonthAfterYear) {
9859 html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
9860 }
9861 html += "</div>"; // Close datepicker_header
9862 return html;
9863 },
9864
9865 /* Adjust one of the date sub-fields. */
9866 _adjustInstDate: function(inst, offset, period) {
9867 var year = inst.drawYear + (period === "Y" ? offset : 0),
9868 month = inst.drawMonth + (period === "M" ? offset : 0),
9869 day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
9870 date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
9871
9872 inst.selectedDay = date.getDate();
9873 inst.drawMonth = inst.selectedMonth = date.getMonth();
9874 inst.drawYear = inst.selectedYear = date.getFullYear();
9875 if (period === "M" || period === "Y") {
9876 this._notifyChange(inst);
9877 }
9878 },
9879
9880 /* Ensure a date is within any min/max bounds. */
9881 _restrictMinMax: function(inst, date) {
9882 var minDate = this._getMinMaxDate(inst, "min"),
9883 maxDate = this._getMinMaxDate(inst, "max"),
9884 newDate = (minDate && date < minDate ? minDate : date);
9885 return (maxDate && newDate > maxDate ? maxDate : newDate);
9886 },
9887
9888 /* Notify change of month/year. */
9889 _notifyChange: function(inst) {
9890 var onChange = this._get(inst, "onChangeMonthYear");
9891 if (onChange) {
9892 onChange.apply((inst.input ? inst.input[0] : null),
9893 [inst.selectedYear, inst.selectedMonth + 1, inst]);
9894 }
9895 },
9896
9897 /* Determine the number of months to show. */
9898 _getNumberOfMonths: function(inst) {
9899 var numMonths = this._get(inst, "numberOfMonths");
9900 return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
9901 },
9902
9903 /* Determine the current maximum date - ensure no time components are set. */
9904 _getMinMaxDate: function(inst, minMax) {
9905 return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
9906 },
9907
9908 /* Find the number of days in a given month. */
9909 _getDaysInMonth: function(year, month) {
9910 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
9911 },
9912
9913 /* Find the day of the week of the first of a month. */
9914 _getFirstDayOfMonth: function(year, month) {
9915 return new Date(year, month, 1).getDay();
9916 },
9917
9918 /* Determines if we should allow a "next/prev" month display change. */
9919 _canAdjustMonth: function(inst, offset, curYear, curMonth) {
9920 var numMonths = this._getNumberOfMonths(inst),
9921 date = this._daylightSavingAdjust(new Date(curYear,
9922 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
9923
9924 if (offset < 0) {
9925 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
9926 }
9927 return this._isInRange(inst, date);
9928 },
9929
9930 /* Is the given date in the accepted range? */
9931 _isInRange: function(inst, date) {
9932 var yearSplit, currentYear,
9933 minDate = this._getMinMaxDate(inst, "min"),
9934 maxDate = this._getMinMaxDate(inst, "max"),
9935 minYear = null,
9936 maxYear = null,
9937 years = this._get(inst, "yearRange");
9938 if (years){
9939 yearSplit = years.split(":");
9940 currentYear = new Date().getFullYear();
9941 minYear = parseInt(yearSplit[0], 10);
9942 maxYear = parseInt(yearSplit[1], 10);
9943 if ( yearSplit[0].match(/[+\-].*/) ) {
9944 minYear += currentYear;
9945 }
9946 if ( yearSplit[1].match(/[+\-].*/) ) {
9947 maxYear += currentYear;
9948 }
9949 }
9950
9951 return ((!minDate || date.getTime() >= minDate.getTime()) &&
9952 (!maxDate || date.getTime() <= maxDate.getTime()) &&
9953 (!minYear || date.getFullYear() >= minYear) &&
9954 (!maxYear || date.getFullYear() <= maxYear));
9955 },
9956
9957 /* Provide the configuration settings for formatting/parsing. */
9958 _getFormatConfig: function(inst) {
9959 var shortYearCutoff = this._get(inst, "shortYearCutoff");
9960 shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
9961 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
9962 return {shortYearCutoff: shortYearCutoff,
9963 dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
9964 monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
9965 },
9966
9967 /* Format the given date for display. */
9968 _formatDate: function(inst, day, month, year) {
9969 if (!day) {
9970 inst.currentDay = inst.selectedDay;
9971 inst.currentMonth = inst.selectedMonth;
9972 inst.currentYear = inst.selectedYear;
9973 }
9974 var date = (day ? (typeof day === "object" ? day :
9975 this._daylightSavingAdjust(new Date(year, month, day))) :
9976 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
9977 return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
9978 }
9979});
9980
9981/*
9982 * Bind hover events for datepicker elements.
9983 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9984 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9985 */
9986function datepicker_bindHover(dpDiv) {
9987 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
9988 return dpDiv.delegate(selector, "mouseout", function() {
9989 $(this).removeClass("ui-state-hover");
9990 if (this.className.indexOf("ui-datepicker-prev") !== -1) {
9991 $(this).removeClass("ui-datepicker-prev-hover");
9992 }
9993 if (this.className.indexOf("ui-datepicker-next") !== -1) {
9994 $(this).removeClass("ui-datepicker-next-hover");
9995 }
9996 })
9997 .delegate( selector, "mouseover", datepicker_handleMouseover );
9998}
9999
10000function datepicker_handleMouseover() {
10001 if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) {
10002 $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
10003 $(this).addClass("ui-state-hover");
10004 if (this.className.indexOf("ui-datepicker-prev") !== -1) {
10005 $(this).addClass("ui-datepicker-prev-hover");
10006 }
10007 if (this.className.indexOf("ui-datepicker-next") !== -1) {
10008 $(this).addClass("ui-datepicker-next-hover");
10009 }
10010 }
10011}
10012
10013/* jQuery extend now ignores nulls! */
10014function datepicker_extendRemove(target, props) {
10015 $.extend(target, props);
10016 for (var name in props) {
10017 if (props[name] == null) {
10018 target[name] = props[name];
10019 }
10020 }
10021 return target;
10022}
10023
10024/* Invoke the datepicker functionality.
10025 @param options string - a command, optionally followed by additional parameters or
10026 Object - settings for attaching new datepicker functionality
10027 @return jQuery object */
10028$.fn.datepicker = function(options){
10029
10030 /* Verify an empty collection wasn't passed - Fixes #6976 */
10031 if ( !this.length ) {
10032 return this;
10033 }
10034
10035 /* Initialise the date picker. */
10036 if (!$.datepicker.initialized) {
10037 $(document).mousedown($.datepicker._checkExternalClick);
10038 $.datepicker.initialized = true;
10039 }
10040
10041 /* Append datepicker main container to body if not exist. */
10042 if ($("#"+$.datepicker._mainDivId).length === 0) {
10043 $("body").append($.datepicker.dpDiv);
10044 }
10045
10046 var otherArgs = Array.prototype.slice.call(arguments, 1);
10047 if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
10048 return $.datepicker["_" + options + "Datepicker"].
10049 apply($.datepicker, [this[0]].concat(otherArgs));
10050 }
10051 if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
10052 return $.datepicker["_" + options + "Datepicker"].
10053 apply($.datepicker, [this[0]].concat(otherArgs));
10054 }
10055 return this.each(function() {
10056 typeof options === "string" ?
10057 $.datepicker["_" + options + "Datepicker"].
10058 apply($.datepicker, [this].concat(otherArgs)) :
10059 $.datepicker._attachDatepicker(this, options);
10060 });
10061};
10062
10063$.datepicker = new Datepicker(); // singleton instance
10064$.datepicker.initialized = false;
10065$.datepicker.uuid = new Date().getTime();
10066$.datepicker.version = "1.11.3";
10067
10068var datepicker = $.datepicker;
10069
10070
10071/*!
10072 * jQuery UI Dialog 1.11.3
10073 * http://jqueryui.com
10074 *
10075 * Copyright jQuery Foundation and other contributors
10076 * Released under the MIT license.
10077 * http://jquery.org/license
10078 *
10079 * http://api.jqueryui.com/dialog/
10080 */
10081
10082
10083var dialog = $.widget( "ui.dialog", {
10084 version: "1.11.3",
10085 options: {
10086 appendTo: "body",
10087 autoOpen: true,
10088 buttons: [],
10089 closeOnEscape: true,
10090 closeText: "Close",
10091 dialogClass: "",
10092 draggable: true,
10093 hide: null,
10094 height: "auto",
10095 maxHeight: null,
10096 maxWidth: null,
10097 minHeight: 150,
10098 minWidth: 150,
10099 modal: false,
10100 position: {
10101 my: "center",
10102 at: "center",
10103 of: window,
10104 collision: "fit",
10105 // Ensure the titlebar is always visible
10106 using: function( pos ) {
10107 var topOffset = $( this ).css( pos ).offset().top;
10108 if ( topOffset < 0 ) {
10109 $( this ).css( "top", pos.top - topOffset );
10110 }
10111 }
10112 },
10113 resizable: true,
10114 show: null,
10115 title: null,
10116 width: 300,
10117
10118 // callbacks
10119 beforeClose: null,
10120 close: null,
10121 drag: null,
10122 dragStart: null,
10123 dragStop: null,
10124 focus: null,
10125 open: null,
10126 resize: null,
10127 resizeStart: null,
10128 resizeStop: null
10129 },
10130
10131 sizeRelatedOptions: {
10132 buttons: true,
10133 height: true,
10134 maxHeight: true,
10135 maxWidth: true,
10136 minHeight: true,
10137 minWidth: true,
10138 width: true
10139 },
10140
10141 resizableRelatedOptions: {
10142 maxHeight: true,
10143 maxWidth: true,
10144 minHeight: true,
10145 minWidth: true
10146 },
10147
10148 _create: function() {
10149 this.originalCss = {
10150 display: this.element[ 0 ].style.display,
10151 width: this.element[ 0 ].style.width,
10152 minHeight: this.element[ 0 ].style.minHeight,
10153 maxHeight: this.element[ 0 ].style.maxHeight,
10154 height: this.element[ 0 ].style.height
10155 };
10156 this.originalPosition = {
10157 parent: this.element.parent(),
10158 index: this.element.parent().children().index( this.element )
10159 };
10160 this.originalTitle = this.element.attr( "title" );
10161 this.options.title = this.options.title || this.originalTitle;
10162
10163 this._createWrapper();
10164
10165 this.element
10166 .show()
10167 .removeAttr( "title" )
10168 .addClass( "ui-dialog-content ui-widget-content" )
10169 .appendTo( this.uiDialog );
10170
10171 this._createTitlebar();
10172 this._createButtonPane();
10173
10174 if ( this.options.draggable && $.fn.draggable ) {
10175 this._makeDraggable();
10176 }
10177 if ( this.options.resizable && $.fn.resizable ) {
10178 this._makeResizable();
10179 }
10180
10181 this._isOpen = false;
10182
10183 this._trackFocus();
10184 },
10185
10186 _init: function() {
10187 if ( this.options.autoOpen ) {
10188 this.open();
10189 }
10190 },
10191
10192 _appendTo: function() {
10193 var element = this.options.appendTo;
10194 if ( element && (element.jquery || element.nodeType) ) {
10195 return $( element );
10196 }
10197 return this.document.find( element || "body" ).eq( 0 );
10198 },
10199
10200 _destroy: function() {
10201 var next,
10202 originalPosition = this.originalPosition;
10203
10204 this._destroyOverlay();
10205
10206 this.element
10207 .removeUniqueId()
10208 .removeClass( "ui-dialog-content ui-widget-content" )
10209 .css( this.originalCss )
10210 // Without detaching first, the following becomes really slow
10211 .detach();
10212
10213 this.uiDialog.stop( true, true ).remove();
10214
10215 if ( this.originalTitle ) {
10216 this.element.attr( "title", this.originalTitle );
10217 }
10218
10219 next = originalPosition.parent.children().eq( originalPosition.index );
10220 // Don't try to place the dialog next to itself (#8613)
10221 if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
10222 next.before( this.element );
10223 } else {
10224 originalPosition.parent.append( this.element );
10225 }
10226 },
10227
10228 widget: function() {
10229 return this.uiDialog;
10230 },
10231
10232 disable: $.noop,
10233 enable: $.noop,
10234
10235 close: function( event ) {
10236 var activeElement,
10237 that = this;
10238
10239 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
10240 return;
10241 }
10242
10243 this._isOpen = false;
10244 this._focusedElement = null;
10245 this._destroyOverlay();
10246 this._untrackInstance();
10247
10248 if ( !this.opener.filter( ":focusable" ).focus().length ) {
10249
10250 // support: IE9
10251 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
10252 try {
10253 activeElement = this.document[ 0 ].activeElement;
10254
10255 // Support: IE9, IE10
10256 // If the <body> is blurred, IE will switch windows, see #4520
10257 if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {
10258
10259 // Hiding a focused element doesn't trigger blur in WebKit
10260 // so in case we have nothing to focus on, explicitly blur the active element
10261 // https://bugs.webkit.org/show_bug.cgi?id=47182
10262 $( activeElement ).blur();
10263 }
10264 } catch ( error ) {}
10265 }
10266
10267 this._hide( this.uiDialog, this.options.hide, function() {
10268 that._trigger( "close", event );
10269 });
10270 },
10271
10272 isOpen: function() {
10273 return this._isOpen;
10274 },
10275
10276 moveToTop: function() {
10277 this._moveToTop();
10278 },
10279
10280 _moveToTop: function( event, silent ) {
10281 var moved = false,
10282 zIndicies = this.uiDialog.siblings( ".ui-front:visible" ).map(function() {
10283 return +$( this ).css( "z-index" );
10284 }).get(),
10285 zIndexMax = Math.max.apply( null, zIndicies );
10286
10287 if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
10288 this.uiDialog.css( "z-index", zIndexMax + 1 );
10289 moved = true;
10290 }
10291
10292 if ( moved && !silent ) {
10293 this._trigger( "focus", event );
10294 }
10295 return moved;
10296 },
10297
10298 open: function() {
10299 var that = this;
10300 if ( this._isOpen ) {
10301 if ( this._moveToTop() ) {
10302 this._focusTabbable();
10303 }
10304 return;
10305 }
10306
10307 this._isOpen = true;
10308 this.opener = $( this.document[ 0 ].activeElement );
10309
10310 this._size();
10311 this._position();
10312 this._createOverlay();
10313 this._moveToTop( null, true );
10314
10315 // Ensure the overlay is moved to the top with the dialog, but only when
10316 // opening. The overlay shouldn't move after the dialog is open so that
10317 // modeless dialogs opened after the modal dialog stack properly.
10318 if ( this.overlay ) {
10319 this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
10320 }
10321
10322 this._show( this.uiDialog, this.options.show, function() {
10323 that._focusTabbable();
10324 that._trigger( "focus" );
10325 });
10326
10327 // Track the dialog immediately upon openening in case a focus event
10328 // somehow occurs outside of the dialog before an element inside the
10329 // dialog is focused (#10152)
10330 this._makeFocusTarget();
10331
10332 this._trigger( "open" );
10333 },
10334
10335 _focusTabbable: function() {
10336 // Set focus to the first match:
10337 // 1. An element that was focused previously
10338 // 2. First element inside the dialog matching [autofocus]
10339 // 3. Tabbable element inside the content element
10340 // 4. Tabbable element inside the buttonpane
10341 // 5. The close button
10342 // 6. The dialog itself
10343 var hasFocus = this._focusedElement;
10344 if ( !hasFocus ) {
10345 hasFocus = this.element.find( "[autofocus]" );
10346 }
10347 if ( !hasFocus.length ) {
10348 hasFocus = this.element.find( ":tabbable" );
10349 }
10350 if ( !hasFocus.length ) {
10351 hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
10352 }
10353 if ( !hasFocus.length ) {
10354 hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
10355 }
10356 if ( !hasFocus.length ) {
10357 hasFocus = this.uiDialog;
10358 }
10359 hasFocus.eq( 0 ).focus();
10360 },
10361
10362 _keepFocus: function( event ) {
10363 function checkFocus() {
10364 var activeElement = this.document[0].activeElement,
10365 isActive = this.uiDialog[0] === activeElement ||
10366 $.contains( this.uiDialog[0], activeElement );
10367 if ( !isActive ) {
10368 this._focusTabbable();
10369 }
10370 }
10371 event.preventDefault();
10372 checkFocus.call( this );
10373 // support: IE
10374 // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
10375 // so we check again later
10376 this._delay( checkFocus );
10377 },
10378
10379 _createWrapper: function() {
10380 this.uiDialog = $("<div>")
10381 .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
10382 this.options.dialogClass )
10383 .hide()
10384 .attr({
10385 // Setting tabIndex makes the div focusable
10386 tabIndex: -1,
10387 role: "dialog"
10388 })
10389 .appendTo( this._appendTo() );
10390
10391 this._on( this.uiDialog, {
10392 keydown: function( event ) {
10393 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
10394 event.keyCode === $.ui.keyCode.ESCAPE ) {
10395 event.preventDefault();
10396 this.close( event );
10397 return;
10398 }
10399
10400 // prevent tabbing out of dialogs
10401 if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
10402 return;
10403 }
10404 var tabbables = this.uiDialog.find( ":tabbable" ),
10405 first = tabbables.filter( ":first" ),
10406 last = tabbables.filter( ":last" );
10407
10408 if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
10409 this._delay(function() {
10410 first.focus();
10411 });
10412 event.preventDefault();
10413 } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
10414 this._delay(function() {
10415 last.focus();
10416 });
10417 event.preventDefault();
10418 }
10419 },
10420 mousedown: function( event ) {
10421 if ( this._moveToTop( event ) ) {
10422 this._focusTabbable();
10423 }
10424 }
10425 });
10426
10427 // We assume that any existing aria-describedby attribute means
10428 // that the dialog content is marked up properly
10429 // otherwise we brute force the content as the description
10430 if ( !this.element.find( "[aria-describedby]" ).length ) {
10431 this.uiDialog.attr({
10432 "aria-describedby": this.element.uniqueId().attr( "id" )
10433 });
10434 }
10435 },
10436
10437 _createTitlebar: function() {
10438 var uiDialogTitle;
10439
10440 this.uiDialogTitlebar = $( "<div>" )
10441 .addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" )
10442 .prependTo( this.uiDialog );
10443 this._on( this.uiDialogTitlebar, {
10444 mousedown: function( event ) {
10445 // Don't prevent click on close button (#8838)
10446 // Focusing a dialog that is partially scrolled out of view
10447 // causes the browser to scroll it into view, preventing the click event
10448 if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
10449 // Dialog isn't getting focus when dragging (#8063)
10450 this.uiDialog.focus();
10451 }
10452 }
10453 });
10454
10455 // support: IE
10456 // Use type="button" to prevent enter keypresses in textboxes from closing the
10457 // dialog in IE (#9312)
10458 this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
10459 .button({
10460 label: this.options.closeText,
10461 icons: {
10462 primary: "ui-icon-closethick"
10463 },
10464 text: false
10465 })
10466 .addClass( "ui-dialog-titlebar-close" )
10467 .appendTo( this.uiDialogTitlebar );
10468 this._on( this.uiDialogTitlebarClose, {
10469 click: function( event ) {
10470 event.preventDefault();
10471 this.close( event );
10472 }
10473 });
10474
10475 uiDialogTitle = $( "<span>" )
10476 .uniqueId()
10477 .addClass( "ui-dialog-title" )
10478 .prependTo( this.uiDialogTitlebar );
10479 this._title( uiDialogTitle );
10480
10481 this.uiDialog.attr({
10482 "aria-labelledby": uiDialogTitle.attr( "id" )
10483 });
10484 },
10485
10486 _title: function( title ) {
10487 if ( !this.options.title ) {
10488 title.html( "&#160;" );
10489 }
10490 title.text( this.options.title );
10491 },
10492
10493 _createButtonPane: function() {
10494 this.uiDialogButtonPane = $( "<div>" )
10495 .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
10496
10497 this.uiButtonSet = $( "<div>" )
10498 .addClass( "ui-dialog-buttonset" )
10499 .appendTo( this.uiDialogButtonPane );
10500
10501 this._createButtons();
10502 },
10503
10504 _createButtons: function() {
10505 var that = this,
10506 buttons = this.options.buttons;
10507
10508 // if we already have a button pane, remove it
10509 this.uiDialogButtonPane.remove();
10510 this.uiButtonSet.empty();
10511
10512 if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
10513 this.uiDialog.removeClass( "ui-dialog-buttons" );
10514 return;
10515 }
10516
10517 $.each( buttons, function( name, props ) {
10518 var click, buttonOptions;
10519 props = $.isFunction( props ) ?
10520 { click: props, text: name } :
10521 props;
10522 // Default to a non-submitting button
10523 props = $.extend( { type: "button" }, props );
10524 // Change the context for the click callback to be the main element
10525 click = props.click;
10526 props.click = function() {
10527 click.apply( that.element[ 0 ], arguments );
10528 };
10529 buttonOptions = {
10530 icons: props.icons,
10531 text: props.showText
10532 };
10533 delete props.icons;
10534 delete props.showText;
10535 $( "<button></button>", props )
10536 .button( buttonOptions )
10537 .appendTo( that.uiButtonSet );
10538 });
10539 this.uiDialog.addClass( "ui-dialog-buttons" );
10540 this.uiDialogButtonPane.appendTo( this.uiDialog );
10541 },
10542
10543 _makeDraggable: function() {
10544 var that = this,
10545 options = this.options;
10546
10547 function filteredUi( ui ) {
10548 return {
10549 position: ui.position,
10550 offset: ui.offset
10551 };
10552 }
10553
10554 this.uiDialog.draggable({
10555 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
10556 handle: ".ui-dialog-titlebar",
10557 containment: "document",
10558 start: function( event, ui ) {
10559 $( this ).addClass( "ui-dialog-dragging" );
10560 that._blockFrames();
10561 that._trigger( "dragStart", event, filteredUi( ui ) );
10562 },
10563 drag: function( event, ui ) {
10564 that._trigger( "drag", event, filteredUi( ui ) );
10565 },
10566 stop: function( event, ui ) {
10567 var left = ui.offset.left - that.document.scrollLeft(),
10568 top = ui.offset.top - that.document.scrollTop();
10569
10570 options.position = {
10571 my: "left top",
10572 at: "left" + (left >= 0 ? "+" : "") + left + " " +
10573 "top" + (top >= 0 ? "+" : "") + top,
10574 of: that.window
10575 };
10576 $( this ).removeClass( "ui-dialog-dragging" );
10577 that._unblockFrames();
10578 that._trigger( "dragStop", event, filteredUi( ui ) );
10579 }
10580 });
10581 },
10582
10583 _makeResizable: function() {
10584 var that = this,
10585 options = this.options,
10586 handles = options.resizable,
10587 // .ui-resizable has position: relative defined in the stylesheet
10588 // but dialogs have to use absolute or fixed positioning
10589 position = this.uiDialog.css("position"),
10590 resizeHandles = typeof handles === "string" ?
10591 handles :
10592 "n,e,s,w,se,sw,ne,nw";
10593
10594 function filteredUi( ui ) {
10595 return {
10596 originalPosition: ui.originalPosition,
10597 originalSize: ui.originalSize,
10598 position: ui.position,
10599 size: ui.size
10600 };
10601 }
10602
10603 this.uiDialog.resizable({
10604 cancel: ".ui-dialog-content",
10605 containment: "document",
10606 alsoResize: this.element,
10607 maxWidth: options.maxWidth,
10608 maxHeight: options.maxHeight,
10609 minWidth: options.minWidth,
10610 minHeight: this._minHeight(),
10611 handles: resizeHandles,
10612 start: function( event, ui ) {
10613 $( this ).addClass( "ui-dialog-resizing" );
10614 that._blockFrames();
10615 that._trigger( "resizeStart", event, filteredUi( ui ) );
10616 },
10617 resize: function( event, ui ) {
10618 that._trigger( "resize", event, filteredUi( ui ) );
10619 },
10620 stop: function( event, ui ) {
10621 var offset = that.uiDialog.offset(),
10622 left = offset.left - that.document.scrollLeft(),
10623 top = offset.top - that.document.scrollTop();
10624
10625 options.height = that.uiDialog.height();
10626 options.width = that.uiDialog.width();
10627 options.position = {
10628 my: "left top",
10629 at: "left" + (left >= 0 ? "+" : "") + left + " " +
10630 "top" + (top >= 0 ? "+" : "") + top,
10631 of: that.window
10632 };
10633 $( this ).removeClass( "ui-dialog-resizing" );
10634 that._unblockFrames();
10635 that._trigger( "resizeStop", event, filteredUi( ui ) );
10636 }
10637 })
10638 .css( "position", position );
10639 },
10640
10641 _trackFocus: function() {
10642 this._on( this.widget(), {
10643 focusin: function( event ) {
10644 this._makeFocusTarget();
10645 this._focusedElement = $( event.target );
10646 }
10647 });
10648 },
10649
10650 _makeFocusTarget: function() {
10651 this._untrackInstance();
10652 this._trackingInstances().unshift( this );
10653 },
10654
10655 _untrackInstance: function() {
10656 var instances = this._trackingInstances(),
10657 exists = $.inArray( this, instances );
10658 if ( exists !== -1 ) {
10659 instances.splice( exists, 1 );
10660 }
10661 },
10662
10663 _trackingInstances: function() {
10664 var instances = this.document.data( "ui-dialog-instances" );
10665 if ( !instances ) {
10666 instances = [];
10667 this.document.data( "ui-dialog-instances", instances );
10668 }
10669 return instances;
10670 },
10671
10672 _minHeight: function() {
10673 var options = this.options;
10674
10675 return options.height === "auto" ?
10676 options.minHeight :
10677 Math.min( options.minHeight, options.height );
10678 },
10679
10680 _position: function() {
10681 // Need to show the dialog to get the actual offset in the position plugin
10682 var isVisible = this.uiDialog.is( ":visible" );
10683 if ( !isVisible ) {
10684 this.uiDialog.show();
10685 }
10686 this.uiDialog.position( this.options.position );
10687 if ( !isVisible ) {
10688 this.uiDialog.hide();
10689 }
10690 },
10691
10692 _setOptions: function( options ) {
10693 var that = this,
10694 resize = false,
10695 resizableOptions = {};
10696
10697 $.each( options, function( key, value ) {
10698 that._setOption( key, value );
10699
10700 if ( key in that.sizeRelatedOptions ) {
10701 resize = true;
10702 }
10703 if ( key in that.resizableRelatedOptions ) {
10704 resizableOptions[ key ] = value;
10705 }
10706 });
10707
10708 if ( resize ) {
10709 this._size();
10710 this._position();
10711 }
10712 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
10713 this.uiDialog.resizable( "option", resizableOptions );
10714 }
10715 },
10716
10717 _setOption: function( key, value ) {
10718 var isDraggable, isResizable,
10719 uiDialog = this.uiDialog;
10720
10721 if ( key === "dialogClass" ) {
10722 uiDialog
10723 .removeClass( this.options.dialogClass )
10724 .addClass( value );
10725 }
10726
10727 if ( key === "disabled" ) {
10728 return;
10729 }
10730
10731 this._super( key, value );
10732
10733 if ( key === "appendTo" ) {
10734 this.uiDialog.appendTo( this._appendTo() );
10735 }
10736
10737 if ( key === "buttons" ) {
10738 this._createButtons();
10739 }
10740
10741 if ( key === "closeText" ) {
10742 this.uiDialogTitlebarClose.button({
10743 // Ensure that we always pass a string
10744 label: "" + value
10745 });
10746 }
10747
10748 if ( key === "draggable" ) {
10749 isDraggable = uiDialog.is( ":data(ui-draggable)" );
10750 if ( isDraggable && !value ) {
10751 uiDialog.draggable( "destroy" );
10752 }
10753
10754 if ( !isDraggable && value ) {
10755 this._makeDraggable();
10756 }
10757 }
10758
10759 if ( key === "position" ) {
10760 this._position();
10761 }
10762
10763 if ( key === "resizable" ) {
10764 // currently resizable, becoming non-resizable
10765 isResizable = uiDialog.is( ":data(ui-resizable)" );
10766 if ( isResizable && !value ) {
10767 uiDialog.resizable( "destroy" );
10768 }
10769
10770 // currently resizable, changing handles
10771 if ( isResizable && typeof value === "string" ) {
10772 uiDialog.resizable( "option", "handles", value );
10773 }
10774
10775 // currently non-resizable, becoming resizable
10776 if ( !isResizable && value !== false ) {
10777 this._makeResizable();
10778 }
10779 }
10780
10781 if ( key === "title" ) {
10782 this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
10783 }
10784 },
10785
10786 _size: function() {
10787 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
10788 // divs will both have width and height set, so we need to reset them
10789 var nonContentHeight, minContentHeight, maxContentHeight,
10790 options = this.options;
10791
10792 // Reset content sizing
10793 this.element.show().css({
10794 width: "auto",
10795 minHeight: 0,
10796 maxHeight: "none",
10797 height: 0
10798 });
10799
10800 if ( options.minWidth > options.width ) {
10801 options.width = options.minWidth;
10802 }
10803
10804 // reset wrapper sizing
10805 // determine the height of all the non-content elements
10806 nonContentHeight = this.uiDialog.css({
10807 height: "auto",
10808 width: options.width
10809 })
10810 .outerHeight();
10811 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
10812 maxContentHeight = typeof options.maxHeight === "number" ?
10813 Math.max( 0, options.maxHeight - nonContentHeight ) :
10814 "none";
10815
10816 if ( options.height === "auto" ) {
10817 this.element.css({
10818 minHeight: minContentHeight,
10819 maxHeight: maxContentHeight,
10820 height: "auto"
10821 });
10822 } else {
10823 this.element.height( Math.max( 0, options.height - nonContentHeight ) );
10824 }
10825
10826 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
10827 this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
10828 }
10829 },
10830
10831 _blockFrames: function() {
10832 this.iframeBlocks = this.document.find( "iframe" ).map(function() {
10833 var iframe = $( this );
10834
10835 return $( "<div>" )
10836 .css({
10837 position: "absolute",
10838 width: iframe.outerWidth(),
10839 height: iframe.outerHeight()
10840 })
10841 .appendTo( iframe.parent() )
10842 .offset( iframe.offset() )[0];
10843 });
10844 },
10845
10846 _unblockFrames: function() {
10847 if ( this.iframeBlocks ) {
10848 this.iframeBlocks.remove();
10849 delete this.iframeBlocks;
10850 }
10851 },
10852
10853 _allowInteraction: function( event ) {
10854 if ( $( event.target ).closest( ".ui-dialog" ).length ) {
10855 return true;
10856 }
10857
10858 // TODO: Remove hack when datepicker implements
10859 // the .ui-front logic (#8989)
10860 return !!$( event.target ).closest( ".ui-datepicker" ).length;
10861 },
10862
10863 _createOverlay: function() {
10864 if ( !this.options.modal ) {
10865 return;
10866 }
10867
10868 // We use a delay in case the overlay is created from an
10869 // event that we're going to be cancelling (#2804)
10870 var isOpening = true;
10871 this._delay(function() {
10872 isOpening = false;
10873 });
10874
10875 if ( !this.document.data( "ui-dialog-overlays" ) ) {
10876
10877 // Prevent use of anchors and inputs
10878 // Using _on() for an event handler shared across many instances is
10879 // safe because the dialogs stack and must be closed in reverse order
10880 this._on( this.document, {
10881 focusin: function( event ) {
10882 if ( isOpening ) {
10883 return;
10884 }
10885
10886 if ( !this._allowInteraction( event ) ) {
10887 event.preventDefault();
10888 this._trackingInstances()[ 0 ]._focusTabbable();
10889 }
10890 }
10891 });
10892 }
10893
10894 this.overlay = $( "<div>" )
10895 .addClass( "ui-widget-overlay ui-front" )
10896 .appendTo( this._appendTo() );
10897 this._on( this.overlay, {
10898 mousedown: "_keepFocus"
10899 });
10900 this.document.data( "ui-dialog-overlays",
10901 (this.document.data( "ui-dialog-overlays" ) || 0) + 1 );
10902 },
10903
10904 _destroyOverlay: function() {
10905 if ( !this.options.modal ) {
10906 return;
10907 }
10908
10909 if ( this.overlay ) {
10910 var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
10911
10912 if ( !overlays ) {
10913 this.document
10914 .unbind( "focusin" )
10915 .removeData( "ui-dialog-overlays" );
10916 } else {
10917 this.document.data( "ui-dialog-overlays", overlays );
10918 }
10919
10920 this.overlay.remove();
10921 this.overlay = null;
10922 }
10923 }
10924});
10925
10926
10927/*!
10928 * jQuery UI Progressbar 1.11.3
10929 * http://jqueryui.com
10930 *
10931 * Copyright jQuery Foundation and other contributors
10932 * Released under the MIT license.
10933 * http://jquery.org/license
10934 *
10935 * http://api.jqueryui.com/progressbar/
10936 */
10937
10938
10939var progressbar = $.widget( "ui.progressbar", {
10940 version: "1.11.3",
10941 options: {
10942 max: 100,
10943 value: 0,
10944
10945 change: null,
10946 complete: null
10947 },
10948
10949 min: 0,
10950
10951 _create: function() {
10952 // Constrain initial value
10953 this.oldValue = this.options.value = this._constrainedValue();
10954
10955 this.element
10956 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10957 .attr({
10958 // Only set static values, aria-valuenow and aria-valuemax are
10959 // set inside _refreshValue()
10960 role: "progressbar",
10961 "aria-valuemin": this.min
10962 });
10963
10964 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
10965 .appendTo( this.element );
10966
10967 this._refreshValue();
10968 },
10969
10970 _destroy: function() {
10971 this.element
10972 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10973 .removeAttr( "role" )
10974 .removeAttr( "aria-valuemin" )
10975 .removeAttr( "aria-valuemax" )
10976 .removeAttr( "aria-valuenow" );
10977
10978 this.valueDiv.remove();
10979 },
10980
10981 value: function( newValue ) {
10982 if ( newValue === undefined ) {
10983 return this.options.value;
10984 }
10985
10986 this.options.value = this._constrainedValue( newValue );
10987 this._refreshValue();
10988 },
10989
10990 _constrainedValue: function( newValue ) {
10991 if ( newValue === undefined ) {
10992 newValue = this.options.value;
10993 }
10994
10995 this.indeterminate = newValue === false;
10996
10997 // sanitize value
10998 if ( typeof newValue !== "number" ) {
10999 newValue = 0;
11000 }
11001
11002 return this.indeterminate ? false :
11003 Math.min( this.options.max, Math.max( this.min, newValue ) );
11004 },
11005
11006 _setOptions: function( options ) {
11007 // Ensure "value" option is set after other values (like max)
11008 var value = options.value;
11009 delete options.value;
11010
11011 this._super( options );
11012
11013 this.options.value = this._constrainedValue( value );
11014 this._refreshValue();
11015 },
11016
11017 _setOption: function( key, value ) {
11018 if ( key === "max" ) {
11019 // Don't allow a max less than min
11020 value = Math.max( this.min, value );
11021 }
11022 if ( key === "disabled" ) {
11023 this.element
11024 .toggleClass( "ui-state-disabled", !!value )
11025 .attr( "aria-disabled", value );
11026 }
11027 this._super( key, value );
11028 },
11029
11030 _percentage: function() {
11031 return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
11032 },
11033
11034 _refreshValue: function() {
11035 var value = this.options.value,
11036 percentage = this._percentage();
11037
11038 this.valueDiv
11039 .toggle( this.indeterminate || value > this.min )
11040 .toggleClass( "ui-corner-right", value === this.options.max )
11041 .width( percentage.toFixed(0) + "%" );
11042
11043 this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
11044
11045 if ( this.indeterminate ) {
11046 this.element.removeAttr( "aria-valuenow" );
11047 if ( !this.overlayDiv ) {
11048 this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
11049 }
11050 } else {
11051 this.element.attr({
11052 "aria-valuemax": this.options.max,
11053 "aria-valuenow": value
11054 });
11055 if ( this.overlayDiv ) {
11056 this.overlayDiv.remove();
11057 this.overlayDiv = null;
11058 }
11059 }
11060
11061 if ( this.oldValue !== value ) {
11062 this.oldValue = value;
11063 this._trigger( "change" );
11064 }
11065 if ( value === this.options.max ) {
11066 this._trigger( "complete" );
11067 }
11068 }
11069});
11070
11071
11072/*!
11073 * jQuery UI Selectmenu 1.11.3
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/selectmenu
11081 */
11082
11083
11084var selectmenu = $.widget( "ui.selectmenu", {
11085 version: "1.11.3",
11086 defaultElement: "<select>",
11087 options: {
11088 appendTo: null,
11089 disabled: null,
11090 icons: {
11091 button: "ui-icon-triangle-1-s"
11092 },
11093 position: {
11094 my: "left top",
11095 at: "left bottom",
11096 collision: "none"
11097 },
11098 width: null,
11099
11100 // callbacks
11101 change: null,
11102 close: null,
11103 focus: null,
11104 open: null,
11105 select: null
11106 },
11107
11108 _create: function() {
11109 var selectmenuId = this.element.uniqueId().attr( "id" );
11110 this.ids = {
11111 element: selectmenuId,
11112 button: selectmenuId + "-button",
11113 menu: selectmenuId + "-menu"
11114 };
11115
11116 this._drawButton();
11117 this._drawMenu();
11118
11119 if ( this.options.disabled ) {
11120 this.disable();
11121 }
11122 },
11123
11124 _drawButton: function() {
11125 var that = this;
11126
11127 // Associate existing label with the new button
11128 this.label = $( "label[for='" + this.ids.element + "']" ).attr( "for", this.ids.button );
11129 this._on( this.label, {
11130 click: function( event ) {
11131 this.button.focus();
11132 event.preventDefault();
11133 }
11134 });
11135
11136 // Hide original select element
11137 this.element.hide();
11138
11139 // Create button
11140 this.button = $( "<span>", {
11141 "class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all",
11142 tabindex: this.options.disabled ? -1 : 0,
11143 id: this.ids.button,
11144 role: "combobox",
11145 "aria-expanded": "false",
11146 "aria-autocomplete": "list",
11147 "aria-owns": this.ids.menu,
11148 "aria-haspopup": "true"
11149 })
11150 .insertAfter( this.element );
11151
11152 $( "<span>", {
11153 "class": "ui-icon " + this.options.icons.button
11154 })
11155 .prependTo( this.button );
11156
11157 this.buttonText = $( "<span>", {
11158 "class": "ui-selectmenu-text"
11159 })
11160 .appendTo( this.button );
11161
11162 this._setText( this.buttonText, this.element.find( "option:selected" ).text() );
11163 this._resizeButton();
11164
11165 this._on( this.button, this._buttonEvents );
11166 this.button.one( "focusin", function() {
11167
11168 // Delay rendering the menu items until the button receives focus.
11169 // The menu may have already been rendered via a programmatic open.
11170 if ( !that.menuItems ) {
11171 that._refreshMenu();
11172 }
11173 });
11174 this._hoverable( this.button );
11175 this._focusable( this.button );
11176 },
11177
11178 _drawMenu: function() {
11179 var that = this;
11180
11181 // Create menu
11182 this.menu = $( "<ul>", {
11183 "aria-hidden": "true",
11184 "aria-labelledby": this.ids.button,
11185 id: this.ids.menu
11186 });
11187
11188 // Wrap menu
11189 this.menuWrap = $( "<div>", {
11190 "class": "ui-selectmenu-menu ui-front"
11191 })
11192 .append( this.menu )
11193 .appendTo( this._appendTo() );
11194
11195 // Initialize menu widget
11196 this.menuInstance = this.menu
11197 .menu({
11198 role: "listbox",
11199 select: function( event, ui ) {
11200 event.preventDefault();
11201
11202 // support: IE8
11203 // If the item was selected via a click, the text selection
11204 // will be destroyed in IE
11205 that._setSelection();
11206
11207 that._select( ui.item.data( "ui-selectmenu-item" ), event );
11208 },
11209 focus: function( event, ui ) {
11210 var item = ui.item.data( "ui-selectmenu-item" );
11211
11212 // Prevent inital focus from firing and check if its a newly focused item
11213 if ( that.focusIndex != null && item.index !== that.focusIndex ) {
11214 that._trigger( "focus", event, { item: item } );
11215 if ( !that.isOpen ) {
11216 that._select( item, event );
11217 }
11218 }
11219 that.focusIndex = item.index;
11220
11221 that.button.attr( "aria-activedescendant",
11222 that.menuItems.eq( item.index ).attr( "id" ) );
11223 }
11224 })
11225 .menu( "instance" );
11226
11227 // Adjust menu styles to dropdown
11228 this.menu
11229 .addClass( "ui-corner-bottom" )
11230 .removeClass( "ui-corner-all" );
11231
11232 // Don't close the menu on mouseleave
11233 this.menuInstance._off( this.menu, "mouseleave" );
11234
11235 // Cancel the menu's collapseAll on document click
11236 this.menuInstance._closeOnDocumentClick = function() {
11237 return false;
11238 };
11239
11240 // Selects often contain empty items, but never contain dividers
11241 this.menuInstance._isDivider = function() {
11242 return false;
11243 };
11244 },
11245
11246 refresh: function() {
11247 this._refreshMenu();
11248 this._setText( this.buttonText, this._getSelectedItem().text() );
11249 if ( !this.options.width ) {
11250 this._resizeButton();
11251 }
11252 },
11253
11254 _refreshMenu: function() {
11255 this.menu.empty();
11256
11257 var item,
11258 options = this.element.find( "option" );
11259
11260 if ( !options.length ) {
11261 return;
11262 }
11263
11264 this._parseOptions( options );
11265 this._renderMenu( this.menu, this.items );
11266
11267 this.menuInstance.refresh();
11268 this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" );
11269
11270 item = this._getSelectedItem();
11271
11272 // Update the menu to have the correct item focused
11273 this.menuInstance.focus( null, item );
11274 this._setAria( item.data( "ui-selectmenu-item" ) );
11275
11276 // Set disabled state
11277 this._setOption( "disabled", this.element.prop( "disabled" ) );
11278 },
11279
11280 open: function( event ) {
11281 if ( this.options.disabled ) {
11282 return;
11283 }
11284
11285 // If this is the first time the menu is being opened, render the items
11286 if ( !this.menuItems ) {
11287 this._refreshMenu();
11288 } else {
11289
11290 // Menu clears focus on close, reset focus to selected item
11291 this.menu.find( ".ui-state-focus" ).removeClass( "ui-state-focus" );
11292 this.menuInstance.focus( null, this._getSelectedItem() );
11293 }
11294
11295 this.isOpen = true;
11296 this._toggleAttr();
11297 this._resizeMenu();
11298 this._position();
11299
11300 this._on( this.document, this._documentClick );
11301
11302 this._trigger( "open", event );
11303 },
11304
11305 _position: function() {
11306 this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
11307 },
11308
11309 close: function( event ) {
11310 if ( !this.isOpen ) {
11311 return;
11312 }
11313
11314 this.isOpen = false;
11315 this._toggleAttr();
11316
11317 this.range = null;
11318 this._off( this.document );
11319
11320 this._trigger( "close", event );
11321 },
11322
11323 widget: function() {
11324 return this.button;
11325 },
11326
11327 menuWidget: function() {
11328 return this.menu;
11329 },
11330
11331 _renderMenu: function( ul, items ) {
11332 var that = this,
11333 currentOptgroup = "";
11334
11335 $.each( items, function( index, item ) {
11336 if ( item.optgroup !== currentOptgroup ) {
11337 $( "<li>", {
11338 "class": "ui-selectmenu-optgroup ui-menu-divider" +
11339 ( item.element.parent( "optgroup" ).prop( "disabled" ) ?
11340 " ui-state-disabled" :
11341 "" ),
11342 text: item.optgroup
11343 })
11344 .appendTo( ul );
11345
11346 currentOptgroup = item.optgroup;
11347 }
11348
11349 that._renderItemData( ul, item );
11350 });
11351 },
11352
11353 _renderItemData: function( ul, item ) {
11354 return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
11355 },
11356
11357 _renderItem: function( ul, item ) {
11358 var li = $( "<li>" );
11359
11360 if ( item.disabled ) {
11361 li.addClass( "ui-state-disabled" );
11362 }
11363 this._setText( li, item.label );
11364
11365 return li.appendTo( ul );
11366 },
11367
11368 _setText: function( element, value ) {
11369 if ( value ) {
11370 element.text( value );
11371 } else {
11372 element.html( "&#160;" );
11373 }
11374 },
11375
11376 _move: function( direction, event ) {
11377 var item, next,
11378 filter = ".ui-menu-item";
11379
11380 if ( this.isOpen ) {
11381 item = this.menuItems.eq( this.focusIndex );
11382 } else {
11383 item = this.menuItems.eq( this.element[ 0 ].selectedIndex );
11384 filter += ":not(.ui-state-disabled)";
11385 }
11386
11387 if ( direction === "first" || direction === "last" ) {
11388 next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
11389 } else {
11390 next = item[ direction + "All" ]( filter ).eq( 0 );
11391 }
11392
11393 if ( next.length ) {
11394 this.menuInstance.focus( event, next );
11395 }
11396 },
11397
11398 _getSelectedItem: function() {
11399 return this.menuItems.eq( this.element[ 0 ].selectedIndex );
11400 },
11401
11402 _toggle: function( event ) {
11403 this[ this.isOpen ? "close" : "open" ]( event );
11404 },
11405
11406 _setSelection: function() {
11407 var selection;
11408
11409 if ( !this.range ) {
11410 return;
11411 }
11412
11413 if ( window.getSelection ) {
11414 selection = window.getSelection();
11415 selection.removeAllRanges();
11416 selection.addRange( this.range );
11417
11418 // support: IE8
11419 } else {
11420 this.range.select();
11421 }
11422
11423 // support: IE
11424 // Setting the text selection kills the button focus in IE, but
11425 // restoring the focus doesn't kill the selection.
11426 this.button.focus();
11427 },
11428
11429 _documentClick: {
11430 mousedown: function( event ) {
11431 if ( !this.isOpen ) {
11432 return;
11433 }
11434
11435 if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + this.ids.button ).length ) {
11436 this.close( event );
11437 }
11438 }
11439 },
11440
11441 _buttonEvents: {
11442
11443 // Prevent text selection from being reset when interacting with the selectmenu (#10144)
11444 mousedown: function() {
11445 var selection;
11446
11447 if ( window.getSelection ) {
11448 selection = window.getSelection();
11449 if ( selection.rangeCount ) {
11450 this.range = selection.getRangeAt( 0 );
11451 }
11452
11453 // support: IE8
11454 } else {
11455 this.range = document.selection.createRange();
11456 }
11457 },
11458
11459 click: function( event ) {
11460 this._setSelection();
11461 this._toggle( event );
11462 },
11463
11464 keydown: function( event ) {
11465 var preventDefault = true;
11466 switch ( event.keyCode ) {
11467 case $.ui.keyCode.TAB:
11468 case $.ui.keyCode.ESCAPE:
11469 this.close( event );
11470 preventDefault = false;
11471 break;
11472 case $.ui.keyCode.ENTER:
11473 if ( this.isOpen ) {
11474 this._selectFocusedItem( event );
11475 }
11476 break;
11477 case $.ui.keyCode.UP:
11478 if ( event.altKey ) {
11479 this._toggle( event );
11480 } else {
11481 this._move( "prev", event );
11482 }
11483 break;
11484 case $.ui.keyCode.DOWN:
11485 if ( event.altKey ) {
11486 this._toggle( event );
11487 } else {
11488 this._move( "next", event );
11489 }
11490 break;
11491 case $.ui.keyCode.SPACE:
11492 if ( this.isOpen ) {
11493 this._selectFocusedItem( event );
11494 } else {
11495 this._toggle( event );
11496 }
11497 break;
11498 case $.ui.keyCode.LEFT:
11499 this._move( "prev", event );
11500 break;
11501 case $.ui.keyCode.RIGHT:
11502 this._move( "next", event );
11503 break;
11504 case $.ui.keyCode.HOME:
11505 case $.ui.keyCode.PAGE_UP:
11506 this._move( "first", event );
11507 break;
11508 case $.ui.keyCode.END:
11509 case $.ui.keyCode.PAGE_DOWN:
11510 this._move( "last", event );
11511 break;
11512 default:
11513 this.menu.trigger( event );
11514 preventDefault = false;
11515 }
11516
11517 if ( preventDefault ) {
11518 event.preventDefault();
11519 }
11520 }
11521 },
11522
11523 _selectFocusedItem: function( event ) {
11524 var item = this.menuItems.eq( this.focusIndex );
11525 if ( !item.hasClass( "ui-state-disabled" ) ) {
11526 this._select( item.data( "ui-selectmenu-item" ), event );
11527 }
11528 },
11529
11530 _select: function( item, event ) {
11531 var oldIndex = this.element[ 0 ].selectedIndex;
11532
11533 // Change native select element
11534 this.element[ 0 ].selectedIndex = item.index;
11535 this._setText( this.buttonText, item.label );
11536 this._setAria( item );
11537 this._trigger( "select", event, { item: item } );
11538
11539 if ( item.index !== oldIndex ) {
11540 this._trigger( "change", event, { item: item } );
11541 }
11542
11543 this.close( event );
11544 },
11545
11546 _setAria: function( item ) {
11547 var id = this.menuItems.eq( item.index ).attr( "id" );
11548
11549 this.button.attr({
11550 "aria-labelledby": id,
11551 "aria-activedescendant": id
11552 });
11553 this.menu.attr( "aria-activedescendant", id );
11554 },
11555
11556 _setOption: function( key, value ) {
11557 if ( key === "icons" ) {
11558 this.button.find( "span.ui-icon" )
11559 .removeClass( this.options.icons.button )
11560 .addClass( value.button );
11561 }
11562
11563 this._super( key, value );
11564
11565 if ( key === "appendTo" ) {
11566 this.menuWrap.appendTo( this._appendTo() );
11567 }
11568
11569 if ( key === "disabled" ) {
11570 this.menuInstance.option( "disabled", value );
11571 this.button
11572 .toggleClass( "ui-state-disabled", value )
11573 .attr( "aria-disabled", value );
11574
11575 this.element.prop( "disabled", value );
11576 if ( value ) {
11577 this.button.attr( "tabindex", -1 );
11578 this.close();
11579 } else {
11580 this.button.attr( "tabindex", 0 );
11581 }
11582 }
11583
11584 if ( key === "width" ) {
11585 this._resizeButton();
11586 }
11587 },
11588
11589 _appendTo: function() {
11590 var element = this.options.appendTo;
11591
11592 if ( element ) {
11593 element = element.jquery || element.nodeType ?
11594 $( element ) :
11595 this.document.find( element ).eq( 0 );
11596 }
11597
11598 if ( !element || !element[ 0 ] ) {
11599 element = this.element.closest( ".ui-front" );
11600 }
11601
11602 if ( !element.length ) {
11603 element = this.document[ 0 ].body;
11604 }
11605
11606 return element;
11607 },
11608
11609 _toggleAttr: function() {
11610 this.button
11611 .toggleClass( "ui-corner-top", this.isOpen )
11612 .toggleClass( "ui-corner-all", !this.isOpen )
11613 .attr( "aria-expanded", this.isOpen );
11614 this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen );
11615 this.menu.attr( "aria-hidden", !this.isOpen );
11616 },
11617
11618 _resizeButton: function() {
11619 var width = this.options.width;
11620
11621 if ( !width ) {
11622 width = this.element.show().outerWidth();
11623 this.element.hide();
11624 }
11625
11626 this.button.outerWidth( width );
11627 },
11628
11629 _resizeMenu: function() {
11630 this.menu.outerWidth( Math.max(
11631 this.button.outerWidth(),
11632
11633 // support: IE10
11634 // IE10 wraps long text (possibly a rounding bug)
11635 // so we add 1px to avoid the wrapping
11636 this.menu.width( "" ).outerWidth() + 1
11637 ) );
11638 },
11639
11640 _getCreateOptions: function() {
11641 return { disabled: this.element.prop( "disabled" ) };
11642 },
11643
11644 _parseOptions: function( options ) {
11645 var data = [];
11646 options.each(function( index, item ) {
11647 var option = $( item ),
11648 optgroup = option.parent( "optgroup" );
11649 data.push({
11650 element: option,
11651 index: index,
11652 value: option.val(),
11653 label: option.text(),
11654 optgroup: optgroup.attr( "label" ) || "",
11655 disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
11656 });
11657 });
11658 this.items = data;
11659 },
11660
11661 _destroy: function() {
11662 this.menuWrap.remove();
11663 this.button.remove();
11664 this.element.show();
11665 this.element.removeUniqueId();
11666 this.label.attr( "for", this.ids.element );
11667 }
11668});
11669
11670
11671/*!
11672 * jQuery UI Slider 1.11.3
11673 * http://jqueryui.com
11674 *
11675 * Copyright jQuery Foundation and other contributors
11676 * Released under the MIT license.
11677 * http://jquery.org/license
11678 *
11679 * http://api.jqueryui.com/slider/
11680 */
11681
11682
11683var slider = $.widget( "ui.slider", $.ui.mouse, {
11684 version: "1.11.3",
11685 widgetEventPrefix: "slide",
11686
11687 options: {
11688 animate: false,
11689 distance: 0,
11690 max: 100,
11691 min: 0,
11692 orientation: "horizontal",
11693 range: false,
11694 step: 1,
11695 value: 0,
11696 values: null,
11697
11698 // callbacks
11699 change: null,
11700 slide: null,
11701 start: null,
11702 stop: null
11703 },
11704
11705 // number of pages in a slider
11706 // (how many times can you page up/down to go through the whole range)
11707 numPages: 5,
11708
11709 _create: function() {
11710 this._keySliding = false;
11711 this._mouseSliding = false;
11712 this._animateOff = true;
11713 this._handleIndex = null;
11714 this._detectOrientation();
11715 this._mouseInit();
11716 this._calculateNewMax();
11717
11718 this.element
11719 .addClass( "ui-slider" +
11720 " ui-slider-" + this.orientation +
11721 " ui-widget" +
11722 " ui-widget-content" +
11723 " ui-corner-all");
11724
11725 this._refresh();
11726 this._setOption( "disabled", this.options.disabled );
11727
11728 this._animateOff = false;
11729 },
11730
11731 _refresh: function() {
11732 this._createRange();
11733 this._createHandles();
11734 this._setupEvents();
11735 this._refreshValue();
11736 },
11737
11738 _createHandles: function() {
11739 var i, handleCount,
11740 options = this.options,
11741 existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
11742 handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>",
11743 handles = [];
11744
11745 handleCount = ( options.values && options.values.length ) || 1;
11746
11747 if ( existingHandles.length > handleCount ) {
11748 existingHandles.slice( handleCount ).remove();
11749 existingHandles = existingHandles.slice( 0, handleCount );
11750 }
11751
11752 for ( i = existingHandles.length; i < handleCount; i++ ) {
11753 handles.push( handle );
11754 }
11755
11756 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
11757
11758 this.handle = this.handles.eq( 0 );
11759
11760 this.handles.each(function( i ) {
11761 $( this ).data( "ui-slider-handle-index", i );
11762 });
11763 },
11764
11765 _createRange: function() {
11766 var options = this.options,
11767 classes = "";
11768
11769 if ( options.range ) {
11770 if ( options.range === true ) {
11771 if ( !options.values ) {
11772 options.values = [ this._valueMin(), this._valueMin() ];
11773 } else if ( options.values.length && options.values.length !== 2 ) {
11774 options.values = [ options.values[0], options.values[0] ];
11775 } else if ( $.isArray( options.values ) ) {
11776 options.values = options.values.slice(0);
11777 }
11778 }
11779
11780 if ( !this.range || !this.range.length ) {
11781 this.range = $( "<div></div>" )
11782 .appendTo( this.element );
11783
11784 classes = "ui-slider-range" +
11785 // note: this isn't the most fittingly semantic framework class for this element,
11786 // but worked best visually with a variety of themes
11787 " ui-widget-header ui-corner-all";
11788 } else {
11789 this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
11790 // Handle range switching from true to min/max
11791 .css({
11792 "left": "",
11793 "bottom": ""
11794 });
11795 }
11796
11797 this.range.addClass( classes +
11798 ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
11799 } else {
11800 if ( this.range ) {
11801 this.range.remove();
11802 }
11803 this.range = null;
11804 }
11805 },
11806
11807 _setupEvents: function() {
11808 this._off( this.handles );
11809 this._on( this.handles, this._handleEvents );
11810 this._hoverable( this.handles );
11811 this._focusable( this.handles );
11812 },
11813
11814 _destroy: function() {
11815 this.handles.remove();
11816 if ( this.range ) {
11817 this.range.remove();
11818 }
11819
11820 this.element
11821 .removeClass( "ui-slider" +
11822 " ui-slider-horizontal" +
11823 " ui-slider-vertical" +
11824 " ui-widget" +
11825 " ui-widget-content" +
11826 " ui-corner-all" );
11827
11828 this._mouseDestroy();
11829 },
11830
11831 _mouseCapture: function( event ) {
11832 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
11833 that = this,
11834 o = this.options;
11835
11836 if ( o.disabled ) {
11837 return false;
11838 }
11839
11840 this.elementSize = {
11841 width: this.element.outerWidth(),
11842 height: this.element.outerHeight()
11843 };
11844 this.elementOffset = this.element.offset();
11845
11846 position = { x: event.pageX, y: event.pageY };
11847 normValue = this._normValueFromMouse( position );
11848 distance = this._valueMax() - this._valueMin() + 1;
11849 this.handles.each(function( i ) {
11850 var thisDistance = Math.abs( normValue - that.values(i) );
11851 if (( distance > thisDistance ) ||
11852 ( distance === thisDistance &&
11853 (i === that._lastChangedValue || that.values(i) === o.min ))) {
11854 distance = thisDistance;
11855 closestHandle = $( this );
11856 index = i;
11857 }
11858 });
11859
11860 allowed = this._start( event, index );
11861 if ( allowed === false ) {
11862 return false;
11863 }
11864 this._mouseSliding = true;
11865
11866 this._handleIndex = index;
11867
11868 closestHandle
11869 .addClass( "ui-state-active" )
11870 .focus();
11871
11872 offset = closestHandle.offset();
11873 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
11874 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
11875 left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
11876 top: event.pageY - offset.top -
11877 ( closestHandle.height() / 2 ) -
11878 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
11879 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
11880 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
11881 };
11882
11883 if ( !this.handles.hasClass( "ui-state-hover" ) ) {
11884 this._slide( event, index, normValue );
11885 }
11886 this._animateOff = true;
11887 return true;
11888 },
11889
11890 _mouseStart: function() {
11891 return true;
11892 },
11893
11894 _mouseDrag: function( event ) {
11895 var position = { x: event.pageX, y: event.pageY },
11896 normValue = this._normValueFromMouse( position );
11897
11898 this._slide( event, this._handleIndex, normValue );
11899
11900 return false;
11901 },
11902
11903 _mouseStop: function( event ) {
11904 this.handles.removeClass( "ui-state-active" );
11905 this._mouseSliding = false;
11906
11907 this._stop( event, this._handleIndex );
11908 this._change( event, this._handleIndex );
11909
11910 this._handleIndex = null;
11911 this._clickOffset = null;
11912 this._animateOff = false;
11913
11914 return false;
11915 },
11916
11917 _detectOrientation: function() {
11918 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
11919 },
11920
11921 _normValueFromMouse: function( position ) {
11922 var pixelTotal,
11923 pixelMouse,
11924 percentMouse,
11925 valueTotal,
11926 valueMouse;
11927
11928 if ( this.orientation === "horizontal" ) {
11929 pixelTotal = this.elementSize.width;
11930 pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
11931 } else {
11932 pixelTotal = this.elementSize.height;
11933 pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
11934 }
11935
11936 percentMouse = ( pixelMouse / pixelTotal );
11937 if ( percentMouse > 1 ) {
11938 percentMouse = 1;
11939 }
11940 if ( percentMouse < 0 ) {
11941 percentMouse = 0;
11942 }
11943 if ( this.orientation === "vertical" ) {
11944 percentMouse = 1 - percentMouse;
11945 }
11946
11947 valueTotal = this._valueMax() - this._valueMin();
11948 valueMouse = this._valueMin() + percentMouse * valueTotal;
11949
11950 return this._trimAlignValue( valueMouse );
11951 },
11952
11953 _start: function( event, index ) {
11954 var uiHash = {
11955 handle: this.handles[ index ],
11956 value: this.value()
11957 };
11958 if ( this.options.values && this.options.values.length ) {
11959 uiHash.value = this.values( index );
11960 uiHash.values = this.values();
11961 }
11962 return this._trigger( "start", event, uiHash );
11963 },
11964
11965 _slide: function( event, index, newVal ) {
11966 var otherVal,
11967 newValues,
11968 allowed;
11969
11970 if ( this.options.values && this.options.values.length ) {
11971 otherVal = this.values( index ? 0 : 1 );
11972
11973 if ( ( this.options.values.length === 2 && this.options.range === true ) &&
11974 ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
11975 ) {
11976 newVal = otherVal;
11977 }
11978
11979 if ( newVal !== this.values( index ) ) {
11980 newValues = this.values();
11981 newValues[ index ] = newVal;
11982 // A slide can be canceled by returning false from the slide callback
11983 allowed = this._trigger( "slide", event, {
11984 handle: this.handles[ index ],
11985 value: newVal,
11986 values: newValues
11987 } );
11988 otherVal = this.values( index ? 0 : 1 );
11989 if ( allowed !== false ) {
11990 this.values( index, newVal );
11991 }
11992 }
11993 } else {
11994 if ( newVal !== this.value() ) {
11995 // A slide can be canceled by returning false from the slide callback
11996 allowed = this._trigger( "slide", event, {
11997 handle: this.handles[ index ],
11998 value: newVal
11999 } );
12000 if ( allowed !== false ) {
12001 this.value( newVal );
12002 }
12003 }
12004 }
12005 },
12006
12007 _stop: function( event, index ) {
12008 var uiHash = {
12009 handle: this.handles[ index ],
12010 value: this.value()
12011 };
12012 if ( this.options.values && this.options.values.length ) {
12013 uiHash.value = this.values( index );
12014 uiHash.values = this.values();
12015 }
12016
12017 this._trigger( "stop", event, uiHash );
12018 },
12019
12020 _change: function( event, index ) {
12021 if ( !this._keySliding && !this._mouseSliding ) {
12022 var uiHash = {
12023 handle: this.handles[ index ],
12024 value: this.value()
12025 };
12026 if ( this.options.values && this.options.values.length ) {
12027 uiHash.value = this.values( index );
12028 uiHash.values = this.values();
12029 }
12030
12031 //store the last changed value index for reference when handles overlap
12032 this._lastChangedValue = index;
12033
12034 this._trigger( "change", event, uiHash );
12035 }
12036 },
12037
12038 value: function( newValue ) {
12039 if ( arguments.length ) {
12040 this.options.value = this._trimAlignValue( newValue );
12041 this._refreshValue();
12042 this._change( null, 0 );
12043 return;
12044 }
12045
12046 return this._value();
12047 },
12048
12049 values: function( index, newValue ) {
12050 var vals,
12051 newValues,
12052 i;
12053
12054 if ( arguments.length > 1 ) {
12055 this.options.values[ index ] = this._trimAlignValue( newValue );
12056 this._refreshValue();
12057 this._change( null, index );
12058 return;
12059 }
12060
12061 if ( arguments.length ) {
12062 if ( $.isArray( arguments[ 0 ] ) ) {
12063 vals = this.options.values;
12064 newValues = arguments[ 0 ];
12065 for ( i = 0; i < vals.length; i += 1 ) {
12066 vals[ i ] = this._trimAlignValue( newValues[ i ] );
12067 this._change( null, i );
12068 }
12069 this._refreshValue();
12070 } else {
12071 if ( this.options.values && this.options.values.length ) {
12072 return this._values( index );
12073 } else {
12074 return this.value();
12075 }
12076 }
12077 } else {
12078 return this._values();
12079 }
12080 },
12081
12082 _setOption: function( key, value ) {
12083 var i,
12084 valsLength = 0;
12085
12086 if ( key === "range" && this.options.range === true ) {
12087 if ( value === "min" ) {
12088 this.options.value = this._values( 0 );
12089 this.options.values = null;
12090 } else if ( value === "max" ) {
12091 this.options.value = this._values( this.options.values.length - 1 );
12092 this.options.values = null;
12093 }
12094 }
12095
12096 if ( $.isArray( this.options.values ) ) {
12097 valsLength = this.options.values.length;
12098 }
12099
12100 if ( key === "disabled" ) {
12101 this.element.toggleClass( "ui-state-disabled", !!value );
12102 }
12103
12104 this._super( key, value );
12105
12106 switch ( key ) {
12107 case "orientation":
12108 this._detectOrientation();
12109 this.element
12110 .removeClass( "ui-slider-horizontal ui-slider-vertical" )
12111 .addClass( "ui-slider-" + this.orientation );
12112 this._refreshValue();
12113
12114 // Reset positioning from previous orientation
12115 this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
12116 break;
12117 case "value":
12118 this._animateOff = true;
12119 this._refreshValue();
12120 this._change( null, 0 );
12121 this._animateOff = false;
12122 break;
12123 case "values":
12124 this._animateOff = true;
12125 this._refreshValue();
12126 for ( i = 0; i < valsLength; i += 1 ) {
12127 this._change( null, i );
12128 }
12129 this._animateOff = false;
12130 break;
12131 case "step":
12132 case "min":
12133 case "max":
12134 this._animateOff = true;
12135 this._calculateNewMax();
12136 this._refreshValue();
12137 this._animateOff = false;
12138 break;
12139 case "range":
12140 this._animateOff = true;
12141 this._refresh();
12142 this._animateOff = false;
12143 break;
12144 }
12145 },
12146
12147 //internal value getter
12148 // _value() returns value trimmed by min and max, aligned by step
12149 _value: function() {
12150 var val = this.options.value;
12151 val = this._trimAlignValue( val );
12152
12153 return val;
12154 },
12155
12156 //internal values getter
12157 // _values() returns array of values trimmed by min and max, aligned by step
12158 // _values( index ) returns single value trimmed by min and max, aligned by step
12159 _values: function( index ) {
12160 var val,
12161 vals,
12162 i;
12163
12164 if ( arguments.length ) {
12165 val = this.options.values[ index ];
12166 val = this._trimAlignValue( val );
12167
12168 return val;
12169 } else if ( this.options.values && this.options.values.length ) {
12170 // .slice() creates a copy of the array
12171 // this copy gets trimmed by min and max and then returned
12172 vals = this.options.values.slice();
12173 for ( i = 0; i < vals.length; i += 1) {
12174 vals[ i ] = this._trimAlignValue( vals[ i ] );
12175 }
12176
12177 return vals;
12178 } else {
12179 return [];
12180 }
12181 },
12182
12183 // returns the step-aligned value that val is closest to, between (inclusive) min and max
12184 _trimAlignValue: function( val ) {
12185 if ( val <= this._valueMin() ) {
12186 return this._valueMin();
12187 }
12188 if ( val >= this._valueMax() ) {
12189 return this._valueMax();
12190 }
12191 var step = ( this.options.step > 0 ) ? this.options.step : 1,
12192 valModStep = (val - this._valueMin()) % step,
12193 alignValue = val - valModStep;
12194
12195 if ( Math.abs(valModStep) * 2 >= step ) {
12196 alignValue += ( valModStep > 0 ) ? step : ( -step );
12197 }
12198
12199 // Since JavaScript has problems with large floats, round
12200 // the final value to 5 digits after the decimal point (see #4124)
12201 return parseFloat( alignValue.toFixed(5) );
12202 },
12203
12204 _calculateNewMax: function() {
12205 var max = this.options.max,
12206 min = this._valueMin(),
12207 step = this.options.step,
12208 aboveMin = Math.floor( ( max - min ) / step ) * step;
12209 max = aboveMin + min;
12210 this.max = parseFloat( max.toFixed( this._precision() ) );
12211 },
12212
12213 _precision: function() {
12214 var precision = this._precisionOf( this.options.step );
12215 if ( this.options.min !== null ) {
12216 precision = Math.max( precision, this._precisionOf( this.options.min ) );
12217 }
12218 return precision;
12219 },
12220
12221 _precisionOf: function( num ) {
12222 var str = num.toString(),
12223 decimal = str.indexOf( "." );
12224 return decimal === -1 ? 0 : str.length - decimal - 1;
12225 },
12226
12227 _valueMin: function() {
12228 return this.options.min;
12229 },
12230
12231 _valueMax: function() {
12232 return this.max;
12233 },
12234
12235 _refreshValue: function() {
12236 var lastValPercent, valPercent, value, valueMin, valueMax,
12237 oRange = this.options.range,
12238 o = this.options,
12239 that = this,
12240 animate = ( !this._animateOff ) ? o.animate : false,
12241 _set = {};
12242
12243 if ( this.options.values && this.options.values.length ) {
12244 this.handles.each(function( i ) {
12245 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
12246 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
12247 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
12248 if ( that.options.range === true ) {
12249 if ( that.orientation === "horizontal" ) {
12250 if ( i === 0 ) {
12251 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
12252 }
12253 if ( i === 1 ) {
12254 that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
12255 }
12256 } else {
12257 if ( i === 0 ) {
12258 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
12259 }
12260 if ( i === 1 ) {
12261 that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
12262 }
12263 }
12264 }
12265 lastValPercent = valPercent;
12266 });
12267 } else {
12268 value = this.value();
12269 valueMin = this._valueMin();
12270 valueMax = this._valueMax();
12271 valPercent = ( valueMax !== valueMin ) ?
12272 ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
12273 0;
12274 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
12275 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
12276
12277 if ( oRange === "min" && this.orientation === "horizontal" ) {
12278 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
12279 }
12280 if ( oRange === "max" && this.orientation === "horizontal" ) {
12281 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
12282 }
12283 if ( oRange === "min" && this.orientation === "vertical" ) {
12284 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
12285 }
12286 if ( oRange === "max" && this.orientation === "vertical" ) {
12287 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
12288 }
12289 }
12290 },
12291
12292 _handleEvents: {
12293 keydown: function( event ) {
12294 var allowed, curVal, newVal, step,
12295 index = $( event.target ).data( "ui-slider-handle-index" );
12296
12297 switch ( event.keyCode ) {
12298 case $.ui.keyCode.HOME:
12299 case $.ui.keyCode.END:
12300 case $.ui.keyCode.PAGE_UP:
12301 case $.ui.keyCode.PAGE_DOWN:
12302 case $.ui.keyCode.UP:
12303 case $.ui.keyCode.RIGHT:
12304 case $.ui.keyCode.DOWN:
12305 case $.ui.keyCode.LEFT:
12306 event.preventDefault();
12307 if ( !this._keySliding ) {
12308 this._keySliding = true;
12309 $( event.target ).addClass( "ui-state-active" );
12310 allowed = this._start( event, index );
12311 if ( allowed === false ) {
12312 return;
12313 }
12314 }
12315 break;
12316 }
12317
12318 step = this.options.step;
12319 if ( this.options.values && this.options.values.length ) {
12320 curVal = newVal = this.values( index );
12321 } else {
12322 curVal = newVal = this.value();
12323 }
12324
12325 switch ( event.keyCode ) {
12326 case $.ui.keyCode.HOME:
12327 newVal = this._valueMin();
12328 break;
12329 case $.ui.keyCode.END:
12330 newVal = this._valueMax();
12331 break;
12332 case $.ui.keyCode.PAGE_UP:
12333 newVal = this._trimAlignValue(
12334 curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
12335 );
12336 break;
12337 case $.ui.keyCode.PAGE_DOWN:
12338 newVal = this._trimAlignValue(
12339 curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) );
12340 break;
12341 case $.ui.keyCode.UP:
12342 case $.ui.keyCode.RIGHT:
12343 if ( curVal === this._valueMax() ) {
12344 return;
12345 }
12346 newVal = this._trimAlignValue( curVal + step );
12347 break;
12348 case $.ui.keyCode.DOWN:
12349 case $.ui.keyCode.LEFT:
12350 if ( curVal === this._valueMin() ) {
12351 return;
12352 }
12353 newVal = this._trimAlignValue( curVal - step );
12354 break;
12355 }
12356
12357 this._slide( event, index, newVal );
12358 },
12359 keyup: function( event ) {
12360 var index = $( event.target ).data( "ui-slider-handle-index" );
12361
12362 if ( this._keySliding ) {
12363 this._keySliding = false;
12364 this._stop( event, index );
12365 this._change( event, index );
12366 $( event.target ).removeClass( "ui-state-active" );
12367 }
12368 }
12369 }
12370});
12371
12372
12373/*!
12374 * jQuery UI Spinner 1.11.3
12375 * http://jqueryui.com
12376 *
12377 * Copyright jQuery Foundation and other contributors
12378 * Released under the MIT license.
12379 * http://jquery.org/license
12380 *
12381 * http://api.jqueryui.com/spinner/
12382 */
12383
12384
12385function spinner_modifier( fn ) {
12386 return function() {
12387 var previous = this.element.val();
12388 fn.apply( this, arguments );
12389 this._refresh();
12390 if ( previous !== this.element.val() ) {
12391 this._trigger( "change" );
12392 }
12393 };
12394}
12395
12396var spinner = $.widget( "ui.spinner", {
12397 version: "1.11.3",
12398 defaultElement: "<input>",
12399 widgetEventPrefix: "spin",
12400 options: {
12401 culture: null,
12402 icons: {
12403 down: "ui-icon-triangle-1-s",
12404 up: "ui-icon-triangle-1-n"
12405 },
12406 incremental: true,
12407 max: null,
12408 min: null,
12409 numberFormat: null,
12410 page: 10,
12411 step: 1,
12412
12413 change: null,
12414 spin: null,
12415 start: null,
12416 stop: null
12417 },
12418
12419 _create: function() {
12420 // handle string values that need to be parsed
12421 this._setOption( "max", this.options.max );
12422 this._setOption( "min", this.options.min );
12423 this._setOption( "step", this.options.step );
12424
12425 // Only format if there is a value, prevents the field from being marked
12426 // as invalid in Firefox, see #9573.
12427 if ( this.value() !== "" ) {
12428 // Format the value, but don't constrain.
12429 this._value( this.element.val(), true );
12430 }
12431
12432 this._draw();
12433 this._on( this._events );
12434 this._refresh();
12435
12436 // turning off autocomplete prevents the browser from remembering the
12437 // value when navigating through history, so we re-enable autocomplete
12438 // if the page is unloaded before the widget is destroyed. #7790
12439 this._on( this.window, {
12440 beforeunload: function() {
12441 this.element.removeAttr( "autocomplete" );
12442 }
12443 });
12444 },
12445
12446 _getCreateOptions: function() {
12447 var options = {},
12448 element = this.element;
12449
12450 $.each( [ "min", "max", "step" ], function( i, option ) {
12451 var value = element.attr( option );
12452 if ( value !== undefined && value.length ) {
12453 options[ option ] = value;
12454 }
12455 });
12456
12457 return options;
12458 },
12459
12460 _events: {
12461 keydown: function( event ) {
12462 if ( this._start( event ) && this._keydown( event ) ) {
12463 event.preventDefault();
12464 }
12465 },
12466 keyup: "_stop",
12467 focus: function() {
12468 this.previous = this.element.val();
12469 },
12470 blur: function( event ) {
12471 if ( this.cancelBlur ) {
12472 delete this.cancelBlur;
12473 return;
12474 }
12475
12476 this._stop();
12477 this._refresh();
12478 if ( this.previous !== this.element.val() ) {
12479 this._trigger( "change", event );
12480 }
12481 },
12482 mousewheel: function( event, delta ) {
12483 if ( !delta ) {
12484 return;
12485 }
12486 if ( !this.spinning && !this._start( event ) ) {
12487 return false;
12488 }
12489
12490 this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
12491 clearTimeout( this.mousewheelTimer );
12492 this.mousewheelTimer = this._delay(function() {
12493 if ( this.spinning ) {
12494 this._stop( event );
12495 }
12496 }, 100 );
12497 event.preventDefault();
12498 },
12499 "mousedown .ui-spinner-button": function( event ) {
12500 var previous;
12501
12502 // We never want the buttons to have focus; whenever the user is
12503 // interacting with the spinner, the focus should be on the input.
12504 // If the input is focused then this.previous is properly set from
12505 // when the input first received focus. If the input is not focused
12506 // then we need to set this.previous based on the value before spinning.
12507 previous = this.element[0] === this.document[0].activeElement ?
12508 this.previous : this.element.val();
12509 function checkFocus() {
12510 var isActive = this.element[0] === this.document[0].activeElement;
12511 if ( !isActive ) {
12512 this.element.focus();
12513 this.previous = previous;
12514 // support: IE
12515 // IE sets focus asynchronously, so we need to check if focus
12516 // moved off of the input because the user clicked on the button.
12517 this._delay(function() {
12518 this.previous = previous;
12519 });
12520 }
12521 }
12522
12523 // ensure focus is on (or stays on) the text field
12524 event.preventDefault();
12525 checkFocus.call( this );
12526
12527 // support: IE
12528 // IE doesn't prevent moving focus even with event.preventDefault()
12529 // so we set a flag to know when we should ignore the blur event
12530 // and check (again) if focus moved off of the input.
12531 this.cancelBlur = true;
12532 this._delay(function() {
12533 delete this.cancelBlur;
12534 checkFocus.call( this );
12535 });
12536
12537 if ( this._start( event ) === false ) {
12538 return;
12539 }
12540
12541 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
12542 },
12543 "mouseup .ui-spinner-button": "_stop",
12544 "mouseenter .ui-spinner-button": function( event ) {
12545 // button will add ui-state-active if mouse was down while mouseleave and kept down
12546 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
12547 return;
12548 }
12549
12550 if ( this._start( event ) === false ) {
12551 return false;
12552 }
12553 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
12554 },
12555 // TODO: do we really want to consider this a stop?
12556 // shouldn't we just stop the repeater and wait until mouseup before
12557 // we trigger the stop event?
12558 "mouseleave .ui-spinner-button": "_stop"
12559 },
12560
12561 _draw: function() {
12562 var uiSpinner = this.uiSpinner = this.element
12563 .addClass( "ui-spinner-input" )
12564 .attr( "autocomplete", "off" )
12565 .wrap( this._uiSpinnerHtml() )
12566 .parent()
12567 // add buttons
12568 .append( this._buttonHtml() );
12569
12570 this.element.attr( "role", "spinbutton" );
12571
12572 // button bindings
12573 this.buttons = uiSpinner.find( ".ui-spinner-button" )
12574 .attr( "tabIndex", -1 )
12575 .button()
12576 .removeClass( "ui-corner-all" );
12577
12578 // IE 6 doesn't understand height: 50% for the buttons
12579 // unless the wrapper has an explicit height
12580 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
12581 uiSpinner.height() > 0 ) {
12582 uiSpinner.height( uiSpinner.height() );
12583 }
12584
12585 // disable spinner if element was already disabled
12586 if ( this.options.disabled ) {
12587 this.disable();
12588 }
12589 },
12590
12591 _keydown: function( event ) {
12592 var options = this.options,
12593 keyCode = $.ui.keyCode;
12594
12595 switch ( event.keyCode ) {
12596 case keyCode.UP:
12597 this._repeat( null, 1, event );
12598 return true;
12599 case keyCode.DOWN:
12600 this._repeat( null, -1, event );
12601 return true;
12602 case keyCode.PAGE_UP:
12603 this._repeat( null, options.page, event );
12604 return true;
12605 case keyCode.PAGE_DOWN:
12606 this._repeat( null, -options.page, event );
12607 return true;
12608 }
12609
12610 return false;
12611 },
12612
12613 _uiSpinnerHtml: function() {
12614 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
12615 },
12616
12617 _buttonHtml: function() {
12618 return "" +
12619 "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
12620 "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
12621 "</a>" +
12622 "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
12623 "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
12624 "</a>";
12625 },
12626
12627 _start: function( event ) {
12628 if ( !this.spinning && this._trigger( "start", event ) === false ) {
12629 return false;
12630 }
12631
12632 if ( !this.counter ) {
12633 this.counter = 1;
12634 }
12635 this.spinning = true;
12636 return true;
12637 },
12638
12639 _repeat: function( i, steps, event ) {
12640 i = i || 500;
12641
12642 clearTimeout( this.timer );
12643 this.timer = this._delay(function() {
12644 this._repeat( 40, steps, event );
12645 }, i );
12646
12647 this._spin( steps * this.options.step, event );
12648 },
12649
12650 _spin: function( step, event ) {
12651 var value = this.value() || 0;
12652
12653 if ( !this.counter ) {
12654 this.counter = 1;
12655 }
12656
12657 value = this._adjustValue( value + step * this._increment( this.counter ) );
12658
12659 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
12660 this._value( value );
12661 this.counter++;
12662 }
12663 },
12664
12665 _increment: function( i ) {
12666 var incremental = this.options.incremental;
12667
12668 if ( incremental ) {
12669 return $.isFunction( incremental ) ?
12670 incremental( i ) :
12671 Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
12672 }
12673
12674 return 1;
12675 },
12676
12677 _precision: function() {
12678 var precision = this._precisionOf( this.options.step );
12679 if ( this.options.min !== null ) {
12680 precision = Math.max( precision, this._precisionOf( this.options.min ) );
12681 }
12682 return precision;
12683 },
12684
12685 _precisionOf: function( num ) {
12686 var str = num.toString(),
12687 decimal = str.indexOf( "." );
12688 return decimal === -1 ? 0 : str.length - decimal - 1;
12689 },
12690
12691 _adjustValue: function( value ) {
12692 var base, aboveMin,
12693 options = this.options;
12694
12695 // make sure we're at a valid step
12696 // - find out where we are relative to the base (min or 0)
12697 base = options.min !== null ? options.min : 0;
12698 aboveMin = value - base;
12699 // - round to the nearest step
12700 aboveMin = Math.round(aboveMin / options.step) * options.step;
12701 // - rounding is based on 0, so adjust back to our base
12702 value = base + aboveMin;
12703
12704 // fix precision from bad JS floating point math
12705 value = parseFloat( value.toFixed( this._precision() ) );
12706
12707 // clamp the value
12708 if ( options.max !== null && value > options.max) {
12709 return options.max;
12710 }
12711 if ( options.min !== null && value < options.min ) {
12712 return options.min;
12713 }
12714
12715 return value;
12716 },
12717
12718 _stop: function( event ) {
12719 if ( !this.spinning ) {
12720 return;
12721 }
12722
12723 clearTimeout( this.timer );
12724 clearTimeout( this.mousewheelTimer );
12725 this.counter = 0;
12726 this.spinning = false;
12727 this._trigger( "stop", event );
12728 },
12729
12730 _setOption: function( key, value ) {
12731 if ( key === "culture" || key === "numberFormat" ) {
12732 var prevValue = this._parse( this.element.val() );
12733 this.options[ key ] = value;
12734 this.element.val( this._format( prevValue ) );
12735 return;
12736 }
12737
12738 if ( key === "max" || key === "min" || key === "step" ) {
12739 if ( typeof value === "string" ) {
12740 value = this._parse( value );
12741 }
12742 }
12743 if ( key === "icons" ) {
12744 this.buttons.first().find( ".ui-icon" )
12745 .removeClass( this.options.icons.up )
12746 .addClass( value.up );
12747 this.buttons.last().find( ".ui-icon" )
12748 .removeClass( this.options.icons.down )
12749 .addClass( value.down );
12750 }
12751
12752 this._super( key, value );
12753
12754 if ( key === "disabled" ) {
12755 this.widget().toggleClass( "ui-state-disabled", !!value );
12756 this.element.prop( "disabled", !!value );
12757 this.buttons.button( value ? "disable" : "enable" );
12758 }
12759 },
12760
12761 _setOptions: spinner_modifier(function( options ) {
12762 this._super( options );
12763 }),
12764
12765 _parse: function( val ) {
12766 if ( typeof val === "string" && val !== "" ) {
12767 val = window.Globalize && this.options.numberFormat ?
12768 Globalize.parseFloat( val, 10, this.options.culture ) : +val;
12769 }
12770 return val === "" || isNaN( val ) ? null : val;
12771 },
12772
12773 _format: function( value ) {
12774 if ( value === "" ) {
12775 return "";
12776 }
12777 return window.Globalize && this.options.numberFormat ?
12778 Globalize.format( value, this.options.numberFormat, this.options.culture ) :
12779 value;
12780 },
12781
12782 _refresh: function() {
12783 this.element.attr({
12784 "aria-valuemin": this.options.min,
12785 "aria-valuemax": this.options.max,
12786 // TODO: what should we do with values that can't be parsed?
12787 "aria-valuenow": this._parse( this.element.val() )
12788 });
12789 },
12790
12791 isValid: function() {
12792 var value = this.value();
12793
12794 // null is invalid
12795 if ( value === null ) {
12796 return false;
12797 }
12798
12799 // if value gets adjusted, it's invalid
12800 return value === this._adjustValue( value );
12801 },
12802
12803 // update the value without triggering change
12804 _value: function( value, allowAny ) {
12805 var parsed;
12806 if ( value !== "" ) {
12807 parsed = this._parse( value );
12808 if ( parsed !== null ) {
12809 if ( !allowAny ) {
12810 parsed = this._adjustValue( parsed );
12811 }
12812 value = this._format( parsed );
12813 }
12814 }
12815 this.element.val( value );
12816 this._refresh();
12817 },
12818
12819 _destroy: function() {
12820 this.element
12821 .removeClass( "ui-spinner-input" )
12822 .prop( "disabled", false )
12823 .removeAttr( "autocomplete" )
12824 .removeAttr( "role" )
12825 .removeAttr( "aria-valuemin" )
12826 .removeAttr( "aria-valuemax" )
12827 .removeAttr( "aria-valuenow" );
12828 this.uiSpinner.replaceWith( this.element );
12829 },
12830
12831 stepUp: spinner_modifier(function( steps ) {
12832 this._stepUp( steps );
12833 }),
12834 _stepUp: function( steps ) {
12835 if ( this._start() ) {
12836 this._spin( (steps || 1) * this.options.step );
12837 this._stop();
12838 }
12839 },
12840
12841 stepDown: spinner_modifier(function( steps ) {
12842 this._stepDown( steps );
12843 }),
12844 _stepDown: function( steps ) {
12845 if ( this._start() ) {
12846 this._spin( (steps || 1) * -this.options.step );
12847 this._stop();
12848 }
12849 },
12850
12851 pageUp: spinner_modifier(function( pages ) {
12852 this._stepUp( (pages || 1) * this.options.page );
12853 }),
12854
12855 pageDown: spinner_modifier(function( pages ) {
12856 this._stepDown( (pages || 1) * this.options.page );
12857 }),
12858
12859 value: function( newVal ) {
12860 if ( !arguments.length ) {
12861 return this._parse( this.element.val() );
12862 }
12863 spinner_modifier( this._value ).call( this, newVal );
12864 },
12865
12866 widget: function() {
12867 return this.uiSpinner;
12868 }
12869});
12870
12871
12872/*!
12873 * jQuery UI Tabs 1.11.3
12874 * http://jqueryui.com
12875 *
12876 * Copyright jQuery Foundation and other contributors
12877 * Released under the MIT license.
12878 * http://jquery.org/license
12879 *
12880 * http://api.jqueryui.com/tabs/
12881 */
12882
12883
12884var tabs = $.widget( "ui.tabs", {
12885 version: "1.11.3",
12886 delay: 300,
12887 options: {
12888 active: null,
12889 collapsible: false,
12890 event: "click",
12891 heightStyle: "content",
12892 hide: null,
12893 show: null,
12894
12895 // callbacks
12896 activate: null,
12897 beforeActivate: null,
12898 beforeLoad: null,
12899 load: null
12900 },
12901
12902 _isLocal: (function() {
12903 var rhash = /#.*$/;
12904
12905 return function( anchor ) {
12906 var anchorUrl, locationUrl;
12907
12908 // support: IE7
12909 // IE7 doesn't normalize the href property when set via script (#9317)
12910 anchor = anchor.cloneNode( false );
12911
12912 anchorUrl = anchor.href.replace( rhash, "" );
12913 locationUrl = location.href.replace( rhash, "" );
12914
12915 // decoding may throw an error if the URL isn't UTF-8 (#9518)
12916 try {
12917 anchorUrl = decodeURIComponent( anchorUrl );
12918 } catch ( error ) {}
12919 try {
12920 locationUrl = decodeURIComponent( locationUrl );
12921 } catch ( error ) {}
12922
12923 return anchor.hash.length > 1 && anchorUrl === locationUrl;
12924 };
12925 })(),
12926
12927 _create: function() {
12928 var that = this,
12929 options = this.options;
12930
12931 this.running = false;
12932
12933 this.element
12934 .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
12935 .toggleClass( "ui-tabs-collapsible", options.collapsible );
12936
12937 this._processTabs();
12938 options.active = this._initialActive();
12939
12940 // Take disabling tabs via class attribute from HTML
12941 // into account and update option properly.
12942 if ( $.isArray( options.disabled ) ) {
12943 options.disabled = $.unique( options.disabled.concat(
12944 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
12945 return that.tabs.index( li );
12946 })
12947 ) ).sort();
12948 }
12949
12950 // check for length avoids error when initializing empty list
12951 if ( this.options.active !== false && this.anchors.length ) {
12952 this.active = this._findActive( options.active );
12953 } else {
12954 this.active = $();
12955 }
12956
12957 this._refresh();
12958
12959 if ( this.active.length ) {
12960 this.load( options.active );
12961 }
12962 },
12963
12964 _initialActive: function() {
12965 var active = this.options.active,
12966 collapsible = this.options.collapsible,
12967 locationHash = location.hash.substring( 1 );
12968
12969 if ( active === null ) {
12970 // check the fragment identifier in the URL
12971 if ( locationHash ) {
12972 this.tabs.each(function( i, tab ) {
12973 if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
12974 active = i;
12975 return false;
12976 }
12977 });
12978 }
12979
12980 // check for a tab marked active via a class
12981 if ( active === null ) {
12982 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
12983 }
12984
12985 // no active tab, set to false
12986 if ( active === null || active === -1 ) {
12987 active = this.tabs.length ? 0 : false;
12988 }
12989 }
12990
12991 // handle numbers: negative, out of range
12992 if ( active !== false ) {
12993 active = this.tabs.index( this.tabs.eq( active ) );
12994 if ( active === -1 ) {
12995 active = collapsible ? false : 0;
12996 }
12997 }
12998
12999 // don't allow collapsible: false and active: false
13000 if ( !collapsible && active === false && this.anchors.length ) {
13001 active = 0;
13002 }
13003
13004 return active;
13005 },
13006
13007 _getCreateEventData: function() {
13008 return {
13009 tab: this.active,
13010 panel: !this.active.length ? $() : this._getPanelForTab( this.active )
13011 };
13012 },
13013
13014 _tabKeydown: function( event ) {
13015 var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
13016 selectedIndex = this.tabs.index( focusedTab ),
13017 goingForward = true;
13018
13019 if ( this._handlePageNav( event ) ) {
13020 return;
13021 }
13022
13023 switch ( event.keyCode ) {
13024 case $.ui.keyCode.RIGHT:
13025 case $.ui.keyCode.DOWN:
13026 selectedIndex++;
13027 break;
13028 case $.ui.keyCode.UP:
13029 case $.ui.keyCode.LEFT:
13030 goingForward = false;
13031 selectedIndex--;
13032 break;
13033 case $.ui.keyCode.END:
13034 selectedIndex = this.anchors.length - 1;
13035 break;
13036 case $.ui.keyCode.HOME:
13037 selectedIndex = 0;
13038 break;
13039 case $.ui.keyCode.SPACE:
13040 // Activate only, no collapsing
13041 event.preventDefault();
13042 clearTimeout( this.activating );
13043 this._activate( selectedIndex );
13044 return;
13045 case $.ui.keyCode.ENTER:
13046 // Toggle (cancel delayed activation, allow collapsing)
13047 event.preventDefault();
13048 clearTimeout( this.activating );
13049 // Determine if we should collapse or activate
13050 this._activate( selectedIndex === this.options.active ? false : selectedIndex );
13051 return;
13052 default:
13053 return;
13054 }
13055
13056 // Focus the appropriate tab, based on which key was pressed
13057 event.preventDefault();
13058 clearTimeout( this.activating );
13059 selectedIndex = this._focusNextTab( selectedIndex, goingForward );
13060
13061 // Navigating with control/command key will prevent automatic activation
13062 if ( !event.ctrlKey && !event.metaKey ) {
13063
13064 // Update aria-selected immediately so that AT think the tab is already selected.
13065 // Otherwise AT may confuse the user by stating that they need to activate the tab,
13066 // but the tab will already be activated by the time the announcement finishes.
13067 focusedTab.attr( "aria-selected", "false" );
13068 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
13069
13070 this.activating = this._delay(function() {
13071 this.option( "active", selectedIndex );
13072 }, this.delay );
13073 }
13074 },
13075
13076 _panelKeydown: function( event ) {
13077 if ( this._handlePageNav( event ) ) {
13078 return;
13079 }
13080
13081 // Ctrl+up moves focus to the current tab
13082 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
13083 event.preventDefault();
13084 this.active.focus();
13085 }
13086 },
13087
13088 // Alt+page up/down moves focus to the previous/next tab (and activates)
13089 _handlePageNav: function( event ) {
13090 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
13091 this._activate( this._focusNextTab( this.options.active - 1, false ) );
13092 return true;
13093 }
13094 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
13095 this._activate( this._focusNextTab( this.options.active + 1, true ) );
13096 return true;
13097 }
13098 },
13099
13100 _findNextTab: function( index, goingForward ) {
13101 var lastTabIndex = this.tabs.length - 1;
13102
13103 function constrain() {
13104 if ( index > lastTabIndex ) {
13105 index = 0;
13106 }
13107 if ( index < 0 ) {
13108 index = lastTabIndex;
13109 }
13110 return index;
13111 }
13112
13113 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
13114 index = goingForward ? index + 1 : index - 1;
13115 }
13116
13117 return index;
13118 },
13119
13120 _focusNextTab: function( index, goingForward ) {
13121 index = this._findNextTab( index, goingForward );
13122 this.tabs.eq( index ).focus();
13123 return index;
13124 },
13125
13126 _setOption: function( key, value ) {
13127 if ( key === "active" ) {
13128 // _activate() will handle invalid values and update this.options
13129 this._activate( value );
13130 return;
13131 }
13132
13133 if ( key === "disabled" ) {
13134 // don't use the widget factory's disabled handling
13135 this._setupDisabled( value );
13136 return;
13137 }
13138
13139 this._super( key, value);
13140
13141 if ( key === "collapsible" ) {
13142 this.element.toggleClass( "ui-tabs-collapsible", value );
13143 // Setting collapsible: false while collapsed; open first panel
13144 if ( !value && this.options.active === false ) {
13145 this._activate( 0 );
13146 }
13147 }
13148
13149 if ( key === "event" ) {
13150 this._setupEvents( value );
13151 }
13152
13153 if ( key === "heightStyle" ) {
13154 this._setupHeightStyle( value );
13155 }
13156 },
13157
13158 _sanitizeSelector: function( hash ) {
13159 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
13160 },
13161
13162 refresh: function() {
13163 var options = this.options,
13164 lis = this.tablist.children( ":has(a[href])" );
13165
13166 // get disabled tabs from class attribute from HTML
13167 // this will get converted to a boolean if needed in _refresh()
13168 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
13169 return lis.index( tab );
13170 });
13171
13172 this._processTabs();
13173
13174 // was collapsed or no tabs
13175 if ( options.active === false || !this.anchors.length ) {
13176 options.active = false;
13177 this.active = $();
13178 // was active, but active tab is gone
13179 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
13180 // all remaining tabs are disabled
13181 if ( this.tabs.length === options.disabled.length ) {
13182 options.active = false;
13183 this.active = $();
13184 // activate previous tab
13185 } else {
13186 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
13187 }
13188 // was active, active tab still exists
13189 } else {
13190 // make sure active index is correct
13191 options.active = this.tabs.index( this.active );
13192 }
13193
13194 this._refresh();
13195 },
13196
13197 _refresh: function() {
13198 this._setupDisabled( this.options.disabled );
13199 this._setupEvents( this.options.event );
13200 this._setupHeightStyle( this.options.heightStyle );
13201
13202 this.tabs.not( this.active ).attr({
13203 "aria-selected": "false",
13204 "aria-expanded": "false",
13205 tabIndex: -1
13206 });
13207 this.panels.not( this._getPanelForTab( this.active ) )
13208 .hide()
13209 .attr({
13210 "aria-hidden": "true"
13211 });
13212
13213 // Make sure one tab is in the tab order
13214 if ( !this.active.length ) {
13215 this.tabs.eq( 0 ).attr( "tabIndex", 0 );
13216 } else {
13217 this.active
13218 .addClass( "ui-tabs-active ui-state-active" )
13219 .attr({
13220 "aria-selected": "true",
13221 "aria-expanded": "true",
13222 tabIndex: 0
13223 });
13224 this._getPanelForTab( this.active )
13225 .show()
13226 .attr({
13227 "aria-hidden": "false"
13228 });
13229 }
13230 },
13231
13232 _processTabs: function() {
13233 var that = this,
13234 prevTabs = this.tabs,
13235 prevAnchors = this.anchors,
13236 prevPanels = this.panels;
13237
13238 this.tablist = this._getList()
13239 .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
13240 .attr( "role", "tablist" )
13241
13242 // Prevent users from focusing disabled tabs via click
13243 .delegate( "> li", "mousedown" + this.eventNamespace, function( event ) {
13244 if ( $( this ).is( ".ui-state-disabled" ) ) {
13245 event.preventDefault();
13246 }
13247 })
13248
13249 // support: IE <9
13250 // Preventing the default action in mousedown doesn't prevent IE
13251 // from focusing the element, so if the anchor gets focused, blur.
13252 // We don't have to worry about focusing the previously focused
13253 // element since clicking on a non-focusable element should focus
13254 // the body anyway.
13255 .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
13256 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
13257 this.blur();
13258 }
13259 });
13260
13261 this.tabs = this.tablist.find( "> li:has(a[href])" )
13262 .addClass( "ui-state-default ui-corner-top" )
13263 .attr({
13264 role: "tab",
13265 tabIndex: -1
13266 });
13267
13268 this.anchors = this.tabs.map(function() {
13269 return $( "a", this )[ 0 ];
13270 })
13271 .addClass( "ui-tabs-anchor" )
13272 .attr({
13273 role: "presentation",
13274 tabIndex: -1
13275 });
13276
13277 this.panels = $();
13278
13279 this.anchors.each(function( i, anchor ) {
13280 var selector, panel, panelId,
13281 anchorId = $( anchor ).uniqueId().attr( "id" ),
13282 tab = $( anchor ).closest( "li" ),
13283 originalAriaControls = tab.attr( "aria-controls" );
13284
13285 // inline tab
13286 if ( that._isLocal( anchor ) ) {
13287 selector = anchor.hash;
13288 panelId = selector.substring( 1 );
13289 panel = that.element.find( that._sanitizeSelector( selector ) );
13290 // remote tab
13291 } else {
13292 // If the tab doesn't already have aria-controls,
13293 // generate an id by using a throw-away element
13294 panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
13295 selector = "#" + panelId;
13296 panel = that.element.find( selector );
13297 if ( !panel.length ) {
13298 panel = that._createPanel( panelId );
13299 panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
13300 }
13301 panel.attr( "aria-live", "polite" );
13302 }
13303
13304 if ( panel.length) {
13305 that.panels = that.panels.add( panel );
13306 }
13307 if ( originalAriaControls ) {
13308 tab.data( "ui-tabs-aria-controls", originalAriaControls );
13309 }
13310 tab.attr({
13311 "aria-controls": panelId,
13312 "aria-labelledby": anchorId
13313 });
13314 panel.attr( "aria-labelledby", anchorId );
13315 });
13316
13317 this.panels
13318 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
13319 .attr( "role", "tabpanel" );
13320
13321 // Avoid memory leaks (#10056)
13322 if ( prevTabs ) {
13323 this._off( prevTabs.not( this.tabs ) );
13324 this._off( prevAnchors.not( this.anchors ) );
13325 this._off( prevPanels.not( this.panels ) );
13326 }
13327 },
13328
13329 // allow overriding how to find the list for rare usage scenarios (#7715)
13330 _getList: function() {
13331 return this.tablist || this.element.find( "ol,ul" ).eq( 0 );
13332 },
13333
13334 _createPanel: function( id ) {
13335 return $( "<div>" )
13336 .attr( "id", id )
13337 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
13338 .data( "ui-tabs-destroy", true );
13339 },
13340
13341 _setupDisabled: function( disabled ) {
13342 if ( $.isArray( disabled ) ) {
13343 if ( !disabled.length ) {
13344 disabled = false;
13345 } else if ( disabled.length === this.anchors.length ) {
13346 disabled = true;
13347 }
13348 }
13349
13350 // disable tabs
13351 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
13352 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
13353 $( li )
13354 .addClass( "ui-state-disabled" )
13355 .attr( "aria-disabled", "true" );
13356 } else {
13357 $( li )
13358 .removeClass( "ui-state-disabled" )
13359 .removeAttr( "aria-disabled" );
13360 }
13361 }
13362
13363 this.options.disabled = disabled;
13364 },
13365
13366 _setupEvents: function( event ) {
13367 var events = {};
13368 if ( event ) {
13369 $.each( event.split(" "), function( index, eventName ) {
13370 events[ eventName ] = "_eventHandler";
13371 });
13372 }
13373
13374 this._off( this.anchors.add( this.tabs ).add( this.panels ) );
13375 // Always prevent the default action, even when disabled
13376 this._on( true, this.anchors, {
13377 click: function( event ) {
13378 event.preventDefault();
13379 }
13380 });
13381 this._on( this.anchors, events );
13382 this._on( this.tabs, { keydown: "_tabKeydown" } );
13383 this._on( this.panels, { keydown: "_panelKeydown" } );
13384
13385 this._focusable( this.tabs );
13386 this._hoverable( this.tabs );
13387 },
13388
13389 _setupHeightStyle: function( heightStyle ) {
13390 var maxHeight,
13391 parent = this.element.parent();
13392
13393 if ( heightStyle === "fill" ) {
13394 maxHeight = parent.height();
13395 maxHeight -= this.element.outerHeight() - this.element.height();
13396
13397 this.element.siblings( ":visible" ).each(function() {
13398 var elem = $( this ),
13399 position = elem.css( "position" );
13400
13401 if ( position === "absolute" || position === "fixed" ) {
13402 return;
13403 }
13404 maxHeight -= elem.outerHeight( true );
13405 });
13406
13407 this.element.children().not( this.panels ).each(function() {
13408 maxHeight -= $( this ).outerHeight( true );
13409 });
13410
13411 this.panels.each(function() {
13412 $( this ).height( Math.max( 0, maxHeight -
13413 $( this ).innerHeight() + $( this ).height() ) );
13414 })
13415 .css( "overflow", "auto" );
13416 } else if ( heightStyle === "auto" ) {
13417 maxHeight = 0;
13418 this.panels.each(function() {
13419 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
13420 }).height( maxHeight );
13421 }
13422 },
13423
13424 _eventHandler: function( event ) {
13425 var options = this.options,
13426 active = this.active,
13427 anchor = $( event.currentTarget ),
13428 tab = anchor.closest( "li" ),
13429 clickedIsActive = tab[ 0 ] === active[ 0 ],
13430 collapsing = clickedIsActive && options.collapsible,
13431 toShow = collapsing ? $() : this._getPanelForTab( tab ),
13432 toHide = !active.length ? $() : this._getPanelForTab( active ),
13433 eventData = {
13434 oldTab: active,
13435 oldPanel: toHide,
13436 newTab: collapsing ? $() : tab,
13437 newPanel: toShow
13438 };
13439
13440 event.preventDefault();
13441
13442 if ( tab.hasClass( "ui-state-disabled" ) ||
13443 // tab is already loading
13444 tab.hasClass( "ui-tabs-loading" ) ||
13445 // can't switch durning an animation
13446 this.running ||
13447 // click on active header, but not collapsible
13448 ( clickedIsActive && !options.collapsible ) ||
13449 // allow canceling activation
13450 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
13451 return;
13452 }
13453
13454 options.active = collapsing ? false : this.tabs.index( tab );
13455
13456 this.active = clickedIsActive ? $() : tab;
13457 if ( this.xhr ) {
13458 this.xhr.abort();
13459 }
13460
13461 if ( !toHide.length && !toShow.length ) {
13462 $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
13463 }
13464
13465 if ( toShow.length ) {
13466 this.load( this.tabs.index( tab ), event );
13467 }
13468 this._toggle( event, eventData );
13469 },
13470
13471 // handles show/hide for selecting tabs
13472 _toggle: function( event, eventData ) {
13473 var that = this,
13474 toShow = eventData.newPanel,
13475 toHide = eventData.oldPanel;
13476
13477 this.running = true;
13478
13479 function complete() {
13480 that.running = false;
13481 that._trigger( "activate", event, eventData );
13482 }
13483
13484 function show() {
13485 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
13486
13487 if ( toShow.length && that.options.show ) {
13488 that._show( toShow, that.options.show, complete );
13489 } else {
13490 toShow.show();
13491 complete();
13492 }
13493 }
13494
13495 // start out by hiding, then showing, then completing
13496 if ( toHide.length && this.options.hide ) {
13497 this._hide( toHide, this.options.hide, function() {
13498 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
13499 show();
13500 });
13501 } else {
13502 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
13503 toHide.hide();
13504 show();
13505 }
13506
13507 toHide.attr( "aria-hidden", "true" );
13508 eventData.oldTab.attr({
13509 "aria-selected": "false",
13510 "aria-expanded": "false"
13511 });
13512 // If we're switching tabs, remove the old tab from the tab order.
13513 // If we're opening from collapsed state, remove the previous tab from the tab order.
13514 // If we're collapsing, then keep the collapsing tab in the tab order.
13515 if ( toShow.length && toHide.length ) {
13516 eventData.oldTab.attr( "tabIndex", -1 );
13517 } else if ( toShow.length ) {
13518 this.tabs.filter(function() {
13519 return $( this ).attr( "tabIndex" ) === 0;
13520 })
13521 .attr( "tabIndex", -1 );
13522 }
13523
13524 toShow.attr( "aria-hidden", "false" );
13525 eventData.newTab.attr({
13526 "aria-selected": "true",
13527 "aria-expanded": "true",
13528 tabIndex: 0
13529 });
13530 },
13531
13532 _activate: function( index ) {
13533 var anchor,
13534 active = this._findActive( index );
13535
13536 // trying to activate the already active panel
13537 if ( active[ 0 ] === this.active[ 0 ] ) {
13538 return;
13539 }
13540
13541 // trying to collapse, simulate a click on the current active header
13542 if ( !active.length ) {
13543 active = this.active;
13544 }
13545
13546 anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
13547 this._eventHandler({
13548 target: anchor,
13549 currentTarget: anchor,
13550 preventDefault: $.noop
13551 });
13552 },
13553
13554 _findActive: function( index ) {
13555 return index === false ? $() : this.tabs.eq( index );
13556 },
13557
13558 _getIndex: function( index ) {
13559 // meta-function to give users option to provide a href string instead of a numerical index.
13560 if ( typeof index === "string" ) {
13561 index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
13562 }
13563
13564 return index;
13565 },
13566
13567 _destroy: function() {
13568 if ( this.xhr ) {
13569 this.xhr.abort();
13570 }
13571
13572 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
13573
13574 this.tablist
13575 .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
13576 .removeAttr( "role" );
13577
13578 this.anchors
13579 .removeClass( "ui-tabs-anchor" )
13580 .removeAttr( "role" )
13581 .removeAttr( "tabIndex" )
13582 .removeUniqueId();
13583
13584 this.tablist.unbind( this.eventNamespace );
13585
13586 this.tabs.add( this.panels ).each(function() {
13587 if ( $.data( this, "ui-tabs-destroy" ) ) {
13588 $( this ).remove();
13589 } else {
13590 $( this )
13591 .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
13592 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
13593 .removeAttr( "tabIndex" )
13594 .removeAttr( "aria-live" )
13595 .removeAttr( "aria-busy" )
13596 .removeAttr( "aria-selected" )
13597 .removeAttr( "aria-labelledby" )
13598 .removeAttr( "aria-hidden" )
13599 .removeAttr( "aria-expanded" )
13600 .removeAttr( "role" );
13601 }
13602 });
13603
13604 this.tabs.each(function() {
13605 var li = $( this ),
13606 prev = li.data( "ui-tabs-aria-controls" );
13607 if ( prev ) {
13608 li
13609 .attr( "aria-controls", prev )
13610 .removeData( "ui-tabs-aria-controls" );
13611 } else {
13612 li.removeAttr( "aria-controls" );
13613 }
13614 });
13615
13616 this.panels.show();
13617
13618 if ( this.options.heightStyle !== "content" ) {
13619 this.panels.css( "height", "" );
13620 }
13621 },
13622
13623 enable: function( index ) {
13624 var disabled = this.options.disabled;
13625 if ( disabled === false ) {
13626 return;
13627 }
13628
13629 if ( index === undefined ) {
13630 disabled = false;
13631 } else {
13632 index = this._getIndex( index );
13633 if ( $.isArray( disabled ) ) {
13634 disabled = $.map( disabled, function( num ) {
13635 return num !== index ? num : null;
13636 });
13637 } else {
13638 disabled = $.map( this.tabs, function( li, num ) {
13639 return num !== index ? num : null;
13640 });
13641 }
13642 }
13643 this._setupDisabled( disabled );
13644 },
13645
13646 disable: function( index ) {
13647 var disabled = this.options.disabled;
13648 if ( disabled === true ) {
13649 return;
13650 }
13651
13652 if ( index === undefined ) {
13653 disabled = true;
13654 } else {
13655 index = this._getIndex( index );
13656 if ( $.inArray( index, disabled ) !== -1 ) {
13657 return;
13658 }
13659 if ( $.isArray( disabled ) ) {
13660 disabled = $.merge( [ index ], disabled ).sort();
13661 } else {
13662 disabled = [ index ];
13663 }
13664 }
13665 this._setupDisabled( disabled );
13666 },
13667
13668 load: function( index, event ) {
13669 index = this._getIndex( index );
13670 var that = this,
13671 tab = this.tabs.eq( index ),
13672 anchor = tab.find( ".ui-tabs-anchor" ),
13673 panel = this._getPanelForTab( tab ),
13674 eventData = {
13675 tab: tab,
13676 panel: panel
13677 };
13678
13679 // not remote
13680 if ( this._isLocal( anchor[ 0 ] ) ) {
13681 return;
13682 }
13683
13684 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
13685
13686 // support: jQuery <1.8
13687 // jQuery <1.8 returns false if the request is canceled in beforeSend,
13688 // but as of 1.8, $.ajax() always returns a jqXHR object.
13689 if ( this.xhr && this.xhr.statusText !== "canceled" ) {
13690 tab.addClass( "ui-tabs-loading" );
13691 panel.attr( "aria-busy", "true" );
13692
13693 this.xhr
13694 .success(function( response ) {
13695 // support: jQuery <1.8
13696 // http://bugs.jquery.com/ticket/11778
13697 setTimeout(function() {
13698 panel.html( response );
13699 that._trigger( "load", event, eventData );
13700 }, 1 );
13701 })
13702 .complete(function( jqXHR, status ) {
13703 // support: jQuery <1.8
13704 // http://bugs.jquery.com/ticket/11778
13705 setTimeout(function() {
13706 if ( status === "abort" ) {
13707 that.panels.stop( false, true );
13708 }
13709
13710 tab.removeClass( "ui-tabs-loading" );
13711 panel.removeAttr( "aria-busy" );
13712
13713 if ( jqXHR === that.xhr ) {
13714 delete that.xhr;
13715 }
13716 }, 1 );
13717 });
13718 }
13719 },
13720
13721 _ajaxSettings: function( anchor, event, eventData ) {
13722 var that = this;
13723 return {
13724 url: anchor.attr( "href" ),
13725 beforeSend: function( jqXHR, settings ) {
13726 return that._trigger( "beforeLoad", event,
13727 $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
13728 }
13729 };
13730 },
13731
13732 _getPanelForTab: function( tab ) {
13733 var id = $( tab ).attr( "aria-controls" );
13734 return this.element.find( this._sanitizeSelector( "#" + id ) );
13735 }
13736});
13737
13738
13739/*!
13740 * jQuery UI Tooltip 1.11.3
13741 * http://jqueryui.com
13742 *
13743 * Copyright jQuery Foundation and other contributors
13744 * Released under the MIT license.
13745 * http://jquery.org/license
13746 *
13747 * http://api.jqueryui.com/tooltip/
13748 */
13749
13750
13751var tooltip = $.widget( "ui.tooltip", {
13752 version: "1.11.3",
13753 options: {
13754 content: function() {
13755 // support: IE<9, Opera in jQuery <1.7
13756 // .text() can't accept undefined, so coerce to a string
13757 var title = $( this ).attr( "title" ) || "";
13758 // Escape title, since we're going from an attribute to raw HTML
13759 return $( "<a>" ).text( title ).html();
13760 },
13761 hide: true,
13762 // Disabled elements have inconsistent behavior across browsers (#8661)
13763 items: "[title]:not([disabled])",
13764 position: {
13765 my: "left top+15",
13766 at: "left bottom",
13767 collision: "flipfit flip"
13768 },
13769 show: true,
13770 tooltipClass: null,
13771 track: false,
13772
13773 // callbacks
13774 close: null,
13775 open: null
13776 },
13777
13778 _addDescribedBy: function( elem, id ) {
13779 var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
13780 describedby.push( id );
13781 elem
13782 .data( "ui-tooltip-id", id )
13783 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
13784 },
13785
13786 _removeDescribedBy: function( elem ) {
13787 var id = elem.data( "ui-tooltip-id" ),
13788 describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
13789 index = $.inArray( id, describedby );
13790
13791 if ( index !== -1 ) {
13792 describedby.splice( index, 1 );
13793 }
13794
13795 elem.removeData( "ui-tooltip-id" );
13796 describedby = $.trim( describedby.join( " " ) );
13797 if ( describedby ) {
13798 elem.attr( "aria-describedby", describedby );
13799 } else {
13800 elem.removeAttr( "aria-describedby" );
13801 }
13802 },
13803
13804 _create: function() {
13805 this._on({
13806 mouseover: "open",
13807 focusin: "open"
13808 });
13809
13810 // IDs of generated tooltips, needed for destroy
13811 this.tooltips = {};
13812
13813 // IDs of parent tooltips where we removed the title attribute
13814 this.parents = {};
13815
13816 if ( this.options.disabled ) {
13817 this._disable();
13818 }
13819
13820 // Append the aria-live region so tooltips announce correctly
13821 this.liveRegion = $( "<div>" )
13822 .attr({
13823 role: "log",
13824 "aria-live": "assertive",
13825 "aria-relevant": "additions"
13826 })
13827 .addClass( "ui-helper-hidden-accessible" )
13828 .appendTo( this.document[ 0 ].body );
13829 },
13830
13831 _setOption: function( key, value ) {
13832 var that = this;
13833
13834 if ( key === "disabled" ) {
13835 this[ value ? "_disable" : "_enable" ]();
13836 this.options[ key ] = value;
13837 // disable element style changes
13838 return;
13839 }
13840
13841 this._super( key, value );
13842
13843 if ( key === "content" ) {
13844 $.each( this.tooltips, function( id, tooltipData ) {
13845 that._updateContent( tooltipData.element );
13846 });
13847 }
13848 },
13849
13850 _disable: function() {
13851 var that = this;
13852
13853 // close open tooltips
13854 $.each( this.tooltips, function( id, tooltipData ) {
13855 var event = $.Event( "blur" );
13856 event.target = event.currentTarget = tooltipData.element[ 0 ];
13857 that.close( event, true );
13858 });
13859
13860 // remove title attributes to prevent native tooltips
13861 this.element.find( this.options.items ).addBack().each(function() {
13862 var element = $( this );
13863 if ( element.is( "[title]" ) ) {
13864 element
13865 .data( "ui-tooltip-title", element.attr( "title" ) )
13866 .removeAttr( "title" );
13867 }
13868 });
13869 },
13870
13871 _enable: function() {
13872 // restore title attributes
13873 this.element.find( this.options.items ).addBack().each(function() {
13874 var element = $( this );
13875 if ( element.data( "ui-tooltip-title" ) ) {
13876 element.attr( "title", element.data( "ui-tooltip-title" ) );
13877 }
13878 });
13879 },
13880
13881 open: function( event ) {
13882 var that = this,
13883 target = $( event ? event.target : this.element )
13884 // we need closest here due to mouseover bubbling,
13885 // but always pointing at the same event target
13886 .closest( this.options.items );
13887
13888 // No element to show a tooltip for or the tooltip is already open
13889 if ( !target.length || target.data( "ui-tooltip-id" ) ) {
13890 return;
13891 }
13892
13893 if ( target.attr( "title" ) ) {
13894 target.data( "ui-tooltip-title", target.attr( "title" ) );
13895 }
13896
13897 target.data( "ui-tooltip-open", true );
13898
13899 // kill parent tooltips, custom or native, for hover
13900 if ( event && event.type === "mouseover" ) {
13901 target.parents().each(function() {
13902 var parent = $( this ),
13903 blurEvent;
13904 if ( parent.data( "ui-tooltip-open" ) ) {
13905 blurEvent = $.Event( "blur" );
13906 blurEvent.target = blurEvent.currentTarget = this;
13907 that.close( blurEvent, true );
13908 }
13909 if ( parent.attr( "title" ) ) {
13910 parent.uniqueId();
13911 that.parents[ this.id ] = {
13912 element: this,
13913 title: parent.attr( "title" )
13914 };
13915 parent.attr( "title", "" );
13916 }
13917 });
13918 }
13919
13920 this._updateContent( target, event );
13921 },
13922
13923 _updateContent: function( target, event ) {
13924 var content,
13925 contentOption = this.options.content,
13926 that = this,
13927 eventType = event ? event.type : null;
13928
13929 if ( typeof contentOption === "string" ) {
13930 return this._open( event, target, contentOption );
13931 }
13932
13933 content = contentOption.call( target[0], function( response ) {
13934 // ignore async response if tooltip was closed already
13935 if ( !target.data( "ui-tooltip-open" ) ) {
13936 return;
13937 }
13938 // IE may instantly serve a cached response for ajax requests
13939 // delay this call to _open so the other call to _open runs first
13940 that._delay(function() {
13941 // jQuery creates a special event for focusin when it doesn't
13942 // exist natively. To improve performance, the native event
13943 // object is reused and the type is changed. Therefore, we can't
13944 // rely on the type being correct after the event finished
13945 // bubbling, so we set it back to the previous value. (#8740)
13946 if ( event ) {
13947 event.type = eventType;
13948 }
13949 this._open( event, target, response );
13950 });
13951 });
13952 if ( content ) {
13953 this._open( event, target, content );
13954 }
13955 },
13956
13957 _open: function( event, target, content ) {
13958 var tooltipData, tooltip, events, delayedShow, a11yContent,
13959 positionOption = $.extend( {}, this.options.position );
13960
13961 if ( !content ) {
13962 return;
13963 }
13964
13965 // Content can be updated multiple times. If the tooltip already
13966 // exists, then just update the content and bail.
13967 tooltipData = this._find( target );
13968 if ( tooltipData ) {
13969 tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
13970 return;
13971 }
13972
13973 // if we have a title, clear it to prevent the native tooltip
13974 // we have to check first to avoid defining a title if none exists
13975 // (we don't want to cause an element to start matching [title])
13976 //
13977 // We use removeAttr only for key events, to allow IE to export the correct
13978 // accessible attributes. For mouse events, set to empty string to avoid
13979 // native tooltip showing up (happens only when removing inside mouseover).
13980 if ( target.is( "[title]" ) ) {
13981 if ( event && event.type === "mouseover" ) {
13982 target.attr( "title", "" );
13983 } else {
13984 target.removeAttr( "title" );
13985 }
13986 }
13987
13988 tooltipData = this._tooltip( target );
13989 tooltip = tooltipData.tooltip;
13990 this._addDescribedBy( target, tooltip.attr( "id" ) );
13991 tooltip.find( ".ui-tooltip-content" ).html( content );
13992
13993 // Support: Voiceover on OS X, JAWS on IE <= 9
13994 // JAWS announces deletions even when aria-relevant="additions"
13995 // Voiceover will sometimes re-read the entire log region's contents from the beginning
13996 this.liveRegion.children().hide();
13997 if ( content.clone ) {
13998 a11yContent = content.clone();
13999 a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
14000 } else {
14001 a11yContent = content;
14002 }
14003 $( "<div>" ).html( a11yContent ).appendTo( this.liveRegion );
14004
14005 function position( event ) {
14006 positionOption.of = event;
14007 if ( tooltip.is( ":hidden" ) ) {
14008 return;
14009 }
14010 tooltip.position( positionOption );
14011 }
14012 if ( this.options.track && event && /^mouse/.test( event.type ) ) {
14013 this._on( this.document, {
14014 mousemove: position
14015 });
14016 // trigger once to override element-relative positioning
14017 position( event );
14018 } else {
14019 tooltip.position( $.extend({
14020 of: target
14021 }, this.options.position ) );
14022 }
14023
14024 tooltip.hide();
14025
14026 this._show( tooltip, this.options.show );
14027 // Handle tracking tooltips that are shown with a delay (#8644). As soon
14028 // as the tooltip is visible, position the tooltip using the most recent
14029 // event.
14030 if ( this.options.show && this.options.show.delay ) {
14031 delayedShow = this.delayedShow = setInterval(function() {
14032 if ( tooltip.is( ":visible" ) ) {
14033 position( positionOption.of );
14034 clearInterval( delayedShow );
14035 }
14036 }, $.fx.interval );
14037 }
14038
14039 this._trigger( "open", event, { tooltip: tooltip } );
14040
14041 events = {
14042 keyup: function( event ) {
14043 if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
14044 var fakeEvent = $.Event(event);
14045 fakeEvent.currentTarget = target[0];
14046 this.close( fakeEvent, true );
14047 }
14048 }
14049 };
14050
14051 // Only bind remove handler for delegated targets. Non-delegated
14052 // tooltips will handle this in destroy.
14053 if ( target[ 0 ] !== this.element[ 0 ] ) {
14054 events.remove = function() {
14055 this._removeTooltip( tooltip );
14056 };
14057 }
14058
14059 if ( !event || event.type === "mouseover" ) {
14060 events.mouseleave = "close";
14061 }
14062 if ( !event || event.type === "focusin" ) {
14063 events.focusout = "close";
14064 }
14065 this._on( true, target, events );
14066 },
14067
14068 close: function( event ) {
14069 var tooltip,
14070 that = this,
14071 target = $( event ? event.currentTarget : this.element ),
14072 tooltipData = this._find( target );
14073
14074 // The tooltip may already be closed
14075 if ( !tooltipData ) {
14076 return;
14077 }
14078
14079 tooltip = tooltipData.tooltip;
14080
14081 // disabling closes the tooltip, so we need to track when we're closing
14082 // to avoid an infinite loop in case the tooltip becomes disabled on close
14083 if ( tooltipData.closing ) {
14084 return;
14085 }
14086
14087 // Clear the interval for delayed tracking tooltips
14088 clearInterval( this.delayedShow );
14089
14090 // only set title if we had one before (see comment in _open())
14091 // If the title attribute has changed since open(), don't restore
14092 if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
14093 target.attr( "title", target.data( "ui-tooltip-title" ) );
14094 }
14095
14096 this._removeDescribedBy( target );
14097
14098 tooltipData.hiding = true;
14099 tooltip.stop( true );
14100 this._hide( tooltip, this.options.hide, function() {
14101 that._removeTooltip( $( this ) );
14102 });
14103
14104 target.removeData( "ui-tooltip-open" );
14105 this._off( target, "mouseleave focusout keyup" );
14106
14107 // Remove 'remove' binding only on delegated targets
14108 if ( target[ 0 ] !== this.element[ 0 ] ) {
14109 this._off( target, "remove" );
14110 }
14111 this._off( this.document, "mousemove" );
14112
14113 if ( event && event.type === "mouseleave" ) {
14114 $.each( this.parents, function( id, parent ) {
14115 $( parent.element ).attr( "title", parent.title );
14116 delete that.parents[ id ];
14117 });
14118 }
14119
14120 tooltipData.closing = true;
14121 this._trigger( "close", event, { tooltip: tooltip } );
14122 if ( !tooltipData.hiding ) {
14123 tooltipData.closing = false;
14124 }
14125 },
14126
14127 _tooltip: function( element ) {
14128 var tooltip = $( "<div>" )
14129 .attr( "role", "tooltip" )
14130 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
14131 ( this.options.tooltipClass || "" ) ),
14132 id = tooltip.uniqueId().attr( "id" );
14133
14134 $( "<div>" )
14135 .addClass( "ui-tooltip-content" )
14136 .appendTo( tooltip );
14137
14138 tooltip.appendTo( this.document[0].body );
14139
14140 return this.tooltips[ id ] = {
14141 element: element,
14142 tooltip: tooltip
14143 };
14144 },
14145
14146 _find: function( target ) {
14147 var id = target.data( "ui-tooltip-id" );
14148 return id ? this.tooltips[ id ] : null;
14149 },
14150
14151 _removeTooltip: function( tooltip ) {
14152 tooltip.remove();
14153 delete this.tooltips[ tooltip.attr( "id" ) ];
14154 },
14155
14156 _destroy: function() {
14157 var that = this;
14158
14159 // close open tooltips
14160 $.each( this.tooltips, function( id, tooltipData ) {
14161 // Delegate to close method to handle common cleanup
14162 var event = $.Event( "blur" ),
14163 element = tooltipData.element;
14164 event.target = event.currentTarget = element[ 0 ];
14165 that.close( event, true );
14166
14167 // Remove immediately; destroying an open tooltip doesn't use the
14168 // hide animation
14169 $( "#" + id ).remove();
14170
14171 // Restore the title
14172 if ( element.data( "ui-tooltip-title" ) ) {
14173 // If the title attribute has changed since open(), don't restore
14174 if ( !element.attr( "title" ) ) {
14175 element.attr( "title", element.data( "ui-tooltip-title" ) );
14176 }
14177 element.removeData( "ui-tooltip-title" );
14178 }
14179 });
14180 this.liveRegion.remove();
14181 }
14182});
14183
14184
14185/*!
14186 * jQuery UI Effects 1.11.3
14187 * http://jqueryui.com
14188 *
14189 * Copyright jQuery Foundation and other contributors
14190 * Released under the MIT license.
14191 * http://jquery.org/license
14192 *
14193 * http://api.jqueryui.com/category/effects-core/
14194 */
14195
14196
14197var dataSpace = "ui-effects-",
14198
14199 // Create a local jQuery because jQuery Color relies on it and the
14200 // global may not exist with AMD and a custom build (#10199)
14201 jQuery = $;
14202
14203$.effects = {
14204 effect: {}
14205};
14206
14207/*!
14208 * jQuery Color Animations v2.1.2
14209 * https://github.com/jquery/jquery-color
14210 *
14211 * Copyright 2014 jQuery Foundation and other contributors
14212 * Released under the MIT license.
14213 * http://jquery.org/license
14214 *
14215 * Date: Wed Jan 16 08:47:09 2013 -0600
14216 */
14217(function( jQuery, undefined ) {
14218
14219 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
14220
14221 // plusequals test for += 100 -= 100
14222 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
14223 // a set of RE's that can match strings and generate color tuples.
14224 stringParsers = [ {
14225 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
14226 parse: function( execResult ) {
14227 return [
14228 execResult[ 1 ],
14229 execResult[ 2 ],
14230 execResult[ 3 ],
14231 execResult[ 4 ]
14232 ];
14233 }
14234 }, {
14235 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
14236 parse: function( execResult ) {
14237 return [
14238 execResult[ 1 ] * 2.55,
14239 execResult[ 2 ] * 2.55,
14240 execResult[ 3 ] * 2.55,
14241 execResult[ 4 ]
14242 ];
14243 }
14244 }, {
14245 // this regex ignores A-F because it's compared against an already lowercased string
14246 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
14247 parse: function( execResult ) {
14248 return [
14249 parseInt( execResult[ 1 ], 16 ),
14250 parseInt( execResult[ 2 ], 16 ),
14251 parseInt( execResult[ 3 ], 16 )
14252 ];
14253 }
14254 }, {
14255 // this regex ignores A-F because it's compared against an already lowercased string
14256 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
14257 parse: function( execResult ) {
14258 return [
14259 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
14260 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
14261 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
14262 ];
14263 }
14264 }, {
14265 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
14266 space: "hsla",
14267 parse: function( execResult ) {
14268 return [
14269 execResult[ 1 ],
14270 execResult[ 2 ] / 100,
14271 execResult[ 3 ] / 100,
14272 execResult[ 4 ]
14273 ];
14274 }
14275 } ],
14276
14277 // jQuery.Color( )
14278 color = jQuery.Color = function( color, green, blue, alpha ) {
14279 return new jQuery.Color.fn.parse( color, green, blue, alpha );
14280 },
14281 spaces = {
14282 rgba: {
14283 props: {
14284 red: {
14285 idx: 0,
14286 type: "byte"
14287 },
14288 green: {
14289 idx: 1,
14290 type: "byte"
14291 },
14292 blue: {
14293 idx: 2,
14294 type: "byte"
14295 }
14296 }
14297 },
14298
14299 hsla: {
14300 props: {
14301 hue: {
14302 idx: 0,
14303 type: "degrees"
14304 },
14305 saturation: {
14306 idx: 1,
14307 type: "percent"
14308 },
14309 lightness: {
14310 idx: 2,
14311 type: "percent"
14312 }
14313 }
14314 }
14315 },
14316 propTypes = {
14317 "byte": {
14318 floor: true,
14319 max: 255
14320 },
14321 "percent": {
14322 max: 1
14323 },
14324 "degrees": {
14325 mod: 360,
14326 floor: true
14327 }
14328 },
14329 support = color.support = {},
14330
14331 // element for support tests
14332 supportElem = jQuery( "<p>" )[ 0 ],
14333
14334 // colors = jQuery.Color.names
14335 colors,
14336
14337 // local aliases of functions called often
14338 each = jQuery.each;
14339
14340// determine rgba support immediately
14341supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
14342support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
14343
14344// define cache name and alpha properties
14345// for rgba and hsla spaces
14346each( spaces, function( spaceName, space ) {
14347 space.cache = "_" + spaceName;
14348 space.props.alpha = {
14349 idx: 3,
14350 type: "percent",
14351 def: 1
14352 };
14353});
14354
14355function clamp( value, prop, allowEmpty ) {
14356 var type = propTypes[ prop.type ] || {};
14357
14358 if ( value == null ) {
14359 return (allowEmpty || !prop.def) ? null : prop.def;
14360 }
14361
14362 // ~~ is an short way of doing floor for positive numbers
14363 value = type.floor ? ~~value : parseFloat( value );
14364
14365 // IE will pass in empty strings as value for alpha,
14366 // which will hit this case
14367 if ( isNaN( value ) ) {
14368 return prop.def;
14369 }
14370
14371 if ( type.mod ) {
14372 // we add mod before modding to make sure that negatives values
14373 // get converted properly: -10 -> 350
14374 return (value + type.mod) % type.mod;
14375 }
14376
14377 // for now all property types without mod have min and max
14378 return 0 > value ? 0 : type.max < value ? type.max : value;
14379}
14380
14381function stringParse( string ) {
14382 var inst = color(),
14383 rgba = inst._rgba = [];
14384
14385 string = string.toLowerCase();
14386
14387 each( stringParsers, function( i, parser ) {
14388 var parsed,
14389 match = parser.re.exec( string ),
14390 values = match && parser.parse( match ),
14391 spaceName = parser.space || "rgba";
14392
14393 if ( values ) {
14394 parsed = inst[ spaceName ]( values );
14395
14396 // if this was an rgba parse the assignment might happen twice
14397 // oh well....
14398 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
14399 rgba = inst._rgba = parsed._rgba;
14400
14401 // exit each( stringParsers ) here because we matched
14402 return false;
14403 }
14404 });
14405
14406 // Found a stringParser that handled it
14407 if ( rgba.length ) {
14408
14409 // if this came from a parsed string, force "transparent" when alpha is 0
14410 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
14411 if ( rgba.join() === "0,0,0,0" ) {
14412 jQuery.extend( rgba, colors.transparent );
14413 }
14414 return inst;
14415 }
14416
14417 // named colors
14418 return colors[ string ];
14419}
14420
14421color.fn = jQuery.extend( color.prototype, {
14422 parse: function( red, green, blue, alpha ) {
14423 if ( red === undefined ) {
14424 this._rgba = [ null, null, null, null ];
14425 return this;
14426 }
14427 if ( red.jquery || red.nodeType ) {
14428 red = jQuery( red ).css( green );
14429 green = undefined;
14430 }
14431
14432 var inst = this,
14433 type = jQuery.type( red ),
14434 rgba = this._rgba = [];
14435
14436 // more than 1 argument specified - assume ( red, green, blue, alpha )
14437 if ( green !== undefined ) {
14438 red = [ red, green, blue, alpha ];
14439 type = "array";
14440 }
14441
14442 if ( type === "string" ) {
14443 return this.parse( stringParse( red ) || colors._default );
14444 }
14445
14446 if ( type === "array" ) {
14447 each( spaces.rgba.props, function( key, prop ) {
14448 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
14449 });
14450 return this;
14451 }
14452
14453 if ( type === "object" ) {
14454 if ( red instanceof color ) {
14455 each( spaces, function( spaceName, space ) {
14456 if ( red[ space.cache ] ) {
14457 inst[ space.cache ] = red[ space.cache ].slice();
14458 }
14459 });
14460 } else {
14461 each( spaces, function( spaceName, space ) {
14462 var cache = space.cache;
14463 each( space.props, function( key, prop ) {
14464
14465 // if the cache doesn't exist, and we know how to convert
14466 if ( !inst[ cache ] && space.to ) {
14467
14468 // if the value was null, we don't need to copy it
14469 // if the key was alpha, we don't need to copy it either
14470 if ( key === "alpha" || red[ key ] == null ) {
14471 return;
14472 }
14473 inst[ cache ] = space.to( inst._rgba );
14474 }
14475
14476 // this is the only case where we allow nulls for ALL properties.
14477 // call clamp with alwaysAllowEmpty
14478 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
14479 });
14480
14481 // everything defined but alpha?
14482 if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
14483 // use the default of 1
14484 inst[ cache ][ 3 ] = 1;
14485 if ( space.from ) {
14486 inst._rgba = space.from( inst[ cache ] );
14487 }
14488 }
14489 });
14490 }
14491 return this;
14492 }
14493 },
14494 is: function( compare ) {
14495 var is = color( compare ),
14496 same = true,
14497 inst = this;
14498
14499 each( spaces, function( _, space ) {
14500 var localCache,
14501 isCache = is[ space.cache ];
14502 if (isCache) {
14503 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
14504 each( space.props, function( _, prop ) {
14505 if ( isCache[ prop.idx ] != null ) {
14506 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
14507 return same;
14508 }
14509 });
14510 }
14511 return same;
14512 });
14513 return same;
14514 },
14515 _space: function() {
14516 var used = [],
14517 inst = this;
14518 each( spaces, function( spaceName, space ) {
14519 if ( inst[ space.cache ] ) {
14520 used.push( spaceName );
14521 }
14522 });
14523 return used.pop();
14524 },
14525 transition: function( other, distance ) {
14526 var end = color( other ),
14527 spaceName = end._space(),
14528 space = spaces[ spaceName ],
14529 startColor = this.alpha() === 0 ? color( "transparent" ) : this,
14530 start = startColor[ space.cache ] || space.to( startColor._rgba ),
14531 result = start.slice();
14532
14533 end = end[ space.cache ];
14534 each( space.props, function( key, prop ) {
14535 var index = prop.idx,
14536 startValue = start[ index ],
14537 endValue = end[ index ],
14538 type = propTypes[ prop.type ] || {};
14539
14540 // if null, don't override start value
14541 if ( endValue === null ) {
14542 return;
14543 }
14544 // if null - use end
14545 if ( startValue === null ) {
14546 result[ index ] = endValue;
14547 } else {
14548 if ( type.mod ) {
14549 if ( endValue - startValue > type.mod / 2 ) {
14550 startValue += type.mod;
14551 } else if ( startValue - endValue > type.mod / 2 ) {
14552 startValue -= type.mod;
14553 }
14554 }
14555 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
14556 }
14557 });
14558 return this[ spaceName ]( result );
14559 },
14560 blend: function( opaque ) {
14561 // if we are already opaque - return ourself
14562 if ( this._rgba[ 3 ] === 1 ) {
14563 return this;
14564 }
14565
14566 var rgb = this._rgba.slice(),
14567 a = rgb.pop(),
14568 blend = color( opaque )._rgba;
14569
14570 return color( jQuery.map( rgb, function( v, i ) {
14571 return ( 1 - a ) * blend[ i ] + a * v;
14572 }));
14573 },
14574 toRgbaString: function() {
14575 var prefix = "rgba(",
14576 rgba = jQuery.map( this._rgba, function( v, i ) {
14577 return v == null ? ( i > 2 ? 1 : 0 ) : v;
14578 });
14579
14580 if ( rgba[ 3 ] === 1 ) {
14581 rgba.pop();
14582 prefix = "rgb(";
14583 }
14584
14585 return prefix + rgba.join() + ")";
14586 },
14587 toHslaString: function() {
14588 var prefix = "hsla(",
14589 hsla = jQuery.map( this.hsla(), function( v, i ) {
14590 if ( v == null ) {
14591 v = i > 2 ? 1 : 0;
14592 }
14593
14594 // catch 1 and 2
14595 if ( i && i < 3 ) {
14596 v = Math.round( v * 100 ) + "%";
14597 }
14598 return v;
14599 });
14600
14601 if ( hsla[ 3 ] === 1 ) {
14602 hsla.pop();
14603 prefix = "hsl(";
14604 }
14605 return prefix + hsla.join() + ")";
14606 },
14607 toHexString: function( includeAlpha ) {
14608 var rgba = this._rgba.slice(),
14609 alpha = rgba.pop();
14610
14611 if ( includeAlpha ) {
14612 rgba.push( ~~( alpha * 255 ) );
14613 }
14614
14615 return "#" + jQuery.map( rgba, function( v ) {
14616
14617 // default to 0 when nulls exist
14618 v = ( v || 0 ).toString( 16 );
14619 return v.length === 1 ? "0" + v : v;
14620 }).join("");
14621 },
14622 toString: function() {
14623 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
14624 }
14625});
14626color.fn.parse.prototype = color.fn;
14627
14628// hsla conversions adapted from:
14629// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
14630
14631function hue2rgb( p, q, h ) {
14632 h = ( h + 1 ) % 1;
14633 if ( h * 6 < 1 ) {
14634 return p + ( q - p ) * h * 6;
14635 }
14636 if ( h * 2 < 1) {
14637 return q;
14638 }
14639 if ( h * 3 < 2 ) {
14640 return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
14641 }
14642 return p;
14643}
14644
14645spaces.hsla.to = function( rgba ) {
14646 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
14647 return [ null, null, null, rgba[ 3 ] ];
14648 }
14649 var r = rgba[ 0 ] / 255,
14650 g = rgba[ 1 ] / 255,
14651 b = rgba[ 2 ] / 255,
14652 a = rgba[ 3 ],
14653 max = Math.max( r, g, b ),
14654 min = Math.min( r, g, b ),
14655 diff = max - min,
14656 add = max + min,
14657 l = add * 0.5,
14658 h, s;
14659
14660 if ( min === max ) {
14661 h = 0;
14662 } else if ( r === max ) {
14663 h = ( 60 * ( g - b ) / diff ) + 360;
14664 } else if ( g === max ) {
14665 h = ( 60 * ( b - r ) / diff ) + 120;
14666 } else {
14667 h = ( 60 * ( r - g ) / diff ) + 240;
14668 }
14669
14670 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
14671 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
14672 if ( diff === 0 ) {
14673 s = 0;
14674 } else if ( l <= 0.5 ) {
14675 s = diff / add;
14676 } else {
14677 s = diff / ( 2 - add );
14678 }
14679 return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
14680};
14681
14682spaces.hsla.from = function( hsla ) {
14683 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
14684 return [ null, null, null, hsla[ 3 ] ];
14685 }
14686 var h = hsla[ 0 ] / 360,
14687 s = hsla[ 1 ],
14688 l = hsla[ 2 ],
14689 a = hsla[ 3 ],
14690 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
14691 p = 2 * l - q;
14692
14693 return [
14694 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
14695 Math.round( hue2rgb( p, q, h ) * 255 ),
14696 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
14697 a
14698 ];
14699};
14700
14701each( spaces, function( spaceName, space ) {
14702 var props = space.props,
14703 cache = space.cache,
14704 to = space.to,
14705 from = space.from;
14706
14707 // makes rgba() and hsla()
14708 color.fn[ spaceName ] = function( value ) {
14709
14710 // generate a cache for this space if it doesn't exist
14711 if ( to && !this[ cache ] ) {
14712 this[ cache ] = to( this._rgba );
14713 }
14714 if ( value === undefined ) {
14715 return this[ cache ].slice();
14716 }
14717
14718 var ret,
14719 type = jQuery.type( value ),
14720 arr = ( type === "array" || type === "object" ) ? value : arguments,
14721 local = this[ cache ].slice();
14722
14723 each( props, function( key, prop ) {
14724 var val = arr[ type === "object" ? key : prop.idx ];
14725 if ( val == null ) {
14726 val = local[ prop.idx ];
14727 }
14728 local[ prop.idx ] = clamp( val, prop );
14729 });
14730
14731 if ( from ) {
14732 ret = color( from( local ) );
14733 ret[ cache ] = local;
14734 return ret;
14735 } else {
14736 return color( local );
14737 }
14738 };
14739
14740 // makes red() green() blue() alpha() hue() saturation() lightness()
14741 each( props, function( key, prop ) {
14742 // alpha is included in more than one space
14743 if ( color.fn[ key ] ) {
14744 return;
14745 }
14746 color.fn[ key ] = function( value ) {
14747 var vtype = jQuery.type( value ),
14748 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
14749 local = this[ fn ](),
14750 cur = local[ prop.idx ],
14751 match;
14752
14753 if ( vtype === "undefined" ) {
14754 return cur;
14755 }
14756
14757 if ( vtype === "function" ) {
14758 value = value.call( this, cur );
14759 vtype = jQuery.type( value );
14760 }
14761 if ( value == null && prop.empty ) {
14762 return this;
14763 }
14764 if ( vtype === "string" ) {
14765 match = rplusequals.exec( value );
14766 if ( match ) {
14767 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
14768 }
14769 }
14770 local[ prop.idx ] = value;
14771 return this[ fn ]( local );
14772 };
14773 });
14774});
14775
14776// add cssHook and .fx.step function for each named hook.
14777// accept a space separated string of properties
14778color.hook = function( hook ) {
14779 var hooks = hook.split( " " );
14780 each( hooks, function( i, hook ) {
14781 jQuery.cssHooks[ hook ] = {
14782 set: function( elem, value ) {
14783 var parsed, curElem,
14784 backgroundColor = "";
14785
14786 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
14787 value = color( parsed || value );
14788 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
14789 curElem = hook === "backgroundColor" ? elem.parentNode : elem;
14790 while (
14791 (backgroundColor === "" || backgroundColor === "transparent") &&
14792 curElem && curElem.style
14793 ) {
14794 try {
14795 backgroundColor = jQuery.css( curElem, "backgroundColor" );
14796 curElem = curElem.parentNode;
14797 } catch ( e ) {
14798 }
14799 }
14800
14801 value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
14802 backgroundColor :
14803 "_default" );
14804 }
14805
14806 value = value.toRgbaString();
14807 }
14808 try {
14809 elem.style[ hook ] = value;
14810 } catch ( e ) {
14811 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
14812 }
14813 }
14814 };
14815 jQuery.fx.step[ hook ] = function( fx ) {
14816 if ( !fx.colorInit ) {
14817 fx.start = color( fx.elem, hook );
14818 fx.end = color( fx.end );
14819 fx.colorInit = true;
14820 }
14821 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
14822 };
14823 });
14824
14825};
14826
14827color.hook( stepHooks );
14828
14829jQuery.cssHooks.borderColor = {
14830 expand: function( value ) {
14831 var expanded = {};
14832
14833 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
14834 expanded[ "border" + part + "Color" ] = value;
14835 });
14836 return expanded;
14837 }
14838};
14839
14840// Basic color names only.
14841// Usage of any of the other color names requires adding yourself or including
14842// jquery.color.svg-names.js.
14843colors = jQuery.Color.names = {
14844 // 4.1. Basic color keywords
14845 aqua: "#00ffff",
14846 black: "#000000",
14847 blue: "#0000ff",
14848 fuchsia: "#ff00ff",
14849 gray: "#808080",
14850 green: "#008000",
14851 lime: "#00ff00",
14852 maroon: "#800000",
14853 navy: "#000080",
14854 olive: "#808000",
14855 purple: "#800080",
14856 red: "#ff0000",
14857 silver: "#c0c0c0",
14858 teal: "#008080",
14859 white: "#ffffff",
14860 yellow: "#ffff00",
14861
14862 // 4.2.3. "transparent" color keyword
14863 transparent: [ null, null, null, 0 ],
14864
14865 _default: "#ffffff"
14866};
14867
14868})( jQuery );
14869
14870/******************************************************************************/
14871/****************************** CLASS ANIMATIONS ******************************/
14872/******************************************************************************/
14873(function() {
14874
14875var classAnimationActions = [ "add", "remove", "toggle" ],
14876 shorthandStyles = {
14877 border: 1,
14878 borderBottom: 1,
14879 borderColor: 1,
14880 borderLeft: 1,
14881 borderRight: 1,
14882 borderTop: 1,
14883 borderWidth: 1,
14884 margin: 1,
14885 padding: 1
14886 };
14887
14888$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
14889 $.fx.step[ prop ] = function( fx ) {
14890 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
14891 jQuery.style( fx.elem, prop, fx.end );
14892 fx.setAttr = true;
14893 }
14894 };
14895});
14896
14897function getElementStyles( elem ) {
14898 var key, len,
14899 style = elem.ownerDocument.defaultView ?
14900 elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
14901 elem.currentStyle,
14902 styles = {};
14903
14904 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
14905 len = style.length;
14906 while ( len-- ) {
14907 key = style[ len ];
14908 if ( typeof style[ key ] === "string" ) {
14909 styles[ $.camelCase( key ) ] = style[ key ];
14910 }
14911 }
14912 // support: Opera, IE <9
14913 } else {
14914 for ( key in style ) {
14915 if ( typeof style[ key ] === "string" ) {
14916 styles[ key ] = style[ key ];
14917 }
14918 }
14919 }
14920
14921 return styles;
14922}
14923
14924function styleDifference( oldStyle, newStyle ) {
14925 var diff = {},
14926 name, value;
14927
14928 for ( name in newStyle ) {
14929 value = newStyle[ name ];
14930 if ( oldStyle[ name ] !== value ) {
14931 if ( !shorthandStyles[ name ] ) {
14932 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
14933 diff[ name ] = value;
14934 }
14935 }
14936 }
14937 }
14938
14939 return diff;
14940}
14941
14942// support: jQuery <1.8
14943if ( !$.fn.addBack ) {
14944 $.fn.addBack = function( selector ) {
14945 return this.add( selector == null ?
14946 this.prevObject : this.prevObject.filter( selector )
14947 );
14948 };
14949}
14950
14951$.effects.animateClass = function( value, duration, easing, callback ) {
14952 var o = $.speed( duration, easing, callback );
14953
14954 return this.queue( function() {
14955 var animated = $( this ),
14956 baseClass = animated.attr( "class" ) || "",
14957 applyClassChange,
14958 allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
14959
14960 // map the animated objects to store the original styles.
14961 allAnimations = allAnimations.map(function() {
14962 var el = $( this );
14963 return {
14964 el: el,
14965 start: getElementStyles( this )
14966 };
14967 });
14968
14969 // apply class change
14970 applyClassChange = function() {
14971 $.each( classAnimationActions, function(i, action) {
14972 if ( value[ action ] ) {
14973 animated[ action + "Class" ]( value[ action ] );
14974 }
14975 });
14976 };
14977 applyClassChange();
14978
14979 // map all animated objects again - calculate new styles and diff
14980 allAnimations = allAnimations.map(function() {
14981 this.end = getElementStyles( this.el[ 0 ] );
14982 this.diff = styleDifference( this.start, this.end );
14983 return this;
14984 });
14985
14986 // apply original class
14987 animated.attr( "class", baseClass );
14988
14989 // map all animated objects again - this time collecting a promise
14990 allAnimations = allAnimations.map(function() {
14991 var styleInfo = this,
14992 dfd = $.Deferred(),
14993 opts = $.extend({}, o, {
14994 queue: false,
14995 complete: function() {
14996 dfd.resolve( styleInfo );
14997 }
14998 });
14999
15000 this.el.animate( this.diff, opts );
15001 return dfd.promise();
15002 });
15003
15004 // once all animations have completed:
15005 $.when.apply( $, allAnimations.get() ).done(function() {
15006
15007 // set the final class
15008 applyClassChange();
15009
15010 // for each animated element,
15011 // clear all css properties that were animated
15012 $.each( arguments, function() {
15013 var el = this.el;
15014 $.each( this.diff, function(key) {
15015 el.css( key, "" );
15016 });
15017 });
15018
15019 // this is guarnteed to be there if you use jQuery.speed()
15020 // it also handles dequeuing the next anim...
15021 o.complete.call( animated[ 0 ] );
15022 });
15023 });
15024};
15025
15026$.fn.extend({
15027 addClass: (function( orig ) {
15028 return function( classNames, speed, easing, callback ) {
15029 return speed ?
15030 $.effects.animateClass.call( this,
15031 { add: classNames }, speed, easing, callback ) :
15032 orig.apply( this, arguments );
15033 };
15034 })( $.fn.addClass ),
15035
15036 removeClass: (function( orig ) {
15037 return function( classNames, speed, easing, callback ) {
15038 return arguments.length > 1 ?
15039 $.effects.animateClass.call( this,
15040 { remove: classNames }, speed, easing, callback ) :
15041 orig.apply( this, arguments );
15042 };
15043 })( $.fn.removeClass ),
15044
15045 toggleClass: (function( orig ) {
15046 return function( classNames, force, speed, easing, callback ) {
15047 if ( typeof force === "boolean" || force === undefined ) {
15048 if ( !speed ) {
15049 // without speed parameter
15050 return orig.apply( this, arguments );
15051 } else {
15052 return $.effects.animateClass.call( this,
15053 (force ? { add: classNames } : { remove: classNames }),
15054 speed, easing, callback );
15055 }
15056 } else {
15057 // without force parameter
15058 return $.effects.animateClass.call( this,
15059 { toggle: classNames }, force, speed, easing );
15060 }
15061 };
15062 })( $.fn.toggleClass ),
15063
15064 switchClass: function( remove, add, speed, easing, callback) {
15065 return $.effects.animateClass.call( this, {
15066 add: add,
15067 remove: remove
15068 }, speed, easing, callback );
15069 }
15070});
15071
15072})();
15073
15074/******************************************************************************/
15075/*********************************** EFFECTS **********************************/
15076/******************************************************************************/
15077
15078(function() {
15079
15080$.extend( $.effects, {
15081 version: "1.11.3",
15082
15083 // Saves a set of properties in a data storage
15084 save: function( element, set ) {
15085 for ( var i = 0; i < set.length; i++ ) {
15086 if ( set[ i ] !== null ) {
15087 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
15088 }
15089 }
15090 },
15091
15092 // Restores a set of previously saved properties from a data storage
15093 restore: function( element, set ) {
15094 var val, i;
15095 for ( i = 0; i < set.length; i++ ) {
15096 if ( set[ i ] !== null ) {
15097 val = element.data( dataSpace + set[ i ] );
15098 // support: jQuery 1.6.2
15099 // http://bugs.jquery.com/ticket/9917
15100 // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
15101 // We can't differentiate between "" and 0 here, so we just assume
15102 // empty string since it's likely to be a more common value...
15103 if ( val === undefined ) {
15104 val = "";
15105 }
15106 element.css( set[ i ], val );
15107 }
15108 }
15109 },
15110
15111 setMode: function( el, mode ) {
15112 if (mode === "toggle") {
15113 mode = el.is( ":hidden" ) ? "show" : "hide";
15114 }
15115 return mode;
15116 },
15117
15118 // Translates a [top,left] array into a baseline value
15119 // this should be a little more flexible in the future to handle a string & hash
15120 getBaseline: function( origin, original ) {
15121 var y, x;
15122 switch ( origin[ 0 ] ) {
15123 case "top": y = 0; break;
15124 case "middle": y = 0.5; break;
15125 case "bottom": y = 1; break;
15126 default: y = origin[ 0 ] / original.height;
15127 }
15128 switch ( origin[ 1 ] ) {
15129 case "left": x = 0; break;
15130 case "center": x = 0.5; break;
15131 case "right": x = 1; break;
15132 default: x = origin[ 1 ] / original.width;
15133 }
15134 return {
15135 x: x,
15136 y: y
15137 };
15138 },
15139
15140 // Wraps the element around a wrapper that copies position properties
15141 createWrapper: function( element ) {
15142
15143 // if the element is already wrapped, return it
15144 if ( element.parent().is( ".ui-effects-wrapper" )) {
15145 return element.parent();
15146 }
15147
15148 // wrap the element
15149 var props = {
15150 width: element.outerWidth(true),
15151 height: element.outerHeight(true),
15152 "float": element.css( "float" )
15153 },
15154 wrapper = $( "<div></div>" )
15155 .addClass( "ui-effects-wrapper" )
15156 .css({
15157 fontSize: "100%",
15158 background: "transparent",
15159 border: "none",
15160 margin: 0,
15161 padding: 0
15162 }),
15163 // Store the size in case width/height are defined in % - Fixes #5245
15164 size = {
15165 width: element.width(),
15166 height: element.height()
15167 },
15168 active = document.activeElement;
15169
15170 // support: Firefox
15171 // Firefox incorrectly exposes anonymous content
15172 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
15173 try {
15174 active.id;
15175 } catch ( e ) {
15176 active = document.body;
15177 }
15178
15179 element.wrap( wrapper );
15180
15181 // Fixes #7595 - Elements lose focus when wrapped.
15182 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
15183 $( active ).focus();
15184 }
15185
15186 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
15187
15188 // transfer positioning properties to the wrapper
15189 if ( element.css( "position" ) === "static" ) {
15190 wrapper.css({ position: "relative" });
15191 element.css({ position: "relative" });
15192 } else {
15193 $.extend( props, {
15194 position: element.css( "position" ),
15195 zIndex: element.css( "z-index" )
15196 });
15197 $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
15198 props[ pos ] = element.css( pos );
15199 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
15200 props[ pos ] = "auto";
15201 }
15202 });
15203 element.css({
15204 position: "relative",
15205 top: 0,
15206 left: 0,
15207 right: "auto",
15208 bottom: "auto"
15209 });
15210 }
15211 element.css(size);
15212
15213 return wrapper.css( props ).show();
15214 },
15215
15216 removeWrapper: function( element ) {
15217 var active = document.activeElement;
15218
15219 if ( element.parent().is( ".ui-effects-wrapper" ) ) {
15220 element.parent().replaceWith( element );
15221
15222 // Fixes #7595 - Elements lose focus when wrapped.
15223 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
15224 $( active ).focus();
15225 }
15226 }
15227
15228 return element;
15229 },
15230
15231 setTransition: function( element, list, factor, value ) {
15232 value = value || {};
15233 $.each( list, function( i, x ) {
15234 var unit = element.cssUnit( x );
15235 if ( unit[ 0 ] > 0 ) {
15236 value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
15237 }
15238 });
15239 return value;
15240 }
15241});
15242
15243// return an effect options object for the given parameters:
15244function _normalizeArguments( effect, options, speed, callback ) {
15245
15246 // allow passing all options as the first parameter
15247 if ( $.isPlainObject( effect ) ) {
15248 options = effect;
15249 effect = effect.effect;
15250 }
15251
15252 // convert to an object
15253 effect = { effect: effect };
15254
15255 // catch (effect, null, ...)
15256 if ( options == null ) {
15257 options = {};
15258 }
15259
15260 // catch (effect, callback)
15261 if ( $.isFunction( options ) ) {
15262 callback = options;
15263 speed = null;
15264 options = {};
15265 }
15266
15267 // catch (effect, speed, ?)
15268 if ( typeof options === "number" || $.fx.speeds[ options ] ) {
15269 callback = speed;
15270 speed = options;
15271 options = {};
15272 }
15273
15274 // catch (effect, options, callback)
15275 if ( $.isFunction( speed ) ) {
15276 callback = speed;
15277 speed = null;
15278 }
15279
15280 // add options to effect
15281 if ( options ) {
15282 $.extend( effect, options );
15283 }
15284
15285 speed = speed || options.duration;
15286 effect.duration = $.fx.off ? 0 :
15287 typeof speed === "number" ? speed :
15288 speed in $.fx.speeds ? $.fx.speeds[ speed ] :
15289 $.fx.speeds._default;
15290
15291 effect.complete = callback || options.complete;
15292
15293 return effect;
15294}
15295
15296function standardAnimationOption( option ) {
15297 // Valid standard speeds (nothing, number, named speed)
15298 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
15299 return true;
15300 }
15301
15302 // Invalid strings - treat as "normal" speed
15303 if ( typeof option === "string" && !$.effects.effect[ option ] ) {
15304 return true;
15305 }
15306
15307 // Complete callback
15308 if ( $.isFunction( option ) ) {
15309 return true;
15310 }
15311
15312 // Options hash (but not naming an effect)
15313 if ( typeof option === "object" && !option.effect ) {
15314 return true;
15315 }
15316
15317 // Didn't match any standard API
15318 return false;
15319}
15320
15321$.fn.extend({
15322 effect: function( /* effect, options, speed, callback */ ) {
15323 var args = _normalizeArguments.apply( this, arguments ),
15324 mode = args.mode,
15325 queue = args.queue,
15326 effectMethod = $.effects.effect[ args.effect ];
15327
15328 if ( $.fx.off || !effectMethod ) {
15329 // delegate to the original method (e.g., .show()) if possible
15330 if ( mode ) {
15331 return this[ mode ]( args.duration, args.complete );
15332 } else {
15333 return this.each( function() {
15334 if ( args.complete ) {
15335 args.complete.call( this );
15336 }
15337 });
15338 }
15339 }
15340
15341 function run( next ) {
15342 var elem = $( this ),
15343 complete = args.complete,
15344 mode = args.mode;
15345
15346 function done() {
15347 if ( $.isFunction( complete ) ) {
15348 complete.call( elem[0] );
15349 }
15350 if ( $.isFunction( next ) ) {
15351 next();
15352 }
15353 }
15354
15355 // If the element already has the correct final state, delegate to
15356 // the core methods so the internal tracking of "olddisplay" works.
15357 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
15358 elem[ mode ]();
15359 done();
15360 } else {
15361 effectMethod.call( elem[0], args, done );
15362 }
15363 }
15364
15365 return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
15366 },
15367
15368 show: (function( orig ) {
15369 return function( option ) {
15370 if ( standardAnimationOption( option ) ) {
15371 return orig.apply( this, arguments );
15372 } else {
15373 var args = _normalizeArguments.apply( this, arguments );
15374 args.mode = "show";
15375 return this.effect.call( this, args );
15376 }
15377 };
15378 })( $.fn.show ),
15379
15380 hide: (function( orig ) {
15381 return function( option ) {
15382 if ( standardAnimationOption( option ) ) {
15383 return orig.apply( this, arguments );
15384 } else {
15385 var args = _normalizeArguments.apply( this, arguments );
15386 args.mode = "hide";
15387 return this.effect.call( this, args );
15388 }
15389 };
15390 })( $.fn.hide ),
15391
15392 toggle: (function( orig ) {
15393 return function( option ) {
15394 if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
15395 return orig.apply( this, arguments );
15396 } else {
15397 var args = _normalizeArguments.apply( this, arguments );
15398 args.mode = "toggle";
15399 return this.effect.call( this, args );
15400 }
15401 };
15402 })( $.fn.toggle ),
15403
15404 // helper functions
15405 cssUnit: function(key) {
15406 var style = this.css( key ),
15407 val = [];
15408
15409 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
15410 if ( style.indexOf( unit ) > 0 ) {
15411 val = [ parseFloat( style ), unit ];
15412 }
15413 });
15414 return val;
15415 }
15416});
15417
15418})();
15419
15420/******************************************************************************/
15421/*********************************** EASING ***********************************/
15422/******************************************************************************/
15423
15424(function() {
15425
15426// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
15427
15428var baseEasings = {};
15429
15430$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
15431 baseEasings[ name ] = function( p ) {
15432 return Math.pow( p, i + 2 );
15433 };
15434});
15435
15436$.extend( baseEasings, {
15437 Sine: function( p ) {
15438 return 1 - Math.cos( p * Math.PI / 2 );
15439 },
15440 Circ: function( p ) {
15441 return 1 - Math.sqrt( 1 - p * p );
15442 },
15443 Elastic: function( p ) {
15444 return p === 0 || p === 1 ? p :
15445 -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
15446 },
15447 Back: function( p ) {
15448 return p * p * ( 3 * p - 2 );
15449 },
15450 Bounce: function( p ) {
15451 var pow2,
15452 bounce = 4;
15453
15454 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
15455 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
15456 }
15457});
15458
15459$.each( baseEasings, function( name, easeIn ) {
15460 $.easing[ "easeIn" + name ] = easeIn;
15461 $.easing[ "easeOut" + name ] = function( p ) {
15462 return 1 - easeIn( 1 - p );
15463 };
15464 $.easing[ "easeInOut" + name ] = function( p ) {
15465 return p < 0.5 ?
15466 easeIn( p * 2 ) / 2 :
15467 1 - easeIn( p * -2 + 2 ) / 2;
15468 };
15469});
15470
15471})();
15472
15473var effect = $.effects;
15474
15475
15476/*!
15477 * jQuery UI Effects Blind 1.11.3
15478 * http://jqueryui.com
15479 *
15480 * Copyright jQuery Foundation and other contributors
15481 * Released under the MIT license.
15482 * http://jquery.org/license
15483 *
15484 * http://api.jqueryui.com/blind-effect/
15485 */
15486
15487
15488var effectBlind = $.effects.effect.blind = function( o, done ) {
15489 // Create element
15490 var el = $( this ),
15491 rvertical = /up|down|vertical/,
15492 rpositivemotion = /up|left|vertical|horizontal/,
15493 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
15494 mode = $.effects.setMode( el, o.mode || "hide" ),
15495 direction = o.direction || "up",
15496 vertical = rvertical.test( direction ),
15497 ref = vertical ? "height" : "width",
15498 ref2 = vertical ? "top" : "left",
15499 motion = rpositivemotion.test( direction ),
15500 animation = {},
15501 show = mode === "show",
15502 wrapper, distance, margin;
15503
15504 // if already wrapped, the wrapper's properties are my property. #6245
15505 if ( el.parent().is( ".ui-effects-wrapper" ) ) {
15506 $.effects.save( el.parent(), props );
15507 } else {
15508 $.effects.save( el, props );
15509 }
15510 el.show();
15511 wrapper = $.effects.createWrapper( el ).css({
15512 overflow: "hidden"
15513 });
15514
15515 distance = wrapper[ ref ]();
15516 margin = parseFloat( wrapper.css( ref2 ) ) || 0;
15517
15518 animation[ ref ] = show ? distance : 0;
15519 if ( !motion ) {
15520 el
15521 .css( vertical ? "bottom" : "right", 0 )
15522 .css( vertical ? "top" : "left", "auto" )
15523 .css({ position: "absolute" });
15524
15525 animation[ ref2 ] = show ? margin : distance + margin;
15526 }
15527
15528 // start at 0 if we are showing
15529 if ( show ) {
15530 wrapper.css( ref, 0 );
15531 if ( !motion ) {
15532 wrapper.css( ref2, margin + distance );
15533 }
15534 }
15535
15536 // Animate
15537 wrapper.animate( animation, {
15538 duration: o.duration,
15539 easing: o.easing,
15540 queue: false,
15541 complete: function() {
15542 if ( mode === "hide" ) {
15543 el.hide();
15544 }
15545 $.effects.restore( el, props );
15546 $.effects.removeWrapper( el );
15547 done();
15548 }
15549 });
15550};
15551
15552
15553/*!
15554 * jQuery UI Effects Bounce 1.11.3
15555 * http://jqueryui.com
15556 *
15557 * Copyright jQuery Foundation and other contributors
15558 * Released under the MIT license.
15559 * http://jquery.org/license
15560 *
15561 * http://api.jqueryui.com/bounce-effect/
15562 */
15563
15564
15565var effectBounce = $.effects.effect.bounce = function( o, done ) {
15566 var el = $( this ),
15567 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
15568
15569 // defaults:
15570 mode = $.effects.setMode( el, o.mode || "effect" ),
15571 hide = mode === "hide",
15572 show = mode === "show",
15573 direction = o.direction || "up",
15574 distance = o.distance,
15575 times = o.times || 5,
15576
15577 // number of internal animations
15578 anims = times * 2 + ( show || hide ? 1 : 0 ),
15579 speed = o.duration / anims,
15580 easing = o.easing,
15581
15582 // utility:
15583 ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
15584 motion = ( direction === "up" || direction === "left" ),
15585 i,
15586 upAnim,
15587 downAnim,
15588
15589 // we will need to re-assemble the queue to stack our animations in place
15590 queue = el.queue(),
15591 queuelen = queue.length;
15592
15593 // Avoid touching opacity to prevent clearType and PNG issues in IE
15594 if ( show || hide ) {
15595 props.push( "opacity" );
15596 }
15597
15598 $.effects.save( el, props );
15599 el.show();
15600 $.effects.createWrapper( el ); // Create Wrapper
15601
15602 // default distance for the BIGGEST bounce is the outer Distance / 3
15603 if ( !distance ) {
15604 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
15605 }
15606
15607 if ( show ) {
15608 downAnim = { opacity: 1 };
15609 downAnim[ ref ] = 0;
15610
15611 // if we are showing, force opacity 0 and set the initial position
15612 // then do the "first" animation
15613 el.css( "opacity", 0 )
15614 .css( ref, motion ? -distance * 2 : distance * 2 )
15615 .animate( downAnim, speed, easing );
15616 }
15617
15618 // start at the smallest distance if we are hiding
15619 if ( hide ) {
15620 distance = distance / Math.pow( 2, times - 1 );
15621 }
15622
15623 downAnim = {};
15624 downAnim[ ref ] = 0;
15625 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
15626 for ( i = 0; i < times; i++ ) {
15627 upAnim = {};
15628 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
15629
15630 el.animate( upAnim, speed, easing )
15631 .animate( downAnim, speed, easing );
15632
15633 distance = hide ? distance * 2 : distance / 2;
15634 }
15635
15636 // Last Bounce when Hiding
15637 if ( hide ) {
15638 upAnim = { opacity: 0 };
15639 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
15640
15641 el.animate( upAnim, speed, easing );
15642 }
15643
15644 el.queue(function() {
15645 if ( hide ) {
15646 el.hide();
15647 }
15648 $.effects.restore( el, props );
15649 $.effects.removeWrapper( el );
15650 done();
15651 });
15652
15653 // inject all the animations we just queued to be first in line (after "inprogress")
15654 if ( queuelen > 1) {
15655 queue.splice.apply( queue,
15656 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
15657 }
15658 el.dequeue();
15659
15660};
15661
15662
15663/*!
15664 * jQuery UI Effects Clip 1.11.3
15665 * http://jqueryui.com
15666 *
15667 * Copyright jQuery Foundation and other contributors
15668 * Released under the MIT license.
15669 * http://jquery.org/license
15670 *
15671 * http://api.jqueryui.com/clip-effect/
15672 */
15673
15674
15675var effectClip = $.effects.effect.clip = function( o, done ) {
15676 // Create element
15677 var el = $( this ),
15678 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
15679 mode = $.effects.setMode( el, o.mode || "hide" ),
15680 show = mode === "show",
15681 direction = o.direction || "vertical",
15682 vert = direction === "vertical",
15683 size = vert ? "height" : "width",
15684 position = vert ? "top" : "left",
15685 animation = {},
15686 wrapper, animate, distance;
15687
15688 // Save & Show
15689 $.effects.save( el, props );
15690 el.show();
15691
15692 // Create Wrapper
15693 wrapper = $.effects.createWrapper( el ).css({
15694 overflow: "hidden"
15695 });
15696 animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
15697 distance = animate[ size ]();
15698
15699 // Shift
15700 if ( show ) {
15701 animate.css( size, 0 );
15702 animate.css( position, distance / 2 );
15703 }
15704
15705 // Create Animation Object:
15706 animation[ size ] = show ? distance : 0;
15707 animation[ position ] = show ? 0 : distance / 2;
15708
15709 // Animate
15710 animate.animate( animation, {
15711 queue: false,
15712 duration: o.duration,
15713 easing: o.easing,
15714 complete: function() {
15715 if ( !show ) {
15716 el.hide();
15717 }
15718 $.effects.restore( el, props );
15719 $.effects.removeWrapper( el );
15720 done();
15721 }
15722 });
15723
15724};
15725
15726
15727/*!
15728 * jQuery UI Effects Drop 1.11.3
15729 * http://jqueryui.com
15730 *
15731 * Copyright jQuery Foundation and other contributors
15732 * Released under the MIT license.
15733 * http://jquery.org/license
15734 *
15735 * http://api.jqueryui.com/drop-effect/
15736 */
15737
15738
15739var effectDrop = $.effects.effect.drop = function( o, done ) {
15740
15741 var el = $( this ),
15742 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
15743 mode = $.effects.setMode( el, o.mode || "hide" ),
15744 show = mode === "show",
15745 direction = o.direction || "left",
15746 ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
15747 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
15748 animation = {
15749 opacity: show ? 1 : 0
15750 },
15751 distance;
15752
15753 // Adjust
15754 $.effects.save( el, props );
15755 el.show();
15756 $.effects.createWrapper( el );
15757
15758 distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
15759
15760 if ( show ) {
15761 el
15762 .css( "opacity", 0 )
15763 .css( ref, motion === "pos" ? -distance : distance );
15764 }
15765
15766 // Animation
15767 animation[ ref ] = ( show ?
15768 ( motion === "pos" ? "+=" : "-=" ) :
15769 ( motion === "pos" ? "-=" : "+=" ) ) +
15770 distance;
15771
15772 // Animate
15773 el.animate( animation, {
15774 queue: false,
15775 duration: o.duration,
15776 easing: o.easing,
15777 complete: function() {
15778 if ( mode === "hide" ) {
15779 el.hide();
15780 }
15781 $.effects.restore( el, props );
15782 $.effects.removeWrapper( el );
15783 done();
15784 }
15785 });
15786};
15787
15788
15789/*!
15790 * jQuery UI Effects Explode 1.11.3
15791 * http://jqueryui.com
15792 *
15793 * Copyright jQuery Foundation and other contributors
15794 * Released under the MIT license.
15795 * http://jquery.org/license
15796 *
15797 * http://api.jqueryui.com/explode-effect/
15798 */
15799
15800
15801var effectExplode = $.effects.effect.explode = function( o, done ) {
15802
15803 var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
15804 cells = rows,
15805 el = $( this ),
15806 mode = $.effects.setMode( el, o.mode || "hide" ),
15807 show = mode === "show",
15808
15809 // show and then visibility:hidden the element before calculating offset
15810 offset = el.show().css( "visibility", "hidden" ).offset(),
15811
15812 // width and height of a piece
15813 width = Math.ceil( el.outerWidth() / cells ),
15814 height = Math.ceil( el.outerHeight() / rows ),
15815 pieces = [],
15816
15817 // loop
15818 i, j, left, top, mx, my;
15819
15820 // children animate complete:
15821 function childComplete() {
15822 pieces.push( this );
15823 if ( pieces.length === rows * cells ) {
15824 animComplete();
15825 }
15826 }
15827
15828 // clone the element for each row and cell.
15829 for ( i = 0; i < rows ; i++ ) { // ===>
15830 top = offset.top + i * height;
15831 my = i - ( rows - 1 ) / 2 ;
15832
15833 for ( j = 0; j < cells ; j++ ) { // |||
15834 left = offset.left + j * width;
15835 mx = j - ( cells - 1 ) / 2 ;
15836
15837 // Create a clone of the now hidden main element that will be absolute positioned
15838 // within a wrapper div off the -left and -top equal to size of our pieces
15839 el
15840 .clone()
15841 .appendTo( "body" )
15842 .wrap( "<div></div>" )
15843 .css({
15844 position: "absolute",
15845 visibility: "visible",
15846 left: -j * width,
15847 top: -i * height
15848 })
15849
15850 // select the wrapper - make it overflow: hidden and absolute positioned based on
15851 // where the original was located +left and +top equal to the size of pieces
15852 .parent()
15853 .addClass( "ui-effects-explode" )
15854 .css({
15855 position: "absolute",
15856 overflow: "hidden",
15857 width: width,
15858 height: height,
15859 left: left + ( show ? mx * width : 0 ),
15860 top: top + ( show ? my * height : 0 ),
15861 opacity: show ? 0 : 1
15862 }).animate({
15863 left: left + ( show ? 0 : mx * width ),
15864 top: top + ( show ? 0 : my * height ),
15865 opacity: show ? 1 : 0
15866 }, o.duration || 500, o.easing, childComplete );
15867 }
15868 }
15869
15870 function animComplete() {
15871 el.css({
15872 visibility: "visible"
15873 });
15874 $( pieces ).remove();
15875 if ( !show ) {
15876 el.hide();
15877 }
15878 done();
15879 }
15880};
15881
15882
15883/*!
15884 * jQuery UI Effects Fade 1.11.3
15885 * http://jqueryui.com
15886 *
15887 * Copyright jQuery Foundation and other contributors
15888 * Released under the MIT license.
15889 * http://jquery.org/license
15890 *
15891 * http://api.jqueryui.com/fade-effect/
15892 */
15893
15894
15895var effectFade = $.effects.effect.fade = function( o, done ) {
15896 var el = $( this ),
15897 mode = $.effects.setMode( el, o.mode || "toggle" );
15898
15899 el.animate({
15900 opacity: mode
15901 }, {
15902 queue: false,
15903 duration: o.duration,
15904 easing: o.easing,
15905 complete: done
15906 });
15907};
15908
15909
15910/*!
15911 * jQuery UI Effects Fold 1.11.3
15912 * http://jqueryui.com
15913 *
15914 * Copyright jQuery Foundation and other contributors
15915 * Released under the MIT license.
15916 * http://jquery.org/license
15917 *
15918 * http://api.jqueryui.com/fold-effect/
15919 */
15920
15921
15922var effectFold = $.effects.effect.fold = function( o, done ) {
15923
15924 // Create element
15925 var el = $( this ),
15926 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
15927 mode = $.effects.setMode( el, o.mode || "hide" ),
15928 show = mode === "show",
15929 hide = mode === "hide",
15930 size = o.size || 15,
15931 percent = /([0-9]+)%/.exec( size ),
15932 horizFirst = !!o.horizFirst,
15933 widthFirst = show !== horizFirst,
15934 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
15935 duration = o.duration / 2,
15936 wrapper, distance,
15937 animation1 = {},
15938 animation2 = {};
15939
15940 $.effects.save( el, props );
15941 el.show();
15942
15943 // Create Wrapper
15944 wrapper = $.effects.createWrapper( el ).css({
15945 overflow: "hidden"
15946 });
15947 distance = widthFirst ?
15948 [ wrapper.width(), wrapper.height() ] :
15949 [ wrapper.height(), wrapper.width() ];
15950
15951 if ( percent ) {
15952 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
15953 }
15954 if ( show ) {
15955 wrapper.css( horizFirst ? {
15956 height: 0,
15957 width: size
15958 } : {
15959 height: size,
15960 width: 0
15961 });
15962 }
15963
15964 // Animation
15965 animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
15966 animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
15967
15968 // Animate
15969 wrapper
15970 .animate( animation1, duration, o.easing )
15971 .animate( animation2, duration, o.easing, function() {
15972 if ( hide ) {
15973 el.hide();
15974 }
15975 $.effects.restore( el, props );
15976 $.effects.removeWrapper( el );
15977 done();
15978 });
15979
15980};
15981
15982
15983/*!
15984 * jQuery UI Effects Highlight 1.11.3
15985 * http://jqueryui.com
15986 *
15987 * Copyright jQuery Foundation and other contributors
15988 * Released under the MIT license.
15989 * http://jquery.org/license
15990 *
15991 * http://api.jqueryui.com/highlight-effect/
15992 */
15993
15994
15995var effectHighlight = $.effects.effect.highlight = function( o, done ) {
15996 var elem = $( this ),
15997 props = [ "backgroundImage", "backgroundColor", "opacity" ],
15998 mode = $.effects.setMode( elem, o.mode || "show" ),
15999 animation = {
16000 backgroundColor: elem.css( "backgroundColor" )
16001 };
16002
16003 if (mode === "hide") {
16004 animation.opacity = 0;
16005 }
16006
16007 $.effects.save( elem, props );
16008
16009 elem
16010 .show()
16011 .css({
16012 backgroundImage: "none",
16013 backgroundColor: o.color || "#ffff99"
16014 })
16015 .animate( animation, {
16016 queue: false,
16017 duration: o.duration,
16018 easing: o.easing,
16019 complete: function() {
16020 if ( mode === "hide" ) {
16021 elem.hide();
16022 }
16023 $.effects.restore( elem, props );
16024 done();
16025 }
16026 });
16027};
16028
16029
16030/*!
16031 * jQuery UI Effects Size 1.11.3
16032 * http://jqueryui.com
16033 *
16034 * Copyright jQuery Foundation and other contributors
16035 * Released under the MIT license.
16036 * http://jquery.org/license
16037 *
16038 * http://api.jqueryui.com/size-effect/
16039 */
16040
16041
16042var effectSize = $.effects.effect.size = function( o, done ) {
16043
16044 // Create element
16045 var original, baseline, factor,
16046 el = $( this ),
16047 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
16048
16049 // Always restore
16050 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
16051
16052 // Copy for children
16053 props2 = [ "width", "height", "overflow" ],
16054 cProps = [ "fontSize" ],
16055 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
16056 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
16057
16058 // Set options
16059 mode = $.effects.setMode( el, o.mode || "effect" ),
16060 restore = o.restore || mode !== "effect",
16061 scale = o.scale || "both",
16062 origin = o.origin || [ "middle", "center" ],
16063 position = el.css( "position" ),
16064 props = restore ? props0 : props1,
16065 zero = {
16066 height: 0,
16067 width: 0,
16068 outerHeight: 0,
16069 outerWidth: 0
16070 };
16071
16072 if ( mode === "show" ) {
16073 el.show();
16074 }
16075 original = {
16076 height: el.height(),
16077 width: el.width(),
16078 outerHeight: el.outerHeight(),
16079 outerWidth: el.outerWidth()
16080 };
16081
16082 if ( o.mode === "toggle" && mode === "show" ) {
16083 el.from = o.to || zero;
16084 el.to = o.from || original;
16085 } else {
16086 el.from = o.from || ( mode === "show" ? zero : original );
16087 el.to = o.to || ( mode === "hide" ? zero : original );
16088 }
16089
16090 // Set scaling factor
16091 factor = {
16092 from: {
16093 y: el.from.height / original.height,
16094 x: el.from.width / original.width
16095 },
16096 to: {
16097 y: el.to.height / original.height,
16098 x: el.to.width / original.width
16099 }
16100 };
16101
16102 // Scale the css box
16103 if ( scale === "box" || scale === "both" ) {
16104
16105 // Vertical props scaling
16106 if ( factor.from.y !== factor.to.y ) {
16107 props = props.concat( vProps );
16108 el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
16109 el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
16110 }
16111
16112 // Horizontal props scaling
16113 if ( factor.from.x !== factor.to.x ) {
16114 props = props.concat( hProps );
16115 el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
16116 el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
16117 }
16118 }
16119
16120 // Scale the content
16121 if ( scale === "content" || scale === "both" ) {
16122
16123 // Vertical props scaling
16124 if ( factor.from.y !== factor.to.y ) {
16125 props = props.concat( cProps ).concat( props2 );
16126 el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
16127 el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
16128 }
16129 }
16130
16131 $.effects.save( el, props );
16132 el.show();
16133 $.effects.createWrapper( el );
16134 el.css( "overflow", "hidden" ).css( el.from );
16135
16136 // Adjust
16137 if (origin) { // Calculate baseline shifts
16138 baseline = $.effects.getBaseline( origin, original );
16139 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
16140 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
16141 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
16142 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
16143 }
16144 el.css( el.from ); // set top & left
16145
16146 // Animate
16147 if ( scale === "content" || scale === "both" ) { // Scale the children
16148
16149 // Add margins/font-size
16150 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
16151 hProps = hProps.concat([ "marginLeft", "marginRight" ]);
16152 props2 = props0.concat(vProps).concat(hProps);
16153
16154 el.find( "*[width]" ).each( function() {
16155 var child = $( this ),
16156 c_original = {
16157 height: child.height(),
16158 width: child.width(),
16159 outerHeight: child.outerHeight(),
16160 outerWidth: child.outerWidth()
16161 };
16162 if (restore) {
16163 $.effects.save(child, props2);
16164 }
16165
16166 child.from = {
16167 height: c_original.height * factor.from.y,
16168 width: c_original.width * factor.from.x,
16169 outerHeight: c_original.outerHeight * factor.from.y,
16170 outerWidth: c_original.outerWidth * factor.from.x
16171 };
16172 child.to = {
16173 height: c_original.height * factor.to.y,
16174 width: c_original.width * factor.to.x,
16175 outerHeight: c_original.height * factor.to.y,
16176 outerWidth: c_original.width * factor.to.x
16177 };
16178
16179 // Vertical props scaling
16180 if ( factor.from.y !== factor.to.y ) {
16181 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
16182 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
16183 }
16184
16185 // Horizontal props scaling
16186 if ( factor.from.x !== factor.to.x ) {
16187 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
16188 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
16189 }
16190
16191 // Animate children
16192 child.css( child.from );
16193 child.animate( child.to, o.duration, o.easing, function() {
16194
16195 // Restore children
16196 if ( restore ) {
16197 $.effects.restore( child, props2 );
16198 }
16199 });
16200 });
16201 }
16202
16203 // Animate
16204 el.animate( el.to, {
16205 queue: false,
16206 duration: o.duration,
16207 easing: o.easing,
16208 complete: function() {
16209 if ( el.to.opacity === 0 ) {
16210 el.css( "opacity", el.from.opacity );
16211 }
16212 if ( mode === "hide" ) {
16213 el.hide();
16214 }
16215 $.effects.restore( el, props );
16216 if ( !restore ) {
16217
16218 // we need to calculate our new positioning based on the scaling
16219 if ( position === "static" ) {
16220 el.css({
16221 position: "relative",
16222 top: el.to.top,
16223 left: el.to.left
16224 });
16225 } else {
16226 $.each([ "top", "left" ], function( idx, pos ) {
16227 el.css( pos, function( _, str ) {
16228 var val = parseInt( str, 10 ),
16229 toRef = idx ? el.to.left : el.to.top;
16230
16231 // if original was "auto", recalculate the new value from wrapper
16232 if ( str === "auto" ) {
16233 return toRef + "px";
16234 }
16235
16236 return val + toRef + "px";
16237 });
16238 });
16239 }
16240 }
16241
16242 $.effects.removeWrapper( el );
16243 done();
16244 }
16245 });
16246
16247};
16248
16249
16250/*!
16251 * jQuery UI Effects Scale 1.11.3
16252 * http://jqueryui.com
16253 *
16254 * Copyright jQuery Foundation and other contributors
16255 * Released under the MIT license.
16256 * http://jquery.org/license
16257 *
16258 * http://api.jqueryui.com/scale-effect/
16259 */
16260
16261
16262var effectScale = $.effects.effect.scale = function( o, done ) {
16263
16264 // Create element
16265 var el = $( this ),
16266 options = $.extend( true, {}, o ),
16267 mode = $.effects.setMode( el, o.mode || "effect" ),
16268 percent = parseInt( o.percent, 10 ) ||
16269 ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
16270 direction = o.direction || "both",
16271 origin = o.origin,
16272 original = {
16273 height: el.height(),
16274 width: el.width(),
16275 outerHeight: el.outerHeight(),
16276 outerWidth: el.outerWidth()
16277 },
16278 factor = {
16279 y: direction !== "horizontal" ? (percent / 100) : 1,
16280 x: direction !== "vertical" ? (percent / 100) : 1
16281 };
16282
16283 // We are going to pass this effect to the size effect:
16284 options.effect = "size";
16285 options.queue = false;
16286 options.complete = done;
16287
16288 // Set default origin and restore for show/hide
16289 if ( mode !== "effect" ) {
16290 options.origin = origin || [ "middle", "center" ];
16291 options.restore = true;
16292 }
16293
16294 options.from = o.from || ( mode === "show" ? {
16295 height: 0,
16296 width: 0,
16297 outerHeight: 0,
16298 outerWidth: 0
16299 } : original );
16300 options.to = {
16301 height: original.height * factor.y,
16302 width: original.width * factor.x,
16303 outerHeight: original.outerHeight * factor.y,
16304 outerWidth: original.outerWidth * factor.x
16305 };
16306
16307 // Fade option to support puff
16308 if ( options.fade ) {
16309 if ( mode === "show" ) {
16310 options.from.opacity = 0;
16311 options.to.opacity = 1;
16312 }
16313 if ( mode === "hide" ) {
16314 options.from.opacity = 1;
16315 options.to.opacity = 0;
16316 }
16317 }
16318
16319 // Animate
16320 el.effect( options );
16321
16322};
16323
16324
16325/*!
16326 * jQuery UI Effects Puff 1.11.3
16327 * http://jqueryui.com
16328 *
16329 * Copyright jQuery Foundation and other contributors
16330 * Released under the MIT license.
16331 * http://jquery.org/license
16332 *
16333 * http://api.jqueryui.com/puff-effect/
16334 */
16335
16336
16337var effectPuff = $.effects.effect.puff = function( o, done ) {
16338 var elem = $( this ),
16339 mode = $.effects.setMode( elem, o.mode || "hide" ),
16340 hide = mode === "hide",
16341 percent = parseInt( o.percent, 10 ) || 150,
16342 factor = percent / 100,
16343 original = {
16344 height: elem.height(),
16345 width: elem.width(),
16346 outerHeight: elem.outerHeight(),
16347 outerWidth: elem.outerWidth()
16348 };
16349
16350 $.extend( o, {
16351 effect: "scale",
16352 queue: false,
16353 fade: true,
16354 mode: mode,
16355 complete: done,
16356 percent: hide ? percent : 100,
16357 from: hide ?
16358 original :
16359 {
16360 height: original.height * factor,
16361 width: original.width * factor,
16362 outerHeight: original.outerHeight * factor,
16363 outerWidth: original.outerWidth * factor
16364 }
16365 });
16366
16367 elem.effect( o );
16368};
16369
16370
16371/*!
16372 * jQuery UI Effects Pulsate 1.11.3
16373 * http://jqueryui.com
16374 *
16375 * Copyright jQuery Foundation and other contributors
16376 * Released under the MIT license.
16377 * http://jquery.org/license
16378 *
16379 * http://api.jqueryui.com/pulsate-effect/
16380 */
16381
16382
16383var effectPulsate = $.effects.effect.pulsate = function( o, done ) {
16384 var elem = $( this ),
16385 mode = $.effects.setMode( elem, o.mode || "show" ),
16386 show = mode === "show",
16387 hide = mode === "hide",
16388 showhide = ( show || mode === "hide" ),
16389
16390 // showing or hiding leaves of the "last" animation
16391 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
16392 duration = o.duration / anims,
16393 animateTo = 0,
16394 queue = elem.queue(),
16395 queuelen = queue.length,
16396 i;
16397
16398 if ( show || !elem.is(":visible")) {
16399 elem.css( "opacity", 0 ).show();
16400 animateTo = 1;
16401 }
16402
16403 // anims - 1 opacity "toggles"
16404 for ( i = 1; i < anims; i++ ) {
16405 elem.animate({
16406 opacity: animateTo
16407 }, duration, o.easing );
16408 animateTo = 1 - animateTo;
16409 }
16410
16411 elem.animate({
16412 opacity: animateTo
16413 }, duration, o.easing);
16414
16415 elem.queue(function() {
16416 if ( hide ) {
16417 elem.hide();
16418 }
16419 done();
16420 });
16421
16422 // We just queued up "anims" animations, we need to put them next in the queue
16423 if ( queuelen > 1 ) {
16424 queue.splice.apply( queue,
16425 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
16426 }
16427 elem.dequeue();
16428};
16429
16430
16431/*!
16432 * jQuery UI Effects Shake 1.11.3
16433 * http://jqueryui.com
16434 *
16435 * Copyright jQuery Foundation and other contributors
16436 * Released under the MIT license.
16437 * http://jquery.org/license
16438 *
16439 * http://api.jqueryui.com/shake-effect/
16440 */
16441
16442
16443var effectShake = $.effects.effect.shake = function( o, done ) {
16444
16445 var el = $( this ),
16446 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
16447 mode = $.effects.setMode( el, o.mode || "effect" ),
16448 direction = o.direction || "left",
16449 distance = o.distance || 20,
16450 times = o.times || 3,
16451 anims = times * 2 + 1,
16452 speed = Math.round( o.duration / anims ),
16453 ref = (direction === "up" || direction === "down") ? "top" : "left",
16454 positiveMotion = (direction === "up" || direction === "left"),
16455 animation = {},
16456 animation1 = {},
16457 animation2 = {},
16458 i,
16459
16460 // we will need to re-assemble the queue to stack our animations in place
16461 queue = el.queue(),
16462 queuelen = queue.length;
16463
16464 $.effects.save( el, props );
16465 el.show();
16466 $.effects.createWrapper( el );
16467
16468 // Animation
16469 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
16470 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
16471 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
16472
16473 // Animate
16474 el.animate( animation, speed, o.easing );
16475
16476 // Shakes
16477 for ( i = 1; i < times; i++ ) {
16478 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
16479 }
16480 el
16481 .animate( animation1, speed, o.easing )
16482 .animate( animation, speed / 2, o.easing )
16483 .queue(function() {
16484 if ( mode === "hide" ) {
16485 el.hide();
16486 }
16487 $.effects.restore( el, props );
16488 $.effects.removeWrapper( el );
16489 done();
16490 });
16491
16492 // inject all the animations we just queued to be first in line (after "inprogress")
16493 if ( queuelen > 1) {
16494 queue.splice.apply( queue,
16495 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
16496 }
16497 el.dequeue();
16498
16499};
16500
16501
16502/*!
16503 * jQuery UI Effects Slide 1.11.3
16504 * http://jqueryui.com
16505 *
16506 * Copyright jQuery Foundation and other contributors
16507 * Released under the MIT license.
16508 * http://jquery.org/license
16509 *
16510 * http://api.jqueryui.com/slide-effect/
16511 */
16512
16513
16514var effectSlide = $.effects.effect.slide = function( o, done ) {
16515
16516 // Create element
16517 var el = $( this ),
16518 props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
16519 mode = $.effects.setMode( el, o.mode || "show" ),
16520 show = mode === "show",
16521 direction = o.direction || "left",
16522 ref = (direction === "up" || direction === "down") ? "top" : "left",
16523 positiveMotion = (direction === "up" || direction === "left"),
16524 distance,
16525 animation = {};
16526
16527 // Adjust
16528 $.effects.save( el, props );
16529 el.show();
16530 distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
16531
16532 $.effects.createWrapper( el ).css({
16533 overflow: "hidden"
16534 });
16535
16536 if ( show ) {
16537 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
16538 }
16539
16540 // Animation
16541 animation[ ref ] = ( show ?
16542 ( positiveMotion ? "+=" : "-=") :
16543 ( positiveMotion ? "-=" : "+=")) +
16544 distance;
16545
16546 // Animate
16547 el.animate( animation, {
16548 queue: false,
16549 duration: o.duration,
16550 easing: o.easing,
16551 complete: function() {
16552 if ( mode === "hide" ) {
16553 el.hide();
16554 }
16555 $.effects.restore( el, props );
16556 $.effects.removeWrapper( el );
16557 done();
16558 }
16559 });
16560};
16561
16562
16563/*!
16564 * jQuery UI Effects Transfer 1.11.3
16565 * http://jqueryui.com
16566 *
16567 * Copyright jQuery Foundation and other contributors
16568 * Released under the MIT license.
16569 * http://jquery.org/license
16570 *
16571 * http://api.jqueryui.com/transfer-effect/
16572 */
16573
16574
16575var effectTransfer = $.effects.effect.transfer = function( o, done ) {
16576 var elem = $( this ),
16577 target = $( o.to ),
16578 targetFixed = target.css( "position" ) === "fixed",
16579 body = $("body"),
16580 fixTop = targetFixed ? body.scrollTop() : 0,
16581 fixLeft = targetFixed ? body.scrollLeft() : 0,
16582 endPosition = target.offset(),
16583 animation = {
16584 top: endPosition.top - fixTop,
16585 left: endPosition.left - fixLeft,
16586 height: target.innerHeight(),
16587 width: target.innerWidth()
16588 },
16589 startPosition = elem.offset(),
16590 transfer = $( "<div class='ui-effects-transfer'></div>" )
16591 .appendTo( document.body )
16592 .addClass( o.className )
16593 .css({
16594 top: startPosition.top - fixTop,
16595 left: startPosition.left - fixLeft,
16596 height: elem.innerHeight(),
16597 width: elem.innerWidth(),
16598 position: targetFixed ? "fixed" : "absolute"
16599 })
16600 .animate( animation, o.duration, o.easing, function() {
16601 transfer.remove();
16602 done();
16603 });
16604};
16605
16606
16607
16608}));
\No newline at end of file