Bug 18810: Update Font Awesome to 4.7.0
[koha.git] / koha-tmpl / intranet-tmpl / lib / jquery / jquery-ui-1.11.4.js
1 /*! jQuery UI - v1.11.4 - 2016-02-22
2 * http://jqueryui.com
3 * Includes: core.js, widget.js, mouse.js, position.js, draggable.js, droppable.js, sortable.js, accordion.js, autocomplete.js, button.js, datepicker.js, menu.js, progressbar.js, slider.js, tabs.js, effect.js, effect-highlight.js
4 * Copyright jQuery Foundation and other contributors; Licensed MIT */
5
6 (function( factory ) {
7         if ( typeof define === "function" && define.amd ) {
8
9                 // AMD. Register as an anonymous module.
10                 define([ "jquery" ], factory );
11         } else {
12
13                 // Browser globals
14                 factory( jQuery );
15         }
16 }(function( $ ) {
17 /*!
18  * jQuery UI Core 1.11.4
19  * http://jqueryui.com
20  *
21  * Copyright jQuery Foundation and other contributors
22  * Released under the MIT license.
23  * http://jquery.org/license
24  *
25  * http://api.jqueryui.com/category/ui-core/
26  */
27
28
29 // $.ui might exist from components with no dependencies, e.g., $.ui.position
30 $.ui = $.ui || {};
31
32 $.extend( $.ui, {
33         version: "1.11.4",
34
35         keyCode: {
36                 BACKSPACE: 8,
37                 COMMA: 188,
38                 DELETE: 46,
39                 DOWN: 40,
40                 END: 35,
41                 ENTER: 13,
42                 ESCAPE: 27,
43                 HOME: 36,
44                 LEFT: 37,
45                 PAGE_DOWN: 34,
46                 PAGE_UP: 33,
47                 PERIOD: 190,
48                 RIGHT: 39,
49                 SPACE: 32,
50                 TAB: 9,
51                 UP: 38
52         }
53 });
54
55 // plugins
56 $.fn.extend({
57         scrollParent: function( includeHidden ) {
58                 var position = this.css( "position" ),
59                         excludeStaticParent = position === "absolute",
60                         overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
61                         scrollParent = this.parents().filter( function() {
62                                 var parent = $( this );
63                                 if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
64                                         return false;
65                                 }
66                                 return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) );
67                         }).eq( 0 );
68
69                 return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent;
70         },
71
72         uniqueId: (function() {
73                 var uuid = 0;
74
75                 return function() {
76                         return this.each(function() {
77                                 if ( !this.id ) {
78                                         this.id = "ui-id-" + ( ++uuid );
79                                 }
80                         });
81                 };
82         })(),
83
84         removeUniqueId: function() {
85                 return this.each(function() {
86                         if ( /^ui-id-\d+$/.test( this.id ) ) {
87                                 $( this ).removeAttr( "id" );
88                         }
89                 });
90         }
91 });
92
93 // selectors
94 function focusable( element, isTabIndexNotNaN ) {
95         var map, mapName, img,
96                 nodeName = element.nodeName.toLowerCase();
97         if ( "area" === nodeName ) {
98                 map = element.parentNode;
99                 mapName = map.name;
100                 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
101                         return false;
102                 }
103                 img = $( "img[usemap='#" + mapName + "']" )[ 0 ];
104                 return !!img && visible( img );
105         }
106         return ( /^(input|select|textarea|button|object)$/.test( nodeName ) ?
107                 !element.disabled :
108                 "a" === nodeName ?
109                         element.href || isTabIndexNotNaN :
110                         isTabIndexNotNaN) &&
111                 // the element and all of its ancestors must be visible
112                 visible( element );
113 }
114
115 function visible( element ) {
116         return $.expr.filters.visible( element ) &&
117                 !$( element ).parents().addBack().filter(function() {
118                         return $.css( this, "visibility" ) === "hidden";
119                 }).length;
120 }
121
122 $.extend( $.expr[ ":" ], {
123         data: $.expr.createPseudo ?
124                 $.expr.createPseudo(function( dataName ) {
125                         return function( elem ) {
126                                 return !!$.data( elem, dataName );
127                         };
128                 }) :
129                 // support: jQuery <1.8
130                 function( elem, i, match ) {
131                         return !!$.data( elem, match[ 3 ] );
132                 },
133
134         focusable: function( element ) {
135                 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
136         },
137
138         tabbable: function( element ) {
139                 var tabIndex = $.attr( element, "tabindex" ),
140                         isTabIndexNaN = isNaN( tabIndex );
141                 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
142         }
143 });
144
145 // support: jQuery <1.8
146 if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
147         $.each( [ "Width", "Height" ], function( i, name ) {
148                 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
149                         type = name.toLowerCase(),
150                         orig = {
151                                 innerWidth: $.fn.innerWidth,
152                                 innerHeight: $.fn.innerHeight,
153                                 outerWidth: $.fn.outerWidth,
154                                 outerHeight: $.fn.outerHeight
155                         };
156
157                 function reduce( elem, size, border, margin ) {
158                         $.each( side, function() {
159                                 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
160                                 if ( border ) {
161                                         size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
162                                 }
163                                 if ( margin ) {
164                                         size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
165                                 }
166                         });
167                         return size;
168                 }
169
170                 $.fn[ "inner" + name ] = function( size ) {
171                         if ( size === undefined ) {
172                                 return orig[ "inner" + name ].call( this );
173                         }
174
175                         return this.each(function() {
176                                 $( this ).css( type, reduce( this, size ) + "px" );
177                         });
178                 };
179
180                 $.fn[ "outer" + name] = function( size, margin ) {
181                         if ( typeof size !== "number" ) {
182                                 return orig[ "outer" + name ].call( this, size );
183                         }
184
185                         return this.each(function() {
186                                 $( this).css( type, reduce( this, size, true, margin ) + "px" );
187                         });
188                 };
189         });
190 }
191
192 // support: jQuery <1.8
193 if ( !$.fn.addBack ) {
194         $.fn.addBack = function( selector ) {
195                 return this.add( selector == null ?
196                         this.prevObject : this.prevObject.filter( selector )
197                 );
198         };
199 }
200
201 // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
202 if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
203         $.fn.removeData = (function( removeData ) {
204                 return function( key ) {
205                         if ( arguments.length ) {
206                                 return removeData.call( this, $.camelCase( key ) );
207                         } else {
208                                 return removeData.call( this );
209                         }
210                 };
211         })( $.fn.removeData );
212 }
213
214 // deprecated
215 $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
216
217 $.fn.extend({
218         focus: (function( orig ) {
219                 return function( delay, fn ) {
220                         return typeof delay === "number" ?
221                                 this.each(function() {
222                                         var elem = this;
223                                         setTimeout(function() {
224                                                 $( elem ).focus();
225                                                 if ( fn ) {
226                                                         fn.call( elem );
227                                                 }
228                                         }, delay );
229                                 }) :
230                                 orig.apply( this, arguments );
231                 };
232         })( $.fn.focus ),
233
234         disableSelection: (function() {
235                 var eventType = "onselectstart" in document.createElement( "div" ) ?
236                         "selectstart" :
237                         "mousedown";
238
239                 return function() {
240                         return this.bind( eventType + ".ui-disableSelection", function( event ) {
241                                 event.preventDefault();
242                         });
243                 };
244         })(),
245
246         enableSelection: function() {
247                 return this.unbind( ".ui-disableSelection" );
248         },
249
250         zIndex: function( zIndex ) {
251                 if ( zIndex !== undefined ) {
252                         return this.css( "zIndex", zIndex );
253                 }
254
255                 if ( this.length ) {
256                         var elem = $( this[ 0 ] ), position, value;
257                         while ( elem.length && elem[ 0 ] !== document ) {
258                                 // Ignore z-index if position is set to a value where z-index is ignored by the browser
259                                 // This makes behavior of this function consistent across browsers
260                                 // WebKit always returns auto if the element is positioned
261                                 position = elem.css( "position" );
262                                 if ( position === "absolute" || position === "relative" || position === "fixed" ) {
263                                         // IE returns 0 when zIndex is not specified
264                                         // other browsers return a string
265                                         // we ignore the case of nested elements with an explicit value of 0
266                                         // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
267                                         value = parseInt( elem.css( "zIndex" ), 10 );
268                                         if ( !isNaN( value ) && value !== 0 ) {
269                                                 return value;
270                                         }
271                                 }
272                                 elem = elem.parent();
273                         }
274                 }
275
276                 return 0;
277         }
278 });
279
280 // $.ui.plugin is deprecated. Use $.widget() extensions instead.
281 $.ui.plugin = {
282         add: function( module, option, set ) {
283                 var i,
284                         proto = $.ui[ module ].prototype;
285                 for ( i in set ) {
286                         proto.plugins[ i ] = proto.plugins[ i ] || [];
287                         proto.plugins[ i ].push( [ option, set[ i ] ] );
288                 }
289         },
290         call: function( instance, name, args, allowDisconnected ) {
291                 var i,
292                         set = instance.plugins[ name ];
293
294                 if ( !set ) {
295                         return;
296                 }
297
298                 if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
299                         return;
300                 }
301
302                 for ( i = 0; i < set.length; i++ ) {
303                         if ( instance.options[ set[ i ][ 0 ] ] ) {
304                                 set[ i ][ 1 ].apply( instance.element, args );
305                         }
306                 }
307         }
308 };
309
310
311 /*!
312  * jQuery UI Widget 1.11.4
313  * http://jqueryui.com
314  *
315  * Copyright jQuery Foundation and other contributors
316  * Released under the MIT license.
317  * http://jquery.org/license
318  *
319  * http://api.jqueryui.com/jQuery.widget/
320  */
321
322
323 var widget_uuid = 0,
324         widget_slice = Array.prototype.slice;
325
326 $.cleanData = (function( orig ) {
327         return function( elems ) {
328                 var events, elem, i;
329                 for ( i = 0; (elem = elems[i]) != null; i++ ) {
330                         try {
331
332                                 // Only trigger remove when necessary to save time
333                                 events = $._data( elem, "events" );
334                                 if ( events && events.remove ) {
335                                         $( elem ).triggerHandler( "remove" );
336                                 }
337
338                         // http://bugs.jquery.com/ticket/8235
339                         } catch ( e ) {}
340                 }
341                 orig( elems );
342         };
343 })( $.cleanData );
344
345 $.widget = function( name, base, prototype ) {
346         var fullName, existingConstructor, constructor, basePrototype,
347                 // proxiedPrototype allows the provided prototype to remain unmodified
348                 // so that it can be used as a mixin for multiple widgets (#8876)
349                 proxiedPrototype = {},
350                 namespace = name.split( "." )[ 0 ];
351
352         name = name.split( "." )[ 1 ];
353         fullName = namespace + "-" + name;
354
355         if ( !prototype ) {
356                 prototype = base;
357                 base = $.Widget;
358         }
359
360         // create selector for plugin
361         $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
362                 return !!$.data( elem, fullName );
363         };
364
365         $[ namespace ] = $[ namespace ] || {};
366         existingConstructor = $[ namespace ][ name ];
367         constructor = $[ namespace ][ name ] = function( options, element ) {
368                 // allow instantiation without "new" keyword
369                 if ( !this._createWidget ) {
370                         return new constructor( options, element );
371                 }
372
373                 // allow instantiation without initializing for simple inheritance
374                 // must use "new" keyword (the code above always passes args)
375                 if ( arguments.length ) {
376                         this._createWidget( options, element );
377                 }
378         };
379         // extend with the existing constructor to carry over any static properties
380         $.extend( constructor, existingConstructor, {
381                 version: prototype.version,
382                 // copy the object used to create the prototype in case we need to
383                 // redefine the widget later
384                 _proto: $.extend( {}, prototype ),
385                 // track widgets that inherit from this widget in case this widget is
386                 // redefined after a widget inherits from it
387                 _childConstructors: []
388         });
389
390         basePrototype = new base();
391         // we need to make the options hash a property directly on the new instance
392         // otherwise we'll modify the options hash on the prototype that we're
393         // inheriting from
394         basePrototype.options = $.widget.extend( {}, basePrototype.options );
395         $.each( prototype, function( prop, value ) {
396                 if ( !$.isFunction( value ) ) {
397                         proxiedPrototype[ prop ] = value;
398                         return;
399                 }
400                 proxiedPrototype[ prop ] = (function() {
401                         var _super = function() {
402                                         return base.prototype[ prop ].apply( this, arguments );
403                                 },
404                                 _superApply = function( args ) {
405                                         return base.prototype[ prop ].apply( this, args );
406                                 };
407                         return function() {
408                                 var __super = this._super,
409                                         __superApply = this._superApply,
410                                         returnValue;
411
412                                 this._super = _super;
413                                 this._superApply = _superApply;
414
415                                 returnValue = value.apply( this, arguments );
416
417                                 this._super = __super;
418                                 this._superApply = __superApply;
419
420                                 return returnValue;
421                         };
422                 })();
423         });
424         constructor.prototype = $.widget.extend( basePrototype, {
425                 // TODO: remove support for widgetEventPrefix
426                 // always use the name + a colon as the prefix, e.g., draggable:start
427                 // don't prefix for widgets that aren't DOM-based
428                 widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
429         }, proxiedPrototype, {
430                 constructor: constructor,
431                 namespace: namespace,
432                 widgetName: name,
433                 widgetFullName: fullName
434         });
435
436         // If this widget is being redefined then we need to find all widgets that
437         // are inheriting from it and redefine all of them so that they inherit from
438         // the new version of this widget. We're essentially trying to replace one
439         // level in the prototype chain.
440         if ( existingConstructor ) {
441                 $.each( existingConstructor._childConstructors, function( i, child ) {
442                         var childPrototype = child.prototype;
443
444                         // redefine the child widget using the same prototype that was
445                         // originally used, but inherit from the new version of the base
446                         $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
447                 });
448                 // remove the list of existing child constructors from the old constructor
449                 // so the old child constructors can be garbage collected
450                 delete existingConstructor._childConstructors;
451         } else {
452                 base._childConstructors.push( constructor );
453         }
454
455         $.widget.bridge( name, constructor );
456
457         return constructor;
458 };
459
460 $.widget.extend = function( target ) {
461         var input = widget_slice.call( arguments, 1 ),
462                 inputIndex = 0,
463                 inputLength = input.length,
464                 key,
465                 value;
466         for ( ; inputIndex < inputLength; inputIndex++ ) {
467                 for ( key in input[ inputIndex ] ) {
468                         value = input[ inputIndex ][ key ];
469                         if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
470                                 // Clone objects
471                                 if ( $.isPlainObject( value ) ) {
472                                         target[ key ] = $.isPlainObject( target[ key ] ) ?
473                                                 $.widget.extend( {}, target[ key ], value ) :
474                                                 // Don't extend strings, arrays, etc. with objects
475                                                 $.widget.extend( {}, value );
476                                 // Copy everything else by reference
477                                 } else {
478                                         target[ key ] = value;
479                                 }
480                         }
481                 }
482         }
483         return target;
484 };
485
486 $.widget.bridge = function( name, object ) {
487         var fullName = object.prototype.widgetFullName || name;
488         $.fn[ name ] = function( options ) {
489                 var isMethodCall = typeof options === "string",
490                         args = widget_slice.call( arguments, 1 ),
491                         returnValue = this;
492
493                 if ( isMethodCall ) {
494                         this.each(function() {
495                                 var methodValue,
496                                         instance = $.data( this, fullName );
497                                 if ( options === "instance" ) {
498                                         returnValue = instance;
499                                         return false;
500                                 }
501                                 if ( !instance ) {
502                                         return $.error( "cannot call methods on " + name + " prior to initialization; " +
503                                                 "attempted to call method '" + options + "'" );
504                                 }
505                                 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
506                                         return $.error( "no such method '" + options + "' for " + name + " widget instance" );
507                                 }
508                                 methodValue = instance[ options ].apply( instance, args );
509                                 if ( methodValue !== instance && methodValue !== undefined ) {
510                                         returnValue = methodValue && methodValue.jquery ?
511                                                 returnValue.pushStack( methodValue.get() ) :
512                                                 methodValue;
513                                         return false;
514                                 }
515                         });
516                 } else {
517
518                         // Allow multiple hashes to be passed on init
519                         if ( args.length ) {
520                                 options = $.widget.extend.apply( null, [ options ].concat(args) );
521                         }
522
523                         this.each(function() {
524                                 var instance = $.data( this, fullName );
525                                 if ( instance ) {
526                                         instance.option( options || {} );
527                                         if ( instance._init ) {
528                                                 instance._init();
529                                         }
530                                 } else {
531                                         $.data( this, fullName, new object( options, this ) );
532                                 }
533                         });
534                 }
535
536                 return returnValue;
537         };
538 };
539
540 $.Widget = function( /* options, element */ ) {};
541 $.Widget._childConstructors = [];
542
543 $.Widget.prototype = {
544         widgetName: "widget",
545         widgetEventPrefix: "",
546         defaultElement: "<div>",
547         options: {
548                 disabled: false,
549
550                 // callbacks
551                 create: null
552         },
553         _createWidget: function( options, element ) {
554                 element = $( element || this.defaultElement || this )[ 0 ];
555                 this.element = $( element );
556                 this.uuid = widget_uuid++;
557                 this.eventNamespace = "." + this.widgetName + this.uuid;
558
559                 this.bindings = $();
560                 this.hoverable = $();
561                 this.focusable = $();
562
563                 if ( element !== this ) {
564                         $.data( element, this.widgetFullName, this );
565                         this._on( true, this.element, {
566                                 remove: function( event ) {
567                                         if ( event.target === element ) {
568                                                 this.destroy();
569                                         }
570                                 }
571                         });
572                         this.document = $( element.style ?
573                                 // element within the document
574                                 element.ownerDocument :
575                                 // element is window or document
576                                 element.document || element );
577                         this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
578                 }
579
580                 this.options = $.widget.extend( {},
581                         this.options,
582                         this._getCreateOptions(),
583                         options );
584
585                 this._create();
586                 this._trigger( "create", null, this._getCreateEventData() );
587                 this._init();
588         },
589         _getCreateOptions: $.noop,
590         _getCreateEventData: $.noop,
591         _create: $.noop,
592         _init: $.noop,
593
594         destroy: function() {
595                 this._destroy();
596                 // we can probably remove the unbind calls in 2.0
597                 // all event bindings should go through this._on()
598                 this.element
599                         .unbind( this.eventNamespace )
600                         .removeData( this.widgetFullName )
601                         // support: jquery <1.6.3
602                         // http://bugs.jquery.com/ticket/9413
603                         .removeData( $.camelCase( this.widgetFullName ) );
604                 this.widget()
605                         .unbind( this.eventNamespace )
606                         .removeAttr( "aria-disabled" )
607                         .removeClass(
608                                 this.widgetFullName + "-disabled " +
609                                 "ui-state-disabled" );
610
611                 // clean up events and states
612                 this.bindings.unbind( this.eventNamespace );
613                 this.hoverable.removeClass( "ui-state-hover" );
614                 this.focusable.removeClass( "ui-state-focus" );
615         },
616         _destroy: $.noop,
617
618         widget: function() {
619                 return this.element;
620         },
621
622         option: function( key, value ) {
623                 var options = key,
624                         parts,
625                         curOption,
626                         i;
627
628                 if ( arguments.length === 0 ) {
629                         // don't return a reference to the internal hash
630                         return $.widget.extend( {}, this.options );
631                 }
632
633                 if ( typeof key === "string" ) {
634                         // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
635                         options = {};
636                         parts = key.split( "." );
637                         key = parts.shift();
638                         if ( parts.length ) {
639                                 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
640                                 for ( i = 0; i < parts.length - 1; i++ ) {
641                                         curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
642                                         curOption = curOption[ parts[ i ] ];
643                                 }
644                                 key = parts.pop();
645                                 if ( arguments.length === 1 ) {
646                                         return curOption[ key ] === undefined ? null : curOption[ key ];
647                                 }
648                                 curOption[ key ] = value;
649                         } else {
650                                 if ( arguments.length === 1 ) {
651                                         return this.options[ key ] === undefined ? null : this.options[ key ];
652                                 }
653                                 options[ key ] = value;
654                         }
655                 }
656
657                 this._setOptions( options );
658
659                 return this;
660         },
661         _setOptions: function( options ) {
662                 var key;
663
664                 for ( key in options ) {
665                         this._setOption( key, options[ key ] );
666                 }
667
668                 return this;
669         },
670         _setOption: function( key, value ) {
671                 this.options[ key ] = value;
672
673                 if ( key === "disabled" ) {
674                         this.widget()
675                                 .toggleClass( this.widgetFullName + "-disabled", !!value );
676
677                         // If the widget is becoming disabled, then nothing is interactive
678                         if ( value ) {
679                                 this.hoverable.removeClass( "ui-state-hover" );
680                                 this.focusable.removeClass( "ui-state-focus" );
681                         }
682                 }
683
684                 return this;
685         },
686
687         enable: function() {
688                 return this._setOptions({ disabled: false });
689         },
690         disable: function() {
691                 return this._setOptions({ disabled: true });
692         },
693
694         _on: function( suppressDisabledCheck, element, handlers ) {
695                 var delegateElement,
696                         instance = this;
697
698                 // no suppressDisabledCheck flag, shuffle arguments
699                 if ( typeof suppressDisabledCheck !== "boolean" ) {
700                         handlers = element;
701                         element = suppressDisabledCheck;
702                         suppressDisabledCheck = false;
703                 }
704
705                 // no element argument, shuffle and use this.element
706                 if ( !handlers ) {
707                         handlers = element;
708                         element = this.element;
709                         delegateElement = this.widget();
710                 } else {
711                         element = delegateElement = $( element );
712                         this.bindings = this.bindings.add( element );
713                 }
714
715                 $.each( handlers, function( event, handler ) {
716                         function handlerProxy() {
717                                 // allow widgets to customize the disabled handling
718                                 // - disabled as an array instead of boolean
719                                 // - disabled class as method for disabling individual parts
720                                 if ( !suppressDisabledCheck &&
721                                                 ( instance.options.disabled === true ||
722                                                         $( this ).hasClass( "ui-state-disabled" ) ) ) {
723                                         return;
724                                 }
725                                 return ( typeof handler === "string" ? instance[ handler ] : handler )
726                                         .apply( instance, arguments );
727                         }
728
729                         // copy the guid so direct unbinding works
730                         if ( typeof handler !== "string" ) {
731                                 handlerProxy.guid = handler.guid =
732                                         handler.guid || handlerProxy.guid || $.guid++;
733                         }
734
735                         var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
736                                 eventName = match[1] + instance.eventNamespace,
737                                 selector = match[2];
738                         if ( selector ) {
739                                 delegateElement.delegate( selector, eventName, handlerProxy );
740                         } else {
741                                 element.bind( eventName, handlerProxy );
742                         }
743                 });
744         },
745
746         _off: function( element, eventName ) {
747                 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
748                         this.eventNamespace;
749                 element.unbind( eventName ).undelegate( eventName );
750
751                 // Clear the stack to avoid memory leaks (#10056)
752                 this.bindings = $( this.bindings.not( element ).get() );
753                 this.focusable = $( this.focusable.not( element ).get() );
754                 this.hoverable = $( this.hoverable.not( element ).get() );
755         },
756
757         _delay: function( handler, delay ) {
758                 function handlerProxy() {
759                         return ( typeof handler === "string" ? instance[ handler ] : handler )
760                                 .apply( instance, arguments );
761                 }
762                 var instance = this;
763                 return setTimeout( handlerProxy, delay || 0 );
764         },
765
766         _hoverable: function( element ) {
767                 this.hoverable = this.hoverable.add( element );
768                 this._on( element, {
769                         mouseenter: function( event ) {
770                                 $( event.currentTarget ).addClass( "ui-state-hover" );
771                         },
772                         mouseleave: function( event ) {
773                                 $( event.currentTarget ).removeClass( "ui-state-hover" );
774                         }
775                 });
776         },
777
778         _focusable: function( element ) {
779                 this.focusable = this.focusable.add( element );
780                 this._on( element, {
781                         focusin: function( event ) {
782                                 $( event.currentTarget ).addClass( "ui-state-focus" );
783                         },
784                         focusout: function( event ) {
785                                 $( event.currentTarget ).removeClass( "ui-state-focus" );
786                         }
787                 });
788         },
789
790         _trigger: function( type, event, data ) {
791                 var prop, orig,
792                         callback = this.options[ type ];
793
794                 data = data || {};
795                 event = $.Event( event );
796                 event.type = ( type === this.widgetEventPrefix ?
797                         type :
798                         this.widgetEventPrefix + type ).toLowerCase();
799                 // the original event may come from any element
800                 // so we need to reset the target on the new event
801                 event.target = this.element[ 0 ];
802
803                 // copy original event properties over to the new event
804                 orig = event.originalEvent;
805                 if ( orig ) {
806                         for ( prop in orig ) {
807                                 if ( !( prop in event ) ) {
808                                         event[ prop ] = orig[ prop ];
809                                 }
810                         }
811                 }
812
813                 this.element.trigger( event, data );
814                 return !( $.isFunction( callback ) &&
815                         callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
816                         event.isDefaultPrevented() );
817         }
818 };
819
820 $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
821         $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
822                 if ( typeof options === "string" ) {
823                         options = { effect: options };
824                 }
825                 var hasOptions,
826                         effectName = !options ?
827                                 method :
828                                 options === true || typeof options === "number" ?
829                                         defaultEffect :
830                                         options.effect || defaultEffect;
831                 options = options || {};
832                 if ( typeof options === "number" ) {
833                         options = { duration: options };
834                 }
835                 hasOptions = !$.isEmptyObject( options );
836                 options.complete = callback;
837                 if ( options.delay ) {
838                         element.delay( options.delay );
839                 }
840                 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
841                         element[ method ]( options );
842                 } else if ( effectName !== method && element[ effectName ] ) {
843                         element[ effectName ]( options.duration, options.easing, callback );
844                 } else {
845                         element.queue(function( next ) {
846                                 $( this )[ method ]();
847                                 if ( callback ) {
848                                         callback.call( element[ 0 ] );
849                                 }
850                                 next();
851                         });
852                 }
853         };
854 });
855
856 var widget = $.widget;
857
858
859 /*!
860  * jQuery UI Mouse 1.11.4
861  * http://jqueryui.com
862  *
863  * Copyright jQuery Foundation and other contributors
864  * Released under the MIT license.
865  * http://jquery.org/license
866  *
867  * http://api.jqueryui.com/mouse/
868  */
869
870
871 var mouseHandled = false;
872 $( document ).mouseup( function() {
873         mouseHandled = false;
874 });
875
876 var mouse = $.widget("ui.mouse", {
877         version: "1.11.4",
878         options: {
879                 cancel: "input,textarea,button,select,option",
880                 distance: 1,
881                 delay: 0
882         },
883         _mouseInit: function() {
884                 var that = this;
885
886                 this.element
887                         .bind("mousedown." + this.widgetName, function(event) {
888                                 return that._mouseDown(event);
889                         })
890                         .bind("click." + this.widgetName, function(event) {
891                                 if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
892                                         $.removeData(event.target, that.widgetName + ".preventClickEvent");
893                                         event.stopImmediatePropagation();
894                                         return false;
895                                 }
896                         });
897
898                 this.started = false;
899         },
900
901         // TODO: make sure destroying one instance of mouse doesn't mess with
902         // other instances of mouse
903         _mouseDestroy: function() {
904                 this.element.unbind("." + this.widgetName);
905                 if ( this._mouseMoveDelegate ) {
906                         this.document
907                                 .unbind("mousemove." + this.widgetName, this._mouseMoveDelegate)
908                                 .unbind("mouseup." + this.widgetName, this._mouseUpDelegate);
909                 }
910         },
911
912         _mouseDown: function(event) {
913                 // don't let more than one widget handle mouseStart
914                 if ( mouseHandled ) {
915                         return;
916                 }
917
918                 this._mouseMoved = false;
919
920                 // we may have missed mouseup (out of window)
921                 (this._mouseStarted && this._mouseUp(event));
922
923                 this._mouseDownEvent = event;
924
925                 var that = this,
926                         btnIsLeft = (event.which === 1),
927                         // event.target.nodeName works around a bug in IE 8 with
928                         // disabled inputs (#7620)
929                         elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
930                 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
931                         return true;
932                 }
933
934                 this.mouseDelayMet = !this.options.delay;
935                 if (!this.mouseDelayMet) {
936                         this._mouseDelayTimer = setTimeout(function() {
937                                 that.mouseDelayMet = true;
938                         }, this.options.delay);
939                 }
940
941                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
942                         this._mouseStarted = (this._mouseStart(event) !== false);
943                         if (!this._mouseStarted) {
944                                 event.preventDefault();
945                                 return true;
946                         }
947                 }
948
949                 // Click event may never have fired (Gecko & Opera)
950                 if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
951                         $.removeData(event.target, this.widgetName + ".preventClickEvent");
952                 }
953
954                 // these delegates are required to keep context
955                 this._mouseMoveDelegate = function(event) {
956                         return that._mouseMove(event);
957                 };
958                 this._mouseUpDelegate = function(event) {
959                         return that._mouseUp(event);
960                 };
961
962                 this.document
963                         .bind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
964                         .bind( "mouseup." + this.widgetName, this._mouseUpDelegate );
965
966                 event.preventDefault();
967
968                 mouseHandled = true;
969                 return true;
970         },
971
972         _mouseMove: function(event) {
973                 // Only check for mouseups outside the document if you've moved inside the document
974                 // at least once. This prevents the firing of mouseup in the case of IE<9, which will
975                 // fire a mousemove event if content is placed under the cursor. See #7778
976                 // Support: IE <9
977                 if ( this._mouseMoved ) {
978                         // IE mouseup check - mouseup happened when mouse was out of window
979                         if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
980                                 return this._mouseUp(event);
981
982                         // Iframe mouseup check - mouseup occurred in another document
983                         } else if ( !event.which ) {
984                                 return this._mouseUp( event );
985                         }
986                 }
987
988                 if ( event.which || event.button ) {
989                         this._mouseMoved = true;
990                 }
991
992                 if (this._mouseStarted) {
993                         this._mouseDrag(event);
994                         return event.preventDefault();
995                 }
996
997                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
998                         this._mouseStarted =
999                                 (this._mouseStart(this._mouseDownEvent, event) !== false);
1000                         (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
1001                 }
1002
1003                 return !this._mouseStarted;
1004         },
1005
1006         _mouseUp: function(event) {
1007                 this.document
1008                         .unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
1009                         .unbind( "mouseup." + this.widgetName, this._mouseUpDelegate );
1010
1011                 if (this._mouseStarted) {
1012                         this._mouseStarted = false;
1013
1014                         if (event.target === this._mouseDownEvent.target) {
1015                                 $.data(event.target, this.widgetName + ".preventClickEvent", true);
1016                         }
1017
1018                         this._mouseStop(event);
1019                 }
1020
1021                 mouseHandled = false;
1022                 return false;
1023         },
1024
1025         _mouseDistanceMet: function(event) {
1026                 return (Math.max(
1027                                 Math.abs(this._mouseDownEvent.pageX - event.pageX),
1028                                 Math.abs(this._mouseDownEvent.pageY - event.pageY)
1029                         ) >= this.options.distance
1030                 );
1031         },
1032
1033         _mouseDelayMet: function(/* event */) {
1034                 return this.mouseDelayMet;
1035         },
1036
1037         // These are placeholder methods, to be overriden by extending plugin
1038         _mouseStart: function(/* event */) {},
1039         _mouseDrag: function(/* event */) {},
1040         _mouseStop: function(/* event */) {},
1041         _mouseCapture: function(/* event */) { return true; }
1042 });
1043
1044
1045 /*!
1046  * jQuery UI Position 1.11.4
1047  * http://jqueryui.com
1048  *
1049  * Copyright jQuery Foundation and other contributors
1050  * Released under the MIT license.
1051  * http://jquery.org/license
1052  *
1053  * http://api.jqueryui.com/position/
1054  */
1055
1056 (function() {
1057
1058 $.ui = $.ui || {};
1059
1060 var cachedScrollbarWidth, supportsOffsetFractions,
1061         max = Math.max,
1062         abs = Math.abs,
1063         round = Math.round,
1064         rhorizontal = /left|center|right/,
1065         rvertical = /top|center|bottom/,
1066         roffset = /[\+\-]\d+(\.[\d]+)?%?/,
1067         rposition = /^\w+/,
1068         rpercent = /%$/,
1069         _position = $.fn.position;
1070
1071 function getOffsets( offsets, width, height ) {
1072         return [
1073                 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
1074                 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
1075         ];
1076 }
1077
1078 function parseCss( element, property ) {
1079         return parseInt( $.css( element, property ), 10 ) || 0;
1080 }
1081
1082 function getDimensions( elem ) {
1083         var raw = elem[0];
1084         if ( raw.nodeType === 9 ) {
1085                 return {
1086                         width: elem.width(),
1087                         height: elem.height(),
1088                         offset: { top: 0, left: 0 }
1089                 };
1090         }
1091         if ( $.isWindow( raw ) ) {
1092                 return {
1093                         width: elem.width(),
1094                         height: elem.height(),
1095                         offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
1096                 };
1097         }
1098         if ( raw.preventDefault ) {
1099                 return {
1100                         width: 0,
1101                         height: 0,
1102                         offset: { top: raw.pageY, left: raw.pageX }
1103                 };
1104         }
1105         return {
1106                 width: elem.outerWidth(),
1107                 height: elem.outerHeight(),
1108                 offset: elem.offset()
1109         };
1110 }
1111
1112 $.position = {
1113         scrollbarWidth: function() {
1114                 if ( cachedScrollbarWidth !== undefined ) {
1115                         return cachedScrollbarWidth;
1116                 }
1117                 var w1, w2,
1118                         div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
1119                         innerDiv = div.children()[0];
1120
1121                 $( "body" ).append( div );
1122                 w1 = innerDiv.offsetWidth;
1123                 div.css( "overflow", "scroll" );
1124
1125                 w2 = innerDiv.offsetWidth;
1126
1127                 if ( w1 === w2 ) {
1128                         w2 = div[0].clientWidth;
1129                 }
1130
1131                 div.remove();
1132
1133                 return (cachedScrollbarWidth = w1 - w2);
1134         },
1135         getScrollInfo: function( within ) {
1136                 var overflowX = within.isWindow || within.isDocument ? "" :
1137                                 within.element.css( "overflow-x" ),
1138                         overflowY = within.isWindow || within.isDocument ? "" :
1139                                 within.element.css( "overflow-y" ),
1140                         hasOverflowX = overflowX === "scroll" ||
1141                                 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
1142                         hasOverflowY = overflowY === "scroll" ||
1143                                 ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
1144                 return {
1145                         width: hasOverflowY ? $.position.scrollbarWidth() : 0,
1146                         height: hasOverflowX ? $.position.scrollbarWidth() : 0
1147                 };
1148         },
1149         getWithinInfo: function( element ) {
1150                 var withinElement = $( element || window ),
1151                         isWindow = $.isWindow( withinElement[0] ),
1152                         isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
1153                 return {
1154                         element: withinElement,
1155                         isWindow: isWindow,
1156                         isDocument: isDocument,
1157                         offset: withinElement.offset() || { left: 0, top: 0 },
1158                         scrollLeft: withinElement.scrollLeft(),
1159                         scrollTop: withinElement.scrollTop(),
1160
1161                         // support: jQuery 1.6.x
1162                         // jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows
1163                         width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(),
1164                         height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight()
1165                 };
1166         }
1167 };
1168
1169 $.fn.position = function( options ) {
1170         if ( !options || !options.of ) {
1171                 return _position.apply( this, arguments );
1172         }
1173
1174         // make a copy, we don't want to modify arguments
1175         options = $.extend( {}, options );
1176
1177         var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
1178                 target = $( options.of ),
1179                 within = $.position.getWithinInfo( options.within ),
1180                 scrollInfo = $.position.getScrollInfo( within ),
1181                 collision = ( options.collision || "flip" ).split( " " ),
1182                 offsets = {};
1183
1184         dimensions = getDimensions( target );
1185         if ( target[0].preventDefault ) {
1186                 // force left top to allow flipping
1187                 options.at = "left top";
1188         }
1189         targetWidth = dimensions.width;
1190         targetHeight = dimensions.height;
1191         targetOffset = dimensions.offset;
1192         // clone to reuse original targetOffset later
1193         basePosition = $.extend( {}, targetOffset );
1194
1195         // force my and at to have valid horizontal and vertical positions
1196         // if a value is missing or invalid, it will be converted to center
1197         $.each( [ "my", "at" ], function() {
1198                 var pos = ( options[ this ] || "" ).split( " " ),
1199                         horizontalOffset,
1200                         verticalOffset;
1201
1202                 if ( pos.length === 1) {
1203                         pos = rhorizontal.test( pos[ 0 ] ) ?
1204                                 pos.concat( [ "center" ] ) :
1205                                 rvertical.test( pos[ 0 ] ) ?
1206                                         [ "center" ].concat( pos ) :
1207                                         [ "center", "center" ];
1208                 }
1209                 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
1210                 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
1211
1212                 // calculate offsets
1213                 horizontalOffset = roffset.exec( pos[ 0 ] );
1214                 verticalOffset = roffset.exec( pos[ 1 ] );
1215                 offsets[ this ] = [
1216                         horizontalOffset ? horizontalOffset[ 0 ] : 0,
1217                         verticalOffset ? verticalOffset[ 0 ] : 0
1218                 ];
1219
1220                 // reduce to just the positions without the offsets
1221                 options[ this ] = [
1222                         rposition.exec( pos[ 0 ] )[ 0 ],
1223                         rposition.exec( pos[ 1 ] )[ 0 ]
1224                 ];
1225         });
1226
1227         // normalize collision option
1228         if ( collision.length === 1 ) {
1229                 collision[ 1 ] = collision[ 0 ];
1230         }
1231
1232         if ( options.at[ 0 ] === "right" ) {
1233                 basePosition.left += targetWidth;
1234         } else if ( options.at[ 0 ] === "center" ) {
1235                 basePosition.left += targetWidth / 2;
1236         }
1237
1238         if ( options.at[ 1 ] === "bottom" ) {
1239                 basePosition.top += targetHeight;
1240         } else if ( options.at[ 1 ] === "center" ) {
1241                 basePosition.top += targetHeight / 2;
1242         }
1243
1244         atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
1245         basePosition.left += atOffset[ 0 ];
1246         basePosition.top += atOffset[ 1 ];
1247
1248         return this.each(function() {
1249                 var collisionPosition, using,
1250                         elem = $( this ),
1251                         elemWidth = elem.outerWidth(),
1252                         elemHeight = elem.outerHeight(),
1253                         marginLeft = parseCss( this, "marginLeft" ),
1254                         marginTop = parseCss( this, "marginTop" ),
1255                         collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
1256                         collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
1257                         position = $.extend( {}, basePosition ),
1258                         myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1259
1260                 if ( options.my[ 0 ] === "right" ) {
1261                         position.left -= elemWidth;
1262                 } else if ( options.my[ 0 ] === "center" ) {
1263                         position.left -= elemWidth / 2;
1264                 }
1265
1266                 if ( options.my[ 1 ] === "bottom" ) {
1267                         position.top -= elemHeight;
1268                 } else if ( options.my[ 1 ] === "center" ) {
1269                         position.top -= elemHeight / 2;
1270                 }
1271
1272                 position.left += myOffset[ 0 ];
1273                 position.top += myOffset[ 1 ];
1274
1275                 // if the browser doesn't support fractions, then round for consistent results
1276                 if ( !supportsOffsetFractions ) {
1277                         position.left = round( position.left );
1278                         position.top = round( position.top );
1279                 }
1280
1281                 collisionPosition = {
1282                         marginLeft: marginLeft,
1283                         marginTop: marginTop
1284                 };
1285
1286                 $.each( [ "left", "top" ], function( i, dir ) {
1287                         if ( $.ui.position[ collision[ i ] ] ) {
1288                                 $.ui.position[ collision[ i ] ][ dir ]( position, {
1289                                         targetWidth: targetWidth,
1290                                         targetHeight: targetHeight,
1291                                         elemWidth: elemWidth,
1292                                         elemHeight: elemHeight,
1293                                         collisionPosition: collisionPosition,
1294                                         collisionWidth: collisionWidth,
1295                                         collisionHeight: collisionHeight,
1296                                         offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1297                                         my: options.my,
1298                                         at: options.at,
1299                                         within: within,
1300                                         elem: elem
1301                                 });
1302                         }
1303                 });
1304
1305                 if ( options.using ) {
1306                         // adds feedback as second argument to using callback, if present
1307                         using = function( props ) {
1308                                 var left = targetOffset.left - position.left,
1309                                         right = left + targetWidth - elemWidth,
1310                                         top = targetOffset.top - position.top,
1311                                         bottom = top + targetHeight - elemHeight,
1312                                         feedback = {
1313                                                 target: {
1314                                                         element: target,
1315                                                         left: targetOffset.left,
1316                                                         top: targetOffset.top,
1317                                                         width: targetWidth,
1318                                                         height: targetHeight
1319                                                 },
1320                                                 element: {
1321                                                         element: elem,
1322                                                         left: position.left,
1323                                                         top: position.top,
1324                                                         width: elemWidth,
1325                                                         height: elemHeight
1326                                                 },
1327                                                 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1328                                                 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1329                                         };
1330                                 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1331                                         feedback.horizontal = "center";
1332                                 }
1333                                 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1334                                         feedback.vertical = "middle";
1335                                 }
1336                                 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1337                                         feedback.important = "horizontal";
1338                                 } else {
1339                                         feedback.important = "vertical";
1340                                 }
1341                                 options.using.call( this, props, feedback );
1342                         };
1343                 }
1344
1345                 elem.offset( $.extend( position, { using: using } ) );
1346         });
1347 };
1348
1349 $.ui.position = {
1350         fit: {
1351                 left: function( position, data ) {
1352                         var within = data.within,
1353                                 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1354                                 outerWidth = within.width,
1355                                 collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1356                                 overLeft = withinOffset - collisionPosLeft,
1357                                 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1358                                 newOverRight;
1359
1360                         // element is wider than within
1361                         if ( data.collisionWidth > outerWidth ) {
1362                                 // element is initially over the left side of within
1363                                 if ( overLeft > 0 && overRight <= 0 ) {
1364                                         newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
1365                                         position.left += overLeft - newOverRight;
1366                                 // element is initially over right side of within
1367                                 } else if ( overRight > 0 && overLeft <= 0 ) {
1368                                         position.left = withinOffset;
1369                                 // element is initially over both left and right sides of within
1370                                 } else {
1371                                         if ( overLeft > overRight ) {
1372                                                 position.left = withinOffset + outerWidth - data.collisionWidth;
1373                                         } else {
1374                                                 position.left = withinOffset;
1375                                         }
1376                                 }
1377                         // too far left -> align with left edge
1378                         } else if ( overLeft > 0 ) {
1379                                 position.left += overLeft;
1380                         // too far right -> align with right edge
1381                         } else if ( overRight > 0 ) {
1382                                 position.left -= overRight;
1383                         // adjust based on position and margin
1384                         } else {
1385                                 position.left = max( position.left - collisionPosLeft, position.left );
1386                         }
1387                 },
1388                 top: function( position, data ) {
1389                         var within = data.within,
1390                                 withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1391                                 outerHeight = data.within.height,
1392                                 collisionPosTop = position.top - data.collisionPosition.marginTop,
1393                                 overTop = withinOffset - collisionPosTop,
1394                                 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1395                                 newOverBottom;
1396
1397                         // element is taller than within
1398                         if ( data.collisionHeight > outerHeight ) {
1399                                 // element is initially over the top of within
1400                                 if ( overTop > 0 && overBottom <= 0 ) {
1401                                         newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
1402                                         position.top += overTop - newOverBottom;
1403                                 // element is initially over bottom of within
1404                                 } else if ( overBottom > 0 && overTop <= 0 ) {
1405                                         position.top = withinOffset;
1406                                 // element is initially over both top and bottom of within
1407                                 } else {
1408                                         if ( overTop > overBottom ) {
1409                                                 position.top = withinOffset + outerHeight - data.collisionHeight;
1410                                         } else {
1411                                                 position.top = withinOffset;
1412                                         }
1413                                 }
1414                         // too far up -> align with top
1415                         } else if ( overTop > 0 ) {
1416                                 position.top += overTop;
1417                         // too far down -> align with bottom edge
1418                         } else if ( overBottom > 0 ) {
1419                                 position.top -= overBottom;
1420                         // adjust based on position and margin
1421                         } else {
1422                                 position.top = max( position.top - collisionPosTop, position.top );
1423                         }
1424                 }
1425         },
1426         flip: {
1427                 left: function( position, data ) {
1428                         var within = data.within,
1429                                 withinOffset = within.offset.left + within.scrollLeft,
1430                                 outerWidth = within.width,
1431                                 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1432                                 collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1433                                 overLeft = collisionPosLeft - offsetLeft,
1434                                 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1435                                 myOffset = data.my[ 0 ] === "left" ?
1436                                         -data.elemWidth :
1437                                         data.my[ 0 ] === "right" ?
1438                                                 data.elemWidth :
1439                                                 0,
1440                                 atOffset = data.at[ 0 ] === "left" ?
1441                                         data.targetWidth :
1442                                         data.at[ 0 ] === "right" ?
1443                                                 -data.targetWidth :
1444                                                 0,
1445                                 offset = -2 * data.offset[ 0 ],
1446                                 newOverRight,
1447                                 newOverLeft;
1448
1449                         if ( overLeft < 0 ) {
1450                                 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
1451                                 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1452                                         position.left += myOffset + atOffset + offset;
1453                                 }
1454                         } else if ( overRight > 0 ) {
1455                                 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
1456                                 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1457                                         position.left += myOffset + atOffset + offset;
1458                                 }
1459                         }
1460                 },
1461                 top: function( position, data ) {
1462                         var within = data.within,
1463                                 withinOffset = within.offset.top + within.scrollTop,
1464                                 outerHeight = within.height,
1465                                 offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1466                                 collisionPosTop = position.top - data.collisionPosition.marginTop,
1467                                 overTop = collisionPosTop - offsetTop,
1468                                 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1469                                 top = data.my[ 1 ] === "top",
1470                                 myOffset = top ?
1471                                         -data.elemHeight :
1472                                         data.my[ 1 ] === "bottom" ?
1473                                                 data.elemHeight :
1474                                                 0,
1475                                 atOffset = data.at[ 1 ] === "top" ?
1476                                         data.targetHeight :
1477                                         data.at[ 1 ] === "bottom" ?
1478                                                 -data.targetHeight :
1479                                                 0,
1480                                 offset = -2 * data.offset[ 1 ],
1481                                 newOverTop,
1482                                 newOverBottom;
1483                         if ( overTop < 0 ) {
1484                                 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
1485                                 if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
1486                                         position.top += myOffset + atOffset + offset;
1487                                 }
1488                         } else if ( overBottom > 0 ) {
1489                                 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
1490                                 if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
1491                                         position.top += myOffset + atOffset + offset;
1492                                 }
1493                         }
1494                 }
1495         },
1496         flipfit: {
1497                 left: function() {
1498                         $.ui.position.flip.left.apply( this, arguments );
1499                         $.ui.position.fit.left.apply( this, arguments );
1500                 },
1501                 top: function() {
1502                         $.ui.position.flip.top.apply( this, arguments );
1503                         $.ui.position.fit.top.apply( this, arguments );
1504                 }
1505         }
1506 };
1507
1508 // fraction support test
1509 (function() {
1510         var testElement, testElementParent, testElementStyle, offsetLeft, i,
1511                 body = document.getElementsByTagName( "body" )[ 0 ],
1512                 div = document.createElement( "div" );
1513
1514         //Create a "fake body" for testing based on method used in jQuery.support
1515         testElement = document.createElement( body ? "div" : "body" );
1516         testElementStyle = {
1517                 visibility: "hidden",
1518                 width: 0,
1519                 height: 0,
1520                 border: 0,
1521                 margin: 0,
1522                 background: "none"
1523         };
1524         if ( body ) {
1525                 $.extend( testElementStyle, {
1526                         position: "absolute",
1527                         left: "-1000px",
1528                         top: "-1000px"
1529                 });
1530         }
1531         for ( i in testElementStyle ) {
1532                 testElement.style[ i ] = testElementStyle[ i ];
1533         }
1534         testElement.appendChild( div );
1535         testElementParent = body || document.documentElement;
1536         testElementParent.insertBefore( testElement, testElementParent.firstChild );
1537
1538         div.style.cssText = "position: absolute; left: 10.7432222px;";
1539
1540         offsetLeft = $( div ).offset().left;
1541         supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11;
1542
1543         testElement.innerHTML = "";
1544         testElementParent.removeChild( testElement );
1545 })();
1546
1547 })();
1548
1549 var position = $.ui.position;
1550
1551
1552 /*!
1553  * jQuery UI Draggable 1.11.4
1554  * http://jqueryui.com
1555  *
1556  * Copyright jQuery Foundation and other contributors
1557  * Released under the MIT license.
1558  * http://jquery.org/license
1559  *
1560  * http://api.jqueryui.com/draggable/
1561  */
1562
1563
1564 $.widget("ui.draggable", $.ui.mouse, {
1565         version: "1.11.4",
1566         widgetEventPrefix: "drag",
1567         options: {
1568                 addClasses: true,
1569                 appendTo: "parent",
1570                 axis: false,
1571                 connectToSortable: false,
1572                 containment: false,
1573                 cursor: "auto",
1574                 cursorAt: false,
1575                 grid: false,
1576                 handle: false,
1577                 helper: "original",
1578                 iframeFix: false,
1579                 opacity: false,
1580                 refreshPositions: false,
1581                 revert: false,
1582                 revertDuration: 500,
1583                 scope: "default",
1584                 scroll: true,
1585                 scrollSensitivity: 20,
1586                 scrollSpeed: 20,
1587                 snap: false,
1588                 snapMode: "both",
1589                 snapTolerance: 20,
1590                 stack: false,
1591                 zIndex: false,
1592
1593                 // callbacks
1594                 drag: null,
1595                 start: null,
1596                 stop: null
1597         },
1598         _create: function() {
1599
1600                 if ( this.options.helper === "original" ) {
1601                         this._setPositionRelative();
1602                 }
1603                 if (this.options.addClasses){
1604                         this.element.addClass("ui-draggable");
1605                 }
1606                 if (this.options.disabled){
1607                         this.element.addClass("ui-draggable-disabled");
1608                 }
1609                 this._setHandleClassName();
1610
1611                 this._mouseInit();
1612         },
1613
1614         _setOption: function( key, value ) {
1615                 this._super( key, value );
1616                 if ( key === "handle" ) {
1617                         this._removeHandleClassName();
1618                         this._setHandleClassName();
1619                 }
1620         },
1621
1622         _destroy: function() {
1623                 if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
1624                         this.destroyOnClear = true;
1625                         return;
1626                 }
1627                 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1628                 this._removeHandleClassName();
1629                 this._mouseDestroy();
1630         },
1631
1632         _mouseCapture: function(event) {
1633                 var o = this.options;
1634
1635                 this._blurActiveElement( event );
1636
1637                 // among others, prevent a drag on a resizable-handle
1638                 if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
1639                         return false;
1640                 }
1641
1642                 //Quit if we're not on a valid handle
1643                 this.handle = this._getHandle(event);
1644                 if (!this.handle) {
1645                         return false;
1646                 }
1647
1648                 this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
1649
1650                 return true;
1651
1652         },
1653
1654         _blockFrames: function( selector ) {
1655                 this.iframeBlocks = this.document.find( selector ).map(function() {
1656                         var iframe = $( this );
1657
1658                         return $( "<div>" )
1659                                 .css( "position", "absolute" )
1660                                 .appendTo( iframe.parent() )
1661                                 .outerWidth( iframe.outerWidth() )
1662                                 .outerHeight( iframe.outerHeight() )
1663                                 .offset( iframe.offset() )[ 0 ];
1664                 });
1665         },
1666
1667         _unblockFrames: function() {
1668                 if ( this.iframeBlocks ) {
1669                         this.iframeBlocks.remove();
1670                         delete this.iframeBlocks;
1671                 }
1672         },
1673
1674         _blurActiveElement: function( event ) {
1675                 var document = this.document[ 0 ];
1676
1677                 // Only need to blur if the event occurred on the draggable itself, see #10527
1678                 if ( !this.handleElement.is( event.target ) ) {
1679                         return;
1680                 }
1681
1682                 // support: IE9
1683                 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
1684                 try {
1685
1686                         // Support: IE9, IE10
1687                         // If the <body> is blurred, IE will switch windows, see #9520
1688                         if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) {
1689
1690                                 // Blur any element that currently has focus, see #4261
1691                                 $( document.activeElement ).blur();
1692                         }
1693                 } catch ( error ) {}
1694         },
1695
1696         _mouseStart: function(event) {
1697
1698                 var o = this.options;
1699
1700                 //Create and append the visible helper
1701                 this.helper = this._createHelper(event);
1702
1703                 this.helper.addClass("ui-draggable-dragging");
1704
1705                 //Cache the helper size
1706                 this._cacheHelperProportions();
1707
1708                 //If ddmanager is used for droppables, set the global draggable
1709                 if ($.ui.ddmanager) {
1710                         $.ui.ddmanager.current = this;
1711                 }
1712
1713                 /*
1714                  * - Position generation -
1715                  * This block generates everything position related - it's the core of draggables.
1716                  */
1717
1718                 //Cache the margins of the original element
1719                 this._cacheMargins();
1720
1721                 //Store the helper's css position
1722                 this.cssPosition = this.helper.css( "position" );
1723                 this.scrollParent = this.helper.scrollParent( true );
1724                 this.offsetParent = this.helper.offsetParent();
1725                 this.hasFixedAncestor = this.helper.parents().filter(function() {
1726                                 return $( this ).css( "position" ) === "fixed";
1727                         }).length > 0;
1728
1729                 //The element's absolute position on the page minus margins
1730                 this.positionAbs = this.element.offset();
1731                 this._refreshOffsets( event );
1732
1733                 //Generate the original position
1734                 this.originalPosition = this.position = this._generatePosition( event, false );
1735                 this.originalPageX = event.pageX;
1736                 this.originalPageY = event.pageY;
1737
1738                 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
1739                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1740
1741                 //Set a containment if given in the options
1742                 this._setContainment();
1743
1744                 //Trigger event + callbacks
1745                 if (this._trigger("start", event) === false) {
1746                         this._clear();
1747                         return false;
1748                 }
1749
1750                 //Recache the helper size
1751                 this._cacheHelperProportions();
1752
1753                 //Prepare the droppable offsets
1754                 if ($.ui.ddmanager && !o.dropBehaviour) {
1755                         $.ui.ddmanager.prepareOffsets(this, event);
1756                 }
1757
1758                 // Reset helper's right/bottom css if they're set and set explicit width/height instead
1759                 // as this prevents resizing of elements with right/bottom set (see #7772)
1760                 this._normalizeRightBottom();
1761
1762                 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1763
1764                 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1765                 if ( $.ui.ddmanager ) {
1766                         $.ui.ddmanager.dragStart(this, event);
1767                 }
1768
1769                 return true;
1770         },
1771
1772         _refreshOffsets: function( event ) {
1773                 this.offset = {
1774                         top: this.positionAbs.top - this.margins.top,
1775                         left: this.positionAbs.left - this.margins.left,
1776                         scroll: false,
1777                         parent: this._getParentOffset(),
1778                         relative: this._getRelativeOffset()
1779                 };
1780
1781                 this.offset.click = {
1782                         left: event.pageX - this.offset.left,
1783                         top: event.pageY - this.offset.top
1784                 };
1785         },
1786
1787         _mouseDrag: function(event, noPropagation) {
1788                 // reset any necessary cached properties (see #5009)
1789                 if ( this.hasFixedAncestor ) {
1790                         this.offset.parent = this._getParentOffset();
1791                 }
1792
1793                 //Compute the helpers position
1794                 this.position = this._generatePosition( event, true );
1795                 this.positionAbs = this._convertPositionTo("absolute");
1796
1797                 //Call plugins and callbacks and use the resulting position if something is returned
1798                 if (!noPropagation) {
1799                         var ui = this._uiHash();
1800                         if (this._trigger("drag", event, ui) === false) {
1801                                 this._mouseUp({});
1802                                 return false;
1803                         }
1804                         this.position = ui.position;
1805                 }
1806
1807                 this.helper[ 0 ].style.left = this.position.left + "px";
1808                 this.helper[ 0 ].style.top = this.position.top + "px";
1809
1810                 if ($.ui.ddmanager) {
1811                         $.ui.ddmanager.drag(this, event);
1812                 }
1813
1814                 return false;
1815         },
1816
1817         _mouseStop: function(event) {
1818
1819                 //If we are using droppables, inform the manager about the drop
1820                 var that = this,
1821                         dropped = false;
1822                 if ($.ui.ddmanager && !this.options.dropBehaviour) {
1823                         dropped = $.ui.ddmanager.drop(this, event);
1824                 }
1825
1826                 //if a drop comes from outside (a sortable)
1827                 if (this.dropped) {
1828                         dropped = this.dropped;
1829                         this.dropped = false;
1830                 }
1831
1832                 if ((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
1833                         $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1834                                 if (that._trigger("stop", event) !== false) {
1835                                         that._clear();
1836                                 }
1837                         });
1838                 } else {
1839                         if (this._trigger("stop", event) !== false) {
1840                                 this._clear();
1841                         }
1842                 }
1843
1844                 return false;
1845         },
1846
1847         _mouseUp: function( event ) {
1848                 this._unblockFrames();
1849
1850                 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1851                 if ( $.ui.ddmanager ) {
1852                         $.ui.ddmanager.dragStop(this, event);
1853                 }
1854
1855                 // Only need to focus if the event occurred on the draggable itself, see #10527
1856                 if ( this.handleElement.is( event.target ) ) {
1857                         // The interaction is over; whether or not the click resulted in a drag, focus the element
1858                         this.element.focus();
1859                 }
1860
1861                 return $.ui.mouse.prototype._mouseUp.call(this, event);
1862         },
1863
1864         cancel: function() {
1865
1866                 if (this.helper.is(".ui-draggable-dragging")) {
1867                         this._mouseUp({});
1868                 } else {
1869                         this._clear();
1870                 }
1871
1872                 return this;
1873
1874         },
1875
1876         _getHandle: function(event) {
1877                 return this.options.handle ?
1878                         !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
1879                         true;
1880         },
1881
1882         _setHandleClassName: function() {
1883                 this.handleElement = this.options.handle ?
1884                         this.element.find( this.options.handle ) : this.element;
1885                 this.handleElement.addClass( "ui-draggable-handle" );
1886         },
1887
1888         _removeHandleClassName: function() {
1889                 this.handleElement.removeClass( "ui-draggable-handle" );
1890         },
1891
1892         _createHelper: function(event) {
1893
1894                 var o = this.options,
1895                         helperIsFunction = $.isFunction( o.helper ),
1896                         helper = helperIsFunction ?
1897                                 $( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
1898                                 ( o.helper === "clone" ?
1899                                         this.element.clone().removeAttr( "id" ) :
1900                                         this.element );
1901
1902                 if (!helper.parents("body").length) {
1903                         helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
1904                 }
1905
1906                 // http://bugs.jqueryui.com/ticket/9446
1907                 // a helper function can return the original element
1908                 // which wouldn't have been set to relative in _create
1909                 if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
1910                         this._setPositionRelative();
1911                 }
1912
1913                 if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
1914                         helper.css("position", "absolute");
1915                 }
1916
1917                 return helper;
1918
1919         },
1920
1921         _setPositionRelative: function() {
1922                 if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
1923                         this.element[ 0 ].style.position = "relative";
1924                 }
1925         },
1926
1927         _adjustOffsetFromHelper: function(obj) {
1928                 if (typeof obj === "string") {
1929                         obj = obj.split(" ");
1930                 }
1931                 if ($.isArray(obj)) {
1932                         obj = { left: +obj[0], top: +obj[1] || 0 };
1933                 }
1934                 if ("left" in obj) {
1935                         this.offset.click.left = obj.left + this.margins.left;
1936                 }
1937                 if ("right" in obj) {
1938                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1939                 }
1940                 if ("top" in obj) {
1941                         this.offset.click.top = obj.top + this.margins.top;
1942                 }
1943                 if ("bottom" in obj) {
1944                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1945                 }
1946         },
1947
1948         _isRootNode: function( element ) {
1949                 return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
1950         },
1951
1952         _getParentOffset: function() {
1953
1954                 //Get the offsetParent and cache its position
1955                 var po = this.offsetParent.offset(),
1956                         document = this.document[ 0 ];
1957
1958                 // This is a special case where we need to modify a offset calculated on start, since the following happened:
1959                 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1960                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1961                 //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1962                 if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1963                         po.left += this.scrollParent.scrollLeft();
1964                         po.top += this.scrollParent.scrollTop();
1965                 }
1966
1967                 if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
1968                         po = { top: 0, left: 0 };
1969                 }
1970
1971                 return {
1972                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0),
1973                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0)
1974                 };
1975
1976         },
1977
1978         _getRelativeOffset: function() {
1979                 if ( this.cssPosition !== "relative" ) {
1980                         return { top: 0, left: 0 };
1981                 }
1982
1983                 var p = this.element.position(),
1984                         scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
1985
1986                 return {
1987                         top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
1988                         left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
1989                 };
1990
1991         },
1992
1993         _cacheMargins: function() {
1994                 this.margins = {
1995                         left: (parseInt(this.element.css("marginLeft"), 10) || 0),
1996                         top: (parseInt(this.element.css("marginTop"), 10) || 0),
1997                         right: (parseInt(this.element.css("marginRight"), 10) || 0),
1998                         bottom: (parseInt(this.element.css("marginBottom"), 10) || 0)
1999                 };
2000         },
2001
2002         _cacheHelperProportions: function() {
2003                 this.helperProportions = {
2004                         width: this.helper.outerWidth(),
2005                         height: this.helper.outerHeight()
2006                 };
2007         },
2008
2009         _setContainment: function() {
2010
2011                 var isUserScrollable, c, ce,
2012                         o = this.options,
2013                         document = this.document[ 0 ];
2014
2015                 this.relativeContainer = null;
2016
2017                 if ( !o.containment ) {
2018                         this.containment = null;
2019                         return;
2020                 }
2021
2022                 if ( o.containment === "window" ) {
2023                         this.containment = [
2024                                 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
2025                                 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
2026                                 $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
2027                                 $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
2028                         ];
2029                         return;
2030                 }
2031
2032                 if ( o.containment === "document") {
2033                         this.containment = [
2034                                 0,
2035                                 0,
2036                                 $( document ).width() - this.helperProportions.width - this.margins.left,
2037                                 ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
2038                         ];
2039                         return;
2040                 }
2041
2042                 if ( o.containment.constructor === Array ) {
2043                         this.containment = o.containment;
2044                         return;
2045                 }
2046
2047                 if ( o.containment === "parent" ) {
2048                         o.containment = this.helper[ 0 ].parentNode;
2049                 }
2050
2051                 c = $( o.containment );
2052                 ce = c[ 0 ];
2053
2054                 if ( !ce ) {
2055                         return;
2056                 }
2057
2058                 isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
2059
2060                 this.containment = [
2061                         ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
2062                         ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
2063                         ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
2064                                 ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
2065                                 ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
2066                                 this.helperProportions.width -
2067                                 this.margins.left -
2068                                 this.margins.right,
2069                         ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
2070                                 ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
2071                                 ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
2072                                 this.helperProportions.height -
2073                                 this.margins.top -
2074                                 this.margins.bottom
2075                 ];
2076                 this.relativeContainer = c;
2077         },
2078
2079         _convertPositionTo: function(d, pos) {
2080
2081                 if (!pos) {
2082                         pos = this.position;
2083                 }
2084
2085                 var mod = d === "absolute" ? 1 : -1,
2086                         scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
2087
2088                 return {
2089                         top: (
2090                                 pos.top +                                                                                                                               // The absolute mouse position
2091                                 this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
2092                                 this.offset.parent.top * mod -                                                                          // The offsetParent's offset without borders (offset + border)
2093                                 ( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)
2094                         ),
2095                         left: (
2096                                 pos.left +                                                                                                                              // The absolute mouse position
2097                                 this.offset.relative.left * mod +                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
2098                                 this.offset.parent.left * mod   -                                                                               // The offsetParent's offset without borders (offset + border)
2099                                 ( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod)
2100                         )
2101                 };
2102
2103         },
2104
2105         _generatePosition: function( event, constrainPosition ) {
2106
2107                 var containment, co, top, left,
2108                         o = this.options,
2109                         scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
2110                         pageX = event.pageX,
2111                         pageY = event.pageY;
2112
2113                 // Cache the scroll
2114                 if ( !scrollIsRootNode || !this.offset.scroll ) {
2115                         this.offset.scroll = {
2116                                 top: this.scrollParent.scrollTop(),
2117                                 left: this.scrollParent.scrollLeft()
2118                         };
2119                 }
2120
2121                 /*
2122                  * - Position constraining -
2123                  * Constrain the position to a mix of grid, containment.
2124                  */
2125
2126                 // If we are not dragging yet, we won't check for options
2127                 if ( constrainPosition ) {
2128                         if ( this.containment ) {
2129                                 if ( this.relativeContainer ){
2130                                         co = this.relativeContainer.offset();
2131                                         containment = [
2132                                                 this.containment[ 0 ] + co.left,
2133                                                 this.containment[ 1 ] + co.top,
2134                                                 this.containment[ 2 ] + co.left,
2135                                                 this.containment[ 3 ] + co.top
2136                                         ];
2137                                 } else {
2138                                         containment = this.containment;
2139                                 }
2140
2141                                 if (event.pageX - this.offset.click.left < containment[0]) {
2142                                         pageX = containment[0] + this.offset.click.left;
2143                                 }
2144                                 if (event.pageY - this.offset.click.top < containment[1]) {
2145                                         pageY = containment[1] + this.offset.click.top;
2146                                 }
2147                                 if (event.pageX - this.offset.click.left > containment[2]) {
2148                                         pageX = containment[2] + this.offset.click.left;
2149                                 }
2150                                 if (event.pageY - this.offset.click.top > containment[3]) {
2151                                         pageY = containment[3] + this.offset.click.top;
2152                                 }
2153                         }
2154
2155                         if (o.grid) {
2156                                 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
2157                                 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
2158                                 pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
2159
2160                                 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
2161                                 pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
2162                         }
2163
2164                         if ( o.axis === "y" ) {
2165                                 pageX = this.originalPageX;
2166                         }
2167
2168                         if ( o.axis === "x" ) {
2169                                 pageY = this.originalPageY;
2170                         }
2171                 }
2172
2173                 return {
2174                         top: (
2175                                 pageY -                                                                                                                                 // The absolute mouse position
2176                                 this.offset.click.top   -                                                                                               // Click offset (relative to the element)
2177                                 this.offset.relative.top -                                                                                              // Only for relative positioned nodes: Relative offset from element to offset parent
2178                                 this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
2179                                 ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
2180                         ),
2181                         left: (
2182                                 pageX -                                                                                                                                 // The absolute mouse position
2183                                 this.offset.click.left -                                                                                                // Click offset (relative to the element)
2184                                 this.offset.relative.left -                                                                                             // Only for relative positioned nodes: Relative offset from element to offset parent
2185                                 this.offset.parent.left +                                                                                               // The offsetParent's offset without borders (offset + border)
2186                                 ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
2187                         )
2188                 };
2189
2190         },
2191
2192         _clear: function() {
2193                 this.helper.removeClass("ui-draggable-dragging");
2194                 if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
2195                         this.helper.remove();
2196                 }
2197                 this.helper = null;
2198                 this.cancelHelperRemoval = false;
2199                 if ( this.destroyOnClear ) {
2200                         this.destroy();
2201                 }
2202         },
2203
2204         _normalizeRightBottom: function() {
2205                 if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) {
2206                         this.helper.width( this.helper.width() );
2207                         this.helper.css( "right", "auto" );
2208                 }
2209                 if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) {
2210                         this.helper.height( this.helper.height() );
2211                         this.helper.css( "bottom", "auto" );
2212                 }
2213         },
2214
2215         // From now on bulk stuff - mainly helpers
2216
2217         _trigger: function( type, event, ui ) {
2218                 ui = ui || this._uiHash();
2219                 $.ui.plugin.call( this, type, [ event, ui, this ], true );
2220
2221                 // Absolute position and offset (see #6884 ) have to be recalculated after plugins
2222                 if ( /^(drag|start|stop)/.test( type ) ) {
2223                         this.positionAbs = this._convertPositionTo( "absolute" );
2224                         ui.offset = this.positionAbs;
2225                 }
2226                 return $.Widget.prototype._trigger.call( this, type, event, ui );
2227         },
2228
2229         plugins: {},
2230
2231         _uiHash: function() {
2232                 return {
2233                         helper: this.helper,
2234                         position: this.position,
2235                         originalPosition: this.originalPosition,
2236                         offset: this.positionAbs
2237                 };
2238         }
2239
2240 });
2241
2242 $.ui.plugin.add( "draggable", "connectToSortable", {
2243         start: function( event, ui, draggable ) {
2244                 var uiSortable = $.extend( {}, ui, {
2245                         item: draggable.element
2246                 });
2247
2248                 draggable.sortables = [];
2249                 $( draggable.options.connectToSortable ).each(function() {
2250                         var sortable = $( this ).sortable( "instance" );
2251
2252                         if ( sortable && !sortable.options.disabled ) {
2253                                 draggable.sortables.push( sortable );
2254
2255                                 // refreshPositions is called at drag start to refresh the containerCache
2256                                 // which is used in drag. This ensures it's initialized and synchronized
2257                                 // with any changes that might have happened on the page since initialization.
2258                                 sortable.refreshPositions();
2259                                 sortable._trigger("activate", event, uiSortable);
2260                         }
2261                 });
2262         },
2263         stop: function( event, ui, draggable ) {
2264                 var uiSortable = $.extend( {}, ui, {
2265                         item: draggable.element
2266                 });
2267
2268                 draggable.cancelHelperRemoval = false;
2269
2270                 $.each( draggable.sortables, function() {
2271                         var sortable = this;
2272
2273                         if ( sortable.isOver ) {
2274                                 sortable.isOver = 0;
2275
2276                                 // Allow this sortable to handle removing the helper
2277                                 draggable.cancelHelperRemoval = true;
2278                                 sortable.cancelHelperRemoval = false;
2279
2280                                 // Use _storedCSS To restore properties in the sortable,
2281                                 // as this also handles revert (#9675) since the draggable
2282                                 // may have modified them in unexpected ways (#8809)
2283                                 sortable._storedCSS = {
2284                                         position: sortable.placeholder.css( "position" ),
2285                                         top: sortable.placeholder.css( "top" ),
2286                                         left: sortable.placeholder.css( "left" )
2287                                 };
2288
2289                                 sortable._mouseStop(event);
2290
2291                                 // Once drag has ended, the sortable should return to using
2292                                 // its original helper, not the shared helper from draggable
2293                                 sortable.options.helper = sortable.options._helper;
2294                         } else {
2295                                 // Prevent this Sortable from removing the helper.
2296                                 // However, don't set the draggable to remove the helper
2297                                 // either as another connected Sortable may yet handle the removal.
2298                                 sortable.cancelHelperRemoval = true;
2299
2300                                 sortable._trigger( "deactivate", event, uiSortable );
2301                         }
2302                 });
2303         },
2304         drag: function( event, ui, draggable ) {
2305                 $.each( draggable.sortables, function() {
2306                         var innermostIntersecting = false,
2307                                 sortable = this;
2308
2309                         // Copy over variables that sortable's _intersectsWith uses
2310                         sortable.positionAbs = draggable.positionAbs;
2311                         sortable.helperProportions = draggable.helperProportions;
2312                         sortable.offset.click = draggable.offset.click;
2313
2314                         if ( sortable._intersectsWith( sortable.containerCache ) ) {
2315                                 innermostIntersecting = true;
2316
2317                                 $.each( draggable.sortables, function() {
2318                                         // Copy over variables that sortable's _intersectsWith uses
2319                                         this.positionAbs = draggable.positionAbs;
2320                                         this.helperProportions = draggable.helperProportions;
2321                                         this.offset.click = draggable.offset.click;
2322
2323                                         if ( this !== sortable &&
2324                                                         this._intersectsWith( this.containerCache ) &&
2325                                                         $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
2326                                                 innermostIntersecting = false;
2327                                         }
2328
2329                                         return innermostIntersecting;
2330                                 });
2331                         }
2332
2333                         if ( innermostIntersecting ) {
2334                                 // If it intersects, we use a little isOver variable and set it once,
2335                                 // so that the move-in stuff gets fired only once.
2336                                 if ( !sortable.isOver ) {
2337                                         sortable.isOver = 1;
2338
2339                                         // Store draggable's parent in case we need to reappend to it later.
2340                                         draggable._parent = ui.helper.parent();
2341
2342                                         sortable.currentItem = ui.helper
2343                                                 .appendTo( sortable.element )
2344                                                 .data( "ui-sortable-item", true );
2345
2346                                         // Store helper option to later restore it
2347                                         sortable.options._helper = sortable.options.helper;
2348
2349                                         sortable.options.helper = function() {
2350                                                 return ui.helper[ 0 ];
2351                                         };
2352
2353                                         // Fire the start events of the sortable with our passed browser event,
2354                                         // and our own helper (so it doesn't create a new one)
2355                                         event.target = sortable.currentItem[ 0 ];
2356                                         sortable._mouseCapture( event, true );
2357                                         sortable._mouseStart( event, true, true );
2358
2359                                         // Because the browser event is way off the new appended portlet,
2360                                         // modify necessary variables to reflect the changes
2361                                         sortable.offset.click.top = draggable.offset.click.top;
2362                                         sortable.offset.click.left = draggable.offset.click.left;
2363                                         sortable.offset.parent.left -= draggable.offset.parent.left -
2364                                                 sortable.offset.parent.left;
2365                                         sortable.offset.parent.top -= draggable.offset.parent.top -
2366                                                 sortable.offset.parent.top;
2367
2368                                         draggable._trigger( "toSortable", event );
2369
2370                                         // Inform draggable that the helper is in a valid drop zone,
2371                                         // used solely in the revert option to handle "valid/invalid".
2372                                         draggable.dropped = sortable.element;
2373
2374                                         // Need to refreshPositions of all sortables in the case that
2375                                         // adding to one sortable changes the location of the other sortables (#9675)
2376                                         $.each( draggable.sortables, function() {
2377                                                 this.refreshPositions();
2378                                         });
2379
2380                                         // hack so receive/update callbacks work (mostly)
2381                                         draggable.currentItem = draggable.element;
2382                                         sortable.fromOutside = draggable;
2383                                 }
2384
2385                                 if ( sortable.currentItem ) {
2386                                         sortable._mouseDrag( event );
2387                                         // Copy the sortable's position because the draggable's can potentially reflect
2388                                         // a relative position, while sortable is always absolute, which the dragged
2389                                         // element has now become. (#8809)
2390                                         ui.position = sortable.position;
2391                                 }
2392                         } else {
2393                                 // If it doesn't intersect with the sortable, and it intersected before,
2394                                 // we fake the drag stop of the sortable, but make sure it doesn't remove
2395                                 // the helper by using cancelHelperRemoval.
2396                                 if ( sortable.isOver ) {
2397
2398                                         sortable.isOver = 0;
2399                                         sortable.cancelHelperRemoval = true;
2400
2401                                         // Calling sortable's mouseStop would trigger a revert,
2402                                         // so revert must be temporarily false until after mouseStop is called.
2403                                         sortable.options._revert = sortable.options.revert;
2404                                         sortable.options.revert = false;
2405
2406                                         sortable._trigger( "out", event, sortable._uiHash( sortable ) );
2407                                         sortable._mouseStop( event, true );
2408
2409                                         // restore sortable behaviors that were modfied
2410                                         // when the draggable entered the sortable area (#9481)
2411                                         sortable.options.revert = sortable.options._revert;
2412                                         sortable.options.helper = sortable.options._helper;
2413
2414                                         if ( sortable.placeholder ) {
2415                                                 sortable.placeholder.remove();
2416                                         }
2417
2418                                         // Restore and recalculate the draggable's offset considering the sortable
2419                                         // may have modified them in unexpected ways. (#8809, #10669)
2420                                         ui.helper.appendTo( draggable._parent );
2421                                         draggable._refreshOffsets( event );
2422                                         ui.position = draggable._generatePosition( event, true );
2423
2424                                         draggable._trigger( "fromSortable", event );
2425
2426                                         // Inform draggable that the helper is no longer in a valid drop zone
2427                                         draggable.dropped = false;
2428
2429                                         // Need to refreshPositions of all sortables just in case removing
2430                                         // from one sortable changes the location of other sortables (#9675)
2431                                         $.each( draggable.sortables, function() {
2432                                                 this.refreshPositions();
2433                                         });
2434                                 }
2435                         }
2436                 });
2437         }
2438 });
2439
2440 $.ui.plugin.add("draggable", "cursor", {
2441         start: function( event, ui, instance ) {
2442                 var t = $( "body" ),
2443                         o = instance.options;
2444
2445                 if (t.css("cursor")) {
2446                         o._cursor = t.css("cursor");
2447                 }
2448                 t.css("cursor", o.cursor);
2449         },
2450         stop: function( event, ui, instance ) {
2451                 var o = instance.options;
2452                 if (o._cursor) {
2453                         $("body").css("cursor", o._cursor);
2454                 }
2455         }
2456 });
2457
2458 $.ui.plugin.add("draggable", "opacity", {
2459         start: function( event, ui, instance ) {
2460                 var t = $( ui.helper ),
2461                         o = instance.options;
2462                 if (t.css("opacity")) {
2463                         o._opacity = t.css("opacity");
2464                 }
2465                 t.css("opacity", o.opacity);
2466         },
2467         stop: function( event, ui, instance ) {
2468                 var o = instance.options;
2469                 if (o._opacity) {
2470                         $(ui.helper).css("opacity", o._opacity);
2471                 }
2472         }
2473 });
2474
2475 $.ui.plugin.add("draggable", "scroll", {
2476         start: function( event, ui, i ) {
2477                 if ( !i.scrollParentNotHidden ) {
2478                         i.scrollParentNotHidden = i.helper.scrollParent( false );
2479                 }
2480
2481                 if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
2482                         i.overflowOffset = i.scrollParentNotHidden.offset();
2483                 }
2484         },
2485         drag: function( event, ui, i  ) {
2486
2487                 var o = i.options,
2488                         scrolled = false,
2489                         scrollParent = i.scrollParentNotHidden[ 0 ],
2490                         document = i.document[ 0 ];
2491
2492                 if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
2493                         if ( !o.axis || o.axis !== "x" ) {
2494                                 if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) {
2495                                         scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
2496                                 } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
2497                                         scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
2498                                 }
2499                         }
2500
2501                         if ( !o.axis || o.axis !== "y" ) {
2502                                 if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) {
2503                                         scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
2504                                 } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
2505                                         scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
2506                                 }
2507                         }
2508
2509                 } else {
2510
2511                         if (!o.axis || o.axis !== "x") {
2512                                 if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
2513                                         scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
2514                                 } else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
2515                                         scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
2516                                 }
2517                         }
2518
2519                         if (!o.axis || o.axis !== "y") {
2520                                 if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
2521                                         scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
2522                                 } else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
2523                                         scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
2524                                 }
2525                         }
2526
2527                 }
2528
2529                 if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
2530                         $.ui.ddmanager.prepareOffsets(i, event);
2531                 }
2532
2533         }
2534 });
2535
2536 $.ui.plugin.add("draggable", "snap", {
2537         start: function( event, ui, i ) {
2538
2539                 var o = i.options;
2540
2541                 i.snapElements = [];
2542
2543                 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
2544                         var $t = $(this),
2545                                 $o = $t.offset();
2546                         if (this !== i.element[0]) {
2547                                 i.snapElements.push({
2548                                         item: this,
2549                                         width: $t.outerWidth(), height: $t.outerHeight(),
2550                                         top: $o.top, left: $o.left
2551                                 });
2552                         }
2553                 });
2554
2555         },
2556         drag: function( event, ui, inst ) {
2557
2558                 var ts, bs, ls, rs, l, r, t, b, i, first,
2559                         o = inst.options,
2560                         d = o.snapTolerance,
2561                         x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
2562                         y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
2563
2564                 for (i = inst.snapElements.length - 1; i >= 0; i--){
2565
2566                         l = inst.snapElements[i].left - inst.margins.left;
2567                         r = l + inst.snapElements[i].width;
2568                         t = inst.snapElements[i].top - inst.margins.top;
2569                         b = t + inst.snapElements[i].height;
2570
2571                         if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
2572                                 if (inst.snapElements[i].snapping) {
2573                                         (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2574                                 }
2575                                 inst.snapElements[i].snapping = false;
2576                                 continue;
2577                         }
2578
2579                         if (o.snapMode !== "inner") {
2580                                 ts = Math.abs(t - y2) <= d;
2581                                 bs = Math.abs(b - y1) <= d;
2582                                 ls = Math.abs(l - x2) <= d;
2583                                 rs = Math.abs(r - x1) <= d;
2584                                 if (ts) {
2585                                         ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top;
2586                                 }
2587                                 if (bs) {
2588                                         ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top;
2589                                 }
2590                                 if (ls) {
2591                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left;
2592                                 }
2593                                 if (rs) {
2594                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left;
2595                                 }
2596                         }
2597
2598                         first = (ts || bs || ls || rs);
2599
2600                         if (o.snapMode !== "outer") {
2601                                 ts = Math.abs(t - y1) <= d;
2602                                 bs = Math.abs(b - y2) <= d;
2603                                 ls = Math.abs(l - x1) <= d;
2604                                 rs = Math.abs(r - x2) <= d;
2605                                 if (ts) {
2606                                         ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top;
2607                                 }
2608                                 if (bs) {
2609                                         ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top;
2610                                 }
2611                                 if (ls) {
2612                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left;
2613                                 }
2614                                 if (rs) {
2615                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left;
2616                                 }
2617                         }
2618
2619                         if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
2620                                 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2621                         }
2622                         inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
2623
2624                 }
2625
2626         }
2627 });
2628
2629 $.ui.plugin.add("draggable", "stack", {
2630         start: function( event, ui, instance ) {
2631                 var min,
2632                         o = instance.options,
2633                         group = $.makeArray($(o.stack)).sort(function(a, b) {
2634                                 return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0);
2635                         });
2636
2637                 if (!group.length) { return; }
2638
2639                 min = parseInt($(group[0]).css("zIndex"), 10) || 0;
2640                 $(group).each(function(i) {
2641                         $(this).css("zIndex", min + i);
2642                 });
2643                 this.css("zIndex", (min + group.length));
2644         }
2645 });
2646
2647 $.ui.plugin.add("draggable", "zIndex", {
2648         start: function( event, ui, instance ) {
2649                 var t = $( ui.helper ),
2650                         o = instance.options;
2651
2652                 if (t.css("zIndex")) {
2653                         o._zIndex = t.css("zIndex");
2654                 }
2655                 t.css("zIndex", o.zIndex);
2656         },
2657         stop: function( event, ui, instance ) {
2658                 var o = instance.options;
2659
2660                 if (o._zIndex) {
2661                         $(ui.helper).css("zIndex", o._zIndex);
2662                 }
2663         }
2664 });
2665
2666 var draggable = $.ui.draggable;
2667
2668
2669 /*!
2670  * jQuery UI Droppable 1.11.4
2671  * http://jqueryui.com
2672  *
2673  * Copyright jQuery Foundation and other contributors
2674  * Released under the MIT license.
2675  * http://jquery.org/license
2676  *
2677  * http://api.jqueryui.com/droppable/
2678  */
2679
2680
2681 $.widget( "ui.droppable", {
2682         version: "1.11.4",
2683         widgetEventPrefix: "drop",
2684         options: {
2685                 accept: "*",
2686                 activeClass: false,
2687                 addClasses: true,
2688                 greedy: false,
2689                 hoverClass: false,
2690                 scope: "default",
2691                 tolerance: "intersect",
2692
2693                 // callbacks
2694                 activate: null,
2695                 deactivate: null,
2696                 drop: null,
2697                 out: null,
2698                 over: null
2699         },
2700         _create: function() {
2701
2702                 var proportions,
2703                         o = this.options,
2704                         accept = o.accept;
2705
2706                 this.isover = false;
2707                 this.isout = true;
2708
2709                 this.accept = $.isFunction( accept ) ? accept : function( d ) {
2710                         return d.is( accept );
2711                 };
2712
2713                 this.proportions = function( /* valueToWrite */ ) {
2714                         if ( arguments.length ) {
2715                                 // Store the droppable's proportions
2716                                 proportions = arguments[ 0 ];
2717                         } else {
2718                                 // Retrieve or derive the droppable's proportions
2719                                 return proportions ?
2720                                         proportions :
2721                                         proportions = {
2722                                                 width: this.element[ 0 ].offsetWidth,
2723                                                 height: this.element[ 0 ].offsetHeight
2724                                         };
2725                         }
2726                 };
2727
2728                 this._addToManager( o.scope );
2729
2730                 o.addClasses && this.element.addClass( "ui-droppable" );
2731
2732         },
2733
2734         _addToManager: function( scope ) {
2735                 // Add the reference and positions to the manager
2736                 $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
2737                 $.ui.ddmanager.droppables[ scope ].push( this );
2738         },
2739
2740         _splice: function( drop ) {
2741                 var i = 0;
2742                 for ( ; i < drop.length; i++ ) {
2743                         if ( drop[ i ] === this ) {
2744                                 drop.splice( i, 1 );
2745                         }
2746                 }
2747         },
2748
2749         _destroy: function() {
2750                 var drop = $.ui.ddmanager.droppables[ this.options.scope ];
2751
2752                 this._splice( drop );
2753
2754                 this.element.removeClass( "ui-droppable ui-droppable-disabled" );
2755         },
2756
2757         _setOption: function( key, value ) {
2758
2759                 if ( key === "accept" ) {
2760                         this.accept = $.isFunction( value ) ? value : function( d ) {
2761                                 return d.is( value );
2762                         };
2763                 } else if ( key === "scope" ) {
2764                         var drop = $.ui.ddmanager.droppables[ this.options.scope ];
2765
2766                         this._splice( drop );
2767                         this._addToManager( value );
2768                 }
2769
2770                 this._super( key, value );
2771         },
2772
2773         _activate: function( event ) {
2774                 var draggable = $.ui.ddmanager.current;
2775                 if ( this.options.activeClass ) {
2776                         this.element.addClass( this.options.activeClass );
2777                 }
2778                 if ( draggable ){
2779                         this._trigger( "activate", event, this.ui( draggable ) );
2780                 }
2781         },
2782
2783         _deactivate: function( event ) {
2784                 var draggable = $.ui.ddmanager.current;
2785                 if ( this.options.activeClass ) {
2786                         this.element.removeClass( this.options.activeClass );
2787                 }
2788                 if ( draggable ){
2789                         this._trigger( "deactivate", event, this.ui( draggable ) );
2790                 }
2791         },
2792
2793         _over: function( event ) {
2794
2795                 var draggable = $.ui.ddmanager.current;
2796
2797                 // Bail if draggable and droppable are same element
2798                 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2799                         return;
2800                 }
2801
2802                 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2803                         if ( this.options.hoverClass ) {
2804                                 this.element.addClass( this.options.hoverClass );
2805                         }
2806                         this._trigger( "over", event, this.ui( draggable ) );
2807                 }
2808
2809         },
2810
2811         _out: function( event ) {
2812
2813                 var draggable = $.ui.ddmanager.current;
2814
2815                 // Bail if draggable and droppable are same element
2816                 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2817                         return;
2818                 }
2819
2820                 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2821                         if ( this.options.hoverClass ) {
2822                                 this.element.removeClass( this.options.hoverClass );
2823                         }
2824                         this._trigger( "out", event, this.ui( draggable ) );
2825                 }
2826
2827         },
2828
2829         _drop: function( event, custom ) {
2830
2831                 var draggable = custom || $.ui.ddmanager.current,
2832                         childrenIntersection = false;
2833
2834                 // Bail if draggable and droppable are same element
2835                 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2836                         return false;
2837                 }
2838
2839                 this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() {
2840                         var inst = $( this ).droppable( "instance" );
2841                         if (
2842                                 inst.options.greedy &&
2843                                 !inst.options.disabled &&
2844                                 inst.options.scope === draggable.options.scope &&
2845                                 inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) &&
2846                                 $.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event )
2847                         ) { childrenIntersection = true; return false; }
2848                 });
2849                 if ( childrenIntersection ) {
2850                         return false;
2851                 }
2852
2853                 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2854                         if ( this.options.activeClass ) {
2855                                 this.element.removeClass( this.options.activeClass );
2856                         }
2857                         if ( this.options.hoverClass ) {
2858                                 this.element.removeClass( this.options.hoverClass );
2859                         }
2860                         this._trigger( "drop", event, this.ui( draggable ) );
2861                         return this.element;
2862                 }
2863
2864                 return false;
2865
2866         },
2867
2868         ui: function( c ) {
2869                 return {
2870                         draggable: ( c.currentItem || c.element ),
2871                         helper: c.helper,
2872                         position: c.position,
2873                         offset: c.positionAbs
2874                 };
2875         }
2876
2877 });
2878
2879 $.ui.intersect = (function() {
2880         function isOverAxis( x, reference, size ) {
2881                 return ( x >= reference ) && ( x < ( reference + size ) );
2882         }
2883
2884         return function( draggable, droppable, toleranceMode, event ) {
2885
2886                 if ( !droppable.offset ) {
2887                         return false;
2888                 }
2889
2890                 var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left,
2891                         y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top,
2892                         x2 = x1 + draggable.helperProportions.width,
2893                         y2 = y1 + draggable.helperProportions.height,
2894                         l = droppable.offset.left,
2895                         t = droppable.offset.top,
2896                         r = l + droppable.proportions().width,
2897                         b = t + droppable.proportions().height;
2898
2899                 switch ( toleranceMode ) {
2900                 case "fit":
2901                         return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
2902                 case "intersect":
2903                         return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
2904                                 x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
2905                                 t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
2906                                 y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
2907                 case "pointer":
2908                         return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width );
2909                 case "touch":
2910                         return (
2911                                 ( y1 >= t && y1 <= b ) || // Top edge touching
2912                                 ( y2 >= t && y2 <= b ) || // Bottom edge touching
2913                                 ( y1 < t && y2 > b ) // Surrounded vertically
2914                         ) && (
2915                                 ( x1 >= l && x1 <= r ) || // Left edge touching
2916                                 ( x2 >= l && x2 <= r ) || // Right edge touching
2917                                 ( x1 < l && x2 > r ) // Surrounded horizontally
2918                         );
2919                 default:
2920                         return false;
2921                 }
2922         };
2923 })();
2924
2925 /*
2926         This manager tracks offsets of draggables and droppables
2927 */
2928 $.ui.ddmanager = {
2929         current: null,
2930         droppables: { "default": [] },
2931         prepareOffsets: function( t, event ) {
2932
2933                 var i, j,
2934                         m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
2935                         type = event ? event.type : null, // workaround for #2317
2936                         list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
2937
2938                 droppablesLoop: for ( i = 0; i < m.length; i++ ) {
2939
2940                         // No disabled and non-accepted
2941                         if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) {
2942                                 continue;
2943                         }
2944
2945                         // Filter out elements in the current dragged item
2946                         for ( j = 0; j < list.length; j++ ) {
2947                                 if ( list[ j ] === m[ i ].element[ 0 ] ) {
2948                                         m[ i ].proportions().height = 0;
2949                                         continue droppablesLoop;
2950                                 }
2951                         }
2952
2953                         m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
2954                         if ( !m[ i ].visible ) {
2955                                 continue;
2956                         }
2957
2958                         // Activate the droppable if used directly from draggables
2959                         if ( type === "mousedown" ) {
2960                                 m[ i ]._activate.call( m[ i ], event );
2961                         }
2962
2963                         m[ i ].offset = m[ i ].element.offset();
2964                         m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
2965
2966                 }
2967
2968         },
2969         drop: function( draggable, event ) {
2970
2971                 var dropped = false;
2972                 // Create a copy of the droppables in case the list changes during the drop (#9116)
2973                 $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
2974
2975                         if ( !this.options ) {
2976                                 return;
2977                         }
2978                         if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
2979                                 dropped = this._drop.call( this, event ) || dropped;
2980                         }
2981
2982                         if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2983                                 this.isout = true;
2984                                 this.isover = false;
2985                                 this._deactivate.call( this, event );
2986                         }
2987
2988                 });
2989                 return dropped;
2990
2991         },
2992         dragStart: function( draggable, event ) {
2993                 // Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2994                 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2995                         if ( !draggable.options.refreshPositions ) {
2996                                 $.ui.ddmanager.prepareOffsets( draggable, event );
2997                         }
2998                 });
2999         },
3000         drag: function( draggable, event ) {
3001
3002                 // If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
3003                 if ( draggable.options.refreshPositions ) {
3004                         $.ui.ddmanager.prepareOffsets( draggable, event );
3005                 }
3006
3007                 // Run through all droppables and check their positions based on specific tolerance options
3008                 $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
3009
3010                         if ( this.options.disabled || this.greedyChild || !this.visible ) {
3011                                 return;
3012                         }
3013
3014                         var parentInstance, scope, parent,
3015                                 intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
3016                                 c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null );
3017                         if ( !c ) {
3018                                 return;
3019                         }
3020
3021                         if ( this.options.greedy ) {
3022                                 // find droppable parents with same scope
3023                                 scope = this.options.scope;
3024                                 parent = this.element.parents( ":data(ui-droppable)" ).filter(function() {
3025                                         return $( this ).droppable( "instance" ).options.scope === scope;
3026                                 });
3027
3028                                 if ( parent.length ) {
3029                                         parentInstance = $( parent[ 0 ] ).droppable( "instance" );
3030                                         parentInstance.greedyChild = ( c === "isover" );
3031                                 }
3032                         }
3033
3034                         // we just moved into a greedy child
3035                         if ( parentInstance && c === "isover" ) {
3036                                 parentInstance.isover = false;
3037                                 parentInstance.isout = true;
3038                                 parentInstance._out.call( parentInstance, event );
3039                         }
3040
3041                         this[ c ] = true;
3042                         this[c === "isout" ? "isover" : "isout"] = false;
3043                         this[c === "isover" ? "_over" : "_out"].call( this, event );
3044
3045                         // we just moved out of a greedy child
3046                         if ( parentInstance && c === "isout" ) {
3047                                 parentInstance.isout = false;
3048                                 parentInstance.isover = true;
3049                                 parentInstance._over.call( parentInstance, event );
3050                         }
3051                 });
3052
3053         },
3054         dragStop: function( draggable, event ) {
3055                 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
3056                 // Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
3057                 if ( !draggable.options.refreshPositions ) {
3058                         $.ui.ddmanager.prepareOffsets( draggable, event );
3059                 }
3060         }
3061 };
3062
3063 var droppable = $.ui.droppable;
3064
3065
3066 /*!
3067  * jQuery UI Sortable 1.11.4
3068  * http://jqueryui.com
3069  *
3070  * Copyright jQuery Foundation and other contributors
3071  * Released under the MIT license.
3072  * http://jquery.org/license
3073  *
3074  * http://api.jqueryui.com/sortable/
3075  */
3076
3077
3078 var sortable = $.widget("ui.sortable", $.ui.mouse, {
3079         version: "1.11.4",
3080         widgetEventPrefix: "sort",
3081         ready: false,
3082         options: {
3083                 appendTo: "parent",
3084                 axis: false,
3085                 connectWith: false,
3086                 containment: false,
3087                 cursor: "auto",
3088                 cursorAt: false,
3089                 dropOnEmpty: true,
3090                 forcePlaceholderSize: false,
3091                 forceHelperSize: false,
3092                 grid: false,
3093                 handle: false,
3094                 helper: "original",
3095                 items: "> *",
3096                 opacity: false,
3097                 placeholder: false,
3098                 revert: false,
3099                 scroll: true,
3100                 scrollSensitivity: 20,
3101                 scrollSpeed: 20,
3102                 scope: "default",
3103                 tolerance: "intersect",
3104                 zIndex: 1000,
3105
3106                 // callbacks
3107                 activate: null,
3108                 beforeStop: null,
3109                 change: null,
3110                 deactivate: null,
3111                 out: null,
3112                 over: null,
3113                 receive: null,
3114                 remove: null,
3115                 sort: null,
3116                 start: null,
3117                 stop: null,
3118                 update: null
3119         },
3120
3121         _isOverAxis: function( x, reference, size ) {
3122                 return ( x >= reference ) && ( x < ( reference + size ) );
3123         },
3124
3125         _isFloating: function( item ) {
3126                 return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
3127         },
3128
3129         _create: function() {
3130                 this.containerCache = {};
3131                 this.element.addClass("ui-sortable");
3132
3133                 //Get the items
3134                 this.refresh();
3135
3136                 //Let's determine the parent's offset
3137                 this.offset = this.element.offset();
3138
3139                 //Initialize mouse events for interaction
3140                 this._mouseInit();
3141
3142                 this._setHandleClassName();
3143
3144                 //We're ready to go
3145                 this.ready = true;
3146
3147         },
3148
3149         _setOption: function( key, value ) {
3150                 this._super( key, value );
3151
3152                 if ( key === "handle" ) {
3153                         this._setHandleClassName();
3154                 }
3155         },
3156
3157         _setHandleClassName: function() {
3158                 this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" );
3159                 $.each( this.items, function() {
3160                         ( this.instance.options.handle ?
3161                                 this.item.find( this.instance.options.handle ) : this.item )
3162                                 .addClass( "ui-sortable-handle" );
3163                 });
3164         },
3165
3166         _destroy: function() {
3167                 this.element
3168                         .removeClass( "ui-sortable ui-sortable-disabled" )
3169                         .find( ".ui-sortable-handle" )
3170                                 .removeClass( "ui-sortable-handle" );
3171                 this._mouseDestroy();
3172
3173                 for ( var i = this.items.length - 1; i >= 0; i-- ) {
3174                         this.items[i].item.removeData(this.widgetName + "-item");
3175                 }
3176
3177                 return this;
3178         },
3179
3180         _mouseCapture: function(event, overrideHandle) {
3181                 var currentItem = null,
3182                         validHandle = false,
3183                         that = this;
3184
3185                 if (this.reverting) {
3186                         return false;
3187                 }
3188
3189                 if(this.options.disabled || this.options.type === "static") {
3190                         return false;
3191                 }
3192
3193                 //We have to refresh the items data once first
3194                 this._refreshItems(event);
3195
3196                 //Find out if the clicked node (or one of its parents) is a actual item in this.items
3197                 $(event.target).parents().each(function() {
3198                         if($.data(this, that.widgetName + "-item") === that) {
3199                                 currentItem = $(this);
3200                                 return false;
3201                         }
3202                 });
3203                 if($.data(event.target, that.widgetName + "-item") === that) {
3204                         currentItem = $(event.target);
3205                 }
3206
3207                 if(!currentItem) {
3208                         return false;
3209                 }
3210                 if(this.options.handle && !overrideHandle) {
3211                         $(this.options.handle, currentItem).find("*").addBack().each(function() {
3212                                 if(this === event.target) {
3213                                         validHandle = true;
3214                                 }
3215                         });
3216                         if(!validHandle) {
3217                                 return false;
3218                         }
3219                 }
3220
3221                 this.currentItem = currentItem;
3222                 this._removeCurrentsFromItems();
3223                 return true;
3224
3225         },
3226
3227         _mouseStart: function(event, overrideHandle, noActivation) {
3228
3229                 var i, body,
3230                         o = this.options;
3231
3232                 this.currentContainer = this;
3233
3234                 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
3235                 this.refreshPositions();
3236
3237                 //Create and append the visible helper
3238                 this.helper = this._createHelper(event);
3239
3240                 //Cache the helper size
3241                 this._cacheHelperProportions();
3242
3243                 /*
3244                  * - Position generation -
3245                  * This block generates everything position related - it's the core of draggables.
3246                  */
3247
3248                 //Cache the margins of the original element
3249                 this._cacheMargins();
3250
3251                 //Get the next scrolling parent
3252                 this.scrollParent = this.helper.scrollParent();
3253
3254                 //The element's absolute position on the page minus margins
3255                 this.offset = this.currentItem.offset();
3256                 this.offset = {
3257                         top: this.offset.top - this.margins.top,
3258                         left: this.offset.left - this.margins.left
3259                 };
3260
3261                 $.extend(this.offset, {
3262                         click: { //Where the click happened, relative to the element
3263                                 left: event.pageX - this.offset.left,
3264                                 top: event.pageY - this.offset.top
3265                         },
3266                         parent: this._getParentOffset(),
3267                         relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
3268                 });
3269
3270                 // Only after we got the offset, we can change the helper's position to absolute
3271                 // TODO: Still need to figure out a way to make relative sorting possible
3272                 this.helper.css("position", "absolute");
3273                 this.cssPosition = this.helper.css("position");
3274
3275                 //Generate the original position
3276                 this.originalPosition = this._generatePosition(event);
3277                 this.originalPageX = event.pageX;
3278                 this.originalPageY = event.pageY;
3279
3280                 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
3281                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
3282
3283                 //Cache the former DOM position
3284                 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
3285
3286                 //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
3287                 if(this.helper[0] !== this.currentItem[0]) {
3288                         this.currentItem.hide();
3289                 }
3290
3291                 //Create the placeholder
3292                 this._createPlaceholder();
3293
3294                 //Set a containment if given in the options
3295                 if(o.containment) {
3296                         this._setContainment();
3297                 }
3298
3299                 if( o.cursor && o.cursor !== "auto" ) { // cursor option
3300                         body = this.document.find( "body" );
3301
3302                         // support: IE
3303                         this.storedCursor = body.css( "cursor" );
3304                         body.css( "cursor", o.cursor );
3305
3306                         this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
3307                 }
3308
3309                 if(o.opacity) { // opacity option
3310                         if (this.helper.css("opacity")) {
3311                                 this._storedOpacity = this.helper.css("opacity");
3312                         }
3313                         this.helper.css("opacity", o.opacity);
3314                 }
3315
3316                 if(o.zIndex) { // zIndex option
3317                         if (this.helper.css("zIndex")) {
3318                                 this._storedZIndex = this.helper.css("zIndex");
3319                         }
3320                         this.helper.css("zIndex", o.zIndex);
3321                 }
3322
3323                 //Prepare scrolling
3324                 if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
3325                         this.overflowOffset = this.scrollParent.offset();
3326                 }
3327
3328                 //Call callbacks
3329                 this._trigger("start", event, this._uiHash());
3330
3331                 //Recache the helper size
3332                 if(!this._preserveHelperProportions) {
3333                         this._cacheHelperProportions();
3334                 }
3335
3336
3337                 //Post "activate" events to possible containers
3338                 if( !noActivation ) {
3339                         for ( i = this.containers.length - 1; i >= 0; i-- ) {
3340                                 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
3341                         }
3342                 }
3343
3344                 //Prepare possible droppables
3345                 if($.ui.ddmanager) {
3346                         $.ui.ddmanager.current = this;
3347                 }
3348
3349                 if ($.ui.ddmanager && !o.dropBehaviour) {
3350                         $.ui.ddmanager.prepareOffsets(this, event);
3351                 }
3352
3353                 this.dragging = true;
3354
3355                 this.helper.addClass("ui-sortable-helper");
3356                 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
3357                 return true;
3358
3359         },
3360
3361         _mouseDrag: function(event) {
3362                 var i, item, itemElement, intersection,
3363                         o = this.options,
3364                         scrolled = false;
3365
3366                 //Compute the helpers position
3367                 this.position = this._generatePosition(event);
3368                 this.positionAbs = this._convertPositionTo("absolute");
3369
3370                 if (!this.lastPositionAbs) {
3371                         this.lastPositionAbs = this.positionAbs;
3372                 }
3373
3374                 //Do scrolling
3375                 if(this.options.scroll) {
3376                         if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
3377
3378                                 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
3379                                         this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
3380                                 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
3381                                         this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
3382                                 }
3383
3384                                 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
3385                                         this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
3386                                 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
3387                                         this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
3388                                 }
3389
3390                         } else {
3391
3392                                 if(event.pageY - this.document.scrollTop() < o.scrollSensitivity) {
3393                                         scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed);
3394                                 } else if(this.window.height() - (event.pageY - this.document.scrollTop()) < o.scrollSensitivity) {
3395                                         scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed);
3396                                 }
3397
3398                                 if(event.pageX - this.document.scrollLeft() < o.scrollSensitivity) {
3399                                         scrolled = this.document.scrollLeft(this.document.scrollLeft() - o.scrollSpeed);
3400                                 } else if(this.window.width() - (event.pageX - this.document.scrollLeft()) < o.scrollSensitivity) {
3401                                         scrolled = this.document.scrollLeft(this.document.scrollLeft() + o.scrollSpeed);
3402                                 }
3403
3404                         }
3405
3406                         if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
3407                                 $.ui.ddmanager.prepareOffsets(this, event);
3408                         }
3409                 }
3410
3411                 //Regenerate the absolute position used for position checks
3412                 this.positionAbs = this._convertPositionTo("absolute");
3413
3414                 //Set the helper position
3415                 if(!this.options.axis || this.options.axis !== "y") {
3416                         this.helper[0].style.left = this.position.left+"px";
3417                 }
3418                 if(!this.options.axis || this.options.axis !== "x") {
3419                         this.helper[0].style.top = this.position.top+"px";
3420                 }
3421
3422                 //Rearrange
3423                 for (i = this.items.length - 1; i >= 0; i--) {
3424
3425                         //Cache variables and intersection, continue if no intersection
3426                         item = this.items[i];
3427                         itemElement = item.item[0];
3428                         intersection = this._intersectsWithPointer(item);
3429                         if (!intersection) {
3430                                 continue;
3431                         }
3432
3433                         // Only put the placeholder inside the current Container, skip all
3434                         // items from other containers. This works because when moving
3435                         // an item from one container to another the
3436                         // currentContainer is switched before the placeholder is moved.
3437                         //
3438                         // Without this, moving items in "sub-sortables" can cause
3439                         // the placeholder to jitter between the outer and inner container.
3440                         if (item.instance !== this.currentContainer) {
3441                                 continue;
3442                         }
3443
3444                         // cannot intersect with itself
3445                         // no useless actions that have been done before
3446                         // no action if the item moved is the parent of the item checked
3447                         if (itemElement !== this.currentItem[0] &&
3448                                 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
3449                                 !$.contains(this.placeholder[0], itemElement) &&
3450                                 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
3451                         ) {
3452
3453                                 this.direction = intersection === 1 ? "down" : "up";
3454
3455                                 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
3456                                         this._rearrange(event, item);
3457                                 } else {
3458                                         break;
3459                                 }
3460
3461                                 this._trigger("change", event, this._uiHash());
3462                                 break;
3463                         }
3464                 }
3465
3466                 //Post events to containers
3467                 this._contactContainers(event);
3468
3469                 //Interconnect with droppables
3470                 if($.ui.ddmanager) {
3471                         $.ui.ddmanager.drag(this, event);
3472                 }
3473
3474                 //Call callbacks
3475                 this._trigger("sort", event, this._uiHash());
3476
3477                 this.lastPositionAbs = this.positionAbs;
3478                 return false;
3479
3480         },
3481
3482         _mouseStop: function(event, noPropagation) {
3483
3484                 if(!event) {
3485                         return;
3486                 }
3487
3488                 //If we are using droppables, inform the manager about the drop
3489                 if ($.ui.ddmanager && !this.options.dropBehaviour) {
3490                         $.ui.ddmanager.drop(this, event);
3491                 }
3492
3493                 if(this.options.revert) {
3494                         var that = this,
3495                                 cur = this.placeholder.offset(),
3496                                 axis = this.options.axis,
3497                                 animation = {};
3498
3499                         if ( !axis || axis === "x" ) {
3500                                 animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollLeft);
3501                         }
3502                         if ( !axis || axis === "y" ) {
3503                                 animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollTop);
3504                         }
3505                         this.reverting = true;
3506                         $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
3507                                 that._clear(event);
3508                         });
3509                 } else {
3510                         this._clear(event, noPropagation);
3511                 }
3512
3513                 return false;
3514
3515         },
3516
3517         cancel: function() {
3518
3519                 if(this.dragging) {
3520
3521                         this._mouseUp({ target: null });
3522
3523                         if(this.options.helper === "original") {
3524                                 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3525                         } else {
3526                                 this.currentItem.show();
3527                         }
3528
3529                         //Post deactivating events to containers
3530                         for (var i = this.containers.length - 1; i >= 0; i--){
3531                                 this.containers[i]._trigger("deactivate", null, this._uiHash(this));
3532                                 if(this.containers[i].containerCache.over) {
3533                                         this.containers[i]._trigger("out", null, this._uiHash(this));
3534                                         this.containers[i].containerCache.over = 0;
3535                                 }
3536                         }
3537
3538                 }
3539
3540                 if (this.placeholder) {
3541                         //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
3542                         if(this.placeholder[0].parentNode) {
3543                                 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
3544                         }
3545                         if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
3546                                 this.helper.remove();
3547                         }
3548
3549                         $.extend(this, {
3550                                 helper: null,
3551                                 dragging: false,
3552                                 reverting: false,
3553                                 _noFinalSort: null
3554                         });
3555
3556                         if(this.domPosition.prev) {
3557                                 $(this.domPosition.prev).after(this.currentItem);
3558                         } else {
3559                                 $(this.domPosition.parent).prepend(this.currentItem);
3560                         }
3561                 }
3562
3563                 return this;
3564
3565         },
3566
3567         serialize: function(o) {
3568
3569                 var items = this._getItemsAsjQuery(o && o.connected),
3570                         str = [];
3571                 o = o || {};
3572
3573                 $(items).each(function() {
3574                         var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
3575                         if (res) {
3576                                 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
3577                         }
3578                 });
3579
3580                 if(!str.length && o.key) {
3581                         str.push(o.key + "=");
3582                 }
3583
3584                 return str.join("&");
3585
3586         },
3587
3588         toArray: function(o) {
3589
3590                 var items = this._getItemsAsjQuery(o && o.connected),
3591                         ret = [];
3592
3593                 o = o || {};
3594
3595                 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
3596                 return ret;
3597
3598         },
3599
3600         /* Be careful with the following core functions */
3601         _intersectsWith: function(item) {
3602
3603                 var x1 = this.positionAbs.left,
3604                         x2 = x1 + this.helperProportions.width,
3605                         y1 = this.positionAbs.top,
3606                         y2 = y1 + this.helperProportions.height,
3607                         l = item.left,
3608                         r = l + item.width,
3609                         t = item.top,
3610                         b = t + item.height,
3611                         dyClick = this.offset.click.top,
3612                         dxClick = this.offset.click.left,
3613                         isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
3614                         isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
3615                         isOverElement = isOverElementHeight && isOverElementWidth;
3616
3617                 if ( this.options.tolerance === "pointer" ||
3618                         this.options.forcePointerForContainers ||
3619                         (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
3620                 ) {
3621                         return isOverElement;
3622                 } else {
3623
3624                         return (l < x1 + (this.helperProportions.width / 2) && // Right Half
3625                                 x2 - (this.helperProportions.width / 2) < r && // Left Half
3626                                 t < y1 + (this.helperProportions.height / 2) && // Bottom Half
3627                                 y2 - (this.helperProportions.height / 2) < b ); // Top Half
3628
3629                 }
3630         },
3631
3632         _intersectsWithPointer: function(item) {
3633
3634                 var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
3635                         isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
3636                         isOverElement = isOverElementHeight && isOverElementWidth,
3637                         verticalDirection = this._getDragVerticalDirection(),
3638                         horizontalDirection = this._getDragHorizontalDirection();
3639
3640                 if (!isOverElement) {
3641                         return false;
3642                 }
3643
3644                 return this.floating ?
3645                         ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
3646                         : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
3647
3648         },
3649
3650         _intersectsWithSides: function(item) {
3651
3652                 var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
3653                         isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
3654                         verticalDirection = this._getDragVerticalDirection(),
3655                         horizontalDirection = this._getDragHorizontalDirection();
3656
3657                 if (this.floating && horizontalDirection) {
3658                         return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
3659                 } else {
3660                         return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
3661                 }
3662
3663         },
3664
3665         _getDragVerticalDirection: function() {
3666                 var delta = this.positionAbs.top - this.lastPositionAbs.top;
3667                 return delta !== 0 && (delta > 0 ? "down" : "up");
3668         },
3669
3670         _getDragHorizontalDirection: function() {
3671                 var delta = this.positionAbs.left - this.lastPositionAbs.left;
3672                 return delta !== 0 && (delta > 0 ? "right" : "left");
3673         },
3674
3675         refresh: function(event) {
3676                 this._refreshItems(event);
3677                 this._setHandleClassName();
3678                 this.refreshPositions();
3679                 return this;
3680         },
3681
3682         _connectWith: function() {
3683                 var options = this.options;
3684                 return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
3685         },
3686
3687         _getItemsAsjQuery: function(connected) {
3688
3689                 var i, j, cur, inst,
3690                         items = [],
3691                         queries = [],
3692                         connectWith = this._connectWith();
3693
3694                 if(connectWith && connected) {
3695                         for (i = connectWith.length - 1; i >= 0; i--){
3696                                 cur = $(connectWith[i], this.document[0]);
3697                                 for ( j = cur.length - 1; j >= 0; j--){
3698                                         inst = $.data(cur[j], this.widgetFullName);
3699                                         if(inst && inst !== this && !inst.options.disabled) {
3700                                                 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]);
3701                                         }
3702                                 }
3703                         }
3704                 }
3705
3706                 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]);
3707
3708                 function addItems() {
3709                         items.push( this );
3710                 }
3711                 for (i = queries.length - 1; i >= 0; i--){
3712                         queries[i][0].each( addItems );
3713                 }
3714
3715                 return $(items);
3716
3717         },
3718
3719         _removeCurrentsFromItems: function() {
3720
3721                 var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
3722
3723                 this.items = $.grep(this.items, function (item) {
3724                         for (var j=0; j < list.length; j++) {
3725                                 if(list[j] === item.item[0]) {
3726                                         return false;
3727                                 }
3728                         }
3729                         return true;
3730                 });
3731
3732         },
3733
3734         _refreshItems: function(event) {
3735
3736                 this.items = [];
3737                 this.containers = [this];
3738
3739                 var i, j, cur, inst, targetData, _queries, item, queriesLength,
3740                         items = this.items,
3741                         queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
3742                         connectWith = this._connectWith();
3743
3744                 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
3745                         for (i = connectWith.length - 1; i >= 0; i--){
3746                                 cur = $(connectWith[i], this.document[0]);
3747                                 for (j = cur.length - 1; j >= 0; j--){
3748                                         inst = $.data(cur[j], this.widgetFullName);
3749                                         if(inst && inst !== this && !inst.options.disabled) {
3750                                                 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
3751                                                 this.containers.push(inst);
3752                                         }
3753                                 }
3754                         }
3755                 }
3756
3757                 for (i = queries.length - 1; i >= 0; i--) {
3758                         targetData = queries[i][1];
3759                         _queries = queries[i][0];
3760
3761                         for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
3762                                 item = $(_queries[j]);
3763
3764                                 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
3765
3766                                 items.push({
3767                                         item: item,
3768                                         instance: targetData,
3769                                         width: 0, height: 0,
3770                                         left: 0, top: 0
3771                                 });
3772                         }
3773                 }
3774
3775         },
3776
3777         refreshPositions: function(fast) {
3778
3779                 // Determine whether items are being displayed horizontally
3780                 this.floating = this.items.length ?
3781                         this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
3782                         false;
3783
3784                 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
3785                 if(this.offsetParent && this.helper) {
3786                         this.offset.parent = this._getParentOffset();
3787                 }
3788
3789                 var i, item, t, p;
3790
3791                 for (i = this.items.length - 1; i >= 0; i--){
3792                         item = this.items[i];
3793
3794                         //We ignore calculating positions of all connected containers when we're not over them
3795                         if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
3796                                 continue;
3797                         }
3798
3799                         t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
3800
3801                         if (!fast) {
3802                                 item.width = t.outerWidth();
3803                                 item.height = t.outerHeight();
3804                         }
3805
3806                         p = t.offset();
3807                         item.left = p.left;
3808                         item.top = p.top;
3809                 }
3810
3811                 if(this.options.custom && this.options.custom.refreshContainers) {
3812                         this.options.custom.refreshContainers.call(this);
3813                 } else {
3814                         for (i = this.containers.length - 1; i >= 0; i--){
3815                                 p = this.containers[i].element.offset();
3816                                 this.containers[i].containerCache.left = p.left;
3817                                 this.containers[i].containerCache.top = p.top;
3818                                 this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
3819                                 this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
3820                         }
3821                 }
3822
3823                 return this;
3824         },
3825
3826         _createPlaceholder: function(that) {
3827                 that = that || this;
3828                 var className,
3829                         o = that.options;
3830
3831                 if(!o.placeholder || o.placeholder.constructor === String) {
3832                         className = o.placeholder;
3833                         o.placeholder = {
3834                                 element: function() {
3835
3836                                         var nodeName = that.currentItem[0].nodeName.toLowerCase(),
3837                                                 element = $( "<" + nodeName + ">", that.document[0] )
3838                                                         .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
3839                                                         .removeClass("ui-sortable-helper");
3840
3841                                         if ( nodeName === "tbody" ) {
3842                                                 that._createTrPlaceholder(
3843                                                         that.currentItem.find( "tr" ).eq( 0 ),
3844                                                         $( "<tr>", that.document[ 0 ] ).appendTo( element )
3845                                                 );
3846                                         } else if ( nodeName === "tr" ) {
3847                                                 that._createTrPlaceholder( that.currentItem, element );
3848                                         } else if ( nodeName === "img" ) {
3849                                                 element.attr( "src", that.currentItem.attr( "src" ) );
3850                                         }
3851
3852                                         if ( !className ) {
3853                                                 element.css( "visibility", "hidden" );
3854                                         }
3855
3856                                         return element;
3857                                 },
3858                                 update: function(container, p) {
3859
3860                                         // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
3861                                         // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
3862                                         if(className && !o.forcePlaceholderSize) {
3863                                                 return;
3864                                         }
3865
3866                                         //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
3867                                         if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
3868                                         if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
3869                                 }
3870                         };
3871                 }
3872
3873                 //Create the placeholder
3874                 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
3875
3876                 //Append it after the actual current item
3877                 that.currentItem.after(that.placeholder);
3878
3879                 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
3880                 o.placeholder.update(that, that.placeholder);
3881
3882         },
3883
3884         _createTrPlaceholder: function( sourceTr, targetTr ) {
3885                 var that = this;
3886
3887                 sourceTr.children().each(function() {
3888                         $( "<td>&#160;</td>", that.document[ 0 ] )
3889                                 .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
3890                                 .appendTo( targetTr );
3891                 });
3892         },
3893
3894         _contactContainers: function(event) {
3895                 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis,
3896                         innermostContainer = null,
3897                         innermostIndex = null;
3898
3899                 // get innermost container that intersects with item
3900                 for (i = this.containers.length - 1; i >= 0; i--) {
3901
3902                         // never consider a container that's located within the item itself
3903                         if($.contains(this.currentItem[0], this.containers[i].element[0])) {
3904                                 continue;
3905                         }
3906
3907                         if(this._intersectsWith(this.containers[i].containerCache)) {
3908
3909                                 // if we've already found a container and it's more "inner" than this, then continue
3910                                 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
3911                                         continue;
3912                                 }
3913
3914                                 innermostContainer = this.containers[i];
3915                                 innermostIndex = i;
3916
3917                         } else {
3918                                 // container doesn't intersect. trigger "out" event if necessary
3919                                 if(this.containers[i].containerCache.over) {
3920                                         this.containers[i]._trigger("out", event, this._uiHash(this));
3921                                         this.containers[i].containerCache.over = 0;
3922                                 }
3923                         }
3924
3925                 }
3926
3927                 // if no intersecting containers found, return
3928                 if(!innermostContainer) {
3929                         return;
3930                 }
3931
3932                 // move the item into the container if it's not there already
3933                 if(this.containers.length === 1) {
3934                         if (!this.containers[innermostIndex].containerCache.over) {
3935                                 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
3936                                 this.containers[innermostIndex].containerCache.over = 1;
3937                         }
3938                 } else {
3939
3940                         //When entering a new container, we will find the item with the least distance and append our item near it
3941                         dist = 10000;
3942                         itemWithLeastDistance = null;
3943                         floating = innermostContainer.floating || this._isFloating(this.currentItem);
3944                         posProperty = floating ? "left" : "top";
3945                         sizeProperty = floating ? "width" : "height";
3946                         axis = floating ? "clientX" : "clientY";
3947
3948                         for (j = this.items.length - 1; j >= 0; j--) {
3949                                 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
3950                                         continue;
3951                                 }
3952                                 if(this.items[j].item[0] === this.currentItem[0]) {
3953                                         continue;
3954                                 }
3955
3956                                 cur = this.items[j].item.offset()[posProperty];
3957                                 nearBottom = false;
3958                                 if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
3959                                         nearBottom = true;
3960                                 }
3961
3962                                 if ( Math.abs( event[ axis ] - cur ) < dist ) {
3963                                         dist = Math.abs( event[ axis ] - cur );
3964                                         itemWithLeastDistance = this.items[ j ];
3965                                         this.direction = nearBottom ? "up": "down";
3966                                 }
3967                         }
3968
3969                         //Check if dropOnEmpty is enabled
3970                         if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
3971                                 return;
3972                         }
3973
3974                         if(this.currentContainer === this.containers[innermostIndex]) {
3975                                 if ( !this.currentContainer.containerCache.over ) {
3976                                         this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
3977                                         this.currentContainer.containerCache.over = 1;
3978                                 }
3979                                 return;
3980                         }
3981
3982                         itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
3983                         this._trigger("change", event, this._uiHash());
3984                         this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
3985                         this.currentContainer = this.containers[innermostIndex];
3986
3987                         //Update the placeholder
3988                         this.options.placeholder.update(this.currentContainer, this.placeholder);
3989
3990                         this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
3991                         this.containers[innermostIndex].containerCache.over = 1;
3992                 }
3993
3994
3995         },
3996
3997         _createHelper: function(event) {
3998
3999                 var o = this.options,
4000                         helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
4001
4002                 //Add the helper to the DOM if that didn't happen already
4003                 if(!helper.parents("body").length) {
4004                         $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
4005                 }
4006
4007                 if(helper[0] === this.currentItem[0]) {
4008                         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") };
4009                 }
4010
4011                 if(!helper[0].style.width || o.forceHelperSize) {
4012                         helper.width(this.currentItem.width());
4013                 }
4014                 if(!helper[0].style.height || o.forceHelperSize) {
4015                         helper.height(this.currentItem.height());
4016                 }
4017
4018                 return helper;
4019
4020         },
4021
4022         _adjustOffsetFromHelper: function(obj) {
4023                 if (typeof obj === "string") {
4024                         obj = obj.split(" ");
4025                 }
4026                 if ($.isArray(obj)) {
4027                         obj = {left: +obj[0], top: +obj[1] || 0};
4028                 }
4029                 if ("left" in obj) {
4030                         this.offset.click.left = obj.left + this.margins.left;
4031                 }
4032                 if ("right" in obj) {
4033                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
4034                 }
4035                 if ("top" in obj) {
4036                         this.offset.click.top = obj.top + this.margins.top;
4037                 }
4038                 if ("bottom" in obj) {
4039                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
4040                 }
4041         },
4042
4043         _getParentOffset: function() {
4044
4045
4046                 //Get the offsetParent and cache its position
4047                 this.offsetParent = this.helper.offsetParent();
4048                 var po = this.offsetParent.offset();
4049
4050                 // This is a special case where we need to modify a offset calculated on start, since the following happened:
4051                 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
4052                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
4053                 //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
4054                 if(this.cssPosition === "absolute" && this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) {
4055                         po.left += this.scrollParent.scrollLeft();
4056                         po.top += this.scrollParent.scrollTop();
4057                 }
4058
4059                 // This needs to be actually done for all browsers, since pageX/pageY includes this information
4060                 // with an ugly IE fix
4061                 if( this.offsetParent[0] === this.document[0].body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
4062                         po = { top: 0, left: 0 };
4063                 }
4064
4065                 return {
4066                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
4067                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
4068                 };
4069
4070         },
4071
4072         _getRelativeOffset: function() {
4073
4074                 if(this.cssPosition === "relative") {
4075                         var p = this.currentItem.position();
4076                         return {
4077                                 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
4078                                 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
4079                         };
4080                 } else {
4081                         return { top: 0, left: 0 };
4082                 }
4083
4084         },
4085
4086         _cacheMargins: function() {
4087                 this.margins = {
4088                         left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
4089                         top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
4090                 };
4091         },
4092
4093         _cacheHelperProportions: function() {
4094                 this.helperProportions = {
4095                         width: this.helper.outerWidth(),
4096                         height: this.helper.outerHeight()
4097                 };
4098         },
4099
4100         _setContainment: function() {
4101
4102                 var ce, co, over,
4103                         o = this.options;
4104                 if(o.containment === "parent") {
4105                         o.containment = this.helper[0].parentNode;
4106                 }
4107                 if(o.containment === "document" || o.containment === "window") {
4108                         this.containment = [
4109                                 0 - this.offset.relative.left - this.offset.parent.left,
4110                                 0 - this.offset.relative.top - this.offset.parent.top,
4111                                 o.containment === "document" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left,
4112                                 (o.containment === "document" ? this.document.width() : this.window.height() || this.document[0].body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
4113                         ];
4114                 }
4115
4116                 if(!(/^(document|window|parent)$/).test(o.containment)) {
4117                         ce = $(o.containment)[0];
4118                         co = $(o.containment).offset();
4119                         over = ($(ce).css("overflow") !== "hidden");
4120
4121                         this.containment = [
4122                                 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
4123                                 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
4124                                 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,
4125                                 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
4126                         ];
4127                 }
4128
4129         },
4130
4131         _convertPositionTo: function(d, pos) {
4132
4133                 if(!pos) {
4134                         pos = this.position;
4135                 }
4136                 var mod = d === "absolute" ? 1 : -1,
4137                         scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
4138                         scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
4139
4140                 return {
4141                         top: (
4142                                 pos.top +                                                                                                                               // The absolute mouse position
4143                                 this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
4144                                 this.offset.parent.top * mod -                                                                                  // The offsetParent's offset without borders (offset + border)
4145                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
4146                         ),
4147                         left: (
4148                                 pos.left +                                                                                                                              // The absolute mouse position
4149                                 this.offset.relative.left * mod +                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
4150                                 this.offset.parent.left * mod   -                                                                               // The offsetParent's offset without borders (offset + border)
4151                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
4152                         )
4153                 };
4154
4155         },
4156
4157         _generatePosition: function(event) {
4158
4159                 var top, left,
4160                         o = this.options,
4161                         pageX = event.pageX,
4162                         pageY = event.pageY,
4163                         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);
4164
4165                 // This is another very weird special case that only happens for relative elements:
4166                 // 1. If the css position is relative
4167                 // 2. and the scroll parent is the document or similar to the offset parent
4168                 // we have to refresh the relative offset during the scroll so there are no jumps
4169                 if(this.cssPosition === "relative" && !(this.scrollParent[0] !== this.document[0] && this.scrollParent[0] !== this.offsetParent[0])) {
4170                         this.offset.relative = this._getRelativeOffset();
4171                 }
4172
4173                 /*
4174                  * - Position constraining -
4175                  * Constrain the position to a mix of grid, containment.
4176                  */
4177
4178                 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
4179
4180                         if(this.containment) {
4181                                 if(event.pageX - this.offset.click.left < this.containment[0]) {
4182                                         pageX = this.containment[0] + this.offset.click.left;
4183                                 }
4184                                 if(event.pageY - this.offset.click.top < this.containment[1]) {
4185                                         pageY = this.containment[1] + this.offset.click.top;
4186                                 }
4187                                 if(event.pageX - this.offset.click.left > this.containment[2]) {
4188                                         pageX = this.containment[2] + this.offset.click.left;
4189                                 }
4190                                 if(event.pageY - this.offset.click.top > this.containment[3]) {
4191                                         pageY = this.containment[3] + this.offset.click.top;
4192                                 }
4193                         }
4194
4195                         if(o.grid) {
4196                                 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
4197                                 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;
4198
4199                                 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
4200                                 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;
4201                         }
4202
4203                 }
4204
4205                 return {
4206                         top: (
4207                                 pageY -                                                                                                                         // The absolute mouse position
4208                                 this.offset.click.top -                                                                                                 // Click offset (relative to the element)
4209                                 this.offset.relative.top        -                                                                                       // Only for relative positioned nodes: Relative offset from element to offset parent
4210                                 this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
4211                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
4212                         ),
4213                         left: (
4214                                 pageX -                                                                                                                         // The absolute mouse position
4215                                 this.offset.click.left -                                                                                                // Click offset (relative to the element)
4216                                 this.offset.relative.left       -                                                                                       // Only for relative positioned nodes: Relative offset from element to offset parent
4217                                 this.offset.parent.left +                                                                                               // The offsetParent's offset without borders (offset + border)
4218                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
4219                         )
4220                 };
4221
4222         },
4223
4224         _rearrange: function(event, i, a, hardRefresh) {
4225
4226                 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));
4227
4228                 //Various things done here to improve the performance:
4229                 // 1. we create a setTimeout, that calls refreshPositions
4230                 // 2. on the instance, we have a counter variable, that get's higher after every append
4231                 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
4232                 // 4. this lets only the last addition to the timeout stack through
4233                 this.counter = this.counter ? ++this.counter : 1;
4234                 var counter = this.counter;
4235
4236                 this._delay(function() {
4237                         if(counter === this.counter) {
4238                                 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
4239                         }
4240                 });
4241
4242         },
4243
4244         _clear: function(event, noPropagation) {
4245
4246                 this.reverting = false;
4247                 // We delay all events that have to be triggered to after the point where the placeholder has been removed and
4248                 // everything else normalized again
4249                 var i,
4250                         delayedTriggers = [];
4251
4252                 // We first have to update the dom position of the actual currentItem
4253                 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
4254                 if(!this._noFinalSort && this.currentItem.parent().length) {
4255                         this.placeholder.before(this.currentItem);
4256                 }
4257                 this._noFinalSort = null;
4258
4259                 if(this.helper[0] === this.currentItem[0]) {
4260                         for(i in this._storedCSS) {
4261                                 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
4262                                         this._storedCSS[i] = "";
4263                                 }
4264                         }
4265                         this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4266                 } else {
4267                         this.currentItem.show();
4268                 }
4269
4270                 if(this.fromOutside && !noPropagation) {
4271                         delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
4272                 }
4273                 if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
4274                         delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
4275                 }
4276
4277                 // Check if the items Container has Changed and trigger appropriate
4278                 // events.
4279                 if (this !== this.currentContainer) {
4280                         if(!noPropagation) {
4281                                 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
4282                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
4283                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
4284                         }
4285                 }
4286
4287
4288                 //Post events to containers
4289                 function delayEvent( type, instance, container ) {
4290                         return function( event ) {
4291                                 container._trigger( type, event, instance._uiHash( instance ) );
4292                         };
4293                 }
4294                 for (i = this.containers.length - 1; i >= 0; i--){
4295                         if (!noPropagation) {
4296                                 delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
4297                         }
4298                         if(this.containers[i].containerCache.over) {
4299                                 delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
4300                                 this.containers[i].containerCache.over = 0;
4301                         }
4302                 }
4303
4304                 //Do what was originally in plugins
4305                 if ( this.storedCursor ) {
4306                         this.document.find( "body" ).css( "cursor", this.storedCursor );
4307                         this.storedStylesheet.remove();
4308                 }
4309                 if(this._storedOpacity) {
4310                         this.helper.css("opacity", this._storedOpacity);
4311                 }
4312                 if(this._storedZIndex) {
4313                         this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
4314                 }
4315
4316                 this.dragging = false;
4317
4318                 if(!noPropagation) {
4319                         this._trigger("beforeStop", event, this._uiHash());
4320                 }
4321
4322                 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4323                 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4324
4325                 if ( !this.cancelHelperRemoval ) {
4326                         if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
4327                                 this.helper.remove();
4328                         }
4329                         this.helper = null;
4330                 }
4331
4332                 if(!noPropagation) {
4333                         for (i=0; i < delayedTriggers.length; i++) {
4334                                 delayedTriggers[i].call(this, event);
4335                         } //Trigger all delayed events
4336                         this._trigger("stop", event, this._uiHash());
4337                 }
4338
4339                 this.fromOutside = false;
4340                 return !this.cancelHelperRemoval;
4341
4342         },
4343
4344         _trigger: function() {
4345                 if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
4346                         this.cancel();
4347                 }
4348         },
4349
4350         _uiHash: function(_inst) {
4351                 var inst = _inst || this;
4352                 return {
4353                         helper: inst.helper,
4354                         placeholder: inst.placeholder || $([]),
4355                         position: inst.position,
4356                         originalPosition: inst.originalPosition,
4357                         offset: inst.positionAbs,
4358                         item: inst.currentItem,
4359                         sender: _inst ? _inst.element : null
4360                 };
4361         }
4362
4363 });
4364
4365
4366 /*!
4367  * jQuery UI Accordion 1.11.4
4368  * http://jqueryui.com
4369  *
4370  * Copyright jQuery Foundation and other contributors
4371  * Released under the MIT license.
4372  * http://jquery.org/license
4373  *
4374  * http://api.jqueryui.com/accordion/
4375  */
4376
4377
4378 var accordion = $.widget( "ui.accordion", {
4379         version: "1.11.4",
4380         options: {
4381                 active: 0,
4382                 animate: {},
4383                 collapsible: false,
4384                 event: "click",
4385                 header: "> li > :first-child,> :not(li):even",
4386                 heightStyle: "auto",
4387                 icons: {
4388                         activeHeader: "ui-icon-triangle-1-s",
4389                         header: "ui-icon-triangle-1-e"
4390                 },
4391
4392                 // callbacks
4393                 activate: null,
4394                 beforeActivate: null
4395         },
4396
4397         hideProps: {
4398                 borderTopWidth: "hide",
4399                 borderBottomWidth: "hide",
4400                 paddingTop: "hide",
4401                 paddingBottom: "hide",
4402                 height: "hide"
4403         },
4404
4405         showProps: {
4406                 borderTopWidth: "show",
4407                 borderBottomWidth: "show",
4408                 paddingTop: "show",
4409                 paddingBottom: "show",
4410                 height: "show"
4411         },
4412
4413         _create: function() {
4414                 var options = this.options;
4415                 this.prevShow = this.prevHide = $();
4416                 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
4417                         // ARIA
4418                         .attr( "role", "tablist" );
4419
4420                 // don't allow collapsible: false and active: false / null
4421                 if ( !options.collapsible && (options.active === false || options.active == null) ) {
4422                         options.active = 0;
4423                 }
4424
4425                 this._processPanels();
4426                 // handle negative values
4427                 if ( options.active < 0 ) {
4428                         options.active += this.headers.length;
4429                 }
4430                 this._refresh();
4431         },
4432
4433         _getCreateEventData: function() {
4434                 return {
4435                         header: this.active,
4436                         panel: !this.active.length ? $() : this.active.next()
4437                 };
4438         },
4439
4440         _createIcons: function() {
4441                 var icons = this.options.icons;
4442                 if ( icons ) {
4443                         $( "<span>" )
4444                                 .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
4445                                 .prependTo( this.headers );
4446                         this.active.children( ".ui-accordion-header-icon" )
4447                                 .removeClass( icons.header )
4448                                 .addClass( icons.activeHeader );
4449                         this.headers.addClass( "ui-accordion-icons" );
4450                 }
4451         },
4452
4453         _destroyIcons: function() {
4454                 this.headers
4455                         .removeClass( "ui-accordion-icons" )
4456                         .children( ".ui-accordion-header-icon" )
4457                                 .remove();
4458         },
4459
4460         _destroy: function() {
4461                 var contents;
4462
4463                 // clean up main element
4464                 this.element
4465                         .removeClass( "ui-accordion ui-widget ui-helper-reset" )
4466                         .removeAttr( "role" );
4467
4468                 // clean up headers
4469                 this.headers
4470                         .removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " +
4471                                 "ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
4472                         .removeAttr( "role" )
4473                         .removeAttr( "aria-expanded" )
4474                         .removeAttr( "aria-selected" )
4475                         .removeAttr( "aria-controls" )
4476                         .removeAttr( "tabIndex" )
4477                         .removeUniqueId();
4478
4479                 this._destroyIcons();
4480
4481                 // clean up content panels
4482                 contents = this.headers.next()
4483                         .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " +
4484                                 "ui-accordion-content ui-accordion-content-active ui-state-disabled" )
4485                         .css( "display", "" )
4486                         .removeAttr( "role" )
4487                         .removeAttr( "aria-hidden" )
4488                         .removeAttr( "aria-labelledby" )
4489                         .removeUniqueId();
4490
4491                 if ( this.options.heightStyle !== "content" ) {
4492                         contents.css( "height", "" );
4493                 }
4494         },
4495
4496         _setOption: function( key, value ) {
4497                 if ( key === "active" ) {
4498                         // _activate() will handle invalid values and update this.options
4499                         this._activate( value );
4500                         return;
4501                 }
4502
4503                 if ( key === "event" ) {
4504                         if ( this.options.event ) {
4505                                 this._off( this.headers, this.options.event );
4506                         }
4507                         this._setupEvents( value );
4508                 }
4509
4510                 this._super( key, value );
4511
4512                 // setting collapsible: false while collapsed; open first panel
4513                 if ( key === "collapsible" && !value && this.options.active === false ) {
4514                         this._activate( 0 );
4515                 }
4516
4517                 if ( key === "icons" ) {
4518                         this._destroyIcons();
4519                         if ( value ) {
4520                                 this._createIcons();
4521                         }
4522                 }
4523
4524                 // #5332 - opacity doesn't cascade to positioned elements in IE
4525                 // so we need to add the disabled class to the headers and panels
4526                 if ( key === "disabled" ) {
4527                         this.element
4528                                 .toggleClass( "ui-state-disabled", !!value )
4529                                 .attr( "aria-disabled", value );
4530                         this.headers.add( this.headers.next() )
4531                                 .toggleClass( "ui-state-disabled", !!value );
4532                 }
4533         },
4534
4535         _keydown: function( event ) {
4536                 if ( event.altKey || event.ctrlKey ) {
4537                         return;
4538                 }
4539
4540                 var keyCode = $.ui.keyCode,
4541                         length = this.headers.length,
4542                         currentIndex = this.headers.index( event.target ),
4543                         toFocus = false;
4544
4545                 switch ( event.keyCode ) {
4546                         case keyCode.RIGHT:
4547                         case keyCode.DOWN:
4548                                 toFocus = this.headers[ ( currentIndex + 1 ) % length ];
4549                                 break;
4550                         case keyCode.LEFT:
4551                         case keyCode.UP:
4552                                 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
4553                                 break;
4554                         case keyCode.SPACE:
4555                         case keyCode.ENTER:
4556                                 this._eventHandler( event );
4557                                 break;
4558                         case keyCode.HOME:
4559                                 toFocus = this.headers[ 0 ];
4560                                 break;
4561                         case keyCode.END:
4562                                 toFocus = this.headers[ length - 1 ];
4563                                 break;
4564                 }
4565
4566                 if ( toFocus ) {
4567                         $( event.target ).attr( "tabIndex", -1 );
4568                         $( toFocus ).attr( "tabIndex", 0 );
4569                         toFocus.focus();
4570                         event.preventDefault();
4571                 }
4572         },
4573
4574         _panelKeyDown: function( event ) {
4575                 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
4576                         $( event.currentTarget ).prev().focus();
4577                 }
4578         },
4579
4580         refresh: function() {
4581                 var options = this.options;
4582                 this._processPanels();
4583
4584                 // was collapsed or no panel
4585                 if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
4586                         options.active = false;
4587                         this.active = $();
4588                 // active false only when collapsible is true
4589                 } else if ( options.active === false ) {
4590                         this._activate( 0 );
4591                 // was active, but active panel is gone
4592                 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
4593                         // all remaining panel are disabled
4594                         if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
4595                                 options.active = false;
4596                                 this.active = $();
4597                         // activate previous panel
4598                         } else {
4599                                 this._activate( Math.max( 0, options.active - 1 ) );
4600                         }
4601                 // was active, active panel still exists
4602                 } else {
4603                         // make sure active index is correct
4604                         options.active = this.headers.index( this.active );
4605                 }
4606
4607                 this._destroyIcons();
4608
4609                 this._refresh();
4610         },
4611
4612         _processPanels: function() {
4613                 var prevHeaders = this.headers,
4614                         prevPanels = this.panels;
4615
4616                 this.headers = this.element.find( this.options.header )
4617                         .addClass( "ui-accordion-header ui-state-default ui-corner-all" );
4618
4619                 this.panels = this.headers.next()
4620                         .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
4621                         .filter( ":not(.ui-accordion-content-active)" )
4622                         .hide();
4623
4624                 // Avoid memory leaks (#10056)
4625                 if ( prevPanels ) {
4626                         this._off( prevHeaders.not( this.headers ) );
4627                         this._off( prevPanels.not( this.panels ) );
4628                 }
4629         },
4630
4631         _refresh: function() {
4632                 var maxHeight,
4633                         options = this.options,
4634                         heightStyle = options.heightStyle,
4635                         parent = this.element.parent();
4636
4637                 this.active = this._findActive( options.active )
4638                         .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
4639                         .removeClass( "ui-corner-all" );
4640                 this.active.next()
4641                         .addClass( "ui-accordion-content-active" )
4642                         .show();
4643
4644                 this.headers
4645                         .attr( "role", "tab" )
4646                         .each(function() {
4647                                 var header = $( this ),
4648                                         headerId = header.uniqueId().attr( "id" ),
4649                                         panel = header.next(),
4650                                         panelId = panel.uniqueId().attr( "id" );
4651                                 header.attr( "aria-controls", panelId );
4652                                 panel.attr( "aria-labelledby", headerId );
4653                         })
4654                         .next()
4655                                 .attr( "role", "tabpanel" );
4656
4657                 this.headers
4658                         .not( this.active )
4659                         .attr({
4660                                 "aria-selected": "false",
4661                                 "aria-expanded": "false",
4662                                 tabIndex: -1
4663                         })
4664                         .next()
4665                                 .attr({
4666                                         "aria-hidden": "true"
4667                                 })
4668                                 .hide();
4669
4670                 // make sure at least one header is in the tab order
4671                 if ( !this.active.length ) {
4672                         this.headers.eq( 0 ).attr( "tabIndex", 0 );
4673                 } else {
4674                         this.active.attr({
4675                                 "aria-selected": "true",
4676                                 "aria-expanded": "true",
4677                                 tabIndex: 0
4678                         })
4679                         .next()
4680                                 .attr({
4681                                         "aria-hidden": "false"
4682                                 });
4683                 }
4684
4685                 this._createIcons();
4686
4687                 this._setupEvents( options.event );
4688
4689                 if ( heightStyle === "fill" ) {
4690                         maxHeight = parent.height();
4691                         this.element.siblings( ":visible" ).each(function() {
4692                                 var elem = $( this ),
4693                                         position = elem.css( "position" );
4694
4695                                 if ( position === "absolute" || position === "fixed" ) {
4696                                         return;
4697                                 }
4698                                 maxHeight -= elem.outerHeight( true );
4699                         });
4700
4701                         this.headers.each(function() {
4702                                 maxHeight -= $( this ).outerHeight( true );
4703                         });
4704
4705                         this.headers.next()
4706                                 .each(function() {
4707                                         $( this ).height( Math.max( 0, maxHeight -
4708                                                 $( this ).innerHeight() + $( this ).height() ) );
4709                                 })
4710                                 .css( "overflow", "auto" );
4711                 } else if ( heightStyle === "auto" ) {
4712                         maxHeight = 0;
4713                         this.headers.next()
4714                                 .each(function() {
4715                                         maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
4716                                 })
4717                                 .height( maxHeight );
4718                 }
4719         },
4720
4721         _activate: function( index ) {
4722                 var active = this._findActive( index )[ 0 ];
4723
4724                 // trying to activate the already active panel
4725                 if ( active === this.active[ 0 ] ) {
4726                         return;
4727                 }
4728
4729                 // trying to collapse, simulate a click on the currently active header
4730                 active = active || this.active[ 0 ];
4731
4732                 this._eventHandler({
4733                         target: active,
4734                         currentTarget: active,
4735                         preventDefault: $.noop
4736                 });
4737         },
4738
4739         _findActive: function( selector ) {
4740                 return typeof selector === "number" ? this.headers.eq( selector ) : $();
4741         },
4742
4743         _setupEvents: function( event ) {
4744                 var events = {
4745                         keydown: "_keydown"
4746                 };
4747                 if ( event ) {
4748                         $.each( event.split( " " ), function( index, eventName ) {
4749                                 events[ eventName ] = "_eventHandler";
4750                         });
4751                 }
4752
4753                 this._off( this.headers.add( this.headers.next() ) );
4754                 this._on( this.headers, events );
4755                 this._on( this.headers.next(), { keydown: "_panelKeyDown" });
4756                 this._hoverable( this.headers );
4757                 this._focusable( this.headers );
4758         },
4759
4760         _eventHandler: function( event ) {
4761                 var options = this.options,
4762                         active = this.active,
4763                         clicked = $( event.currentTarget ),
4764                         clickedIsActive = clicked[ 0 ] === active[ 0 ],
4765                         collapsing = clickedIsActive && options.collapsible,
4766                         toShow = collapsing ? $() : clicked.next(),
4767                         toHide = active.next(),
4768                         eventData = {
4769                                 oldHeader: active,
4770                                 oldPanel: toHide,
4771                                 newHeader: collapsing ? $() : clicked,
4772                                 newPanel: toShow
4773                         };
4774
4775                 event.preventDefault();
4776
4777                 if (
4778                                 // click on active header, but not collapsible
4779                                 ( clickedIsActive && !options.collapsible ) ||
4780                                 // allow canceling activation
4781                                 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
4782                         return;
4783                 }
4784
4785                 options.active = collapsing ? false : this.headers.index( clicked );
4786
4787                 // when the call to ._toggle() comes after the class changes
4788                 // it causes a very odd bug in IE 8 (see #6720)
4789                 this.active = clickedIsActive ? $() : clicked;
4790                 this._toggle( eventData );
4791
4792                 // switch classes
4793                 // corner classes on the previously active header stay after the animation
4794                 active.removeClass( "ui-accordion-header-active ui-state-active" );
4795                 if ( options.icons ) {
4796                         active.children( ".ui-accordion-header-icon" )
4797                                 .removeClass( options.icons.activeHeader )
4798                                 .addClass( options.icons.header );
4799                 }
4800
4801                 if ( !clickedIsActive ) {
4802                         clicked
4803                                 .removeClass( "ui-corner-all" )
4804                                 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
4805                         if ( options.icons ) {
4806                                 clicked.children( ".ui-accordion-header-icon" )
4807                                         .removeClass( options.icons.header )
4808                                         .addClass( options.icons.activeHeader );
4809                         }
4810
4811                         clicked
4812                                 .next()
4813                                 .addClass( "ui-accordion-content-active" );
4814                 }
4815         },
4816
4817         _toggle: function( data ) {
4818                 var toShow = data.newPanel,
4819                         toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
4820
4821                 // handle activating a panel during the animation for another activation
4822                 this.prevShow.add( this.prevHide ).stop( true, true );
4823                 this.prevShow = toShow;
4824                 this.prevHide = toHide;
4825
4826                 if ( this.options.animate ) {
4827                         this._animate( toShow, toHide, data );
4828                 } else {
4829                         toHide.hide();
4830                         toShow.show();
4831                         this._toggleComplete( data );
4832                 }
4833
4834                 toHide.attr({
4835                         "aria-hidden": "true"
4836                 });
4837                 toHide.prev().attr({
4838                         "aria-selected": "false",
4839                         "aria-expanded": "false"
4840                 });
4841                 // if we're switching panels, remove the old header from the tab order
4842                 // if we're opening from collapsed state, remove the previous header from the tab order
4843                 // if we're collapsing, then keep the collapsing header in the tab order
4844                 if ( toShow.length && toHide.length ) {
4845                         toHide.prev().attr({
4846                                 "tabIndex": -1,
4847                                 "aria-expanded": "false"
4848                         });
4849                 } else if ( toShow.length ) {
4850                         this.headers.filter(function() {
4851                                 return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
4852                         })
4853                         .attr( "tabIndex", -1 );
4854                 }
4855
4856                 toShow
4857                         .attr( "aria-hidden", "false" )
4858                         .prev()
4859                                 .attr({
4860                                         "aria-selected": "true",
4861                                         "aria-expanded": "true",
4862                                         tabIndex: 0
4863                                 });
4864         },
4865
4866         _animate: function( toShow, toHide, data ) {
4867                 var total, easing, duration,
4868                         that = this,
4869                         adjust = 0,
4870                         boxSizing = toShow.css( "box-sizing" ),
4871                         down = toShow.length &&
4872                                 ( !toHide.length || ( toShow.index() < toHide.index() ) ),
4873                         animate = this.options.animate || {},
4874                         options = down && animate.down || animate,
4875                         complete = function() {
4876                                 that._toggleComplete( data );
4877                         };
4878
4879                 if ( typeof options === "number" ) {
4880                         duration = options;
4881                 }
4882                 if ( typeof options === "string" ) {
4883                         easing = options;
4884                 }
4885                 // fall back from options to animation in case of partial down settings
4886                 easing = easing || options.easing || animate.easing;
4887                 duration = duration || options.duration || animate.duration;
4888
4889                 if ( !toHide.length ) {
4890                         return toShow.animate( this.showProps, duration, easing, complete );
4891                 }
4892                 if ( !toShow.length ) {
4893                         return toHide.animate( this.hideProps, duration, easing, complete );
4894                 }
4895
4896                 total = toShow.show().outerHeight();
4897                 toHide.animate( this.hideProps, {
4898                         duration: duration,
4899                         easing: easing,
4900                         step: function( now, fx ) {
4901                                 fx.now = Math.round( now );
4902                         }
4903                 });
4904                 toShow
4905                         .hide()
4906                         .animate( this.showProps, {
4907                                 duration: duration,
4908                                 easing: easing,
4909                                 complete: complete,
4910                                 step: function( now, fx ) {
4911                                         fx.now = Math.round( now );
4912                                         if ( fx.prop !== "height" ) {
4913                                                 if ( boxSizing === "content-box" ) {
4914                                                         adjust += fx.now;
4915                                                 }
4916                                         } else if ( that.options.heightStyle !== "content" ) {
4917                                                 fx.now = Math.round( total - toHide.outerHeight() - adjust );
4918                                                 adjust = 0;
4919                                         }
4920                                 }
4921                         });
4922         },
4923
4924         _toggleComplete: function( data ) {
4925                 var toHide = data.oldPanel;
4926
4927                 toHide
4928                         .removeClass( "ui-accordion-content-active" )
4929                         .prev()
4930                                 .removeClass( "ui-corner-top" )
4931                                 .addClass( "ui-corner-all" );
4932
4933                 // Work around for rendering bug in IE (#5421)
4934                 if ( toHide.length ) {
4935                         toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
4936                 }
4937                 this._trigger( "activate", null, data );
4938         }
4939 });
4940
4941
4942 /*!
4943  * jQuery UI Menu 1.11.4
4944  * http://jqueryui.com
4945  *
4946  * Copyright jQuery Foundation and other contributors
4947  * Released under the MIT license.
4948  * http://jquery.org/license
4949  *
4950  * http://api.jqueryui.com/menu/
4951  */
4952
4953
4954 var menu = $.widget( "ui.menu", {
4955         version: "1.11.4",
4956         defaultElement: "<ul>",
4957         delay: 300,
4958         options: {
4959                 icons: {
4960                         submenu: "ui-icon-carat-1-e"
4961                 },
4962                 items: "> *",
4963                 menus: "ul",
4964                 position: {
4965                         my: "left-1 top",
4966                         at: "right top"
4967                 },
4968                 role: "menu",
4969
4970                 // callbacks
4971                 blur: null,
4972                 focus: null,
4973                 select: null
4974         },
4975
4976         _create: function() {
4977                 this.activeMenu = this.element;
4978
4979                 // Flag used to prevent firing of the click handler
4980                 // as the event bubbles up through nested menus
4981                 this.mouseHandled = false;
4982                 this.element
4983                         .uniqueId()
4984                         .addClass( "ui-menu ui-widget ui-widget-content" )
4985                         .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
4986                         .attr({
4987                                 role: this.options.role,
4988                                 tabIndex: 0
4989                         });
4990
4991                 if ( this.options.disabled ) {
4992                         this.element
4993                                 .addClass( "ui-state-disabled" )
4994                                 .attr( "aria-disabled", "true" );
4995                 }
4996
4997                 this._on({
4998                         // Prevent focus from sticking to links inside menu after clicking
4999                         // them (focus should always stay on UL during navigation).
5000                         "mousedown .ui-menu-item": function( event ) {
5001                                 event.preventDefault();
5002                         },
5003                         "click .ui-menu-item": function( event ) {
5004                                 var target = $( event.target );
5005                                 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
5006                                         this.select( event );
5007
5008                                         // Only set the mouseHandled flag if the event will bubble, see #9469.
5009                                         if ( !event.isPropagationStopped() ) {
5010                                                 this.mouseHandled = true;
5011                                         }
5012
5013                                         // Open submenu on click
5014                                         if ( target.has( ".ui-menu" ).length ) {
5015                                                 this.expand( event );
5016                                         } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
5017
5018                                                 // Redirect focus to the menu
5019                                                 this.element.trigger( "focus", [ true ] );
5020
5021                                                 // If the active item is on the top level, let it stay active.
5022                                                 // Otherwise, blur the active item since it is no longer visible.
5023                                                 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
5024                                                         clearTimeout( this.timer );
5025                                                 }
5026                                         }
5027                                 }
5028                         },
5029                         "mouseenter .ui-menu-item": function( event ) {
5030                                 // Ignore mouse events while typeahead is active, see #10458.
5031                                 // Prevents focusing the wrong item when typeahead causes a scroll while the mouse
5032                                 // is over an item in the menu
5033                                 if ( this.previousFilter ) {
5034                                         return;
5035                                 }
5036                                 var target = $( event.currentTarget );
5037                                 // Remove ui-state-active class from siblings of the newly focused menu item
5038                                 // to avoid a jump caused by adjacent elements both having a class with a border
5039                                 target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" );
5040                                 this.focus( event, target );
5041                         },
5042                         mouseleave: "collapseAll",
5043                         "mouseleave .ui-menu": "collapseAll",
5044                         focus: function( event, keepActiveItem ) {
5045                                 // If there's already an active item, keep it active
5046                                 // If not, activate the first item
5047                                 var item = this.active || this.element.find( this.options.items ).eq( 0 );
5048
5049                                 if ( !keepActiveItem ) {
5050                                         this.focus( event, item );
5051                                 }
5052                         },
5053                         blur: function( event ) {
5054                                 this._delay(function() {
5055                                         if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
5056                                                 this.collapseAll( event );
5057                                         }
5058                                 });
5059                         },
5060                         keydown: "_keydown"
5061                 });
5062
5063                 this.refresh();
5064
5065                 // Clicks outside of a menu collapse any open menus
5066                 this._on( this.document, {
5067                         click: function( event ) {
5068                                 if ( this._closeOnDocumentClick( event ) ) {
5069                                         this.collapseAll( event );
5070                                 }
5071
5072                                 // Reset the mouseHandled flag
5073                                 this.mouseHandled = false;
5074                         }
5075                 });
5076         },
5077
5078         _destroy: function() {
5079                 // Destroy (sub)menus
5080                 this.element
5081                         .removeAttr( "aria-activedescendant" )
5082                         .find( ".ui-menu" ).addBack()
5083                                 .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" )
5084                                 .removeAttr( "role" )
5085                                 .removeAttr( "tabIndex" )
5086                                 .removeAttr( "aria-labelledby" )
5087                                 .removeAttr( "aria-expanded" )
5088                                 .removeAttr( "aria-hidden" )
5089                                 .removeAttr( "aria-disabled" )
5090                                 .removeUniqueId()
5091                                 .show();
5092
5093                 // Destroy menu items
5094                 this.element.find( ".ui-menu-item" )
5095                         .removeClass( "ui-menu-item" )
5096                         .removeAttr( "role" )
5097                         .removeAttr( "aria-disabled" )
5098                         .removeUniqueId()
5099                         .removeClass( "ui-state-hover" )
5100                         .removeAttr( "tabIndex" )
5101                         .removeAttr( "role" )
5102                         .removeAttr( "aria-haspopup" )
5103                         .children().each( function() {
5104                                 var elem = $( this );
5105                                 if ( elem.data( "ui-menu-submenu-carat" ) ) {
5106                                         elem.remove();
5107                                 }
5108                         });
5109
5110                 // Destroy menu dividers
5111                 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
5112         },
5113
5114         _keydown: function( event ) {
5115                 var match, prev, character, skip,
5116                         preventDefault = true;
5117
5118                 switch ( event.keyCode ) {
5119                 case $.ui.keyCode.PAGE_UP:
5120                         this.previousPage( event );
5121                         break;
5122                 case $.ui.keyCode.PAGE_DOWN:
5123                         this.nextPage( event );
5124                         break;
5125                 case $.ui.keyCode.HOME:
5126                         this._move( "first", "first", event );
5127                         break;
5128                 case $.ui.keyCode.END:
5129                         this._move( "last", "last", event );
5130                         break;
5131                 case $.ui.keyCode.UP:
5132                         this.previous( event );
5133                         break;
5134                 case $.ui.keyCode.DOWN:
5135                         this.next( event );
5136                         break;
5137                 case $.ui.keyCode.LEFT:
5138                         this.collapse( event );
5139                         break;
5140                 case $.ui.keyCode.RIGHT:
5141                         if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
5142                                 this.expand( event );
5143                         }
5144                         break;
5145                 case $.ui.keyCode.ENTER:
5146                 case $.ui.keyCode.SPACE:
5147                         this._activate( event );
5148                         break;
5149                 case $.ui.keyCode.ESCAPE:
5150                         this.collapse( event );
5151                         break;
5152                 default:
5153                         preventDefault = false;
5154                         prev = this.previousFilter || "";
5155                         character = String.fromCharCode( event.keyCode );
5156                         skip = false;
5157
5158                         clearTimeout( this.filterTimer );
5159
5160                         if ( character === prev ) {
5161                                 skip = true;
5162                         } else {
5163                                 character = prev + character;
5164                         }
5165
5166                         match = this._filterMenuItems( character );
5167                         match = skip && match.index( this.active.next() ) !== -1 ?
5168                                 this.active.nextAll( ".ui-menu-item" ) :
5169                                 match;
5170
5171                         // If no matches on the current filter, reset to the last character pressed
5172                         // to move down the menu to the first item that starts with that character
5173                         if ( !match.length ) {
5174                                 character = String.fromCharCode( event.keyCode );
5175                                 match = this._filterMenuItems( character );
5176                         }
5177
5178                         if ( match.length ) {
5179                                 this.focus( event, match );
5180                                 this.previousFilter = character;
5181                                 this.filterTimer = this._delay(function() {
5182                                         delete this.previousFilter;
5183                                 }, 1000 );
5184                         } else {
5185                                 delete this.previousFilter;
5186                         }
5187                 }
5188
5189                 if ( preventDefault ) {
5190                         event.preventDefault();
5191                 }
5192         },
5193
5194         _activate: function( event ) {
5195                 if ( !this.active.is( ".ui-state-disabled" ) ) {
5196                         if ( this.active.is( "[aria-haspopup='true']" ) ) {
5197                                 this.expand( event );
5198                         } else {
5199                                 this.select( event );
5200                         }
5201                 }
5202         },
5203
5204         refresh: function() {
5205                 var menus, items,
5206                         that = this,
5207                         icon = this.options.icons.submenu,
5208                         submenus = this.element.find( this.options.menus );
5209
5210                 this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
5211
5212                 // Initialize nested menus
5213                 submenus.filter( ":not(.ui-menu)" )
5214                         .addClass( "ui-menu ui-widget ui-widget-content ui-front" )
5215                         .hide()
5216                         .attr({
5217                                 role: this.options.role,
5218                                 "aria-hidden": "true",
5219                                 "aria-expanded": "false"
5220                         })
5221                         .each(function() {
5222                                 var menu = $( this ),
5223                                         item = menu.parent(),
5224                                         submenuCarat = $( "<span>" )
5225                                                 .addClass( "ui-menu-icon ui-icon " + icon )
5226                                                 .data( "ui-menu-submenu-carat", true );
5227
5228                                 item
5229                                         .attr( "aria-haspopup", "true" )
5230                                         .prepend( submenuCarat );
5231                                 menu.attr( "aria-labelledby", item.attr( "id" ) );
5232                         });
5233
5234                 menus = submenus.add( this.element );
5235                 items = menus.find( this.options.items );
5236
5237                 // Initialize menu-items containing spaces and/or dashes only as dividers
5238                 items.not( ".ui-menu-item" ).each(function() {
5239                         var item = $( this );
5240                         if ( that._isDivider( item ) ) {
5241                                 item.addClass( "ui-widget-content ui-menu-divider" );
5242                         }
5243                 });
5244
5245                 // Don't refresh list items that are already adapted
5246                 items.not( ".ui-menu-item, .ui-menu-divider" )
5247                         .addClass( "ui-menu-item" )
5248                         .uniqueId()
5249                         .attr({
5250                                 tabIndex: -1,
5251                                 role: this._itemRole()
5252                         });
5253
5254                 // Add aria-disabled attribute to any disabled menu item
5255                 items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
5256
5257                 // If the active item has been removed, blur the menu
5258                 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
5259                         this.blur();
5260                 }
5261         },
5262
5263         _itemRole: function() {
5264                 return {
5265                         menu: "menuitem",
5266                         listbox: "option"
5267                 }[ this.options.role ];
5268         },
5269
5270         _setOption: function( key, value ) {
5271                 if ( key === "icons" ) {
5272                         this.element.find( ".ui-menu-icon" )
5273                                 .removeClass( this.options.icons.submenu )
5274                                 .addClass( value.submenu );
5275                 }
5276                 if ( key === "disabled" ) {
5277                         this.element
5278                                 .toggleClass( "ui-state-disabled", !!value )
5279                                 .attr( "aria-disabled", value );
5280                 }
5281                 this._super( key, value );
5282         },
5283
5284         focus: function( event, item ) {
5285                 var nested, focused;
5286                 this.blur( event, event && event.type === "focus" );
5287
5288                 this._scrollIntoView( item );
5289
5290                 this.active = item.first();
5291                 focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" );
5292                 // Only update aria-activedescendant if there's a role
5293                 // otherwise we assume focus is managed elsewhere
5294                 if ( this.options.role ) {
5295                         this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
5296                 }
5297
5298                 // Highlight active parent menu item, if any
5299                 this.active
5300                         .parent()
5301                         .closest( ".ui-menu-item" )
5302                         .addClass( "ui-state-active" );
5303
5304                 if ( event && event.type === "keydown" ) {
5305                         this._close();
5306                 } else {
5307                         this.timer = this._delay(function() {
5308                                 this._close();
5309                         }, this.delay );
5310                 }
5311
5312                 nested = item.children( ".ui-menu" );
5313                 if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
5314                         this._startOpening(nested);
5315                 }
5316                 this.activeMenu = item.parent();
5317
5318                 this._trigger( "focus", event, { item: item } );
5319         },
5320
5321         _scrollIntoView: function( item ) {
5322                 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
5323                 if ( this._hasScroll() ) {
5324                         borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
5325                         paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
5326                         offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
5327                         scroll = this.activeMenu.scrollTop();
5328                         elementHeight = this.activeMenu.height();
5329                         itemHeight = item.outerHeight();
5330
5331                         if ( offset < 0 ) {
5332                                 this.activeMenu.scrollTop( scroll + offset );
5333                         } else if ( offset + itemHeight > elementHeight ) {
5334                                 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
5335                         }
5336                 }
5337         },
5338
5339         blur: function( event, fromFocus ) {
5340                 if ( !fromFocus ) {
5341                         clearTimeout( this.timer );
5342                 }
5343
5344                 if ( !this.active ) {
5345                         return;
5346                 }
5347
5348                 this.active.removeClass( "ui-state-focus" );
5349                 this.active = null;
5350
5351                 this._trigger( "blur", event, { item: this.active } );
5352         },
5353
5354         _startOpening: function( submenu ) {
5355                 clearTimeout( this.timer );
5356
5357                 // Don't open if already open fixes a Firefox bug that caused a .5 pixel
5358                 // shift in the submenu position when mousing over the carat icon
5359                 if ( submenu.attr( "aria-hidden" ) !== "true" ) {
5360                         return;
5361                 }
5362
5363                 this.timer = this._delay(function() {
5364                         this._close();
5365                         this._open( submenu );
5366                 }, this.delay );
5367         },
5368
5369         _open: function( submenu ) {
5370                 var position = $.extend({
5371                         of: this.active
5372                 }, this.options.position );
5373
5374                 clearTimeout( this.timer );
5375                 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
5376                         .hide()
5377                         .attr( "aria-hidden", "true" );
5378
5379                 submenu
5380                         .show()
5381                         .removeAttr( "aria-hidden" )
5382                         .attr( "aria-expanded", "true" )
5383                         .position( position );
5384         },
5385
5386         collapseAll: function( event, all ) {
5387                 clearTimeout( this.timer );
5388                 this.timer = this._delay(function() {
5389                         // If we were passed an event, look for the submenu that contains the event
5390                         var currentMenu = all ? this.element :
5391                                 $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
5392
5393                         // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
5394                         if ( !currentMenu.length ) {
5395                                 currentMenu = this.element;
5396                         }
5397
5398                         this._close( currentMenu );
5399
5400                         this.blur( event );
5401                         this.activeMenu = currentMenu;
5402                 }, this.delay );
5403         },
5404
5405         // With no arguments, closes the currently active menu - if nothing is active
5406         // it closes all menus.  If passed an argument, it will search for menus BELOW
5407         _close: function( startMenu ) {
5408                 if ( !startMenu ) {
5409                         startMenu = this.active ? this.active.parent() : this.element;
5410                 }
5411
5412                 startMenu
5413                         .find( ".ui-menu" )
5414                                 .hide()
5415                                 .attr( "aria-hidden", "true" )
5416                                 .attr( "aria-expanded", "false" )
5417                         .end()
5418                         .find( ".ui-state-active" ).not( ".ui-state-focus" )
5419                                 .removeClass( "ui-state-active" );
5420         },
5421
5422         _closeOnDocumentClick: function( event ) {
5423                 return !$( event.target ).closest( ".ui-menu" ).length;
5424         },
5425
5426         _isDivider: function( item ) {
5427
5428                 // Match hyphen, em dash, en dash
5429                 return !/[^\-\u2014\u2013\s]/.test( item.text() );
5430         },
5431
5432         collapse: function( event ) {
5433                 var newItem = this.active &&
5434                         this.active.parent().closest( ".ui-menu-item", this.element );
5435                 if ( newItem && newItem.length ) {
5436                         this._close();
5437                         this.focus( event, newItem );
5438                 }
5439         },
5440
5441         expand: function( event ) {
5442                 var newItem = this.active &&
5443                         this.active
5444                                 .children( ".ui-menu " )
5445                                 .find( this.options.items )
5446                                 .first();
5447
5448                 if ( newItem && newItem.length ) {
5449                         this._open( newItem.parent() );
5450
5451                         // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
5452                         this._delay(function() {
5453                                 this.focus( event, newItem );
5454                         });
5455                 }
5456         },
5457
5458         next: function( event ) {
5459                 this._move( "next", "first", event );
5460         },
5461
5462         previous: function( event ) {
5463                 this._move( "prev", "last", event );
5464         },
5465
5466         isFirstItem: function() {
5467                 return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
5468         },
5469
5470         isLastItem: function() {
5471                 return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
5472         },
5473
5474         _move: function( direction, filter, event ) {
5475                 var next;
5476                 if ( this.active ) {
5477                         if ( direction === "first" || direction === "last" ) {
5478                                 next = this.active
5479                                         [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
5480                                         .eq( -1 );
5481                         } else {
5482                                 next = this.active
5483                                         [ direction + "All" ]( ".ui-menu-item" )
5484                                         .eq( 0 );
5485                         }
5486                 }
5487                 if ( !next || !next.length || !this.active ) {
5488                         next = this.activeMenu.find( this.options.items )[ filter ]();
5489                 }
5490
5491                 this.focus( event, next );
5492         },
5493
5494         nextPage: function( event ) {
5495                 var item, base, height;
5496
5497                 if ( !this.active ) {
5498                         this.next( event );
5499                         return;
5500                 }
5501                 if ( this.isLastItem() ) {
5502                         return;
5503                 }
5504                 if ( this._hasScroll() ) {
5505                         base = this.active.offset().top;
5506                         height = this.element.height();
5507                         this.active.nextAll( ".ui-menu-item" ).each(function() {
5508                                 item = $( this );
5509                                 return item.offset().top - base - height < 0;
5510                         });
5511
5512                         this.focus( event, item );
5513                 } else {
5514                         this.focus( event, this.activeMenu.find( this.options.items )
5515                                 [ !this.active ? "first" : "last" ]() );
5516                 }
5517         },
5518
5519         previousPage: function( event ) {
5520                 var item, base, height;
5521                 if ( !this.active ) {
5522                         this.next( event );
5523                         return;
5524                 }
5525                 if ( this.isFirstItem() ) {
5526                         return;
5527                 }
5528                 if ( this._hasScroll() ) {
5529                         base = this.active.offset().top;
5530                         height = this.element.height();
5531                         this.active.prevAll( ".ui-menu-item" ).each(function() {
5532                                 item = $( this );
5533                                 return item.offset().top - base + height > 0;
5534                         });
5535
5536                         this.focus( event, item );
5537                 } else {
5538                         this.focus( event, this.activeMenu.find( this.options.items ).first() );
5539                 }
5540         },
5541
5542         _hasScroll: function() {
5543                 return this.element.outerHeight() < this.element.prop( "scrollHeight" );
5544         },
5545
5546         select: function( event ) {
5547                 // TODO: It should never be possible to not have an active item at this
5548                 // point, but the tests don't trigger mouseenter before click.
5549                 this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
5550                 var ui = { item: this.active };
5551                 if ( !this.active.has( ".ui-menu" ).length ) {
5552                         this.collapseAll( event, true );
5553                 }
5554                 this._trigger( "select", event, ui );
5555         },
5556
5557         _filterMenuItems: function(character) {
5558                 var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
5559                         regex = new RegExp( "^" + escapedCharacter, "i" );
5560
5561                 return this.activeMenu
5562                         .find( this.options.items )
5563
5564                         // Only match on items, not dividers or other content (#10571)
5565                         .filter( ".ui-menu-item" )
5566                         .filter(function() {
5567                                 return regex.test( $.trim( $( this ).text() ) );
5568                         });
5569         }
5570 });
5571
5572
5573 /*!
5574  * jQuery UI Autocomplete 1.11.4
5575  * http://jqueryui.com
5576  *
5577  * Copyright jQuery Foundation and other contributors
5578  * Released under the MIT license.
5579  * http://jquery.org/license
5580  *
5581  * http://api.jqueryui.com/autocomplete/
5582  */
5583
5584
5585 $.widget( "ui.autocomplete", {
5586         version: "1.11.4",
5587         defaultElement: "<input>",
5588         options: {
5589                 appendTo: null,
5590                 autoFocus: false,
5591                 delay: 300,
5592                 minLength: 1,
5593                 position: {
5594                         my: "left top",
5595                         at: "left bottom",
5596                         collision: "none"
5597                 },
5598                 source: null,
5599
5600                 // callbacks
5601                 change: null,
5602                 close: null,
5603                 focus: null,
5604                 open: null,
5605                 response: null,
5606                 search: null,
5607                 select: null
5608         },
5609
5610         requestIndex: 0,
5611         pending: 0,
5612
5613         _create: function() {
5614                 // Some browsers only repeat keydown events, not keypress events,
5615                 // so we use the suppressKeyPress flag to determine if we've already
5616                 // handled the keydown event. #7269
5617                 // Unfortunately the code for & in keypress is the same as the up arrow,
5618                 // so we use the suppressKeyPressRepeat flag to avoid handling keypress
5619                 // events when we know the keydown event was used to modify the
5620                 // search term. #7799
5621                 var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
5622                         nodeName = this.element[ 0 ].nodeName.toLowerCase(),
5623                         isTextarea = nodeName === "textarea",
5624                         isInput = nodeName === "input";
5625
5626                 this.isMultiLine =
5627                         // Textareas are always multi-line
5628                         isTextarea ? true :
5629                         // Inputs are always single-line, even if inside a contentEditable element
5630                         // IE also treats inputs as contentEditable
5631                         isInput ? false :
5632                         // All other element types are determined by whether or not they're contentEditable
5633                         this.element.prop( "isContentEditable" );
5634
5635                 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
5636                 this.isNewMenu = true;
5637
5638                 this.element
5639                         .addClass( "ui-autocomplete-input" )
5640                         .attr( "autocomplete", "off" );
5641
5642                 this._on( this.element, {
5643                         keydown: function( event ) {
5644                                 if ( this.element.prop( "readOnly" ) ) {
5645                                         suppressKeyPress = true;
5646                                         suppressInput = true;
5647                                         suppressKeyPressRepeat = true;
5648                                         return;
5649                                 }
5650
5651                                 suppressKeyPress = false;
5652                                 suppressInput = false;
5653                                 suppressKeyPressRepeat = false;
5654                                 var keyCode = $.ui.keyCode;
5655                                 switch ( event.keyCode ) {
5656                                 case keyCode.PAGE_UP:
5657                                         suppressKeyPress = true;
5658                                         this._move( "previousPage", event );
5659                                         break;
5660                                 case keyCode.PAGE_DOWN:
5661                                         suppressKeyPress = true;
5662                                         this._move( "nextPage", event );
5663                                         break;
5664                                 case keyCode.UP:
5665                                         suppressKeyPress = true;
5666                                         this._keyEvent( "previous", event );
5667                                         break;
5668                                 case keyCode.DOWN:
5669                                         suppressKeyPress = true;
5670                                         this._keyEvent( "next", event );
5671                                         break;
5672                                 case keyCode.ENTER:
5673                                         // when menu is open and has focus
5674                                         if ( this.menu.active ) {
5675                                                 // #6055 - Opera still allows the keypress to occur
5676                                                 // which causes forms to submit
5677                                                 suppressKeyPress = true;
5678                                                 event.preventDefault();
5679                                                 this.menu.select( event );
5680                                         }
5681                                         break;
5682                                 case keyCode.TAB:
5683                                         if ( this.menu.active ) {
5684                                                 this.menu.select( event );
5685                                         }
5686                                         break;
5687                                 case keyCode.ESCAPE:
5688                                         if ( this.menu.element.is( ":visible" ) ) {
5689                                                 if ( !this.isMultiLine ) {
5690                                                         this._value( this.term );
5691                                                 }
5692                                                 this.close( event );
5693                                                 // Different browsers have different default behavior for escape
5694                                                 // Single press can mean undo or clear
5695                                                 // Double press in IE means clear the whole form
5696                                                 event.preventDefault();
5697                                         }
5698                                         break;
5699                                 default:
5700                                         suppressKeyPressRepeat = true;
5701                                         // search timeout should be triggered before the input value is changed
5702                                         this._searchTimeout( event );
5703                                         break;
5704                                 }
5705                         },
5706                         keypress: function( event ) {
5707                                 if ( suppressKeyPress ) {
5708                                         suppressKeyPress = false;
5709                                         if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
5710                                                 event.preventDefault();
5711                                         }
5712                                         return;
5713                                 }
5714                                 if ( suppressKeyPressRepeat ) {
5715                                         return;
5716                                 }
5717
5718                                 // replicate some key handlers to allow them to repeat in Firefox and Opera
5719                                 var keyCode = $.ui.keyCode;
5720                                 switch ( event.keyCode ) {
5721                                 case keyCode.PAGE_UP:
5722                                         this._move( "previousPage", event );
5723                                         break;
5724                                 case keyCode.PAGE_DOWN:
5725                                         this._move( "nextPage", event );
5726                                         break;
5727                                 case keyCode.UP:
5728                                         this._keyEvent( "previous", event );
5729                                         break;
5730                                 case keyCode.DOWN:
5731                                         this._keyEvent( "next", event );
5732                                         break;
5733                                 }
5734                         },
5735                         input: function( event ) {
5736                                 if ( suppressInput ) {
5737                                         suppressInput = false;
5738                                         event.preventDefault();
5739                                         return;
5740                                 }
5741                                 this._searchTimeout( event );
5742                         },
5743                         focus: function() {
5744                                 this.selectedItem = null;
5745                                 this.previous = this._value();
5746                         },
5747                         blur: function( event ) {
5748                                 if ( this.cancelBlur ) {
5749                                         delete this.cancelBlur;
5750                                         return;
5751                                 }
5752
5753                                 clearTimeout( this.searching );
5754                                 this.close( event );
5755                                 this._change( event );
5756                         }
5757                 });
5758
5759                 this._initSource();
5760                 this.menu = $( "<ul>" )
5761                         .addClass( "ui-autocomplete ui-front" )
5762                         .appendTo( this._appendTo() )
5763                         .menu({
5764                                 // disable ARIA support, the live region takes care of that
5765                                 role: null
5766                         })
5767                         .hide()
5768                         .menu( "instance" );
5769
5770                 this._on( this.menu.element, {
5771                         mousedown: function( event ) {
5772                                 // prevent moving focus out of the text field
5773                                 event.preventDefault();
5774
5775                                 // IE doesn't prevent moving focus even with event.preventDefault()
5776                                 // so we set a flag to know when we should ignore the blur event
5777                                 this.cancelBlur = true;
5778                                 this._delay(function() {
5779                                         delete this.cancelBlur;
5780                                 });
5781
5782                                 // clicking on the scrollbar causes focus to shift to the body
5783                                 // but we can't detect a mouseup or a click immediately afterward
5784                                 // so we have to track the next mousedown and close the menu if
5785                                 // the user clicks somewhere outside of the autocomplete
5786                                 var menuElement = this.menu.element[ 0 ];
5787                                 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
5788                                         this._delay(function() {
5789                                                 var that = this;
5790                                                 this.document.one( "mousedown", function( event ) {
5791                                                         if ( event.target !== that.element[ 0 ] &&
5792                                                                         event.target !== menuElement &&
5793                                                                         !$.contains( menuElement, event.target ) ) {
5794                                                                 that.close();
5795                                                         }
5796                                                 });
5797                                         });
5798                                 }
5799                         },
5800                         menufocus: function( event, ui ) {
5801                                 var label, item;
5802                                 // support: Firefox
5803                                 // Prevent accidental activation of menu items in Firefox (#7024 #9118)
5804                                 if ( this.isNewMenu ) {
5805                                         this.isNewMenu = false;
5806                                         if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
5807                                                 this.menu.blur();
5808
5809                                                 this.document.one( "mousemove", function() {
5810                                                         $( event.target ).trigger( event.originalEvent );
5811                                                 });
5812
5813                                                 return;
5814                                         }
5815                                 }
5816
5817                                 item = ui.item.data( "ui-autocomplete-item" );
5818                                 if ( false !== this._trigger( "focus", event, { item: item } ) ) {
5819                                         // use value to match what will end up in the input, if it was a key event
5820                                         if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
5821                                                 this._value( item.value );
5822                                         }
5823                                 }
5824
5825                                 // Announce the value in the liveRegion
5826                                 label = ui.item.attr( "aria-label" ) || item.value;
5827                                 if ( label && $.trim( label ).length ) {
5828                                         this.liveRegion.children().hide();
5829                                         $( "<div>" ).text( label ).appendTo( this.liveRegion );
5830                                 }
5831                         },
5832                         menuselect: function( event, ui ) {
5833                                 var item = ui.item.data( "ui-autocomplete-item" ),
5834                                         previous = this.previous;
5835
5836                                 // only trigger when focus was lost (click on menu)
5837                                 if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
5838                                         this.element.focus();
5839                                         this.previous = previous;
5840                                         // #6109 - IE triggers two focus events and the second
5841                                         // is asynchronous, so we need to reset the previous
5842                                         // term synchronously and asynchronously :-(
5843                                         this._delay(function() {
5844                                                 this.previous = previous;
5845                                                 this.selectedItem = item;
5846                                         });
5847                                 }
5848
5849                                 if ( false !== this._trigger( "select", event, { item: item } ) ) {
5850                                         this._value( item.value );
5851                                 }
5852                                 // reset the term after the select event
5853                                 // this allows custom select handling to work properly
5854                                 this.term = this._value();
5855
5856                                 this.close( event );
5857                                 this.selectedItem = item;
5858                         }
5859                 });
5860
5861                 this.liveRegion = $( "<span>", {
5862                                 role: "status",
5863                                 "aria-live": "assertive",
5864                                 "aria-relevant": "additions"
5865                         })
5866                         .addClass( "ui-helper-hidden-accessible" )
5867                         .appendTo( this.document[ 0 ].body );
5868
5869                 // turning off autocomplete prevents the browser from remembering the
5870                 // value when navigating through history, so we re-enable autocomplete
5871                 // if the page is unloaded before the widget is destroyed. #7790
5872                 this._on( this.window, {
5873                         beforeunload: function() {
5874                                 this.element.removeAttr( "autocomplete" );
5875                         }
5876                 });
5877         },
5878
5879         _destroy: function() {
5880                 clearTimeout( this.searching );
5881                 this.element
5882                         .removeClass( "ui-autocomplete-input" )
5883                         .removeAttr( "autocomplete" );
5884                 this.menu.element.remove();
5885                 this.liveRegion.remove();
5886         },
5887
5888         _setOption: function( key, value ) {
5889                 this._super( key, value );
5890                 if ( key === "source" ) {
5891                         this._initSource();
5892                 }
5893                 if ( key === "appendTo" ) {
5894                         this.menu.element.appendTo( this._appendTo() );
5895                 }
5896                 if ( key === "disabled" && value && this.xhr ) {
5897                         this.xhr.abort();
5898                 }
5899         },
5900
5901         _appendTo: function() {
5902                 var element = this.options.appendTo;
5903
5904                 if ( element ) {
5905                         element = element.jquery || element.nodeType ?
5906                                 $( element ) :
5907                                 this.document.find( element ).eq( 0 );
5908                 }
5909
5910                 if ( !element || !element[ 0 ] ) {
5911                         element = this.element.closest( ".ui-front" );
5912                 }
5913
5914                 if ( !element.length ) {
5915                         element = this.document[ 0 ].body;
5916                 }
5917
5918                 return element;
5919         },
5920
5921         _initSource: function() {
5922                 var array, url,
5923                         that = this;
5924                 if ( $.isArray( this.options.source ) ) {
5925                         array = this.options.source;
5926                         this.source = function( request, response ) {
5927                                 response( $.ui.autocomplete.filter( array, request.term ) );
5928                         };
5929                 } else if ( typeof this.options.source === "string" ) {
5930                         url = this.options.source;
5931                         this.source = function( request, response ) {
5932                                 if ( that.xhr ) {
5933                                         that.xhr.abort();
5934                                 }
5935                                 that.xhr = $.ajax({
5936                                         url: url,
5937                                         data: request,
5938                                         dataType: "json",
5939                                         success: function( data ) {
5940                                                 response( data );
5941                                         },
5942                                         error: function() {
5943                                                 response([]);
5944                                         }
5945                                 });
5946                         };
5947                 } else {
5948                         this.source = this.options.source;
5949                 }
5950         },
5951
5952         _searchTimeout: function( event ) {
5953                 clearTimeout( this.searching );
5954                 this.searching = this._delay(function() {
5955
5956                         // Search if the value has changed, or if the user retypes the same value (see #7434)
5957                         var equalValues = this.term === this._value(),
5958                                 menuVisible = this.menu.element.is( ":visible" ),
5959                                 modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
5960
5961                         if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
5962                                 this.selectedItem = null;
5963                                 this.search( null, event );
5964                         }
5965                 }, this.options.delay );
5966         },
5967
5968         search: function( value, event ) {
5969                 value = value != null ? value : this._value();
5970
5971                 // always save the actual value, not the one passed as an argument
5972                 this.term = this._value();
5973
5974                 if ( value.length < this.options.minLength ) {
5975                         return this.close( event );
5976                 }
5977
5978                 if ( this._trigger( "search", event ) === false ) {
5979                         return;
5980                 }
5981
5982                 return this._search( value );
5983         },
5984
5985         _search: function( value ) {
5986                 this.pending++;
5987                 this.element.addClass( "ui-autocomplete-loading" );
5988                 this.cancelSearch = false;
5989
5990                 this.source( { term: value }, this._response() );
5991         },
5992
5993         _response: function() {
5994                 var index = ++this.requestIndex;
5995
5996                 return $.proxy(function( content ) {
5997                         if ( index === this.requestIndex ) {
5998                                 this.__response( content );
5999                         }
6000
6001                         this.pending--;
6002                         if ( !this.pending ) {
6003                                 this.element.removeClass( "ui-autocomplete-loading" );
6004                         }
6005                 }, this );
6006         },
6007
6008         __response: function( content ) {
6009                 if ( content ) {
6010                         content = this._normalize( content );
6011                 }
6012                 this._trigger( "response", null, { content: content } );
6013                 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
6014                         this._suggest( content );
6015                         this._trigger( "open" );
6016                 } else {
6017                         // use ._close() instead of .close() so we don't cancel future searches
6018                         this._close();
6019                 }
6020         },
6021
6022         close: function( event ) {
6023                 this.cancelSearch = true;
6024                 this._close( event );
6025         },
6026
6027         _close: function( event ) {
6028                 if ( this.menu.element.is( ":visible" ) ) {
6029                         this.menu.element.hide();
6030                         this.menu.blur();
6031                         this.isNewMenu = true;
6032                         this._trigger( "close", event );
6033                 }
6034         },
6035
6036         _change: function( event ) {
6037                 if ( this.previous !== this._value() ) {
6038                         this._trigger( "change", event, { item: this.selectedItem } );
6039                 }
6040         },
6041
6042         _normalize: function( items ) {
6043                 // assume all items have the right format when the first item is complete
6044                 if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
6045                         return items;
6046                 }
6047                 return $.map( items, function( item ) {
6048                         if ( typeof item === "string" ) {
6049                                 return {
6050                                         label: item,
6051                                         value: item
6052                                 };
6053                         }
6054                         return $.extend( {}, item, {
6055                                 label: item.label || item.value,
6056                                 value: item.value || item.label
6057                         });
6058                 });
6059         },
6060
6061         _suggest: function( items ) {
6062                 var ul = this.menu.element.empty();
6063                 this._renderMenu( ul, items );
6064                 this.isNewMenu = true;
6065                 this.menu.refresh();
6066
6067                 // size and position menu
6068                 ul.show();
6069                 this._resizeMenu();
6070                 ul.position( $.extend({
6071                         of: this.element
6072                 }, this.options.position ) );
6073
6074                 if ( this.options.autoFocus ) {
6075                         this.menu.next();
6076                 }
6077         },
6078
6079         _resizeMenu: function() {
6080                 var ul = this.menu.element;
6081                 ul.outerWidth( Math.max(
6082                         // Firefox wraps long text (possibly a rounding bug)
6083                         // so we add 1px to avoid the wrapping (#7513)
6084                         ul.width( "" ).outerWidth() + 1,
6085                         this.element.outerWidth()
6086                 ) );
6087         },
6088
6089         _renderMenu: function( ul, items ) {
6090                 var that = this;
6091                 $.each( items, function( index, item ) {
6092                         that._renderItemData( ul, item );
6093                 });
6094         },
6095
6096         _renderItemData: function( ul, item ) {
6097                 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
6098         },
6099
6100         _renderItem: function( ul, item ) {
6101                 return $( "<li>" ).text( item.label ).appendTo( ul );
6102         },
6103
6104         _move: function( direction, event ) {
6105                 if ( !this.menu.element.is( ":visible" ) ) {
6106                         this.search( null, event );
6107                         return;
6108                 }
6109                 if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
6110                                 this.menu.isLastItem() && /^next/.test( direction ) ) {
6111
6112                         if ( !this.isMultiLine ) {
6113                                 this._value( this.term );
6114                         }
6115
6116                         this.menu.blur();
6117                         return;
6118                 }
6119                 this.menu[ direction ]( event );
6120         },
6121
6122         widget: function() {
6123                 return this.menu.element;
6124         },
6125
6126         _value: function() {
6127                 return this.valueMethod.apply( this.element, arguments );
6128         },
6129
6130         _keyEvent: function( keyEvent, event ) {
6131                 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
6132                         this._move( keyEvent, event );
6133
6134                         // prevents moving cursor to beginning/end of the text field in some browsers
6135                         event.preventDefault();
6136                 }
6137         }
6138 });
6139
6140 $.extend( $.ui.autocomplete, {
6141         escapeRegex: function( value ) {
6142                 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
6143         },
6144         filter: function( array, term ) {
6145                 var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
6146                 return $.grep( array, function( value ) {
6147                         return matcher.test( value.label || value.value || value );
6148                 });
6149         }
6150 });
6151
6152 // live region extension, adding a `messages` option
6153 // NOTE: This is an experimental API. We are still investigating
6154 // a full solution for string manipulation and internationalization.
6155 $.widget( "ui.autocomplete", $.ui.autocomplete, {
6156         options: {
6157                 messages: {
6158                         noResults: "No search results.",
6159                         results: function( amount ) {
6160                                 return amount + ( amount > 1 ? " results are" : " result is" ) +
6161                                         " available, use up and down arrow keys to navigate.";
6162                         }
6163                 }
6164         },
6165
6166         __response: function( content ) {
6167                 var message;
6168                 this._superApply( arguments );
6169                 if ( this.options.disabled || this.cancelSearch ) {
6170                         return;
6171                 }
6172                 if ( content && content.length ) {
6173                         message = this.options.messages.results( content.length );
6174                 } else {
6175                         message = this.options.messages.noResults;
6176                 }
6177                 this.liveRegion.children().hide();
6178                 $( "<div>" ).text( message ).appendTo( this.liveRegion );
6179         }
6180 });
6181
6182 var autocomplete = $.ui.autocomplete;
6183
6184
6185 /*!
6186  * jQuery UI Button 1.11.4
6187  * http://jqueryui.com
6188  *
6189  * Copyright jQuery Foundation and other contributors
6190  * Released under the MIT license.
6191  * http://jquery.org/license
6192  *
6193  * http://api.jqueryui.com/button/
6194  */
6195
6196
6197 var lastActive,
6198         baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
6199         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",
6200         formResetHandler = function() {
6201                 var form = $( this );
6202                 setTimeout(function() {
6203                         form.find( ":ui-button" ).button( "refresh" );
6204                 }, 1 );
6205         },
6206         radioGroup = function( radio ) {
6207                 var name = radio.name,
6208                         form = radio.form,
6209                         radios = $( [] );
6210                 if ( name ) {
6211                         name = name.replace( /'/g, "\\'" );
6212                         if ( form ) {
6213                                 radios = $( form ).find( "[name='" + name + "'][type=radio]" );
6214                         } else {
6215                                 radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument )
6216                                         .filter(function() {
6217                                                 return !this.form;
6218                                         });
6219                         }
6220                 }
6221                 return radios;
6222         };
6223
6224 $.widget( "ui.button", {
6225         version: "1.11.4",
6226         defaultElement: "<button>",
6227         options: {
6228                 disabled: null,
6229                 text: true,
6230                 label: null,
6231                 icons: {
6232                         primary: null,
6233                         secondary: null
6234                 }
6235         },
6236         _create: function() {
6237                 this.element.closest( "form" )
6238                         .unbind( "reset" + this.eventNamespace )
6239                         .bind( "reset" + this.eventNamespace, formResetHandler );
6240
6241                 if ( typeof this.options.disabled !== "boolean" ) {
6242                         this.options.disabled = !!this.element.prop( "disabled" );
6243                 } else {
6244                         this.element.prop( "disabled", this.options.disabled );
6245                 }
6246
6247                 this._determineButtonType();
6248                 this.hasTitle = !!this.buttonElement.attr( "title" );
6249
6250                 var that = this,
6251                         options = this.options,
6252                         toggleButton = this.type === "checkbox" || this.type === "radio",
6253                         activeClass = !toggleButton ? "ui-state-active" : "";
6254
6255                 if ( options.label === null ) {
6256                         options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
6257                 }
6258
6259                 this._hoverable( this.buttonElement );
6260
6261                 this.buttonElement
6262                         .addClass( baseClasses )
6263                         .attr( "role", "button" )
6264                         .bind( "mouseenter" + this.eventNamespace, function() {
6265                                 if ( options.disabled ) {
6266                                         return;
6267                                 }
6268                                 if ( this === lastActive ) {
6269                                         $( this ).addClass( "ui-state-active" );
6270                                 }
6271                         })
6272                         .bind( "mouseleave" + this.eventNamespace, function() {
6273                                 if ( options.disabled ) {
6274                                         return;
6275                                 }
6276                                 $( this ).removeClass( activeClass );
6277                         })
6278                         .bind( "click" + this.eventNamespace, function( event ) {
6279                                 if ( options.disabled ) {
6280                                         event.preventDefault();
6281                                         event.stopImmediatePropagation();
6282                                 }
6283                         });
6284
6285                 // Can't use _focusable() because the element that receives focus
6286                 // and the element that gets the ui-state-focus class are different
6287                 this._on({
6288                         focus: function() {
6289                                 this.buttonElement.addClass( "ui-state-focus" );
6290                         },
6291                         blur: function() {
6292                                 this.buttonElement.removeClass( "ui-state-focus" );
6293                         }
6294                 });
6295
6296                 if ( toggleButton ) {
6297                         this.element.bind( "change" + this.eventNamespace, function() {
6298                                 that.refresh();
6299                         });
6300                 }
6301
6302                 if ( this.type === "checkbox" ) {
6303                         this.buttonElement.bind( "click" + this.eventNamespace, function() {
6304                                 if ( options.disabled ) {
6305                                         return false;
6306                                 }
6307                         });
6308                 } else if ( this.type === "radio" ) {
6309                         this.buttonElement.bind( "click" + this.eventNamespace, function() {
6310                                 if ( options.disabled ) {
6311                                         return false;
6312                                 }
6313                                 $( this ).addClass( "ui-state-active" );
6314                                 that.buttonElement.attr( "aria-pressed", "true" );
6315
6316                                 var radio = that.element[ 0 ];
6317                                 radioGroup( radio )
6318                                         .not( radio )
6319                                         .map(function() {
6320                                                 return $( this ).button( "widget" )[ 0 ];
6321                                         })
6322                                         .removeClass( "ui-state-active" )
6323                                         .attr( "aria-pressed", "false" );
6324                         });
6325                 } else {
6326                         this.buttonElement
6327                                 .bind( "mousedown" + this.eventNamespace, function() {
6328                                         if ( options.disabled ) {
6329                                                 return false;
6330                                         }
6331                                         $( this ).addClass( "ui-state-active" );
6332                                         lastActive = this;
6333                                         that.document.one( "mouseup", function() {
6334                                                 lastActive = null;
6335                                         });
6336                                 })
6337                                 .bind( "mouseup" + this.eventNamespace, function() {
6338                                         if ( options.disabled ) {
6339                                                 return false;
6340                                         }
6341                                         $( this ).removeClass( "ui-state-active" );
6342                                 })
6343                                 .bind( "keydown" + this.eventNamespace, function(event) {
6344                                         if ( options.disabled ) {
6345                                                 return false;
6346                                         }
6347                                         if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
6348                                                 $( this ).addClass( "ui-state-active" );
6349                                         }
6350                                 })
6351                                 // see #8559, we bind to blur here in case the button element loses
6352                                 // focus between keydown and keyup, it would be left in an "active" state
6353                                 .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
6354                                         $( this ).removeClass( "ui-state-active" );
6355                                 });
6356
6357                         if ( this.buttonElement.is("a") ) {
6358                                 this.buttonElement.keyup(function(event) {
6359                                         if ( event.keyCode === $.ui.keyCode.SPACE ) {
6360                                                 // TODO pass through original event correctly (just as 2nd argument doesn't work)
6361                                                 $( this ).click();
6362                                         }
6363                                 });
6364                         }
6365                 }
6366
6367                 this._setOption( "disabled", options.disabled );
6368                 this._resetButton();
6369         },
6370
6371         _determineButtonType: function() {
6372                 var ancestor, labelSelector, checked;
6373
6374                 if ( this.element.is("[type=checkbox]") ) {
6375                         this.type = "checkbox";
6376                 } else if ( this.element.is("[type=radio]") ) {
6377                         this.type = "radio";
6378                 } else if ( this.element.is("input") ) {
6379                         this.type = "input";
6380                 } else {
6381                         this.type = "button";
6382                 }
6383
6384                 if ( this.type === "checkbox" || this.type === "radio" ) {
6385                         // we don't search against the document in case the element
6386                         // is disconnected from the DOM
6387                         ancestor = this.element.parents().last();
6388                         labelSelector = "label[for='" + this.element.attr("id") + "']";
6389                         this.buttonElement = ancestor.find( labelSelector );
6390                         if ( !this.buttonElement.length ) {
6391                                 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
6392                                 this.buttonElement = ancestor.filter( labelSelector );
6393                                 if ( !this.buttonElement.length ) {
6394                                         this.buttonElement = ancestor.find( labelSelector );
6395                                 }
6396                         }
6397                         this.element.addClass( "ui-helper-hidden-accessible" );
6398
6399                         checked = this.element.is( ":checked" );
6400                         if ( checked ) {
6401                                 this.buttonElement.addClass( "ui-state-active" );
6402                         }
6403                         this.buttonElement.prop( "aria-pressed", checked );
6404                 } else {
6405                         this.buttonElement = this.element;
6406                 }
6407         },
6408
6409         widget: function() {
6410                 return this.buttonElement;
6411         },
6412
6413         _destroy: function() {
6414                 this.element
6415                         .removeClass( "ui-helper-hidden-accessible" );
6416                 this.buttonElement
6417                         .removeClass( baseClasses + " ui-state-active " + typeClasses )
6418                         .removeAttr( "role" )
6419                         .removeAttr( "aria-pressed" )
6420                         .html( this.buttonElement.find(".ui-button-text").html() );
6421
6422                 if ( !this.hasTitle ) {
6423                         this.buttonElement.removeAttr( "title" );
6424                 }
6425         },
6426
6427         _setOption: function( key, value ) {
6428                 this._super( key, value );
6429                 if ( key === "disabled" ) {
6430                         this.widget().toggleClass( "ui-state-disabled", !!value );
6431                         this.element.prop( "disabled", !!value );
6432                         if ( value ) {
6433                                 if ( this.type === "checkbox" || this.type === "radio" ) {
6434                                         this.buttonElement.removeClass( "ui-state-focus" );
6435                                 } else {
6436                                         this.buttonElement.removeClass( "ui-state-focus ui-state-active" );
6437                                 }
6438                         }
6439                         return;
6440                 }
6441                 this._resetButton();
6442         },
6443
6444         refresh: function() {
6445                 //See #8237 & #8828
6446                 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
6447
6448                 if ( isDisabled !== this.options.disabled ) {
6449                         this._setOption( "disabled", isDisabled );
6450                 }
6451                 if ( this.type === "radio" ) {
6452                         radioGroup( this.element[0] ).each(function() {
6453                                 if ( $( this ).is( ":checked" ) ) {
6454                                         $( this ).button( "widget" )
6455                                                 .addClass( "ui-state-active" )
6456                                                 .attr( "aria-pressed", "true" );
6457                                 } else {
6458                                         $( this ).button( "widget" )
6459                                                 .removeClass( "ui-state-active" )
6460                                                 .attr( "aria-pressed", "false" );
6461                                 }
6462                         });
6463                 } else if ( this.type === "checkbox" ) {
6464                         if ( this.element.is( ":checked" ) ) {
6465                                 this.buttonElement
6466                                         .addClass( "ui-state-active" )
6467                                         .attr( "aria-pressed", "true" );
6468                         } else {
6469                                 this.buttonElement
6470                                         .removeClass( "ui-state-active" )
6471                                         .attr( "aria-pressed", "false" );
6472                         }
6473                 }
6474         },
6475
6476         _resetButton: function() {
6477                 if ( this.type === "input" ) {
6478                         if ( this.options.label ) {
6479                                 this.element.val( this.options.label );
6480                         }
6481                         return;
6482                 }
6483                 var buttonElement = this.buttonElement.removeClass( typeClasses ),
6484                         buttonText = $( "<span></span>", this.document[0] )
6485                                 .addClass( "ui-button-text" )
6486                                 .html( this.options.label )
6487                                 .appendTo( buttonElement.empty() )
6488                                 .text(),
6489                         icons = this.options.icons,
6490                         multipleIcons = icons.primary && icons.secondary,
6491                         buttonClasses = [];
6492
6493                 if ( icons.primary || icons.secondary ) {
6494                         if ( this.options.text ) {
6495                                 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
6496                         }
6497
6498                         if ( icons.primary ) {
6499                                 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
6500                         }
6501
6502                         if ( icons.secondary ) {
6503                                 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
6504                         }
6505
6506                         if ( !this.options.text ) {
6507                                 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
6508
6509                                 if ( !this.hasTitle ) {
6510                                         buttonElement.attr( "title", $.trim( buttonText ) );
6511                                 }
6512                         }
6513                 } else {
6514                         buttonClasses.push( "ui-button-text-only" );
6515                 }
6516                 buttonElement.addClass( buttonClasses.join( " " ) );
6517         }
6518 });
6519
6520 $.widget( "ui.buttonset", {
6521         version: "1.11.4",
6522         options: {
6523                 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
6524         },
6525
6526         _create: function() {
6527                 this.element.addClass( "ui-buttonset" );
6528         },
6529
6530         _init: function() {
6531                 this.refresh();
6532         },
6533
6534         _setOption: function( key, value ) {
6535                 if ( key === "disabled" ) {
6536                         this.buttons.button( "option", key, value );
6537                 }
6538
6539                 this._super( key, value );
6540         },
6541
6542         refresh: function() {
6543                 var rtl = this.element.css( "direction" ) === "rtl",
6544                         allButtons = this.element.find( this.options.items ),
6545                         existingButtons = allButtons.filter( ":ui-button" );
6546
6547                 // Initialize new buttons
6548                 allButtons.not( ":ui-button" ).button();
6549
6550                 // Refresh existing buttons
6551                 existingButtons.button( "refresh" );
6552
6553                 this.buttons = allButtons
6554                         .map(function() {
6555                                 return $( this ).button( "widget" )[ 0 ];
6556                         })
6557                                 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
6558                                 .filter( ":first" )
6559                                         .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
6560                                 .end()
6561                                 .filter( ":last" )
6562                                         .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
6563                                 .end()
6564                         .end();
6565         },
6566
6567         _destroy: function() {
6568                 this.element.removeClass( "ui-buttonset" );
6569                 this.buttons
6570                         .map(function() {
6571                                 return $( this ).button( "widget" )[ 0 ];
6572                         })
6573                                 .removeClass( "ui-corner-left ui-corner-right" )
6574                         .end()
6575                         .button( "destroy" );
6576         }
6577 });
6578
6579 var button = $.ui.button;
6580
6581
6582 /*!
6583  * jQuery UI Datepicker 1.11.4
6584  * http://jqueryui.com
6585  *
6586  * Copyright jQuery Foundation and other contributors
6587  * Released under the MIT license.
6588  * http://jquery.org/license
6589  *
6590  * http://api.jqueryui.com/datepicker/
6591  */
6592
6593
6594 $.extend($.ui, { datepicker: { version: "1.11.4" } });
6595
6596 var datepicker_instActive;
6597
6598 function datepicker_getZindex( elem ) {
6599         var position, value;
6600         while ( elem.length && elem[ 0 ] !== document ) {
6601                 // Ignore z-index if position is set to a value where z-index is ignored by the browser
6602                 // This makes behavior of this function consistent across browsers
6603                 // WebKit always returns auto if the element is positioned
6604                 position = elem.css( "position" );
6605                 if ( position === "absolute" || position === "relative" || position === "fixed" ) {
6606                         // IE returns 0 when zIndex is not specified
6607                         // other browsers return a string
6608                         // we ignore the case of nested elements with an explicit value of 0
6609                         // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
6610                         value = parseInt( elem.css( "zIndex" ), 10 );
6611                         if ( !isNaN( value ) && value !== 0 ) {
6612                                 return value;
6613                         }
6614                 }
6615                 elem = elem.parent();
6616         }
6617
6618         return 0;
6619 }
6620 /* Date picker manager.
6621    Use the singleton instance of this class, $.datepicker, to interact with the date picker.
6622    Settings for (groups of) date pickers are maintained in an instance object,
6623    allowing multiple different settings on the same page. */
6624
6625 function Datepicker() {
6626         this._curInst = null; // The current instance in use
6627         this._keyEvent = false; // If the last event was a key event
6628         this._disabledInputs = []; // List of date picker inputs that have been disabled
6629         this._datepickerShowing = false; // True if the popup picker is showing , false if not
6630         this._inDialog = false; // True if showing within a "dialog", false if not
6631         this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
6632         this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
6633         this._appendClass = "ui-datepicker-append"; // The name of the append marker class
6634         this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
6635         this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
6636         this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
6637         this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
6638         this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
6639         this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
6640         this.regional = []; // Available regional settings, indexed by language code
6641         this.regional[""] = { // Default regional settings
6642                 closeText: "Done", // Display text for close link
6643                 prevText: "Prev", // Display text for previous month link
6644                 nextText: "Next", // Display text for next month link
6645                 currentText: "Today", // Display text for current month link
6646                 monthNames: ["January","February","March","April","May","June",
6647                         "July","August","September","October","November","December"], // Names of months for drop-down and formatting
6648                 monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
6649                 dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
6650                 dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
6651                 dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
6652                 weekHeader: "Wk", // Column header for week of the year
6653                 dateFormat: "mm/dd/yy", // See format options on parseDate
6654                 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
6655                 isRTL: false, // True if right-to-left language, false if left-to-right
6656                 showMonthAfterYear: false, // True if the year select precedes month, false for month then year
6657                 yearSuffix: "" // Additional text to append to the year in the month headers
6658         };
6659         this._defaults = { // Global defaults for all the date picker instances
6660                 showOn: "focus", // "focus" for popup on focus,
6661                         // "button" for trigger button, or "both" for either
6662                 showAnim: "fadeIn", // Name of jQuery animation for popup
6663                 showOptions: {}, // Options for enhanced animations
6664                 defaultDate: null, // Used when field is blank: actual date,
6665                         // +/-number for offset from today, null for today
6666                 appendText: "", // Display text following the input box, e.g. showing the format
6667                 buttonText: "...", // Text for trigger button
6668                 buttonImage: "", // URL for trigger button image
6669                 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
6670                 hideIfNoPrevNext: false, // True to hide next/previous month links
6671                         // if not applicable, false to just disable them
6672                 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
6673                 gotoCurrent: false, // True if today link goes back to current selection instead
6674                 changeMonth: false, // True if month can be selected directly, false if only prev/next
6675                 changeYear: false, // True if year can be selected directly, false if only prev/next
6676                 yearRange: "c-10:c+10", // Range of years to display in drop-down,
6677                         // either relative to today's year (-nn:+nn), relative to currently displayed year
6678                         // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
6679                 showOtherMonths: false, // True to show dates in other months, false to leave blank
6680                 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
6681                 showWeek: false, // True to show week of the year, false to not show it
6682                 calculateWeek: this.iso8601Week, // How to calculate the week of the year,
6683                         // takes a Date and returns the number of the week for it
6684                 shortYearCutoff: "+10", // Short year values < this are in the current century,
6685                         // > this are in the previous century,
6686                         // string value starting with "+" for current year + value
6687                 minDate: null, // The earliest selectable date, or null for no limit
6688                 maxDate: null, // The latest selectable date, or null for no limit
6689                 duration: "fast", // Duration of display/closure
6690                 beforeShowDay: null, // Function that takes a date and returns an array with
6691                         // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
6692                         // [2] = cell title (optional), e.g. $.datepicker.noWeekends
6693                 beforeShow: null, // Function that takes an input field and
6694                         // returns a set of custom settings for the date picker
6695                 onSelect: null, // Define a callback function when a date is selected
6696                 onChangeMonthYear: null, // Define a callback function when the month or year is changed
6697                 onClose: null, // Define a callback function when the datepicker is closed
6698                 numberOfMonths: 1, // Number of months to show at a time
6699                 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
6700                 stepMonths: 1, // Number of months to step back/forward
6701                 stepBigMonths: 12, // Number of months to step back/forward for the big links
6702                 altField: "", // Selector for an alternate field to store selected dates into
6703                 altFormat: "", // The date format to use for the alternate field
6704                 constrainInput: true, // The input is constrained by the current date format
6705                 showButtonPanel: false, // True to show button panel, false to not show it
6706                 autoSize: false, // True to size the input for the date format, false to leave as is
6707                 disabled: false // The initial disabled state
6708         };
6709         $.extend(this._defaults, this.regional[""]);
6710         this.regional.en = $.extend( true, {}, this.regional[ "" ]);
6711         this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
6712         this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
6713 }
6714
6715 $.extend(Datepicker.prototype, {
6716         /* Class name added to elements to indicate already configured with a date picker. */
6717         markerClassName: "hasDatepicker",
6718
6719         //Keep track of the maximum number of rows displayed (see #7043)
6720         maxRows: 4,
6721
6722         // TODO rename to "widget" when switching to widget factory
6723         _widgetDatepicker: function() {
6724                 return this.dpDiv;
6725         },
6726
6727         /* Override the default settings for all instances of the date picker.
6728          * @param  settings  object - the new settings to use as defaults (anonymous object)
6729          * @return the manager object
6730          */
6731         setDefaults: function(settings) {
6732                 datepicker_extendRemove(this._defaults, settings || {});
6733                 return this;
6734         },
6735
6736         /* Attach the date picker to a jQuery selection.
6737          * @param  target       element - the target input field or division or span
6738          * @param  settings  object - the new settings to use for this date picker instance (anonymous)
6739          */
6740         _attachDatepicker: function(target, settings) {
6741                 var nodeName, inline, inst;
6742                 nodeName = target.nodeName.toLowerCase();
6743                 inline = (nodeName === "div" || nodeName === "span");
6744                 if (!target.id) {
6745                         this.uuid += 1;
6746                         target.id = "dp" + this.uuid;
6747                 }
6748                 inst = this._newInst($(target), inline);
6749                 inst.settings = $.extend({}, settings || {});
6750                 if (nodeName === "input") {
6751                         this._connectDatepicker(target, inst);
6752                 } else if (inline) {
6753                         this._inlineDatepicker(target, inst);
6754                 }
6755         },
6756
6757         /* Create a new instance object. */
6758         _newInst: function(target, inline) {
6759                 var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
6760                 return {id: id, input: target, // associated target
6761                         selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
6762                         drawMonth: 0, drawYear: 0, // month being drawn
6763                         inline: inline, // is datepicker inline or not
6764                         dpDiv: (!inline ? this.dpDiv : // presentation div
6765                         datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
6766         },
6767
6768         /* Attach the date picker to an input field. */
6769         _connectDatepicker: function(target, inst) {
6770                 var input = $(target);
6771                 inst.append = $([]);
6772                 inst.trigger = $([]);
6773                 if (input.hasClass(this.markerClassName)) {
6774                         return;
6775                 }
6776                 this._attachments(input, inst);
6777                 input.addClass(this.markerClassName).keydown(this._doKeyDown).
6778                         keypress(this._doKeyPress).keyup(this._doKeyUp);
6779                 this._autoSize(inst);
6780                 $.data(target, "datepicker", inst);
6781                 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
6782                 if( inst.settings.disabled ) {
6783                         this._disableDatepicker( target );
6784                 }
6785         },
6786
6787         /* Make attachments based on settings. */
6788         _attachments: function(input, inst) {
6789                 var showOn, buttonText, buttonImage,
6790                         appendText = this._get(inst, "appendText"),
6791                         isRTL = this._get(inst, "isRTL");
6792
6793                 if (inst.append) {
6794                         inst.append.remove();
6795                 }
6796                 if (appendText) {
6797                         inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
6798                         input[isRTL ? "before" : "after"](inst.append);
6799                 }
6800
6801                 input.unbind("focus", this._showDatepicker);
6802
6803                 if (inst.trigger) {
6804                         inst.trigger.remove();
6805                 }
6806
6807                 showOn = this._get(inst, "showOn");
6808                 if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
6809                         input.focus(this._showDatepicker);
6810                 }
6811                 if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
6812                         buttonText = this._get(inst, "buttonText");
6813                         buttonImage = this._get(inst, "buttonImage");
6814                         inst.trigger = $(this._get(inst, "buttonImageOnly") ?
6815                                 $("<img/>").addClass(this._triggerClass).
6816                                         attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
6817                                 $("<button type='button'></button>").addClass(this._triggerClass).
6818                                         html(!buttonImage ? buttonText : $("<img/>").attr(
6819                                         { src:buttonImage, alt:buttonText, title:buttonText })));
6820                         input[isRTL ? "before" : "after"](inst.trigger);
6821                         inst.trigger.click(function() {
6822                                 if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
6823                                         $.datepicker._hideDatepicker();
6824                                 } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
6825                                         $.datepicker._hideDatepicker();
6826                                         $.datepicker._showDatepicker(input[0]);
6827                                 } else {
6828                                         $.datepicker._showDatepicker(input[0]);
6829                                 }
6830                                 return false;
6831                         });
6832                 }
6833         },
6834
6835         /* Apply the maximum length for the date format. */
6836         _autoSize: function(inst) {
6837                 if (this._get(inst, "autoSize") && !inst.inline) {
6838                         var findMax, max, maxI, i,
6839                                 date = new Date(2009, 12 - 1, 20), // Ensure double digits
6840                                 dateFormat = this._get(inst, "dateFormat");
6841
6842                         if (dateFormat.match(/[DM]/)) {
6843                                 findMax = function(names) {
6844                                         max = 0;
6845                                         maxI = 0;
6846                                         for (i = 0; i < names.length; i++) {
6847                                                 if (names[i].length > max) {
6848                                                         max = names[i].length;
6849                                                         maxI = i;
6850                                                 }
6851                                         }
6852                                         return maxI;
6853                                 };
6854                                 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
6855                                         "monthNames" : "monthNamesShort"))));
6856                                 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
6857                                         "dayNames" : "dayNamesShort"))) + 20 - date.getDay());
6858                         }
6859                         inst.input.attr("size", this._formatDate(inst, date).length);
6860                 }
6861         },
6862
6863         /* Attach an inline date picker to a div. */
6864         _inlineDatepicker: function(target, inst) {
6865                 var divSpan = $(target);
6866                 if (divSpan.hasClass(this.markerClassName)) {
6867                         return;
6868                 }
6869                 divSpan.addClass(this.markerClassName).append(inst.dpDiv);
6870                 $.data(target, "datepicker", inst);
6871                 this._setDate(inst, this._getDefaultDate(inst), true);
6872                 this._updateDatepicker(inst);
6873                 this._updateAlternate(inst);
6874                 //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
6875                 if( inst.settings.disabled ) {
6876                         this._disableDatepicker( target );
6877                 }
6878                 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
6879                 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
6880                 inst.dpDiv.css( "display", "block" );
6881         },
6882
6883         /* Pop-up the date picker in a "dialog" box.
6884          * @param  input element - ignored
6885          * @param  date string or Date - the initial date to display
6886          * @param  onSelect  function - the function to call when a date is selected
6887          * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
6888          * @param  pos int[2] - coordinates for the dialog's position within the screen or
6889          *                                      event - with x/y coordinates or
6890          *                                      leave empty for default (screen centre)
6891          * @return the manager object
6892          */
6893         _dialogDatepicker: function(input, date, onSelect, settings, pos) {
6894                 var id, browserWidth, browserHeight, scrollX, scrollY,
6895                         inst = this._dialogInst; // internal instance
6896
6897                 if (!inst) {
6898                         this.uuid += 1;
6899                         id = "dp" + this.uuid;
6900                         this._dialogInput = $("<input type='text' id='" + id +
6901                                 "' style='position: absolute; top: -100px; width: 0px;'/>");
6902                         this._dialogInput.keydown(this._doKeyDown);
6903                         $("body").append(this._dialogInput);
6904                         inst = this._dialogInst = this._newInst(this._dialogInput, false);
6905                         inst.settings = {};
6906                         $.data(this._dialogInput[0], "datepicker", inst);
6907                 }
6908                 datepicker_extendRemove(inst.settings, settings || {});
6909                 date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
6910                 this._dialogInput.val(date);
6911
6912                 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
6913                 if (!this._pos) {
6914                         browserWidth = document.documentElement.clientWidth;
6915                         browserHeight = document.documentElement.clientHeight;
6916                         scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
6917                         scrollY = document.documentElement.scrollTop || document.body.scrollTop;
6918                         this._pos = // should use actual width/height below
6919                                 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
6920                 }
6921
6922                 // move input on screen for focus, but hidden behind dialog
6923                 this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
6924                 inst.settings.onSelect = onSelect;
6925                 this._inDialog = true;
6926                 this.dpDiv.addClass(this._dialogClass);
6927                 this._showDatepicker(this._dialogInput[0]);
6928                 if ($.blockUI) {
6929                         $.blockUI(this.dpDiv);
6930                 }
6931                 $.data(this._dialogInput[0], "datepicker", inst);
6932                 return this;
6933         },
6934
6935         /* Detach a datepicker from its control.
6936          * @param  target       element - the target input field or division or span
6937          */
6938         _destroyDatepicker: function(target) {
6939                 var nodeName,
6940                         $target = $(target),
6941                         inst = $.data(target, "datepicker");
6942
6943                 if (!$target.hasClass(this.markerClassName)) {
6944                         return;
6945                 }
6946
6947                 nodeName = target.nodeName.toLowerCase();
6948                 $.removeData(target, "datepicker");
6949                 if (nodeName === "input") {
6950                         inst.append.remove();
6951                         inst.trigger.remove();
6952                         $target.removeClass(this.markerClassName).
6953                                 unbind("focus", this._showDatepicker).
6954                                 unbind("keydown", this._doKeyDown).
6955                                 unbind("keypress", this._doKeyPress).
6956                                 unbind("keyup", this._doKeyUp);
6957                 } else if (nodeName === "div" || nodeName === "span") {
6958                         $target.removeClass(this.markerClassName).empty();
6959                 }
6960
6961                 if ( datepicker_instActive === inst ) {
6962                         datepicker_instActive = null;
6963                 }
6964         },
6965
6966         /* Enable the date picker to a jQuery selection.
6967          * @param  target       element - the target input field or division or span
6968          */
6969         _enableDatepicker: function(target) {
6970                 var nodeName, inline,
6971                         $target = $(target),
6972                         inst = $.data(target, "datepicker");
6973
6974                 if (!$target.hasClass(this.markerClassName)) {
6975                         return;
6976                 }
6977
6978                 nodeName = target.nodeName.toLowerCase();
6979                 if (nodeName === "input") {
6980                         target.disabled = false;
6981                         inst.trigger.filter("button").
6982                                 each(function() { this.disabled = false; }).end().
6983                                 filter("img").css({opacity: "1.0", cursor: ""});
6984                 } else if (nodeName === "div" || nodeName === "span") {
6985                         inline = $target.children("." + this._inlineClass);
6986                         inline.children().removeClass("ui-state-disabled");
6987                         inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
6988                                 prop("disabled", false);
6989                 }
6990                 this._disabledInputs = $.map(this._disabledInputs,
6991                         function(value) { return (value === target ? null : value); }); // delete entry
6992         },
6993
6994         /* Disable the date picker to a jQuery selection.
6995          * @param  target       element - the target input field or division or span
6996          */
6997         _disableDatepicker: function(target) {
6998                 var nodeName, inline,
6999                         $target = $(target),
7000                         inst = $.data(target, "datepicker");
7001
7002                 if (!$target.hasClass(this.markerClassName)) {
7003                         return;
7004                 }
7005
7006                 nodeName = target.nodeName.toLowerCase();
7007                 if (nodeName === "input") {
7008                         target.disabled = true;
7009                         inst.trigger.filter("button").
7010                                 each(function() { this.disabled = true; }).end().
7011                                 filter("img").css({opacity: "0.5", cursor: "default"});
7012                 } else if (nodeName === "div" || nodeName === "span") {
7013                         inline = $target.children("." + this._inlineClass);
7014                         inline.children().addClass("ui-state-disabled");
7015                         inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7016                                 prop("disabled", true);
7017                 }
7018                 this._disabledInputs = $.map(this._disabledInputs,
7019                         function(value) { return (value === target ? null : value); }); // delete entry
7020                 this._disabledInputs[this._disabledInputs.length] = target;
7021         },
7022
7023         /* Is the first field in a jQuery collection disabled as a datepicker?
7024          * @param  target       element - the target input field or division or span
7025          * @return boolean - true if disabled, false if enabled
7026          */
7027         _isDisabledDatepicker: function(target) {
7028                 if (!target) {
7029                         return false;
7030                 }
7031                 for (var i = 0; i < this._disabledInputs.length; i++) {
7032                         if (this._disabledInputs[i] === target) {
7033                                 return true;
7034                         }
7035                 }
7036                 return false;
7037         },
7038
7039         /* Retrieve the instance data for the target control.
7040          * @param  target  element - the target input field or division or span
7041          * @return  object - the associated instance data
7042          * @throws  error if a jQuery problem getting data
7043          */
7044         _getInst: function(target) {
7045                 try {
7046                         return $.data(target, "datepicker");
7047                 }
7048                 catch (err) {
7049                         throw "Missing instance data for this datepicker";
7050                 }
7051         },
7052
7053         /* Update or retrieve the settings for a date picker attached to an input field or division.
7054          * @param  target  element - the target input field or division or span
7055          * @param  name object - the new settings to update or
7056          *                              string - the name of the setting to change or retrieve,
7057          *                              when retrieving also "all" for all instance settings or
7058          *                              "defaults" for all global defaults
7059          * @param  value   any - the new value for the setting
7060          *                              (omit if above is an object or to retrieve a value)
7061          */
7062         _optionDatepicker: function(target, name, value) {
7063                 var settings, date, minDate, maxDate,
7064                         inst = this._getInst(target);
7065
7066                 if (arguments.length === 2 && typeof name === "string") {
7067                         return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
7068                                 (inst ? (name === "all" ? $.extend({}, inst.settings) :
7069                                 this._get(inst, name)) : null));
7070                 }
7071
7072                 settings = name || {};
7073                 if (typeof name === "string") {
7074                         settings = {};
7075                         settings[name] = value;
7076                 }
7077
7078                 if (inst) {
7079                         if (this._curInst === inst) {
7080                                 this._hideDatepicker();
7081                         }
7082
7083                         date = this._getDateDatepicker(target, true);
7084                         minDate = this._getMinMaxDate(inst, "min");
7085                         maxDate = this._getMinMaxDate(inst, "max");
7086                         datepicker_extendRemove(inst.settings, settings);
7087                         // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
7088                         if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
7089                                 inst.settings.minDate = this._formatDate(inst, minDate);
7090                         }
7091                         if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
7092                                 inst.settings.maxDate = this._formatDate(inst, maxDate);
7093                         }
7094                         if ( "disabled" in settings ) {
7095                                 if ( settings.disabled ) {
7096                                         this._disableDatepicker(target);
7097                                 } else {
7098                                         this._enableDatepicker(target);
7099                                 }
7100                         }
7101                         this._attachments($(target), inst);
7102                         this._autoSize(inst);
7103                         this._setDate(inst, date);
7104                         this._updateAlternate(inst);
7105                         this._updateDatepicker(inst);
7106                 }
7107         },
7108
7109         // change method deprecated
7110         _changeDatepicker: function(target, name, value) {
7111                 this._optionDatepicker(target, name, value);
7112         },
7113
7114         /* Redraw the date picker attached to an input field or division.
7115          * @param  target  element - the target input field or division or span
7116          */
7117         _refreshDatepicker: function(target) {
7118                 var inst = this._getInst(target);
7119                 if (inst) {
7120                         this._updateDatepicker(inst);
7121                 }
7122         },
7123
7124         /* Set the dates for a jQuery selection.
7125          * @param  target element - the target input field or division or span
7126          * @param  date Date - the new date
7127          */
7128         _setDateDatepicker: function(target, date) {
7129                 var inst = this._getInst(target);
7130                 if (inst) {
7131                         this._setDate(inst, date);
7132                         this._updateDatepicker(inst);
7133                         this._updateAlternate(inst);
7134                 }
7135         },
7136
7137         /* Get the date(s) for the first entry in a jQuery selection.
7138          * @param  target element - the target input field or division or span
7139          * @param  noDefault boolean - true if no default date is to be used
7140          * @return Date - the current date
7141          */
7142         _getDateDatepicker: function(target, noDefault) {
7143                 var inst = this._getInst(target);
7144                 if (inst && !inst.inline) {
7145                         this._setDateFromField(inst, noDefault);
7146                 }
7147                 return (inst ? this._getDate(inst) : null);
7148         },
7149
7150         /* Handle keystrokes. */
7151         _doKeyDown: function(event) {
7152                 var onSelect, dateStr, sel,
7153                         inst = $.datepicker._getInst(event.target),
7154                         handled = true,
7155                         isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
7156
7157                 inst._keyEvent = true;
7158                 if ($.datepicker._datepickerShowing) {
7159                         switch (event.keyCode) {
7160                                 case 9: $.datepicker._hideDatepicker();
7161                                                 handled = false;
7162                                                 break; // hide on tab out
7163                                 case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
7164                                                                         $.datepicker._currentClass + ")", inst.dpDiv);
7165                                                 if (sel[0]) {
7166                                                         $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
7167                                                 }
7168
7169                                                 onSelect = $.datepicker._get(inst, "onSelect");
7170                                                 if (onSelect) {
7171                                                         dateStr = $.datepicker._formatDate(inst);
7172
7173                                                         // trigger custom callback
7174                                                         onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
7175                                                 } else {
7176                                                         $.datepicker._hideDatepicker();
7177                                                 }
7178
7179                                                 return false; // don't submit the form
7180                                 case 27: $.datepicker._hideDatepicker();
7181                                                 break; // hide on escape
7182                                 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7183                                                         -$.datepicker._get(inst, "stepBigMonths") :
7184                                                         -$.datepicker._get(inst, "stepMonths")), "M");
7185                                                 break; // previous month/year on page up/+ ctrl
7186                                 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7187                                                         +$.datepicker._get(inst, "stepBigMonths") :
7188                                                         +$.datepicker._get(inst, "stepMonths")), "M");
7189                                                 break; // next month/year on page down/+ ctrl
7190                                 case 35: if (event.ctrlKey || event.metaKey) {
7191                                                         $.datepicker._clearDate(event.target);
7192                                                 }
7193                                                 handled = event.ctrlKey || event.metaKey;
7194                                                 break; // clear on ctrl or command +end
7195                                 case 36: if (event.ctrlKey || event.metaKey) {
7196                                                         $.datepicker._gotoToday(event.target);
7197                                                 }
7198                                                 handled = event.ctrlKey || event.metaKey;
7199                                                 break; // current on ctrl or command +home
7200                                 case 37: if (event.ctrlKey || event.metaKey) {
7201                                                         $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
7202                                                 }
7203                                                 handled = event.ctrlKey || event.metaKey;
7204                                                 // -1 day on ctrl or command +left
7205                                                 if (event.originalEvent.altKey) {
7206                                                         $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7207                                                                 -$.datepicker._get(inst, "stepBigMonths") :
7208                                                                 -$.datepicker._get(inst, "stepMonths")), "M");
7209                                                 }
7210                                                 // next month/year on alt +left on Mac
7211                                                 break;
7212                                 case 38: if (event.ctrlKey || event.metaKey) {
7213                                                         $.datepicker._adjustDate(event.target, -7, "D");
7214                                                 }
7215                                                 handled = event.ctrlKey || event.metaKey;
7216                                                 break; // -1 week on ctrl or command +up
7217                                 case 39: if (event.ctrlKey || event.metaKey) {
7218                                                         $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
7219                                                 }
7220                                                 handled = event.ctrlKey || event.metaKey;
7221                                                 // +1 day on ctrl or command +right
7222                                                 if (event.originalEvent.altKey) {
7223                                                         $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7224                                                                 +$.datepicker._get(inst, "stepBigMonths") :
7225                                                                 +$.datepicker._get(inst, "stepMonths")), "M");
7226                                                 }
7227                                                 // next month/year on alt +right
7228                                                 break;
7229                                 case 40: if (event.ctrlKey || event.metaKey) {
7230                                                         $.datepicker._adjustDate(event.target, +7, "D");
7231                                                 }
7232                                                 handled = event.ctrlKey || event.metaKey;
7233                                                 break; // +1 week on ctrl or command +down
7234                                 default: handled = false;
7235                         }
7236                 } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
7237                         $.datepicker._showDatepicker(this);
7238                 } else {
7239                         handled = false;
7240                 }
7241
7242                 if (handled) {
7243                         event.preventDefault();
7244                         event.stopPropagation();
7245                 }
7246         },
7247
7248         /* Filter entered characters - based on date format. */
7249         _doKeyPress: function(event) {
7250                 var chars, chr,
7251                         inst = $.datepicker._getInst(event.target);
7252
7253                 if ($.datepicker._get(inst, "constrainInput")) {
7254                         chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
7255                         chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
7256                         return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
7257                 }
7258         },
7259
7260         /* Synchronise manual entry and field/alternate field. */
7261         _doKeyUp: function(event) {
7262                 var date,
7263                         inst = $.datepicker._getInst(event.target);
7264
7265                 if (inst.input.val() !== inst.lastVal) {
7266                         try {
7267                                 date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
7268                                         (inst.input ? inst.input.val() : null),
7269                                         $.datepicker._getFormatConfig(inst));
7270
7271                                 if (date) { // only if valid
7272                                         $.datepicker._setDateFromField(inst);
7273                                         $.datepicker._updateAlternate(inst);
7274                                         $.datepicker._updateDatepicker(inst);
7275                                 }
7276                         }
7277                         catch (err) {
7278                         }
7279                 }
7280                 return true;
7281         },
7282
7283         /* Pop-up the date picker for a given input field.
7284          * If false returned from beforeShow event handler do not show.
7285          * @param  input  element - the input field attached to the date picker or
7286          *                                      event - if triggered by focus
7287          */
7288         _showDatepicker: function(input) {
7289                 input = input.target || input;
7290                 if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
7291                         input = $("input", input.parentNode)[0];
7292                 }
7293
7294                 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
7295                         return;
7296                 }
7297
7298                 var inst, beforeShow, beforeShowSettings, isFixed,
7299                         offset, showAnim, duration;
7300
7301                 inst = $.datepicker._getInst(input);
7302                 if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
7303                         $.datepicker._curInst.dpDiv.stop(true, true);
7304                         if ( inst && $.datepicker._datepickerShowing ) {
7305                                 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
7306                         }
7307                 }
7308
7309                 beforeShow = $.datepicker._get(inst, "beforeShow");
7310                 beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
7311                 if(beforeShowSettings === false){
7312                         return;
7313                 }
7314                 datepicker_extendRemove(inst.settings, beforeShowSettings);
7315
7316                 inst.lastVal = null;
7317                 $.datepicker._lastInput = input;
7318                 $.datepicker._setDateFromField(inst);
7319
7320                 if ($.datepicker._inDialog) { // hide cursor
7321                         input.value = "";
7322                 }
7323                 if (!$.datepicker._pos) { // position below input
7324                         $.datepicker._pos = $.datepicker._findPos(input);
7325                         $.datepicker._pos[1] += input.offsetHeight; // add the height
7326                 }
7327
7328                 isFixed = false;
7329                 $(input).parents().each(function() {
7330                         isFixed |= $(this).css("position") === "fixed";
7331                         return !isFixed;
7332                 });
7333
7334                 offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
7335                 $.datepicker._pos = null;
7336                 //to avoid flashes on Firefox
7337                 inst.dpDiv.empty();
7338                 // determine sizing offscreen
7339                 inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
7340                 $.datepicker._updateDatepicker(inst);
7341                 // fix width for dynamic number of date pickers
7342                 // and adjust position before showing
7343                 offset = $.datepicker._checkOffset(inst, offset, isFixed);
7344                 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
7345                         "static" : (isFixed ? "fixed" : "absolute")), display: "none",
7346                         left: offset.left + "px", top: offset.top + "px"});
7347
7348                 if (!inst.inline) {
7349                         showAnim = $.datepicker._get(inst, "showAnim");
7350                         duration = $.datepicker._get(inst, "duration");
7351                         inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
7352                         $.datepicker._datepickerShowing = true;
7353
7354                         if ( $.effects && $.effects.effect[ showAnim ] ) {
7355                                 inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
7356                         } else {
7357                                 inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
7358                         }
7359
7360                         if ( $.datepicker._shouldFocusInput( inst ) ) {
7361                                 inst.input.focus();
7362                         }
7363
7364                         $.datepicker._curInst = inst;
7365                 }
7366         },
7367
7368         /* Generate the date picker content. */
7369         _updateDatepicker: function(inst) {
7370                 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
7371                 datepicker_instActive = inst; // for delegate hover events
7372                 inst.dpDiv.empty().append(this._generateHTML(inst));
7373                 this._attachHandlers(inst);
7374
7375                 var origyearshtml,
7376                         numMonths = this._getNumberOfMonths(inst),
7377                         cols = numMonths[1],
7378                         width = 17,
7379                         activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
7380
7381                 if ( activeCell.length > 0 ) {
7382                         datepicker_handleMouseover.apply( activeCell.get( 0 ) );
7383                 }
7384
7385                 inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
7386                 if (cols > 1) {
7387                         inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
7388                 }
7389                 inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
7390                         "Class"]("ui-datepicker-multi");
7391                 inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
7392                         "Class"]("ui-datepicker-rtl");
7393
7394                 if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
7395                         inst.input.focus();
7396                 }
7397
7398                 // deffered render of the years select (to avoid flashes on Firefox)
7399                 if( inst.yearshtml ){
7400                         origyearshtml = inst.yearshtml;
7401                         setTimeout(function(){
7402                                 //assure that inst.yearshtml didn't change.
7403                                 if( origyearshtml === inst.yearshtml && inst.yearshtml ){
7404                                         inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
7405                                 }
7406                                 origyearshtml = inst.yearshtml = null;
7407                         }, 0);
7408                 }
7409         },
7410
7411         // #6694 - don't focus the input if it's already focused
7412         // this breaks the change event in IE
7413         // Support: IE and jQuery <1.9
7414         _shouldFocusInput: function( inst ) {
7415                 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
7416         },
7417
7418         /* Check positioning to remain on screen. */
7419         _checkOffset: function(inst, offset, isFixed) {
7420                 var dpWidth = inst.dpDiv.outerWidth(),
7421                         dpHeight = inst.dpDiv.outerHeight(),
7422                         inputWidth = inst.input ? inst.input.outerWidth() : 0,
7423                         inputHeight = inst.input ? inst.input.outerHeight() : 0,
7424                         viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
7425                         viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
7426
7427                 offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
7428                 offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
7429                 offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
7430
7431                 // now check if datepicker is showing outside window viewport - move to a better place if so.
7432                 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
7433                         Math.abs(offset.left + dpWidth - viewWidth) : 0);
7434                 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
7435                         Math.abs(dpHeight + inputHeight) : 0);
7436
7437                 return offset;
7438         },
7439
7440         /* Find an object's position on the screen. */
7441         _findPos: function(obj) {
7442                 var position,
7443                         inst = this._getInst(obj),
7444                         isRTL = this._get(inst, "isRTL");
7445
7446                 while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
7447                         obj = obj[isRTL ? "previousSibling" : "nextSibling"];
7448                 }
7449
7450                 position = $(obj).offset();
7451                 return [position.left, position.top];
7452         },
7453
7454         /* Hide the date picker from view.
7455          * @param  input  element - the input field attached to the date picker
7456          */
7457         _hideDatepicker: function(input) {
7458                 var showAnim, duration, postProcess, onClose,
7459                         inst = this._curInst;
7460
7461                 if (!inst || (input && inst !== $.data(input, "datepicker"))) {
7462                         return;
7463                 }
7464
7465                 if (this._datepickerShowing) {
7466                         showAnim = this._get(inst, "showAnim");
7467                         duration = this._get(inst, "duration");
7468                         postProcess = function() {
7469                                 $.datepicker._tidyDialog(inst);
7470                         };
7471
7472                         // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
7473                         if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
7474                                 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
7475                         } else {
7476                                 inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
7477                                         (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
7478                         }
7479
7480                         if (!showAnim) {
7481                                 postProcess();
7482                         }
7483                         this._datepickerShowing = false;
7484
7485                         onClose = this._get(inst, "onClose");
7486                         if (onClose) {
7487                                 onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
7488                         }
7489
7490                         this._lastInput = null;
7491                         if (this._inDialog) {
7492                                 this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
7493                                 if ($.blockUI) {
7494                                         $.unblockUI();
7495                                         $("body").append(this.dpDiv);
7496                                 }
7497                         }
7498                         this._inDialog = false;
7499                 }
7500         },
7501
7502         /* Tidy up after a dialog display. */
7503         _tidyDialog: function(inst) {
7504                 inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
7505         },
7506
7507         /* Close date picker if clicked elsewhere. */
7508         _checkExternalClick: function(event) {
7509                 if (!$.datepicker._curInst) {
7510                         return;
7511                 }
7512
7513                 var $target = $(event.target),
7514                         inst = $.datepicker._getInst($target[0]);
7515
7516                 if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
7517                                 $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
7518                                 !$target.hasClass($.datepicker.markerClassName) &&
7519                                 !$target.closest("." + $.datepicker._triggerClass).length &&
7520                                 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
7521                         ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
7522                                 $.datepicker._hideDatepicker();
7523                 }
7524         },
7525
7526         /* Adjust one of the date sub-fields. */
7527         _adjustDate: function(id, offset, period) {
7528                 var target = $(id),
7529                         inst = this._getInst(target[0]);
7530
7531                 if (this._isDisabledDatepicker(target[0])) {
7532                         return;
7533                 }
7534                 this._adjustInstDate(inst, offset +
7535                         (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
7536                         period);
7537                 this._updateDatepicker(inst);
7538         },
7539
7540         /* Action for current link. */
7541         _gotoToday: function(id) {
7542                 var date,
7543                         target = $(id),
7544                         inst = this._getInst(target[0]);
7545
7546                 if (this._get(inst, "gotoCurrent") && inst.currentDay) {
7547                         inst.selectedDay = inst.currentDay;
7548                         inst.drawMonth = inst.selectedMonth = inst.currentMonth;
7549                         inst.drawYear = inst.selectedYear = inst.currentYear;
7550                 } else {
7551                         date = new Date();
7552                         inst.selectedDay = date.getDate();
7553                         inst.drawMonth = inst.selectedMonth = date.getMonth();
7554                         inst.drawYear = inst.selectedYear = date.getFullYear();
7555                 }
7556                 this._notifyChange(inst);
7557                 this._adjustDate(target);
7558         },
7559
7560         /* Action for selecting a new month/year. */
7561         _selectMonthYear: function(id, select, period) {
7562                 var target = $(id),
7563                         inst = this._getInst(target[0]);
7564
7565                 inst["selected" + (period === "M" ? "Month" : "Year")] =
7566                 inst["draw" + (period === "M" ? "Month" : "Year")] =
7567                         parseInt(select.options[select.selectedIndex].value,10);
7568
7569                 this._notifyChange(inst);
7570                 this._adjustDate(target);
7571         },
7572
7573         /* Action for selecting a day. */
7574         _selectDay: function(id, month, year, td) {
7575                 var inst,
7576                         target = $(id);
7577
7578                 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
7579                         return;
7580                 }
7581
7582                 inst = this._getInst(target[0]);
7583                 inst.selectedDay = inst.currentDay = $("a", td).html();
7584                 inst.selectedMonth = inst.currentMonth = month;
7585                 inst.selectedYear = inst.currentYear = year;
7586                 this._selectDate(id, this._formatDate(inst,
7587                         inst.currentDay, inst.currentMonth, inst.currentYear));
7588         },
7589
7590         /* Erase the input field and hide the date picker. */
7591         _clearDate: function(id) {
7592                 var target = $(id);
7593                 this._selectDate(target, "");
7594         },
7595
7596         /* Update the input field with the selected date. */
7597         _selectDate: function(id, dateStr) {
7598                 var onSelect,
7599                         target = $(id),
7600                         inst = this._getInst(target[0]);
7601
7602                 dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
7603                 if (inst.input) {
7604                         inst.input.val(dateStr);
7605                 }
7606                 this._updateAlternate(inst);
7607
7608                 onSelect = this._get(inst, "onSelect");
7609                 if (onSelect) {
7610                         onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
7611                 } else if (inst.input) {
7612                         inst.input.trigger("change"); // fire the change event
7613                 }
7614
7615                 if (inst.inline){
7616                         this._updateDatepicker(inst);
7617                 } else {
7618                         this._hideDatepicker();
7619                         this._lastInput = inst.input[0];
7620                         if (typeof(inst.input[0]) !== "object") {
7621                                 inst.input.focus(); // restore focus
7622                         }
7623                         this._lastInput = null;
7624                 }
7625         },
7626
7627         /* Update any alternate field to synchronise with the main field. */
7628         _updateAlternate: function(inst) {
7629                 var altFormat, date, dateStr,
7630                         altField = this._get(inst, "altField");
7631
7632                 if (altField) { // update alternate field too
7633                         altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
7634                         date = this._getDate(inst);
7635                         dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
7636                         $(altField).each(function() { $(this).val(dateStr); });
7637                 }
7638         },
7639
7640         /* Set as beforeShowDay function to prevent selection of weekends.
7641          * @param  date  Date - the date to customise
7642          * @return [boolean, string] - is this date selectable?, what is its CSS class?
7643          */
7644         noWeekends: function(date) {
7645                 var day = date.getDay();
7646                 return [(day > 0 && day < 6), ""];
7647         },
7648
7649         /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
7650          * @param  date  Date - the date to get the week for
7651          * @return  number - the number of the week within the year that contains this date
7652          */
7653         iso8601Week: function(date) {
7654                 var time,
7655                         checkDate = new Date(date.getTime());
7656
7657                 // Find Thursday of this week starting on Monday
7658                 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
7659
7660                 time = checkDate.getTime();
7661                 checkDate.setMonth(0); // Compare with Jan 1
7662                 checkDate.setDate(1);
7663                 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
7664         },
7665
7666         /* Parse a string value into a date object.
7667          * See formatDate below for the possible formats.
7668          *
7669          * @param  format string - the expected format of the date
7670          * @param  value string - the date in the above format
7671          * @param  settings Object - attributes include:
7672          *                                      shortYearCutoff  number - the cutoff year for determining the century (optional)
7673          *                                      dayNamesShort   string[7] - abbreviated names of the days from Sunday (optional)
7674          *                                      dayNames                string[7] - names of the days from Sunday (optional)
7675          *                                      monthNamesShort string[12] - abbreviated names of the months (optional)
7676          *                                      monthNames              string[12] - names of the months (optional)
7677          * @return  Date - the extracted date value or null if value is blank
7678          */
7679         parseDate: function (format, value, settings) {
7680                 if (format == null || value == null) {
7681                         throw "Invalid arguments";
7682                 }
7683
7684                 value = (typeof value === "object" ? value.toString() : value + "");
7685                 if (value === "") {
7686                         return null;
7687                 }
7688
7689                 var iFormat, dim, extra,
7690                         iValue = 0,
7691                         shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
7692                         shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
7693                                 new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
7694                         dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
7695                         dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
7696                         monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
7697                         monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
7698                         year = -1,
7699                         month = -1,
7700                         day = -1,
7701                         doy = -1,
7702                         literal = false,
7703                         date,
7704                         // Check whether a format character is doubled
7705                         lookAhead = function(match) {
7706                                 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
7707                                 if (matches) {
7708                                         iFormat++;
7709                                 }
7710                                 return matches;
7711                         },
7712                         // Extract a number from the string value
7713                         getNumber = function(match) {
7714                                 var isDoubled = lookAhead(match),
7715                                         size = (match === "@" ? 14 : (match === "!" ? 20 :
7716                                         (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
7717                                         minSize = (match === "y" ? size : 1),
7718                                         digits = new RegExp("^\\d{" + minSize + "," + size + "}"),
7719                                         num = value.substring(iValue).match(digits);
7720                                 if (!num) {
7721                                         throw "Missing number at position " + iValue;
7722                                 }
7723                                 iValue += num[0].length;
7724                                 return parseInt(num[0], 10);
7725                         },
7726                         // Extract a name from the string value and convert to an index
7727                         getName = function(match, shortNames, longNames) {
7728                                 var index = -1,
7729                                         names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
7730                                                 return [ [k, v] ];
7731                                         }).sort(function (a, b) {
7732                                                 return -(a[1].length - b[1].length);
7733                                         });
7734
7735                                 $.each(names, function (i, pair) {
7736                                         var name = pair[1];
7737                                         if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
7738                                                 index = pair[0];
7739                                                 iValue += name.length;
7740                                                 return false;
7741                                         }
7742                                 });
7743                                 if (index !== -1) {
7744                                         return index + 1;
7745                                 } else {
7746                                         throw "Unknown name at position " + iValue;
7747                                 }
7748                         },
7749                         // Confirm that a literal character matches the string value
7750                         checkLiteral = function() {
7751                                 if (value.charAt(iValue) !== format.charAt(iFormat)) {
7752                                         throw "Unexpected literal at position " + iValue;
7753                                 }
7754                                 iValue++;
7755                         };
7756
7757                 for (iFormat = 0; iFormat < format.length; iFormat++) {
7758                         if (literal) {
7759                                 if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
7760                                         literal = false;
7761                                 } else {
7762                                         checkLiteral();
7763                                 }
7764                         } else {
7765                                 switch (format.charAt(iFormat)) {
7766                                         case "d":
7767                                                 day = getNumber("d");
7768                                                 break;
7769                                         case "D":
7770                                                 getName("D", dayNamesShort, dayNames);
7771                                                 break;
7772                                         case "o":
7773                                                 doy = getNumber("o");
7774                                                 break;
7775                                         case "m":
7776                                                 month = getNumber("m");
7777                                                 break;
7778                                         case "M":
7779                                                 month = getName("M", monthNamesShort, monthNames);
7780                                                 break;
7781                                         case "y":
7782                                                 year = getNumber("y");
7783                                                 break;
7784                                         case "@":
7785                                                 date = new Date(getNumber("@"));
7786                                                 year = date.getFullYear();
7787                                                 month = date.getMonth() + 1;
7788                                                 day = date.getDate();
7789                                                 break;
7790                                         case "!":
7791                                                 date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
7792                                                 year = date.getFullYear();
7793                                                 month = date.getMonth() + 1;
7794                                                 day = date.getDate();
7795                                                 break;
7796                                         case "'":
7797                                                 if (lookAhead("'")){
7798                                                         checkLiteral();
7799                                                 } else {
7800                                                         literal = true;
7801                                                 }
7802                                                 break;
7803                                         default:
7804                                                 checkLiteral();
7805                                 }
7806                         }
7807                 }
7808
7809                 if (iValue < value.length){
7810                         extra = value.substr(iValue);
7811                         if (!/^\s+/.test(extra)) {
7812                                 throw "Extra/unparsed characters found in date: " + extra;
7813                         }
7814                 }
7815
7816                 if (year === -1) {
7817                         year = new Date().getFullYear();
7818                 } else if (year < 100) {
7819                         year += new Date().getFullYear() - new Date().getFullYear() % 100 +
7820                                 (year <= shortYearCutoff ? 0 : -100);
7821                 }
7822
7823                 if (doy > -1) {
7824                         month = 1;
7825                         day = doy;
7826                         do {
7827                                 dim = this._getDaysInMonth(year, month - 1);
7828                                 if (day <= dim) {
7829                                         break;
7830                                 }
7831                                 month++;
7832                                 day -= dim;
7833                         } while (true);
7834                 }
7835
7836                 date = this._daylightSavingAdjust(new Date(year, month - 1, day));
7837                 if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
7838                         throw "Invalid date"; // E.g. 31/02/00
7839                 }
7840                 return date;
7841         },
7842
7843         /* Standard date formats. */
7844         ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
7845         COOKIE: "D, dd M yy",
7846         ISO_8601: "yy-mm-dd",
7847         RFC_822: "D, d M y",
7848         RFC_850: "DD, dd-M-y",
7849         RFC_1036: "D, d M y",
7850         RFC_1123: "D, d M yy",
7851         RFC_2822: "D, d M yy",
7852         RSS: "D, d M y", // RFC 822
7853         TICKS: "!",
7854         TIMESTAMP: "@",
7855         W3C: "yy-mm-dd", // ISO 8601
7856
7857         _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
7858                 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
7859
7860         /* Format a date object into a string value.
7861          * The format can be combinations of the following:
7862          * d  - day of month (no leading zero)
7863          * dd - day of month (two digit)
7864          * o  - day of year (no leading zeros)
7865          * oo - day of year (three digit)
7866          * D  - day name short
7867          * DD - day name long
7868          * m  - month of year (no leading zero)
7869          * mm - month of year (two digit)
7870          * M  - month name short
7871          * MM - month name long
7872          * y  - year (two digit)
7873          * yy - year (four digit)
7874          * @ - Unix timestamp (ms since 01/01/1970)
7875          * ! - Windows ticks (100ns since 01/01/0001)
7876          * "..." - literal text
7877          * '' - single quote
7878          *
7879          * @param  format string - the desired format of the date
7880          * @param  date Date - the date value to format
7881          * @param  settings Object - attributes include:
7882          *                                      dayNamesShort   string[7] - abbreviated names of the days from Sunday (optional)
7883          *                                      dayNames                string[7] - names of the days from Sunday (optional)
7884          *                                      monthNamesShort string[12] - abbreviated names of the months (optional)
7885          *                                      monthNames              string[12] - names of the months (optional)
7886          * @return  string - the date in the above format
7887          */
7888         formatDate: function (format, date, settings) {
7889                 if (!date) {
7890                         return "";
7891                 }
7892
7893                 var iFormat,
7894                         dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
7895                         dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
7896                         monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
7897                         monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
7898                         // Check whether a format character is doubled
7899                         lookAhead = function(match) {
7900                                 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
7901                                 if (matches) {
7902                                         iFormat++;
7903                                 }
7904                                 return matches;
7905                         },
7906                         // Format a number, with leading zero if necessary
7907                         formatNumber = function(match, value, len) {
7908                                 var num = "" + value;
7909                                 if (lookAhead(match)) {
7910                                         while (num.length < len) {
7911                                                 num = "0" + num;
7912                                         }
7913                                 }
7914                                 return num;
7915                         },
7916                         // Format a name, short or long as requested
7917                         formatName = function(match, value, shortNames, longNames) {
7918                                 return (lookAhead(match) ? longNames[value] : shortNames[value]);
7919                         },
7920                         output = "",
7921                         literal = false;
7922
7923                 if (date) {
7924                         for (iFormat = 0; iFormat < format.length; iFormat++) {
7925                                 if (literal) {
7926                                         if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
7927                                                 literal = false;
7928                                         } else {
7929                                                 output += format.charAt(iFormat);
7930                                         }
7931                                 } else {
7932                                         switch (format.charAt(iFormat)) {
7933                                                 case "d":
7934                                                         output += formatNumber("d", date.getDate(), 2);
7935                                                         break;
7936                                                 case "D":
7937                                                         output += formatName("D", date.getDay(), dayNamesShort, dayNames);
7938                                                         break;
7939                                                 case "o":
7940                                                         output += formatNumber("o",
7941                                                                 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
7942                                                         break;
7943                                                 case "m":
7944                                                         output += formatNumber("m", date.getMonth() + 1, 2);
7945                                                         break;
7946                                                 case "M":
7947                                                         output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
7948                                                         break;
7949                                                 case "y":
7950                                                         output += (lookAhead("y") ? date.getFullYear() :
7951                                                                 (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
7952                                                         break;
7953                                                 case "@":
7954                                                         output += date.getTime();
7955                                                         break;
7956                                                 case "!":
7957                                                         output += date.getTime() * 10000 + this._ticksTo1970;
7958                                                         break;
7959                                                 case "'":
7960                                                         if (lookAhead("'")) {
7961                                                                 output += "'";
7962                                                         } else {
7963                                                                 literal = true;
7964                                                         }
7965                                                         break;
7966                                                 default:
7967                                                         output += format.charAt(iFormat);
7968                                         }
7969                                 }
7970                         }
7971                 }
7972                 return output;
7973         },
7974
7975         /* Extract all possible characters from the date format. */
7976         _possibleChars: function (format) {
7977                 var iFormat,
7978                         chars = "",
7979                         literal = false,
7980                         // Check whether a format character is doubled
7981                         lookAhead = function(match) {
7982                                 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
7983                                 if (matches) {
7984                                         iFormat++;
7985                                 }
7986                                 return matches;
7987                         };
7988
7989                 for (iFormat = 0; iFormat < format.length; iFormat++) {
7990                         if (literal) {
7991                                 if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
7992                                         literal = false;
7993                                 } else {
7994                                         chars += format.charAt(iFormat);
7995                                 }
7996                         } else {
7997                                 switch (format.charAt(iFormat)) {
7998                                         case "d": case "m": case "y": case "@":
7999                                                 chars += "0123456789";
8000                                                 break;
8001                                         case "D": case "M":
8002                                                 return null; // Accept anything
8003                                         case "'":
8004                                                 if (lookAhead("'")) {
8005                                                         chars += "'";
8006                                                 } else {
8007                                                         literal = true;
8008                                                 }
8009                                                 break;
8010                                         default:
8011                                                 chars += format.charAt(iFormat);
8012                                 }
8013                         }
8014                 }
8015                 return chars;
8016         },
8017
8018         /* Get a setting value, defaulting if necessary. */
8019         _get: function(inst, name) {
8020                 return inst.settings[name] !== undefined ?
8021                         inst.settings[name] : this._defaults[name];
8022         },
8023
8024         /* Parse existing date and initialise date picker. */
8025         _setDateFromField: function(inst, noDefault) {
8026                 if (inst.input.val() === inst.lastVal) {
8027                         return;
8028                 }
8029
8030                 var dateFormat = this._get(inst, "dateFormat"),
8031                         dates = inst.lastVal = inst.input ? inst.input.val() : null,
8032                         defaultDate = this._getDefaultDate(inst),
8033                         date = defaultDate,
8034                         settings = this._getFormatConfig(inst);
8035
8036                 try {
8037                         date = this.parseDate(dateFormat, dates, settings) || defaultDate;
8038                 } catch (event) {
8039                         dates = (noDefault ? "" : dates);
8040                 }
8041                 inst.selectedDay = date.getDate();
8042                 inst.drawMonth = inst.selectedMonth = date.getMonth();
8043                 inst.drawYear = inst.selectedYear = date.getFullYear();
8044                 inst.currentDay = (dates ? date.getDate() : 0);
8045                 inst.currentMonth = (dates ? date.getMonth() : 0);
8046                 inst.currentYear = (dates ? date.getFullYear() : 0);
8047                 this._adjustInstDate(inst);
8048         },
8049
8050         /* Retrieve the default date shown on opening. */
8051         _getDefaultDate: function(inst) {
8052                 return this._restrictMinMax(inst,
8053                         this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
8054         },
8055
8056         /* A date may be specified as an exact value or a relative one. */
8057         _determineDate: function(inst, date, defaultDate) {
8058                 var offsetNumeric = function(offset) {
8059                                 var date = new Date();
8060                                 date.setDate(date.getDate() + offset);
8061                                 return date;
8062                         },
8063                         offsetString = function(offset) {
8064                                 try {
8065                                         return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
8066                                                 offset, $.datepicker._getFormatConfig(inst));
8067                                 }
8068                                 catch (e) {
8069                                         // Ignore
8070                                 }
8071
8072                                 var date = (offset.toLowerCase().match(/^c/) ?
8073                                         $.datepicker._getDate(inst) : null) || new Date(),
8074                                         year = date.getFullYear(),
8075                                         month = date.getMonth(),
8076                                         day = date.getDate(),
8077                                         pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
8078                                         matches = pattern.exec(offset);
8079
8080                                 while (matches) {
8081                                         switch (matches[2] || "d") {
8082                                                 case "d" : case "D" :
8083                                                         day += parseInt(matches[1],10); break;
8084                                                 case "w" : case "W" :
8085                                                         day += parseInt(matches[1],10) * 7; break;
8086                                                 case "m" : case "M" :
8087                                                         month += parseInt(matches[1],10);
8088                                                         day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
8089                                                         break;
8090                                                 case "y": case "Y" :
8091                                                         year += parseInt(matches[1],10);
8092                                                         day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
8093                                                         break;
8094                                         }
8095                                         matches = pattern.exec(offset);
8096                                 }
8097                                 return new Date(year, month, day);
8098                         },
8099                         newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
8100                                 (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
8101
8102                 newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
8103                 if (newDate) {
8104                         newDate.setHours(0);
8105                         newDate.setMinutes(0);
8106                         newDate.setSeconds(0);
8107                         newDate.setMilliseconds(0);
8108                 }
8109                 return this._daylightSavingAdjust(newDate);
8110         },
8111
8112         /* Handle switch to/from daylight saving.
8113          * Hours may be non-zero on daylight saving cut-over:
8114          * > 12 when midnight changeover, but then cannot generate
8115          * midnight datetime, so jump to 1AM, otherwise reset.
8116          * @param  date  (Date) the date to check
8117          * @return  (Date) the corrected date
8118          */
8119         _daylightSavingAdjust: function(date) {
8120                 if (!date) {
8121                         return null;
8122                 }
8123                 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
8124                 return date;
8125         },
8126
8127         /* Set the date(s) directly. */
8128         _setDate: function(inst, date, noChange) {
8129                 var clear = !date,
8130                         origMonth = inst.selectedMonth,
8131                         origYear = inst.selectedYear,
8132                         newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
8133
8134                 inst.selectedDay = inst.currentDay = newDate.getDate();
8135                 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
8136                 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
8137                 if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
8138                         this._notifyChange(inst);
8139                 }
8140                 this._adjustInstDate(inst);
8141                 if (inst.input) {
8142                         inst.input.val(clear ? "" : this._formatDate(inst));
8143                 }
8144         },
8145
8146         /* Retrieve the date(s) directly. */
8147         _getDate: function(inst) {
8148                 var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
8149                         this._daylightSavingAdjust(new Date(
8150                         inst.currentYear, inst.currentMonth, inst.currentDay)));
8151                         return startDate;
8152         },
8153
8154         /* Attach the onxxx handlers.  These are declared statically so
8155          * they work with static code transformers like Caja.
8156          */
8157         _attachHandlers: function(inst) {
8158                 var stepMonths = this._get(inst, "stepMonths"),
8159                         id = "#" + inst.id.replace( /\\\\/g, "\\" );
8160                 inst.dpDiv.find("[data-handler]").map(function () {
8161                         var handler = {
8162                                 prev: function () {
8163                                         $.datepicker._adjustDate(id, -stepMonths, "M");
8164                                 },
8165                                 next: function () {
8166                                         $.datepicker._adjustDate(id, +stepMonths, "M");
8167                                 },
8168                                 hide: function () {
8169                                         $.datepicker._hideDatepicker();
8170                                 },
8171                                 today: function () {
8172                                         $.datepicker._gotoToday(id);
8173                                 },
8174                                 selectDay: function () {
8175                                         $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
8176                                         return false;
8177                                 },
8178                                 selectMonth: function () {
8179                                         $.datepicker._selectMonthYear(id, this, "M");
8180                                         return false;
8181                                 },
8182                                 selectYear: function () {
8183                                         $.datepicker._selectMonthYear(id, this, "Y");
8184                                         return false;
8185                                 }
8186                         };
8187                         $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
8188                 });
8189         },
8190
8191         /* Generate the HTML for the current state of the date picker. */
8192         _generateHTML: function(inst) {
8193                 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
8194                         controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
8195                         monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
8196                         selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
8197                         cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
8198                         printDate, dRow, tbody, daySettings, otherMonth, unselectable,
8199                         tempDate = new Date(),
8200                         today = this._daylightSavingAdjust(
8201                                 new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
8202                         isRTL = this._get(inst, "isRTL"),
8203                         showButtonPanel = this._get(inst, "showButtonPanel"),
8204                         hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
8205                         navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
8206                         numMonths = this._getNumberOfMonths(inst),
8207                         showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
8208                         stepMonths = this._get(inst, "stepMonths"),
8209                         isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
8210                         currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
8211                                 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
8212                         minDate = this._getMinMaxDate(inst, "min"),
8213                         maxDate = this._getMinMaxDate(inst, "max"),
8214                         drawMonth = inst.drawMonth - showCurrentAtPos,
8215                         drawYear = inst.drawYear;
8216
8217                 if (drawMonth < 0) {
8218                         drawMonth += 12;
8219                         drawYear--;
8220                 }
8221                 if (maxDate) {
8222                         maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
8223                                 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
8224                         maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
8225                         while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
8226                                 drawMonth--;
8227                                 if (drawMonth < 0) {
8228                                         drawMonth = 11;
8229                                         drawYear--;
8230                                 }
8231                         }
8232                 }
8233                 inst.drawMonth = drawMonth;
8234                 inst.drawYear = drawYear;
8235
8236                 prevText = this._get(inst, "prevText");
8237                 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
8238                         this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
8239                         this._getFormatConfig(inst)));
8240
8241                 prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
8242                         "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
8243                         " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
8244                         (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>"));
8245
8246                 nextText = this._get(inst, "nextText");
8247                 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
8248                         this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
8249                         this._getFormatConfig(inst)));
8250
8251                 next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
8252                         "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
8253                         " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
8254                         (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>"));
8255
8256                 currentText = this._get(inst, "currentText");
8257                 gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
8258                 currentText = (!navigationAsDateFormat ? currentText :
8259                         this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
8260
8261                 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'>" +
8262                         this._get(inst, "closeText") + "</button>" : "");
8263
8264                 buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
8265                         (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'" +
8266                         ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
8267
8268                 firstDay = parseInt(this._get(inst, "firstDay"),10);
8269                 firstDay = (isNaN(firstDay) ? 0 : firstDay);
8270
8271                 showWeek = this._get(inst, "showWeek");
8272                 dayNames = this._get(inst, "dayNames");
8273                 dayNamesMin = this._get(inst, "dayNamesMin");
8274                 monthNames = this._get(inst, "monthNames");
8275                 monthNamesShort = this._get(inst, "monthNamesShort");
8276                 beforeShowDay = this._get(inst, "beforeShowDay");
8277                 showOtherMonths = this._get(inst, "showOtherMonths");
8278                 selectOtherMonths = this._get(inst, "selectOtherMonths");
8279                 defaultDate = this._getDefaultDate(inst);
8280                 html = "";
8281                 dow;
8282                 for (row = 0; row < numMonths[0]; row++) {
8283                         group = "";
8284                         this.maxRows = 4;
8285                         for (col = 0; col < numMonths[1]; col++) {
8286                                 selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
8287                                 cornerClass = " ui-corner-all";
8288                                 calender = "";
8289                                 if (isMultiMonth) {
8290                                         calender += "<div class='ui-datepicker-group";
8291                                         if (numMonths[1] > 1) {
8292                                                 switch (col) {
8293                                                         case 0: calender += " ui-datepicker-group-first";
8294                                                                 cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
8295                                                         case numMonths[1]-1: calender += " ui-datepicker-group-last";
8296                                                                 cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
8297                                                         default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
8298                                                 }
8299                                         }
8300                                         calender += "'>";
8301                                 }
8302                                 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
8303                                         (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
8304                                         (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
8305                                         this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
8306                                         row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
8307                                         "</div><table class='ui-datepicker-calendar'><thead>" +
8308                                         "<tr>";
8309                                 thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
8310                                 for (dow = 0; dow < 7; dow++) { // days of the week
8311                                         day = (dow + firstDay) % 7;
8312                                         thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
8313                                                 "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
8314                                 }
8315                                 calender += thead + "</tr></thead><tbody>";
8316                                 daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
8317                                 if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
8318                                         inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
8319                                 }
8320                                 leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
8321                                 curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
8322                                 numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
8323                                 this.maxRows = numRows;
8324                                 printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
8325                                 for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
8326                                         calender += "<tr>";
8327                                         tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
8328                                                 this._get(inst, "calculateWeek")(printDate) + "</td>");
8329                                         for (dow = 0; dow < 7; dow++) { // create date picker days
8330                                                 daySettings = (beforeShowDay ?
8331                                                         beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
8332                                                 otherMonth = (printDate.getMonth() !== drawMonth);
8333                                                 unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
8334                                                         (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
8335                                                 tbody += "<td class='" +
8336                                                         ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
8337                                                         (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
8338                                                         ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
8339                                                         (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
8340                                                         // or defaultDate is current printedDate and defaultDate is selectedDate
8341                                                         " " + this._dayOverClass : "") + // highlight selected day
8342                                                         (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
8343                                                         (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
8344                                                         (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
8345                                                         (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
8346                                                         ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
8347                                                         (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
8348                                                         (otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
8349                                                         (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
8350                                                         (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
8351                                                         (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
8352                                                         (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
8353                                                         "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
8354                                                 printDate.setDate(printDate.getDate() + 1);
8355                                                 printDate = this._daylightSavingAdjust(printDate);
8356                                         }
8357                                         calender += tbody + "</tr>";
8358                                 }
8359                                 drawMonth++;
8360                                 if (drawMonth > 11) {
8361                                         drawMonth = 0;
8362                                         drawYear++;
8363                                 }
8364                                 calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
8365                                                         ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
8366                                 group += calender;
8367                         }
8368                         html += group;
8369                 }
8370                 html += buttonPanel;
8371                 inst._keyEvent = false;
8372                 return html;
8373         },
8374
8375         /* Generate the month and year header. */
8376         _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
8377                         secondary, monthNames, monthNamesShort) {
8378
8379                 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
8380                         changeMonth = this._get(inst, "changeMonth"),
8381                         changeYear = this._get(inst, "changeYear"),
8382                         showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
8383                         html = "<div class='ui-datepicker-title'>",
8384                         monthHtml = "";
8385
8386                 // month selection
8387                 if (secondary || !changeMonth) {
8388                         monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
8389                 } else {
8390                         inMinYear = (minDate && minDate.getFullYear() === drawYear);
8391                         inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
8392                         monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
8393                         for ( month = 0; month < 12; month++) {
8394                                 if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
8395                                         monthHtml += "<option value='" + month + "'" +
8396                                                 (month === drawMonth ? " selected='selected'" : "") +
8397                                                 ">" + monthNamesShort[month] + "</option>";
8398                                 }
8399                         }
8400                         monthHtml += "</select>";
8401                 }
8402
8403                 if (!showMonthAfterYear) {
8404                         html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
8405                 }
8406
8407                 // year selection
8408                 if ( !inst.yearshtml ) {
8409                         inst.yearshtml = "";
8410                         if (secondary || !changeYear) {
8411                                 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
8412                         } else {
8413                                 // determine range of years to display
8414                                 years = this._get(inst, "yearRange").split(":");
8415                                 thisYear = new Date().getFullYear();
8416                                 determineYear = function(value) {
8417                                         var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
8418                                                 (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
8419                                                 parseInt(value, 10)));
8420                                         return (isNaN(year) ? thisYear : year);
8421                                 };
8422                                 year = determineYear(years[0]);
8423                                 endYear = Math.max(year, determineYear(years[1] || ""));
8424                                 year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
8425                                 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
8426                                 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
8427                                 for (; year <= endYear; year++) {
8428                                         inst.yearshtml += "<option value='" + year + "'" +
8429                                                 (year === drawYear ? " selected='selected'" : "") +
8430                                                 ">" + year + "</option>";
8431                                 }
8432                                 inst.yearshtml += "</select>";
8433
8434                                 html += inst.yearshtml;
8435                                 inst.yearshtml = null;
8436                         }
8437                 }
8438
8439                 html += this._get(inst, "yearSuffix");
8440                 if (showMonthAfterYear) {
8441                         html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
8442                 }
8443                 html += "</div>"; // Close datepicker_header
8444                 return html;
8445         },
8446
8447         /* Adjust one of the date sub-fields. */
8448         _adjustInstDate: function(inst, offset, period) {
8449                 var year = inst.drawYear + (period === "Y" ? offset : 0),
8450                         month = inst.drawMonth + (period === "M" ? offset : 0),
8451                         day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
8452                         date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
8453
8454                 inst.selectedDay = date.getDate();
8455                 inst.drawMonth = inst.selectedMonth = date.getMonth();
8456                 inst.drawYear = inst.selectedYear = date.getFullYear();
8457                 if (period === "M" || period === "Y") {
8458                         this._notifyChange(inst);
8459                 }
8460         },
8461
8462         /* Ensure a date is within any min/max bounds. */
8463         _restrictMinMax: function(inst, date) {
8464                 var minDate = this._getMinMaxDate(inst, "min"),
8465                         maxDate = this._getMinMaxDate(inst, "max"),
8466                         newDate = (minDate && date < minDate ? minDate : date);
8467                 return (maxDate && newDate > maxDate ? maxDate : newDate);
8468         },
8469
8470         /* Notify change of month/year. */
8471         _notifyChange: function(inst) {
8472                 var onChange = this._get(inst, "onChangeMonthYear");
8473                 if (onChange) {
8474                         onChange.apply((inst.input ? inst.input[0] : null),
8475                                 [inst.selectedYear, inst.selectedMonth + 1, inst]);
8476                 }
8477         },
8478
8479         /* Determine the number of months to show. */
8480         _getNumberOfMonths: function(inst) {
8481                 var numMonths = this._get(inst, "numberOfMonths");
8482                 return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
8483         },
8484
8485         /* Determine the current maximum date - ensure no time components are set. */
8486         _getMinMaxDate: function(inst, minMax) {
8487                 return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
8488         },
8489
8490         /* Find the number of days in a given month. */
8491         _getDaysInMonth: function(year, month) {
8492                 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
8493         },
8494
8495         /* Find the day of the week of the first of a month. */
8496         _getFirstDayOfMonth: function(year, month) {
8497                 return new Date(year, month, 1).getDay();
8498         },
8499
8500         /* Determines if we should allow a "next/prev" month display change. */
8501         _canAdjustMonth: function(inst, offset, curYear, curMonth) {
8502                 var numMonths = this._getNumberOfMonths(inst),
8503                         date = this._daylightSavingAdjust(new Date(curYear,
8504                         curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
8505
8506                 if (offset < 0) {
8507                         date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
8508                 }
8509                 return this._isInRange(inst, date);
8510         },
8511
8512         /* Is the given date in the accepted range? */
8513         _isInRange: function(inst, date) {
8514                 var yearSplit, currentYear,
8515                         minDate = this._getMinMaxDate(inst, "min"),
8516                         maxDate = this._getMinMaxDate(inst, "max"),
8517                         minYear = null,
8518                         maxYear = null,
8519                         years = this._get(inst, "yearRange");
8520                         if (years){
8521                                 yearSplit = years.split(":");
8522                                 currentYear = new Date().getFullYear();
8523                                 minYear = parseInt(yearSplit[0], 10);
8524                                 maxYear = parseInt(yearSplit[1], 10);
8525                                 if ( yearSplit[0].match(/[+\-].*/) ) {
8526                                         minYear += currentYear;
8527                                 }
8528                                 if ( yearSplit[1].match(/[+\-].*/) ) {
8529                                         maxYear += currentYear;
8530                                 }
8531                         }
8532
8533                 return ((!minDate || date.getTime() >= minDate.getTime()) &&
8534                         (!maxDate || date.getTime() <= maxDate.getTime()) &&
8535                         (!minYear || date.getFullYear() >= minYear) &&
8536                         (!maxYear || date.getFullYear() <= maxYear));
8537         },
8538
8539         /* Provide the configuration settings for formatting/parsing. */
8540         _getFormatConfig: function(inst) {
8541                 var shortYearCutoff = this._get(inst, "shortYearCutoff");
8542                 shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
8543                         new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
8544                 return {shortYearCutoff: shortYearCutoff,
8545                         dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
8546                         monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
8547         },
8548
8549         /* Format the given date for display. */
8550         _formatDate: function(inst, day, month, year) {
8551                 if (!day) {
8552                         inst.currentDay = inst.selectedDay;
8553                         inst.currentMonth = inst.selectedMonth;
8554                         inst.currentYear = inst.selectedYear;
8555                 }
8556                 var date = (day ? (typeof day === "object" ? day :
8557                         this._daylightSavingAdjust(new Date(year, month, day))) :
8558                         this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
8559                 return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
8560         }
8561 });
8562
8563 /*
8564  * Bind hover events for datepicker elements.
8565  * Done via delegate so the binding only occurs once in the lifetime of the parent div.
8566  * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
8567  */
8568 function datepicker_bindHover(dpDiv) {
8569         var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
8570         return dpDiv.delegate(selector, "mouseout", function() {
8571                         $(this).removeClass("ui-state-hover");
8572                         if (this.className.indexOf("ui-datepicker-prev") !== -1) {
8573                                 $(this).removeClass("ui-datepicker-prev-hover");
8574                         }
8575                         if (this.className.indexOf("ui-datepicker-next") !== -1) {
8576                                 $(this).removeClass("ui-datepicker-next-hover");
8577                         }
8578                 })
8579                 .delegate( selector, "mouseover", datepicker_handleMouseover );
8580 }
8581
8582 function datepicker_handleMouseover() {
8583         if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) {
8584                 $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
8585                 $(this).addClass("ui-state-hover");
8586                 if (this.className.indexOf("ui-datepicker-prev") !== -1) {
8587                         $(this).addClass("ui-datepicker-prev-hover");
8588                 }
8589                 if (this.className.indexOf("ui-datepicker-next") !== -1) {
8590                         $(this).addClass("ui-datepicker-next-hover");
8591                 }
8592         }
8593 }
8594
8595 /* jQuery extend now ignores nulls! */
8596 function datepicker_extendRemove(target, props) {
8597         $.extend(target, props);
8598         for (var name in props) {
8599                 if (props[name] == null) {
8600                         target[name] = props[name];
8601                 }
8602         }
8603         return target;
8604 }
8605
8606 /* Invoke the datepicker functionality.
8607    @param  options  string - a command, optionally followed by additional parameters or
8608                                         Object - settings for attaching new datepicker functionality
8609    @return  jQuery object */
8610 $.fn.datepicker = function(options){
8611
8612         /* Verify an empty collection wasn't passed - Fixes #6976 */
8613         if ( !this.length ) {
8614                 return this;
8615         }
8616
8617         /* Initialise the date picker. */
8618         if (!$.datepicker.initialized) {
8619                 $(document).mousedown($.datepicker._checkExternalClick);
8620                 $.datepicker.initialized = true;
8621         }
8622
8623         /* Append datepicker main container to body if not exist. */
8624         if ($("#"+$.datepicker._mainDivId).length === 0) {
8625                 $("body").append($.datepicker.dpDiv);
8626         }
8627
8628         var otherArgs = Array.prototype.slice.call(arguments, 1);
8629         if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
8630                 return $.datepicker["_" + options + "Datepicker"].
8631                         apply($.datepicker, [this[0]].concat(otherArgs));
8632         }
8633         if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
8634                 return $.datepicker["_" + options + "Datepicker"].
8635                         apply($.datepicker, [this[0]].concat(otherArgs));
8636         }
8637         return this.each(function() {
8638                 typeof options === "string" ?
8639                         $.datepicker["_" + options + "Datepicker"].
8640                                 apply($.datepicker, [this].concat(otherArgs)) :
8641                         $.datepicker._attachDatepicker(this, options);
8642         });
8643 };
8644
8645 $.datepicker = new Datepicker(); // singleton instance
8646 $.datepicker.initialized = false;
8647 $.datepicker.uuid = new Date().getTime();
8648 $.datepicker.version = "1.11.4";
8649
8650 var datepicker = $.datepicker;
8651
8652
8653 /*!
8654  * jQuery UI Progressbar 1.11.4
8655  * http://jqueryui.com
8656  *
8657  * Copyright jQuery Foundation and other contributors
8658  * Released under the MIT license.
8659  * http://jquery.org/license
8660  *
8661  * http://api.jqueryui.com/progressbar/
8662  */
8663
8664
8665 var progressbar = $.widget( "ui.progressbar", {
8666         version: "1.11.4",
8667         options: {
8668                 max: 100,
8669                 value: 0,
8670
8671                 change: null,
8672                 complete: null
8673         },
8674
8675         min: 0,
8676
8677         _create: function() {
8678                 // Constrain initial value
8679                 this.oldValue = this.options.value = this._constrainedValue();
8680
8681                 this.element
8682                         .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
8683                         .attr({
8684                                 // Only set static values, aria-valuenow and aria-valuemax are
8685                                 // set inside _refreshValue()
8686                                 role: "progressbar",
8687                                 "aria-valuemin": this.min
8688                         });
8689
8690                 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
8691                         .appendTo( this.element );
8692
8693                 this._refreshValue();
8694         },
8695
8696         _destroy: function() {
8697                 this.element
8698                         .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
8699                         .removeAttr( "role" )
8700                         .removeAttr( "aria-valuemin" )
8701                         .removeAttr( "aria-valuemax" )
8702                         .removeAttr( "aria-valuenow" );
8703
8704                 this.valueDiv.remove();
8705         },
8706
8707         value: function( newValue ) {
8708                 if ( newValue === undefined ) {
8709                         return this.options.value;
8710                 }
8711
8712                 this.options.value = this._constrainedValue( newValue );
8713                 this._refreshValue();
8714         },
8715
8716         _constrainedValue: function( newValue ) {
8717                 if ( newValue === undefined ) {
8718                         newValue = this.options.value;
8719                 }
8720
8721                 this.indeterminate = newValue === false;
8722
8723                 // sanitize value
8724                 if ( typeof newValue !== "number" ) {
8725                         newValue = 0;
8726                 }
8727
8728                 return this.indeterminate ? false :
8729                         Math.min( this.options.max, Math.max( this.min, newValue ) );
8730         },
8731
8732         _setOptions: function( options ) {
8733                 // Ensure "value" option is set after other values (like max)
8734                 var value = options.value;
8735                 delete options.value;
8736
8737                 this._super( options );
8738
8739                 this.options.value = this._constrainedValue( value );
8740                 this._refreshValue();
8741         },
8742
8743         _setOption: function( key, value ) {
8744                 if ( key === "max" ) {
8745                         // Don't allow a max less than min
8746                         value = Math.max( this.min, value );
8747                 }
8748                 if ( key === "disabled" ) {
8749                         this.element
8750                                 .toggleClass( "ui-state-disabled", !!value )
8751                                 .attr( "aria-disabled", value );
8752                 }
8753                 this._super( key, value );
8754         },
8755
8756         _percentage: function() {
8757                 return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
8758         },
8759
8760         _refreshValue: function() {
8761                 var value = this.options.value,
8762                         percentage = this._percentage();
8763
8764                 this.valueDiv
8765                         .toggle( this.indeterminate || value > this.min )
8766                         .toggleClass( "ui-corner-right", value === this.options.max )
8767                         .width( percentage.toFixed(0) + "%" );
8768
8769                 this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
8770
8771                 if ( this.indeterminate ) {
8772                         this.element.removeAttr( "aria-valuenow" );
8773                         if ( !this.overlayDiv ) {
8774                                 this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
8775                         }
8776                 } else {
8777                         this.element.attr({
8778                                 "aria-valuemax": this.options.max,
8779                                 "aria-valuenow": value
8780                         });
8781                         if ( this.overlayDiv ) {
8782                                 this.overlayDiv.remove();
8783                                 this.overlayDiv = null;
8784                         }
8785                 }
8786
8787                 if ( this.oldValue !== value ) {
8788                         this.oldValue = value;
8789                         this._trigger( "change" );
8790                 }
8791                 if ( value === this.options.max ) {
8792                         this._trigger( "complete" );
8793                 }
8794         }
8795 });
8796
8797
8798 /*!
8799  * jQuery UI Slider 1.11.4
8800  * http://jqueryui.com
8801  *
8802  * Copyright jQuery Foundation and other contributors
8803  * Released under the MIT license.
8804  * http://jquery.org/license
8805  *
8806  * http://api.jqueryui.com/slider/
8807  */
8808
8809
8810 var slider = $.widget( "ui.slider", $.ui.mouse, {
8811         version: "1.11.4",
8812         widgetEventPrefix: "slide",
8813
8814         options: {
8815                 animate: false,
8816                 distance: 0,
8817                 max: 100,
8818                 min: 0,
8819                 orientation: "horizontal",
8820                 range: false,
8821                 step: 1,
8822                 value: 0,
8823                 values: null,
8824
8825                 // callbacks
8826                 change: null,
8827                 slide: null,
8828                 start: null,
8829                 stop: null
8830         },
8831
8832         // number of pages in a slider
8833         // (how many times can you page up/down to go through the whole range)
8834         numPages: 5,
8835
8836         _create: function() {
8837                 this._keySliding = false;
8838                 this._mouseSliding = false;
8839                 this._animateOff = true;
8840                 this._handleIndex = null;
8841                 this._detectOrientation();
8842                 this._mouseInit();
8843                 this._calculateNewMax();
8844
8845                 this.element
8846                         .addClass( "ui-slider" +
8847                                 " ui-slider-" + this.orientation +
8848                                 " ui-widget" +
8849                                 " ui-widget-content" +
8850                                 " ui-corner-all");
8851
8852                 this._refresh();
8853                 this._setOption( "disabled", this.options.disabled );
8854
8855                 this._animateOff = false;
8856         },
8857
8858         _refresh: function() {
8859                 this._createRange();
8860                 this._createHandles();
8861                 this._setupEvents();
8862                 this._refreshValue();
8863         },
8864
8865         _createHandles: function() {
8866                 var i, handleCount,
8867                         options = this.options,
8868                         existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
8869                         handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>",
8870                         handles = [];
8871
8872                 handleCount = ( options.values && options.values.length ) || 1;
8873
8874                 if ( existingHandles.length > handleCount ) {
8875                         existingHandles.slice( handleCount ).remove();
8876                         existingHandles = existingHandles.slice( 0, handleCount );
8877                 }
8878
8879                 for ( i = existingHandles.length; i < handleCount; i++ ) {
8880                         handles.push( handle );
8881                 }
8882
8883                 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
8884
8885                 this.handle = this.handles.eq( 0 );
8886
8887                 this.handles.each(function( i ) {
8888                         $( this ).data( "ui-slider-handle-index", i );
8889                 });
8890         },
8891
8892         _createRange: function() {
8893                 var options = this.options,
8894                         classes = "";
8895
8896                 if ( options.range ) {
8897                         if ( options.range === true ) {
8898                                 if ( !options.values ) {
8899                                         options.values = [ this._valueMin(), this._valueMin() ];
8900                                 } else if ( options.values.length && options.values.length !== 2 ) {
8901                                         options.values = [ options.values[0], options.values[0] ];
8902                                 } else if ( $.isArray( options.values ) ) {
8903                                         options.values = options.values.slice(0);
8904                                 }
8905                         }
8906
8907                         if ( !this.range || !this.range.length ) {
8908                                 this.range = $( "<div></div>" )
8909                                         .appendTo( this.element );
8910
8911                                 classes = "ui-slider-range" +
8912                                 // note: this isn't the most fittingly semantic framework class for this element,
8913                                 // but worked best visually with a variety of themes
8914                                 " ui-widget-header ui-corner-all";
8915                         } else {
8916                                 this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
8917                                         // Handle range switching from true to min/max
8918                                         .css({
8919                                                 "left": "",
8920                                                 "bottom": ""
8921                                         });
8922                         }
8923
8924                         this.range.addClass( classes +
8925                                 ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
8926                 } else {
8927                         if ( this.range ) {
8928                                 this.range.remove();
8929                         }
8930                         this.range = null;
8931                 }
8932         },
8933
8934         _setupEvents: function() {
8935                 this._off( this.handles );
8936                 this._on( this.handles, this._handleEvents );
8937                 this._hoverable( this.handles );
8938                 this._focusable( this.handles );
8939         },
8940
8941         _destroy: function() {
8942                 this.handles.remove();
8943                 if ( this.range ) {
8944                         this.range.remove();
8945                 }
8946
8947                 this.element
8948                         .removeClass( "ui-slider" +
8949                                 " ui-slider-horizontal" +
8950                                 " ui-slider-vertical" +
8951                                 " ui-widget" +
8952                                 " ui-widget-content" +
8953                                 " ui-corner-all" );
8954
8955                 this._mouseDestroy();
8956         },
8957
8958         _mouseCapture: function( event ) {
8959                 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
8960                         that = this,
8961                         o = this.options;
8962
8963                 if ( o.disabled ) {
8964                         return false;
8965                 }
8966
8967                 this.elementSize = {
8968                         width: this.element.outerWidth(),
8969                         height: this.element.outerHeight()
8970                 };
8971                 this.elementOffset = this.element.offset();
8972
8973                 position = { x: event.pageX, y: event.pageY };
8974                 normValue = this._normValueFromMouse( position );
8975                 distance = this._valueMax() - this._valueMin() + 1;
8976                 this.handles.each(function( i ) {
8977                         var thisDistance = Math.abs( normValue - that.values(i) );
8978                         if (( distance > thisDistance ) ||
8979                                 ( distance === thisDistance &&
8980                                         (i === that._lastChangedValue || that.values(i) === o.min ))) {
8981                                 distance = thisDistance;
8982                                 closestHandle = $( this );
8983                                 index = i;
8984                         }
8985                 });
8986
8987                 allowed = this._start( event, index );
8988                 if ( allowed === false ) {
8989                         return false;
8990                 }
8991                 this._mouseSliding = true;
8992
8993                 this._handleIndex = index;
8994
8995                 closestHandle
8996                         .addClass( "ui-state-active" )
8997                         .focus();
8998
8999                 offset = closestHandle.offset();
9000                 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
9001                 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
9002                         left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
9003                         top: event.pageY - offset.top -
9004                                 ( closestHandle.height() / 2 ) -
9005                                 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
9006                                 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
9007                                 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
9008                 };
9009
9010                 if ( !this.handles.hasClass( "ui-state-hover" ) ) {
9011                         this._slide( event, index, normValue );
9012                 }
9013                 this._animateOff = true;
9014                 return true;
9015         },
9016
9017         _mouseStart: function() {
9018                 return true;
9019         },
9020
9021         _mouseDrag: function( event ) {
9022                 var position = { x: event.pageX, y: event.pageY },
9023                         normValue = this._normValueFromMouse( position );
9024
9025                 this._slide( event, this._handleIndex, normValue );
9026
9027                 return false;
9028         },
9029
9030         _mouseStop: function( event ) {
9031                 this.handles.removeClass( "ui-state-active" );
9032                 this._mouseSliding = false;
9033
9034                 this._stop( event, this._handleIndex );
9035                 this._change( event, this._handleIndex );
9036
9037                 this._handleIndex = null;
9038                 this._clickOffset = null;
9039                 this._animateOff = false;
9040
9041                 return false;
9042         },
9043
9044         _detectOrientation: function() {
9045                 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
9046         },
9047
9048         _normValueFromMouse: function( position ) {
9049                 var pixelTotal,
9050                         pixelMouse,
9051                         percentMouse,
9052                         valueTotal,
9053                         valueMouse;
9054
9055                 if ( this.orientation === "horizontal" ) {
9056                         pixelTotal = this.elementSize.width;
9057                         pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
9058                 } else {
9059                         pixelTotal = this.elementSize.height;
9060                         pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
9061                 }
9062
9063                 percentMouse = ( pixelMouse / pixelTotal );
9064                 if ( percentMouse > 1 ) {
9065                         percentMouse = 1;
9066                 }
9067                 if ( percentMouse < 0 ) {
9068                         percentMouse = 0;
9069                 }
9070                 if ( this.orientation === "vertical" ) {
9071                         percentMouse = 1 - percentMouse;
9072                 }
9073
9074                 valueTotal = this._valueMax() - this._valueMin();
9075                 valueMouse = this._valueMin() + percentMouse * valueTotal;
9076
9077                 return this._trimAlignValue( valueMouse );
9078         },
9079
9080         _start: function( event, index ) {
9081                 var uiHash = {
9082                         handle: this.handles[ index ],
9083                         value: this.value()
9084                 };
9085                 if ( this.options.values && this.options.values.length ) {
9086                         uiHash.value = this.values( index );
9087                         uiHash.values = this.values();
9088                 }
9089                 return this._trigger( "start", event, uiHash );
9090         },
9091
9092         _slide: function( event, index, newVal ) {
9093                 var otherVal,
9094                         newValues,
9095                         allowed;
9096
9097                 if ( this.options.values && this.options.values.length ) {
9098                         otherVal = this.values( index ? 0 : 1 );
9099
9100                         if ( ( this.options.values.length === 2 && this.options.range === true ) &&
9101                                         ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
9102                                 ) {
9103                                 newVal = otherVal;
9104                         }
9105
9106                         if ( newVal !== this.values( index ) ) {
9107                                 newValues = this.values();
9108                                 newValues[ index ] = newVal;
9109                                 // A slide can be canceled by returning false from the slide callback
9110                                 allowed = this._trigger( "slide", event, {
9111                                         handle: this.handles[ index ],
9112                                         value: newVal,
9113                                         values: newValues
9114                                 } );
9115                                 otherVal = this.values( index ? 0 : 1 );
9116                                 if ( allowed !== false ) {
9117                                         this.values( index, newVal );
9118                                 }
9119                         }
9120                 } else {
9121                         if ( newVal !== this.value() ) {
9122                                 // A slide can be canceled by returning false from the slide callback
9123                                 allowed = this._trigger( "slide", event, {
9124                                         handle: this.handles[ index ],
9125                                         value: newVal
9126                                 } );
9127                                 if ( allowed !== false ) {
9128                                         this.value( newVal );
9129                                 }
9130                         }
9131                 }
9132         },
9133
9134         _stop: function( event, index ) {
9135                 var uiHash = {
9136                         handle: this.handles[ index ],
9137                         value: this.value()
9138                 };
9139                 if ( this.options.values && this.options.values.length ) {
9140                         uiHash.value = this.values( index );
9141                         uiHash.values = this.values();
9142                 }
9143
9144                 this._trigger( "stop", event, uiHash );
9145         },
9146
9147         _change: function( event, index ) {
9148                 if ( !this._keySliding && !this._mouseSliding ) {
9149                         var uiHash = {
9150                                 handle: this.handles[ index ],
9151                                 value: this.value()
9152                         };
9153                         if ( this.options.values && this.options.values.length ) {
9154                                 uiHash.value = this.values( index );
9155                                 uiHash.values = this.values();
9156                         }
9157
9158                         //store the last changed value index for reference when handles overlap
9159                         this._lastChangedValue = index;
9160
9161                         this._trigger( "change", event, uiHash );
9162                 }
9163         },
9164
9165         value: function( newValue ) {
9166                 if ( arguments.length ) {
9167                         this.options.value = this._trimAlignValue( newValue );
9168                         this._refreshValue();
9169                         this._change( null, 0 );
9170                         return;
9171                 }
9172
9173                 return this._value();
9174         },
9175
9176         values: function( index, newValue ) {
9177                 var vals,
9178                         newValues,
9179                         i;
9180
9181                 if ( arguments.length > 1 ) {
9182                         this.options.values[ index ] = this._trimAlignValue( newValue );
9183                         this._refreshValue();
9184                         this._change( null, index );
9185                         return;
9186                 }
9187
9188                 if ( arguments.length ) {
9189                         if ( $.isArray( arguments[ 0 ] ) ) {
9190                                 vals = this.options.values;
9191                                 newValues = arguments[ 0 ];
9192                                 for ( i = 0; i < vals.length; i += 1 ) {
9193                                         vals[ i ] = this._trimAlignValue( newValues[ i ] );
9194                                         this._change( null, i );
9195                                 }
9196                                 this._refreshValue();
9197                         } else {
9198                                 if ( this.options.values && this.options.values.length ) {
9199                                         return this._values( index );
9200                                 } else {
9201                                         return this.value();
9202                                 }
9203                         }
9204                 } else {
9205                         return this._values();
9206                 }
9207         },
9208
9209         _setOption: function( key, value ) {
9210                 var i,
9211                         valsLength = 0;
9212
9213                 if ( key === "range" && this.options.range === true ) {
9214                         if ( value === "min" ) {
9215                                 this.options.value = this._values( 0 );
9216                                 this.options.values = null;
9217                         } else if ( value === "max" ) {
9218                                 this.options.value = this._values( this.options.values.length - 1 );
9219                                 this.options.values = null;
9220                         }
9221                 }
9222
9223                 if ( $.isArray( this.options.values ) ) {
9224                         valsLength = this.options.values.length;
9225                 }
9226
9227                 if ( key === "disabled" ) {
9228                         this.element.toggleClass( "ui-state-disabled", !!value );
9229                 }
9230
9231                 this._super( key, value );
9232
9233                 switch ( key ) {
9234                         case "orientation":
9235                                 this._detectOrientation();
9236                                 this.element
9237                                         .removeClass( "ui-slider-horizontal ui-slider-vertical" )
9238                                         .addClass( "ui-slider-" + this.orientation );
9239                                 this._refreshValue();
9240
9241                                 // Reset positioning from previous orientation
9242                                 this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
9243                                 break;
9244                         case "value":
9245                                 this._animateOff = true;
9246                                 this._refreshValue();
9247                                 this._change( null, 0 );
9248                                 this._animateOff = false;
9249                                 break;
9250                         case "values":
9251                                 this._animateOff = true;
9252                                 this._refreshValue();
9253                                 for ( i = 0; i < valsLength; i += 1 ) {
9254                                         this._change( null, i );
9255                                 }
9256                                 this._animateOff = false;
9257                                 break;
9258                         case "step":
9259                         case "min":
9260                         case "max":
9261                                 this._animateOff = true;
9262                                 this._calculateNewMax();
9263                                 this._refreshValue();
9264                                 this._animateOff = false;
9265                                 break;
9266                         case "range":
9267                                 this._animateOff = true;
9268                                 this._refresh();
9269                                 this._animateOff = false;
9270                                 break;
9271                 }
9272         },
9273
9274         //internal value getter
9275         // _value() returns value trimmed by min and max, aligned by step
9276         _value: function() {
9277                 var val = this.options.value;
9278                 val = this._trimAlignValue( val );
9279
9280                 return val;
9281         },
9282
9283         //internal values getter
9284         // _values() returns array of values trimmed by min and max, aligned by step
9285         // _values( index ) returns single value trimmed by min and max, aligned by step
9286         _values: function( index ) {
9287                 var val,
9288                         vals,
9289                         i;
9290
9291                 if ( arguments.length ) {
9292                         val = this.options.values[ index ];
9293                         val = this._trimAlignValue( val );
9294
9295                         return val;
9296                 } else if ( this.options.values && this.options.values.length ) {
9297                         // .slice() creates a copy of the array
9298                         // this copy gets trimmed by min and max and then returned
9299                         vals = this.options.values.slice();
9300                         for ( i = 0; i < vals.length; i += 1) {
9301                                 vals[ i ] = this._trimAlignValue( vals[ i ] );
9302                         }
9303
9304                         return vals;
9305                 } else {
9306                         return [];
9307                 }
9308         },
9309
9310         // returns the step-aligned value that val is closest to, between (inclusive) min and max
9311         _trimAlignValue: function( val ) {
9312                 if ( val <= this._valueMin() ) {
9313                         return this._valueMin();
9314                 }
9315                 if ( val >= this._valueMax() ) {
9316                         return this._valueMax();
9317                 }
9318                 var step = ( this.options.step > 0 ) ? this.options.step : 1,
9319                         valModStep = (val - this._valueMin()) % step,
9320                         alignValue = val - valModStep;
9321
9322                 if ( Math.abs(valModStep) * 2 >= step ) {
9323                         alignValue += ( valModStep > 0 ) ? step : ( -step );
9324                 }
9325
9326                 // Since JavaScript has problems with large floats, round
9327                 // the final value to 5 digits after the decimal point (see #4124)
9328                 return parseFloat( alignValue.toFixed(5) );
9329         },
9330
9331         _calculateNewMax: function() {
9332                 var max = this.options.max,
9333                         min = this._valueMin(),
9334                         step = this.options.step,
9335                         aboveMin = Math.floor( ( +( max - min ).toFixed( this._precision() ) ) / step ) * step;
9336                 max = aboveMin + min;
9337                 this.max = parseFloat( max.toFixed( this._precision() ) );
9338         },
9339
9340         _precision: function() {
9341                 var precision = this._precisionOf( this.options.step );
9342                 if ( this.options.min !== null ) {
9343                         precision = Math.max( precision, this._precisionOf( this.options.min ) );
9344                 }
9345                 return precision;
9346         },
9347
9348         _precisionOf: function( num ) {
9349                 var str = num.toString(),
9350                         decimal = str.indexOf( "." );
9351                 return decimal === -1 ? 0 : str.length - decimal - 1;
9352         },
9353
9354         _valueMin: function() {
9355                 return this.options.min;
9356         },
9357
9358         _valueMax: function() {
9359                 return this.max;
9360         },
9361
9362         _refreshValue: function() {
9363                 var lastValPercent, valPercent, value, valueMin, valueMax,
9364                         oRange = this.options.range,
9365                         o = this.options,
9366                         that = this,
9367                         animate = ( !this._animateOff ) ? o.animate : false,
9368                         _set = {};
9369
9370                 if ( this.options.values && this.options.values.length ) {
9371                         this.handles.each(function( i ) {
9372                                 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
9373                                 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
9374                                 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
9375                                 if ( that.options.range === true ) {
9376                                         if ( that.orientation === "horizontal" ) {
9377                                                 if ( i === 0 ) {
9378                                                         that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
9379                                                 }
9380                                                 if ( i === 1 ) {
9381                                                         that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
9382                                                 }
9383                                         } else {
9384                                                 if ( i === 0 ) {
9385                                                         that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
9386                                                 }
9387                                                 if ( i === 1 ) {
9388                                                         that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
9389                                                 }
9390                                         }
9391                                 }
9392                                 lastValPercent = valPercent;
9393                         });
9394                 } else {
9395                         value = this.value();
9396                         valueMin = this._valueMin();
9397                         valueMax = this._valueMax();
9398                         valPercent = ( valueMax !== valueMin ) ?
9399                                         ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
9400                                         0;
9401                         _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
9402                         this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
9403
9404                         if ( oRange === "min" && this.orientation === "horizontal" ) {
9405                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
9406                         }
9407                         if ( oRange === "max" && this.orientation === "horizontal" ) {
9408                                 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
9409                         }
9410                         if ( oRange === "min" && this.orientation === "vertical" ) {
9411                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
9412                         }
9413                         if ( oRange === "max" && this.orientation === "vertical" ) {
9414                                 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
9415                         }
9416                 }
9417         },
9418
9419         _handleEvents: {
9420                 keydown: function( event ) {
9421                         var allowed, curVal, newVal, step,
9422                                 index = $( event.target ).data( "ui-slider-handle-index" );
9423
9424                         switch ( event.keyCode ) {
9425                                 case $.ui.keyCode.HOME:
9426                                 case $.ui.keyCode.END:
9427                                 case $.ui.keyCode.PAGE_UP:
9428                                 case $.ui.keyCode.PAGE_DOWN:
9429                                 case $.ui.keyCode.UP:
9430                                 case $.ui.keyCode.RIGHT:
9431                                 case $.ui.keyCode.DOWN:
9432                                 case $.ui.keyCode.LEFT:
9433                                         event.preventDefault();
9434                                         if ( !this._keySliding ) {
9435                                                 this._keySliding = true;
9436                                                 $( event.target ).addClass( "ui-state-active" );
9437                                                 allowed = this._start( event, index );
9438                                                 if ( allowed === false ) {
9439                                                         return;
9440                                                 }
9441                                         }
9442                                         break;
9443                         }
9444
9445                         step = this.options.step;
9446                         if ( this.options.values && this.options.values.length ) {
9447                                 curVal = newVal = this.values( index );
9448                         } else {
9449                                 curVal = newVal = this.value();
9450                         }
9451
9452                         switch ( event.keyCode ) {
9453                                 case $.ui.keyCode.HOME:
9454                                         newVal = this._valueMin();
9455                                         break;
9456                                 case $.ui.keyCode.END:
9457                                         newVal = this._valueMax();
9458                                         break;
9459                                 case $.ui.keyCode.PAGE_UP:
9460                                         newVal = this._trimAlignValue(
9461                                                 curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
9462                                         );
9463                                         break;
9464                                 case $.ui.keyCode.PAGE_DOWN:
9465                                         newVal = this._trimAlignValue(
9466                                                 curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) );
9467                                         break;
9468                                 case $.ui.keyCode.UP:
9469                                 case $.ui.keyCode.RIGHT:
9470                                         if ( curVal === this._valueMax() ) {
9471                                                 return;
9472                                         }
9473                                         newVal = this._trimAlignValue( curVal + step );
9474                                         break;
9475                                 case $.ui.keyCode.DOWN:
9476                                 case $.ui.keyCode.LEFT:
9477                                         if ( curVal === this._valueMin() ) {
9478                                                 return;
9479                                         }
9480                                         newVal = this._trimAlignValue( curVal - step );
9481                                         break;
9482                         }
9483
9484                         this._slide( event, index, newVal );
9485                 },
9486                 keyup: function( event ) {
9487                         var index = $( event.target ).data( "ui-slider-handle-index" );
9488
9489                         if ( this._keySliding ) {
9490                                 this._keySliding = false;
9491                                 this._stop( event, index );
9492                                 this._change( event, index );
9493                                 $( event.target ).removeClass( "ui-state-active" );
9494                         }
9495                 }
9496         }
9497 });
9498
9499
9500 /*!
9501  * jQuery UI Tabs 1.11.4
9502  * http://jqueryui.com
9503  *
9504  * Copyright jQuery Foundation and other contributors
9505  * Released under the MIT license.
9506  * http://jquery.org/license
9507  *
9508  * http://api.jqueryui.com/tabs/
9509  */
9510
9511
9512 var tabs = $.widget( "ui.tabs", {
9513         version: "1.11.4",
9514         delay: 300,
9515         options: {
9516                 active: null,
9517                 collapsible: false,
9518                 event: "click",
9519                 heightStyle: "content",
9520                 hide: null,
9521                 show: null,
9522
9523                 // callbacks
9524                 activate: null,
9525                 beforeActivate: null,
9526                 beforeLoad: null,
9527                 load: null
9528         },
9529
9530         _isLocal: (function() {
9531                 var rhash = /#.*$/;
9532
9533                 return function( anchor ) {
9534                         var anchorUrl, locationUrl;
9535
9536                         // support: IE7
9537                         // IE7 doesn't normalize the href property when set via script (#9317)
9538                         anchor = anchor.cloneNode( false );
9539
9540                         anchorUrl = anchor.href.replace( rhash, "" );
9541                         locationUrl = location.href.replace( rhash, "" );
9542
9543                         // decoding may throw an error if the URL isn't UTF-8 (#9518)
9544                         try {
9545                                 anchorUrl = decodeURIComponent( anchorUrl );
9546                         } catch ( error ) {}
9547                         try {
9548                                 locationUrl = decodeURIComponent( locationUrl );
9549                         } catch ( error ) {}
9550
9551                         return anchor.hash.length > 1 && anchorUrl === locationUrl;
9552                 };
9553         })(),
9554
9555         _create: function() {
9556                 var that = this,
9557                         options = this.options;
9558
9559                 this.running = false;
9560
9561                 this.element
9562                         .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
9563                         .toggleClass( "ui-tabs-collapsible", options.collapsible );
9564
9565                 this._processTabs();
9566                 options.active = this._initialActive();
9567
9568                 // Take disabling tabs via class attribute from HTML
9569                 // into account and update option properly.
9570                 if ( $.isArray( options.disabled ) ) {
9571                         options.disabled = $.unique( options.disabled.concat(
9572                                 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
9573                                         return that.tabs.index( li );
9574                                 })
9575                         ) ).sort();
9576                 }
9577
9578                 // check for length avoids error when initializing empty list
9579                 if ( this.options.active !== false && this.anchors.length ) {
9580                         this.active = this._findActive( options.active );
9581                 } else {
9582                         this.active = $();
9583                 }
9584
9585                 this._refresh();
9586
9587                 if ( this.active.length ) {
9588                         this.load( options.active );
9589                 }
9590         },
9591
9592         _initialActive: function() {
9593                 var active = this.options.active,
9594                         collapsible = this.options.collapsible,
9595                         locationHash = location.hash.substring( 1 );
9596
9597                 if ( active === null ) {
9598                         // check the fragment identifier in the URL
9599                         if ( locationHash ) {
9600                                 this.tabs.each(function( i, tab ) {
9601                                         if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
9602                                                 active = i;
9603                                                 return false;
9604                                         }
9605                                 });
9606                         }
9607
9608                         // check for a tab marked active via a class
9609                         if ( active === null ) {
9610                                 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
9611                         }
9612
9613                         // no active tab, set to false
9614                         if ( active === null || active === -1 ) {
9615                                 active = this.tabs.length ? 0 : false;
9616                         }
9617                 }
9618
9619                 // handle numbers: negative, out of range
9620                 if ( active !== false ) {
9621                         active = this.tabs.index( this.tabs.eq( active ) );
9622                         if ( active === -1 ) {
9623                                 active = collapsible ? false : 0;
9624                         }
9625                 }
9626
9627                 // don't allow collapsible: false and active: false
9628                 if ( !collapsible && active === false && this.anchors.length ) {
9629                         active = 0;
9630                 }
9631
9632                 return active;
9633         },
9634
9635         _getCreateEventData: function() {
9636                 return {
9637                         tab: this.active,
9638                         panel: !this.active.length ? $() : this._getPanelForTab( this.active )
9639                 };
9640         },
9641
9642         _tabKeydown: function( event ) {
9643                 var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
9644                         selectedIndex = this.tabs.index( focusedTab ),
9645                         goingForward = true;
9646
9647                 if ( this._handlePageNav( event ) ) {
9648                         return;
9649                 }
9650
9651                 switch ( event.keyCode ) {
9652                         case $.ui.keyCode.RIGHT:
9653                         case $.ui.keyCode.DOWN:
9654                                 selectedIndex++;
9655                                 break;
9656                         case $.ui.keyCode.UP:
9657                         case $.ui.keyCode.LEFT:
9658                                 goingForward = false;
9659                                 selectedIndex--;
9660                                 break;
9661                         case $.ui.keyCode.END:
9662                                 selectedIndex = this.anchors.length - 1;
9663                                 break;
9664                         case $.ui.keyCode.HOME:
9665                                 selectedIndex = 0;
9666                                 break;
9667                         case $.ui.keyCode.SPACE:
9668                                 // Activate only, no collapsing
9669                                 event.preventDefault();
9670                                 clearTimeout( this.activating );
9671                                 this._activate( selectedIndex );
9672                                 return;
9673                         case $.ui.keyCode.ENTER:
9674                                 // Toggle (cancel delayed activation, allow collapsing)
9675                                 event.preventDefault();
9676                                 clearTimeout( this.activating );
9677                                 // Determine if we should collapse or activate
9678                                 this._activate( selectedIndex === this.options.active ? false : selectedIndex );
9679                                 return;
9680                         default:
9681                                 return;
9682                 }
9683
9684                 // Focus the appropriate tab, based on which key was pressed
9685                 event.preventDefault();
9686                 clearTimeout( this.activating );
9687                 selectedIndex = this._focusNextTab( selectedIndex, goingForward );
9688
9689                 // Navigating with control/command key will prevent automatic activation
9690                 if ( !event.ctrlKey && !event.metaKey ) {
9691
9692                         // Update aria-selected immediately so that AT think the tab is already selected.
9693                         // Otherwise AT may confuse the user by stating that they need to activate the tab,
9694                         // but the tab will already be activated by the time the announcement finishes.
9695                         focusedTab.attr( "aria-selected", "false" );
9696                         this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
9697
9698                         this.activating = this._delay(function() {
9699                                 this.option( "active", selectedIndex );
9700                         }, this.delay );
9701                 }
9702         },
9703
9704         _panelKeydown: function( event ) {
9705                 if ( this._handlePageNav( event ) ) {
9706                         return;
9707                 }
9708
9709                 // Ctrl+up moves focus to the current tab
9710                 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
9711                         event.preventDefault();
9712                         this.active.focus();
9713                 }
9714         },
9715
9716         // Alt+page up/down moves focus to the previous/next tab (and activates)
9717         _handlePageNav: function( event ) {
9718                 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
9719                         this._activate( this._focusNextTab( this.options.active - 1, false ) );
9720                         return true;
9721                 }
9722                 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
9723                         this._activate( this._focusNextTab( this.options.active + 1, true ) );
9724                         return true;
9725                 }
9726         },
9727
9728         _findNextTab: function( index, goingForward ) {
9729                 var lastTabIndex = this.tabs.length - 1;
9730
9731                 function constrain() {
9732                         if ( index > lastTabIndex ) {
9733                                 index = 0;
9734                         }
9735                         if ( index < 0 ) {
9736                                 index = lastTabIndex;
9737                         }
9738                         return index;
9739                 }
9740
9741                 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
9742                         index = goingForward ? index + 1 : index - 1;
9743                 }
9744
9745                 return index;
9746         },
9747
9748         _focusNextTab: function( index, goingForward ) {
9749                 index = this._findNextTab( index, goingForward );
9750                 this.tabs.eq( index ).focus();
9751                 return index;
9752         },
9753
9754         _setOption: function( key, value ) {
9755                 if ( key === "active" ) {
9756                         // _activate() will handle invalid values and update this.options
9757                         this._activate( value );
9758                         return;
9759                 }
9760
9761                 if ( key === "disabled" ) {
9762                         // don't use the widget factory's disabled handling
9763                         this._setupDisabled( value );
9764                         return;
9765                 }
9766
9767                 this._super( key, value);
9768
9769                 if ( key === "collapsible" ) {
9770                         this.element.toggleClass( "ui-tabs-collapsible", value );
9771                         // Setting collapsible: false while collapsed; open first panel
9772                         if ( !value && this.options.active === false ) {
9773                                 this._activate( 0 );
9774                         }
9775                 }
9776
9777                 if ( key === "event" ) {
9778                         this._setupEvents( value );
9779                 }
9780
9781                 if ( key === "heightStyle" ) {
9782                         this._setupHeightStyle( value );
9783                 }
9784         },
9785
9786         _sanitizeSelector: function( hash ) {
9787                 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
9788         },
9789
9790         refresh: function() {
9791                 var options = this.options,
9792                         lis = this.tablist.children( ":has(a[href])" );
9793
9794                 // get disabled tabs from class attribute from HTML
9795                 // this will get converted to a boolean if needed in _refresh()
9796                 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
9797                         return lis.index( tab );
9798                 });
9799
9800                 this._processTabs();
9801
9802                 // was collapsed or no tabs
9803                 if ( options.active === false || !this.anchors.length ) {
9804                         options.active = false;
9805                         this.active = $();
9806                 // was active, but active tab is gone
9807                 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
9808                         // all remaining tabs are disabled
9809                         if ( this.tabs.length === options.disabled.length ) {
9810                                 options.active = false;
9811                                 this.active = $();
9812                         // activate previous tab
9813                         } else {
9814                                 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
9815                         }
9816                 // was active, active tab still exists
9817                 } else {
9818                         // make sure active index is correct
9819                         options.active = this.tabs.index( this.active );
9820                 }
9821
9822                 this._refresh();
9823         },
9824
9825         _refresh: function() {
9826                 this._setupDisabled( this.options.disabled );
9827                 this._setupEvents( this.options.event );
9828                 this._setupHeightStyle( this.options.heightStyle );
9829
9830                 this.tabs.not( this.active ).attr({
9831                         "aria-selected": "false",
9832                         "aria-expanded": "false",
9833                         tabIndex: -1
9834                 });
9835                 this.panels.not( this._getPanelForTab( this.active ) )
9836                         .hide()
9837                         .attr({
9838                                 "aria-hidden": "true"
9839                         });
9840
9841                 // Make sure one tab is in the tab order
9842                 if ( !this.active.length ) {
9843                         this.tabs.eq( 0 ).attr( "tabIndex", 0 );
9844                 } else {
9845                         this.active
9846                                 .addClass( "ui-tabs-active ui-state-active" )
9847                                 .attr({
9848                                         "aria-selected": "true",
9849                                         "aria-expanded": "true",
9850                                         tabIndex: 0
9851                                 });
9852                         this._getPanelForTab( this.active )
9853                                 .show()
9854                                 .attr({
9855                                         "aria-hidden": "false"
9856                                 });
9857                 }
9858         },
9859
9860         _processTabs: function() {
9861                 var that = this,
9862                         prevTabs = this.tabs,
9863                         prevAnchors = this.anchors,
9864                         prevPanels = this.panels;
9865
9866                 this.tablist = this._getList()
9867                         .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
9868                         .attr( "role", "tablist" )
9869
9870                         // Prevent users from focusing disabled tabs via click
9871                         .delegate( "> li", "mousedown" + this.eventNamespace, function( event ) {
9872                                 if ( $( this ).is( ".ui-state-disabled" ) ) {
9873                                         event.preventDefault();
9874                                 }
9875                         })
9876
9877                         // support: IE <9
9878                         // Preventing the default action in mousedown doesn't prevent IE
9879                         // from focusing the element, so if the anchor gets focused, blur.
9880                         // We don't have to worry about focusing the previously focused
9881                         // element since clicking on a non-focusable element should focus
9882                         // the body anyway.
9883                         .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
9884                                 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
9885                                         this.blur();
9886                                 }
9887                         });
9888
9889                 this.tabs = this.tablist.find( "> li:has(a[href])" )
9890                         .addClass( "ui-state-default ui-corner-top" )
9891                         .attr({
9892                                 role: "tab",
9893                                 tabIndex: -1
9894                         });
9895
9896                 this.anchors = this.tabs.map(function() {
9897                                 return $( "a", this )[ 0 ];
9898                         })
9899                         .addClass( "ui-tabs-anchor" )
9900                         .attr({
9901                                 role: "presentation",
9902                                 tabIndex: -1
9903                         });
9904
9905                 this.panels = $();
9906
9907                 this.anchors.each(function( i, anchor ) {
9908                         var selector, panel, panelId,
9909                                 anchorId = $( anchor ).uniqueId().attr( "id" ),
9910                                 tab = $( anchor ).closest( "li" ),
9911                                 originalAriaControls = tab.attr( "aria-controls" );
9912
9913                         // inline tab
9914                         if ( that._isLocal( anchor ) ) {
9915                                 selector = anchor.hash;
9916                                 panelId = selector.substring( 1 );
9917                                 panel = that.element.find( that._sanitizeSelector( selector ) );
9918                         // remote tab
9919                         } else {
9920                                 // If the tab doesn't already have aria-controls,
9921                                 // generate an id by using a throw-away element
9922                                 panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
9923                                 selector = "#" + panelId;
9924                                 panel = that.element.find( selector );
9925                                 if ( !panel.length ) {
9926                                         panel = that._createPanel( panelId );
9927                                         panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
9928                                 }
9929                                 panel.attr( "aria-live", "polite" );
9930                         }
9931
9932                         if ( panel.length) {
9933                                 that.panels = that.panels.add( panel );
9934                         }
9935                         if ( originalAriaControls ) {
9936                                 tab.data( "ui-tabs-aria-controls", originalAriaControls );
9937                         }
9938                         tab.attr({
9939                                 "aria-controls": panelId,
9940                                 "aria-labelledby": anchorId
9941                         });
9942                         panel.attr( "aria-labelledby", anchorId );
9943                 });
9944
9945                 this.panels
9946                         .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
9947                         .attr( "role", "tabpanel" );
9948
9949                 // Avoid memory leaks (#10056)
9950                 if ( prevTabs ) {
9951                         this._off( prevTabs.not( this.tabs ) );
9952                         this._off( prevAnchors.not( this.anchors ) );
9953                         this._off( prevPanels.not( this.panels ) );
9954                 }
9955         },
9956
9957         // allow overriding how to find the list for rare usage scenarios (#7715)
9958         _getList: function() {
9959                 return this.tablist || this.element.find( "ol,ul" ).eq( 0 );
9960         },
9961
9962         _createPanel: function( id ) {
9963                 return $( "<div>" )
9964                         .attr( "id", id )
9965                         .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
9966                         .data( "ui-tabs-destroy", true );
9967         },
9968
9969         _setupDisabled: function( disabled ) {
9970                 if ( $.isArray( disabled ) ) {
9971                         if ( !disabled.length ) {
9972                                 disabled = false;
9973                         } else if ( disabled.length === this.anchors.length ) {
9974                                 disabled = true;
9975                         }
9976                 }
9977
9978                 // disable tabs
9979                 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
9980                         if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
9981                                 $( li )
9982                                         .addClass( "ui-state-disabled" )
9983                                         .attr( "aria-disabled", "true" );
9984                         } else {
9985                                 $( li )
9986                                         .removeClass( "ui-state-disabled" )
9987                                         .removeAttr( "aria-disabled" );
9988                         }
9989                 }
9990
9991                 this.options.disabled = disabled;
9992         },
9993
9994         _setupEvents: function( event ) {
9995                 var events = {};
9996                 if ( event ) {
9997                         $.each( event.split(" "), function( index, eventName ) {
9998                                 events[ eventName ] = "_eventHandler";
9999                         });
10000                 }
10001
10002                 this._off( this.anchors.add( this.tabs ).add( this.panels ) );
10003                 // Always prevent the default action, even when disabled
10004                 this._on( true, this.anchors, {
10005                         click: function( event ) {
10006                                 event.preventDefault();
10007                         }
10008                 });
10009                 this._on( this.anchors, events );
10010                 this._on( this.tabs, { keydown: "_tabKeydown" } );
10011                 this._on( this.panels, { keydown: "_panelKeydown" } );
10012
10013                 this._focusable( this.tabs );
10014                 this._hoverable( this.tabs );
10015         },
10016
10017         _setupHeightStyle: function( heightStyle ) {
10018                 var maxHeight,
10019                         parent = this.element.parent();
10020
10021                 if ( heightStyle === "fill" ) {
10022                         maxHeight = parent.height();
10023                         maxHeight -= this.element.outerHeight() - this.element.height();
10024
10025                         this.element.siblings( ":visible" ).each(function() {
10026                                 var elem = $( this ),
10027                                         position = elem.css( "position" );
10028
10029                                 if ( position === "absolute" || position === "fixed" ) {
10030                                         return;
10031                                 }
10032                                 maxHeight -= elem.outerHeight( true );
10033                         });
10034
10035                         this.element.children().not( this.panels ).each(function() {
10036                                 maxHeight -= $( this ).outerHeight( true );
10037                         });
10038
10039                         this.panels.each(function() {
10040                                 $( this ).height( Math.max( 0, maxHeight -
10041                                         $( this ).innerHeight() + $( this ).height() ) );
10042                         })
10043                         .css( "overflow", "auto" );
10044                 } else if ( heightStyle === "auto" ) {
10045                         maxHeight = 0;
10046                         this.panels.each(function() {
10047                                 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
10048                         }).height( maxHeight );
10049                 }
10050         },
10051
10052         _eventHandler: function( event ) {
10053                 var options = this.options,
10054                         active = this.active,
10055                         anchor = $( event.currentTarget ),
10056                         tab = anchor.closest( "li" ),
10057                         clickedIsActive = tab[ 0 ] === active[ 0 ],
10058                         collapsing = clickedIsActive && options.collapsible,
10059                         toShow = collapsing ? $() : this._getPanelForTab( tab ),
10060                         toHide = !active.length ? $() : this._getPanelForTab( active ),
10061                         eventData = {
10062                                 oldTab: active,
10063                                 oldPanel: toHide,
10064                                 newTab: collapsing ? $() : tab,
10065                                 newPanel: toShow
10066                         };
10067
10068                 event.preventDefault();
10069
10070                 if ( tab.hasClass( "ui-state-disabled" ) ||
10071                                 // tab is already loading
10072                                 tab.hasClass( "ui-tabs-loading" ) ||
10073                                 // can't switch durning an animation
10074                                 this.running ||
10075                                 // click on active header, but not collapsible
10076                                 ( clickedIsActive && !options.collapsible ) ||
10077                                 // allow canceling activation
10078                                 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
10079                         return;
10080                 }
10081
10082                 options.active = collapsing ? false : this.tabs.index( tab );
10083
10084                 this.active = clickedIsActive ? $() : tab;
10085                 if ( this.xhr ) {
10086                         this.xhr.abort();
10087                 }
10088
10089                 if ( !toHide.length && !toShow.length ) {
10090                         $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
10091                 }
10092
10093                 if ( toShow.length ) {
10094                         this.load( this.tabs.index( tab ), event );
10095                 }
10096                 this._toggle( event, eventData );
10097         },
10098
10099         // handles show/hide for selecting tabs
10100         _toggle: function( event, eventData ) {
10101                 var that = this,
10102                         toShow = eventData.newPanel,
10103                         toHide = eventData.oldPanel;
10104
10105                 this.running = true;
10106
10107                 function complete() {
10108                         that.running = false;
10109                         that._trigger( "activate", event, eventData );
10110                 }
10111
10112                 function show() {
10113                         eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
10114
10115                         if ( toShow.length && that.options.show ) {
10116                                 that._show( toShow, that.options.show, complete );
10117                         } else {
10118                                 toShow.show();
10119                                 complete();
10120                         }
10121                 }
10122
10123                 // start out by hiding, then showing, then completing
10124                 if ( toHide.length && this.options.hide ) {
10125                         this._hide( toHide, this.options.hide, function() {
10126                                 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
10127                                 show();
10128                         });
10129                 } else {
10130                         eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
10131                         toHide.hide();
10132                         show();
10133                 }
10134
10135                 toHide.attr( "aria-hidden", "true" );
10136                 eventData.oldTab.attr({
10137                         "aria-selected": "false",
10138                         "aria-expanded": "false"
10139                 });
10140                 // If we're switching tabs, remove the old tab from the tab order.
10141                 // If we're opening from collapsed state, remove the previous tab from the tab order.
10142                 // If we're collapsing, then keep the collapsing tab in the tab order.
10143                 if ( toShow.length && toHide.length ) {
10144                         eventData.oldTab.attr( "tabIndex", -1 );
10145                 } else if ( toShow.length ) {
10146                         this.tabs.filter(function() {
10147                                 return $( this ).attr( "tabIndex" ) === 0;
10148                         })
10149                         .attr( "tabIndex", -1 );
10150                 }
10151
10152                 toShow.attr( "aria-hidden", "false" );
10153                 eventData.newTab.attr({
10154                         "aria-selected": "true",
10155                         "aria-expanded": "true",
10156                         tabIndex: 0
10157                 });
10158         },
10159
10160         _activate: function( index ) {
10161                 var anchor,
10162                         active = this._findActive( index );
10163
10164                 // trying to activate the already active panel
10165                 if ( active[ 0 ] === this.active[ 0 ] ) {
10166                         return;
10167                 }
10168
10169                 // trying to collapse, simulate a click on the current active header
10170                 if ( !active.length ) {
10171                         active = this.active;
10172                 }
10173
10174                 anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
10175                 this._eventHandler({
10176                         target: anchor,
10177                         currentTarget: anchor,
10178                         preventDefault: $.noop
10179                 });
10180         },
10181
10182         _findActive: function( index ) {
10183                 return index === false ? $() : this.tabs.eq( index );
10184         },
10185
10186         _getIndex: function( index ) {
10187                 // meta-function to give users option to provide a href string instead of a numerical index.
10188                 if ( typeof index === "string" ) {
10189                         index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
10190                 }
10191
10192                 return index;
10193         },
10194
10195         _destroy: function() {
10196                 if ( this.xhr ) {
10197                         this.xhr.abort();
10198                 }
10199
10200                 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
10201
10202                 this.tablist
10203                         .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
10204                         .removeAttr( "role" );
10205
10206                 this.anchors
10207                         .removeClass( "ui-tabs-anchor" )
10208                         .removeAttr( "role" )
10209                         .removeAttr( "tabIndex" )
10210                         .removeUniqueId();
10211
10212                 this.tablist.unbind( this.eventNamespace );
10213
10214                 this.tabs.add( this.panels ).each(function() {
10215                         if ( $.data( this, "ui-tabs-destroy" ) ) {
10216                                 $( this ).remove();
10217                         } else {
10218                                 $( this )
10219                                         .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
10220                                                 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
10221                                         .removeAttr( "tabIndex" )
10222                                         .removeAttr( "aria-live" )
10223                                         .removeAttr( "aria-busy" )
10224                                         .removeAttr( "aria-selected" )
10225                                         .removeAttr( "aria-labelledby" )
10226                                         .removeAttr( "aria-hidden" )
10227                                         .removeAttr( "aria-expanded" )
10228                                         .removeAttr( "role" );
10229                         }
10230                 });
10231
10232                 this.tabs.each(function() {
10233                         var li = $( this ),
10234                                 prev = li.data( "ui-tabs-aria-controls" );
10235                         if ( prev ) {
10236                                 li
10237                                         .attr( "aria-controls", prev )
10238                                         .removeData( "ui-tabs-aria-controls" );
10239                         } else {
10240                                 li.removeAttr( "aria-controls" );
10241                         }
10242                 });
10243
10244                 this.panels.show();
10245
10246                 if ( this.options.heightStyle !== "content" ) {
10247                         this.panels.css( "height", "" );
10248                 }
10249         },
10250
10251         enable: function( index ) {
10252                 var disabled = this.options.disabled;
10253                 if ( disabled === false ) {
10254                         return;
10255                 }
10256
10257                 if ( index === undefined ) {
10258                         disabled = false;
10259                 } else {
10260                         index = this._getIndex( index );
10261                         if ( $.isArray( disabled ) ) {
10262                                 disabled = $.map( disabled, function( num ) {
10263                                         return num !== index ? num : null;
10264                                 });
10265                         } else {
10266                                 disabled = $.map( this.tabs, function( li, num ) {
10267                                         return num !== index ? num : null;
10268                                 });
10269                         }
10270                 }
10271                 this._setupDisabled( disabled );
10272         },
10273
10274         disable: function( index ) {
10275                 var disabled = this.options.disabled;
10276                 if ( disabled === true ) {
10277                         return;
10278                 }
10279
10280                 if ( index === undefined ) {
10281                         disabled = true;
10282                 } else {
10283                         index = this._getIndex( index );
10284                         if ( $.inArray( index, disabled ) !== -1 ) {
10285                                 return;
10286                         }
10287                         if ( $.isArray( disabled ) ) {
10288                                 disabled = $.merge( [ index ], disabled ).sort();
10289                         } else {
10290                                 disabled = [ index ];
10291                         }
10292                 }
10293                 this._setupDisabled( disabled );
10294         },
10295
10296         load: function( index, event ) {
10297                 index = this._getIndex( index );
10298                 var that = this,
10299                         tab = this.tabs.eq( index ),
10300                         anchor = tab.find( ".ui-tabs-anchor" ),
10301                         panel = this._getPanelForTab( tab ),
10302                         eventData = {
10303                                 tab: tab,
10304                                 panel: panel
10305                         },
10306                         complete = function( jqXHR, status ) {
10307                                 if ( status === "abort" ) {
10308                                         that.panels.stop( false, true );
10309                                 }
10310
10311                                 tab.removeClass( "ui-tabs-loading" );
10312                                 panel.removeAttr( "aria-busy" );
10313
10314                                 if ( jqXHR === that.xhr ) {
10315                                         delete that.xhr;
10316                                 }
10317                         };
10318
10319                 // not remote
10320                 if ( this._isLocal( anchor[ 0 ] ) ) {
10321                         return;
10322                 }
10323
10324                 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
10325
10326                 // support: jQuery <1.8
10327                 // jQuery <1.8 returns false if the request is canceled in beforeSend,
10328                 // but as of 1.8, $.ajax() always returns a jqXHR object.
10329                 if ( this.xhr && this.xhr.statusText !== "canceled" ) {
10330                         tab.addClass( "ui-tabs-loading" );
10331                         panel.attr( "aria-busy", "true" );
10332
10333                         this.xhr
10334                                 .done(function( response, status, jqXHR ) {
10335                                         // support: jQuery <1.8
10336                                         // http://bugs.jquery.com/ticket/11778
10337                                         setTimeout(function() {
10338                                                 panel.html( response );
10339                                                 that._trigger( "load", event, eventData );
10340
10341                                                 complete( jqXHR, status );
10342                                         }, 1 );
10343                                 })
10344                                 .fail(function( jqXHR, status ) {
10345                                         // support: jQuery <1.8
10346                                         // http://bugs.jquery.com/ticket/11778
10347                                         setTimeout(function() {
10348                                                 complete( jqXHR, status );
10349                                         }, 1 );
10350                                 });
10351                 }
10352         },
10353
10354         _ajaxSettings: function( anchor, event, eventData ) {
10355                 var that = this;
10356                 return {
10357                         url: anchor.attr( "href" ),
10358                         beforeSend: function( jqXHR, settings ) {
10359                                 return that._trigger( "beforeLoad", event,
10360                                         $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
10361                         }
10362                 };
10363         },
10364
10365         _getPanelForTab: function( tab ) {
10366                 var id = $( tab ).attr( "aria-controls" );
10367                 return this.element.find( this._sanitizeSelector( "#" + id ) );
10368         }
10369 });
10370
10371
10372 /*!
10373  * jQuery UI Effects 1.11.4
10374  * http://jqueryui.com
10375  *
10376  * Copyright jQuery Foundation and other contributors
10377  * Released under the MIT license.
10378  * http://jquery.org/license
10379  *
10380  * http://api.jqueryui.com/category/effects-core/
10381  */
10382
10383
10384 var dataSpace = "ui-effects-",
10385
10386         // Create a local jQuery because jQuery Color relies on it and the
10387         // global may not exist with AMD and a custom build (#10199)
10388         jQuery = $;
10389
10390 $.effects = {
10391         effect: {}
10392 };
10393
10394 /*!
10395  * jQuery Color Animations v2.1.2
10396  * https://github.com/jquery/jquery-color
10397  *
10398  * Copyright 2014 jQuery Foundation and other contributors
10399  * Released under the MIT license.
10400  * http://jquery.org/license
10401  *
10402  * Date: Wed Jan 16 08:47:09 2013 -0600
10403  */
10404 (function( jQuery, undefined ) {
10405
10406         var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
10407
10408         // plusequals test for += 100 -= 100
10409         rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
10410         // a set of RE's that can match strings and generate color tuples.
10411         stringParsers = [ {
10412                         re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
10413                         parse: function( execResult ) {
10414                                 return [
10415                                         execResult[ 1 ],
10416                                         execResult[ 2 ],
10417                                         execResult[ 3 ],
10418                                         execResult[ 4 ]
10419                                 ];
10420                         }
10421                 }, {
10422                         re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
10423                         parse: function( execResult ) {
10424                                 return [
10425                                         execResult[ 1 ] * 2.55,
10426                                         execResult[ 2 ] * 2.55,
10427                                         execResult[ 3 ] * 2.55,
10428                                         execResult[ 4 ]
10429                                 ];
10430                         }
10431                 }, {
10432                         // this regex ignores A-F because it's compared against an already lowercased string
10433                         re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
10434                         parse: function( execResult ) {
10435                                 return [
10436                                         parseInt( execResult[ 1 ], 16 ),
10437                                         parseInt( execResult[ 2 ], 16 ),
10438                                         parseInt( execResult[ 3 ], 16 )
10439                                 ];
10440                         }
10441                 }, {
10442                         // this regex ignores A-F because it's compared against an already lowercased string
10443                         re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
10444                         parse: function( execResult ) {
10445                                 return [
10446                                         parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
10447                                         parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
10448                                         parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
10449                                 ];
10450                         }
10451                 }, {
10452                         re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
10453                         space: "hsla",
10454                         parse: function( execResult ) {
10455                                 return [
10456                                         execResult[ 1 ],
10457                                         execResult[ 2 ] / 100,
10458                                         execResult[ 3 ] / 100,
10459                                         execResult[ 4 ]
10460                                 ];
10461                         }
10462                 } ],
10463
10464         // jQuery.Color( )
10465         color = jQuery.Color = function( color, green, blue, alpha ) {
10466                 return new jQuery.Color.fn.parse( color, green, blue, alpha );
10467         },
10468         spaces = {
10469                 rgba: {
10470                         props: {
10471                                 red: {
10472                                         idx: 0,
10473                                         type: "byte"
10474                                 },
10475                                 green: {
10476                                         idx: 1,
10477                                         type: "byte"
10478                                 },
10479                                 blue: {
10480                                         idx: 2,
10481                                         type: "byte"
10482                                 }
10483                         }
10484                 },
10485
10486                 hsla: {
10487                         props: {
10488                                 hue: {
10489                                         idx: 0,
10490                                         type: "degrees"
10491                                 },
10492                                 saturation: {
10493                                         idx: 1,
10494                                         type: "percent"
10495                                 },
10496                                 lightness: {
10497                                         idx: 2,
10498                                         type: "percent"
10499                                 }
10500                         }
10501                 }
10502         },
10503         propTypes = {
10504                 "byte": {
10505                         floor: true,
10506                         max: 255
10507                 },
10508                 "percent": {
10509                         max: 1
10510                 },
10511                 "degrees": {
10512                         mod: 360,
10513                         floor: true
10514                 }
10515         },
10516         support = color.support = {},
10517
10518         // element for support tests
10519         supportElem = jQuery( "<p>" )[ 0 ],
10520
10521         // colors = jQuery.Color.names
10522         colors,
10523
10524         // local aliases of functions called often
10525         each = jQuery.each;
10526
10527 // determine rgba support immediately
10528 supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
10529 support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
10530
10531 // define cache name and alpha properties
10532 // for rgba and hsla spaces
10533 each( spaces, function( spaceName, space ) {
10534         space.cache = "_" + spaceName;
10535         space.props.alpha = {
10536                 idx: 3,
10537                 type: "percent",
10538                 def: 1
10539         };
10540 });
10541
10542 function clamp( value, prop, allowEmpty ) {
10543         var type = propTypes[ prop.type ] || {};
10544
10545         if ( value == null ) {
10546                 return (allowEmpty || !prop.def) ? null : prop.def;
10547         }
10548
10549         // ~~ is an short way of doing floor for positive numbers
10550         value = type.floor ? ~~value : parseFloat( value );
10551
10552         // IE will pass in empty strings as value for alpha,
10553         // which will hit this case
10554         if ( isNaN( value ) ) {
10555                 return prop.def;
10556         }
10557
10558         if ( type.mod ) {
10559                 // we add mod before modding to make sure that negatives values
10560                 // get converted properly: -10 -> 350
10561                 return (value + type.mod) % type.mod;
10562         }
10563
10564         // for now all property types without mod have min and max
10565         return 0 > value ? 0 : type.max < value ? type.max : value;
10566 }
10567
10568 function stringParse( string ) {
10569         var inst = color(),
10570                 rgba = inst._rgba = [];
10571
10572         string = string.toLowerCase();
10573
10574         each( stringParsers, function( i, parser ) {
10575                 var parsed,
10576                         match = parser.re.exec( string ),
10577                         values = match && parser.parse( match ),
10578                         spaceName = parser.space || "rgba";
10579
10580                 if ( values ) {
10581                         parsed = inst[ spaceName ]( values );
10582
10583                         // if this was an rgba parse the assignment might happen twice
10584                         // oh well....
10585                         inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
10586                         rgba = inst._rgba = parsed._rgba;
10587
10588                         // exit each( stringParsers ) here because we matched
10589                         return false;
10590                 }
10591         });
10592
10593         // Found a stringParser that handled it
10594         if ( rgba.length ) {
10595
10596                 // if this came from a parsed string, force "transparent" when alpha is 0
10597                 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
10598                 if ( rgba.join() === "0,0,0,0" ) {
10599                         jQuery.extend( rgba, colors.transparent );
10600                 }
10601                 return inst;
10602         }
10603
10604         // named colors
10605         return colors[ string ];
10606 }
10607
10608 color.fn = jQuery.extend( color.prototype, {
10609         parse: function( red, green, blue, alpha ) {
10610                 if ( red === undefined ) {
10611                         this._rgba = [ null, null, null, null ];
10612                         return this;
10613                 }
10614                 if ( red.jquery || red.nodeType ) {
10615                         red = jQuery( red ).css( green );
10616                         green = undefined;
10617                 }
10618
10619                 var inst = this,
10620                         type = jQuery.type( red ),
10621                         rgba = this._rgba = [];
10622
10623                 // more than 1 argument specified - assume ( red, green, blue, alpha )
10624                 if ( green !== undefined ) {
10625                         red = [ red, green, blue, alpha ];
10626                         type = "array";
10627                 }
10628
10629                 if ( type === "string" ) {
10630                         return this.parse( stringParse( red ) || colors._default );
10631                 }
10632
10633                 if ( type === "array" ) {
10634                         each( spaces.rgba.props, function( key, prop ) {
10635                                 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
10636                         });
10637                         return this;
10638                 }
10639
10640                 if ( type === "object" ) {
10641                         if ( red instanceof color ) {
10642                                 each( spaces, function( spaceName, space ) {
10643                                         if ( red[ space.cache ] ) {
10644                                                 inst[ space.cache ] = red[ space.cache ].slice();
10645                                         }
10646                                 });
10647                         } else {
10648                                 each( spaces, function( spaceName, space ) {
10649                                         var cache = space.cache;
10650                                         each( space.props, function( key, prop ) {
10651
10652                                                 // if the cache doesn't exist, and we know how to convert
10653                                                 if ( !inst[ cache ] && space.to ) {
10654
10655                                                         // if the value was null, we don't need to copy it
10656                                                         // if the key was alpha, we don't need to copy it either
10657                                                         if ( key === "alpha" || red[ key ] == null ) {
10658                                                                 return;
10659                                                         }
10660                                                         inst[ cache ] = space.to( inst._rgba );
10661                                                 }
10662
10663                                                 // this is the only case where we allow nulls for ALL properties.
10664                                                 // call clamp with alwaysAllowEmpty
10665                                                 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
10666                                         });
10667
10668                                         // everything defined but alpha?
10669                                         if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
10670                                                 // use the default of 1
10671                                                 inst[ cache ][ 3 ] = 1;
10672                                                 if ( space.from ) {
10673                                                         inst._rgba = space.from( inst[ cache ] );
10674                                                 }
10675                                         }
10676                                 });
10677                         }
10678                         return this;
10679                 }
10680         },
10681         is: function( compare ) {
10682                 var is = color( compare ),
10683                         same = true,
10684                         inst = this;
10685
10686                 each( spaces, function( _, space ) {
10687                         var localCache,
10688                                 isCache = is[ space.cache ];
10689                         if (isCache) {
10690                                 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
10691                                 each( space.props, function( _, prop ) {
10692                                         if ( isCache[ prop.idx ] != null ) {
10693                                                 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
10694                                                 return same;
10695                                         }
10696                                 });
10697                         }
10698                         return same;
10699                 });
10700                 return same;
10701         },
10702         _space: function() {
10703                 var used = [],
10704                         inst = this;
10705                 each( spaces, function( spaceName, space ) {
10706                         if ( inst[ space.cache ] ) {
10707                                 used.push( spaceName );
10708                         }
10709                 });
10710                 return used.pop();
10711         },
10712         transition: function( other, distance ) {
10713                 var end = color( other ),
10714                         spaceName = end._space(),
10715                         space = spaces[ spaceName ],
10716                         startColor = this.alpha() === 0 ? color( "transparent" ) : this,
10717                         start = startColor[ space.cache ] || space.to( startColor._rgba ),
10718                         result = start.slice();
10719
10720                 end = end[ space.cache ];
10721                 each( space.props, function( key, prop ) {
10722                         var index = prop.idx,
10723                                 startValue = start[ index ],
10724                                 endValue = end[ index ],
10725                                 type = propTypes[ prop.type ] || {};
10726
10727                         // if null, don't override start value
10728                         if ( endValue === null ) {
10729                                 return;
10730                         }
10731                         // if null - use end
10732                         if ( startValue === null ) {
10733                                 result[ index ] = endValue;
10734                         } else {
10735                                 if ( type.mod ) {
10736                                         if ( endValue - startValue > type.mod / 2 ) {
10737                                                 startValue += type.mod;
10738                                         } else if ( startValue - endValue > type.mod / 2 ) {
10739                                                 startValue -= type.mod;
10740                                         }
10741                                 }
10742                                 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
10743                         }
10744                 });
10745                 return this[ spaceName ]( result );
10746         },
10747         blend: function( opaque ) {
10748                 // if we are already opaque - return ourself
10749                 if ( this._rgba[ 3 ] === 1 ) {
10750                         return this;
10751                 }
10752
10753                 var rgb = this._rgba.slice(),
10754                         a = rgb.pop(),
10755                         blend = color( opaque )._rgba;
10756
10757                 return color( jQuery.map( rgb, function( v, i ) {
10758                         return ( 1 - a ) * blend[ i ] + a * v;
10759                 }));
10760         },
10761         toRgbaString: function() {
10762                 var prefix = "rgba(",
10763                         rgba = jQuery.map( this._rgba, function( v, i ) {
10764                                 return v == null ? ( i > 2 ? 1 : 0 ) : v;
10765                         });
10766
10767                 if ( rgba[ 3 ] === 1 ) {
10768                         rgba.pop();
10769                         prefix = "rgb(";
10770                 }
10771
10772                 return prefix + rgba.join() + ")";
10773         },
10774         toHslaString: function() {
10775                 var prefix = "hsla(",
10776                         hsla = jQuery.map( this.hsla(), function( v, i ) {
10777                                 if ( v == null ) {
10778                                         v = i > 2 ? 1 : 0;
10779                                 }
10780
10781                                 // catch 1 and 2
10782                                 if ( i && i < 3 ) {
10783                                         v = Math.round( v * 100 ) + "%";
10784                                 }
10785                                 return v;
10786                         });
10787
10788                 if ( hsla[ 3 ] === 1 ) {
10789                         hsla.pop();
10790                         prefix = "hsl(";
10791                 }
10792                 return prefix + hsla.join() + ")";
10793         },
10794         toHexString: function( includeAlpha ) {
10795                 var rgba = this._rgba.slice(),
10796                         alpha = rgba.pop();
10797
10798                 if ( includeAlpha ) {
10799                         rgba.push( ~~( alpha * 255 ) );
10800                 }
10801
10802                 return "#" + jQuery.map( rgba, function( v ) {
10803
10804                         // default to 0 when nulls exist
10805                         v = ( v || 0 ).toString( 16 );
10806                         return v.length === 1 ? "0" + v : v;
10807                 }).join("");
10808         },
10809         toString: function() {
10810                 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
10811         }
10812 });
10813 color.fn.parse.prototype = color.fn;
10814
10815 // hsla conversions adapted from:
10816 // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
10817
10818 function hue2rgb( p, q, h ) {
10819         h = ( h + 1 ) % 1;
10820         if ( h * 6 < 1 ) {
10821                 return p + ( q - p ) * h * 6;
10822         }
10823         if ( h * 2 < 1) {
10824                 return q;
10825         }
10826         if ( h * 3 < 2 ) {
10827                 return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
10828         }
10829         return p;
10830 }
10831
10832 spaces.hsla.to = function( rgba ) {
10833         if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
10834                 return [ null, null, null, rgba[ 3 ] ];
10835         }
10836         var r = rgba[ 0 ] / 255,
10837                 g = rgba[ 1 ] / 255,
10838                 b = rgba[ 2 ] / 255,
10839                 a = rgba[ 3 ],
10840                 max = Math.max( r, g, b ),
10841                 min = Math.min( r, g, b ),
10842                 diff = max - min,
10843                 add = max + min,
10844                 l = add * 0.5,
10845                 h, s;
10846
10847         if ( min === max ) {
10848                 h = 0;
10849         } else if ( r === max ) {
10850                 h = ( 60 * ( g - b ) / diff ) + 360;
10851         } else if ( g === max ) {
10852                 h = ( 60 * ( b - r ) / diff ) + 120;
10853         } else {
10854                 h = ( 60 * ( r - g ) / diff ) + 240;
10855         }
10856
10857         // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
10858         // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
10859         if ( diff === 0 ) {
10860                 s = 0;
10861         } else if ( l <= 0.5 ) {
10862                 s = diff / add;
10863         } else {
10864                 s = diff / ( 2 - add );
10865         }
10866         return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
10867 };
10868
10869 spaces.hsla.from = function( hsla ) {
10870         if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
10871                 return [ null, null, null, hsla[ 3 ] ];
10872         }
10873         var h = hsla[ 0 ] / 360,
10874                 s = hsla[ 1 ],
10875                 l = hsla[ 2 ],
10876                 a = hsla[ 3 ],
10877                 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
10878                 p = 2 * l - q;
10879
10880         return [
10881                 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
10882                 Math.round( hue2rgb( p, q, h ) * 255 ),
10883                 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
10884                 a
10885         ];
10886 };
10887
10888 each( spaces, function( spaceName, space ) {
10889         var props = space.props,
10890                 cache = space.cache,
10891                 to = space.to,
10892                 from = space.from;
10893
10894         // makes rgba() and hsla()
10895         color.fn[ spaceName ] = function( value ) {
10896
10897                 // generate a cache for this space if it doesn't exist
10898                 if ( to && !this[ cache ] ) {
10899                         this[ cache ] = to( this._rgba );
10900                 }
10901                 if ( value === undefined ) {
10902                         return this[ cache ].slice();
10903                 }
10904
10905                 var ret,
10906                         type = jQuery.type( value ),
10907                         arr = ( type === "array" || type === "object" ) ? value : arguments,
10908                         local = this[ cache ].slice();
10909
10910                 each( props, function( key, prop ) {
10911                         var val = arr[ type === "object" ? key : prop.idx ];
10912                         if ( val == null ) {
10913                                 val = local[ prop.idx ];
10914                         }
10915                         local[ prop.idx ] = clamp( val, prop );
10916                 });
10917
10918                 if ( from ) {
10919                         ret = color( from( local ) );
10920                         ret[ cache ] = local;
10921                         return ret;
10922                 } else {
10923                         return color( local );
10924                 }
10925         };
10926
10927         // makes red() green() blue() alpha() hue() saturation() lightness()
10928         each( props, function( key, prop ) {
10929                 // alpha is included in more than one space
10930                 if ( color.fn[ key ] ) {
10931                         return;
10932                 }
10933                 color.fn[ key ] = function( value ) {
10934                         var vtype = jQuery.type( value ),
10935                                 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
10936                                 local = this[ fn ](),
10937                                 cur = local[ prop.idx ],
10938                                 match;
10939
10940                         if ( vtype === "undefined" ) {
10941                                 return cur;
10942                         }
10943
10944                         if ( vtype === "function" ) {
10945                                 value = value.call( this, cur );
10946                                 vtype = jQuery.type( value );
10947                         }
10948                         if ( value == null && prop.empty ) {
10949                                 return this;
10950                         }
10951                         if ( vtype === "string" ) {
10952                                 match = rplusequals.exec( value );
10953                                 if ( match ) {
10954                                         value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
10955                                 }
10956                         }
10957                         local[ prop.idx ] = value;
10958                         return this[ fn ]( local );
10959                 };
10960         });
10961 });
10962
10963 // add cssHook and .fx.step function for each named hook.
10964 // accept a space separated string of properties
10965 color.hook = function( hook ) {
10966         var hooks = hook.split( " " );
10967         each( hooks, function( i, hook ) {
10968                 jQuery.cssHooks[ hook ] = {
10969                         set: function( elem, value ) {
10970                                 var parsed, curElem,
10971                                         backgroundColor = "";
10972
10973                                 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
10974                                         value = color( parsed || value );
10975                                         if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
10976                                                 curElem = hook === "backgroundColor" ? elem.parentNode : elem;
10977                                                 while (
10978                                                         (backgroundColor === "" || backgroundColor === "transparent") &&
10979                                                         curElem && curElem.style
10980                                                 ) {
10981                                                         try {
10982                                                                 backgroundColor = jQuery.css( curElem, "backgroundColor" );
10983                                                                 curElem = curElem.parentNode;
10984                                                         } catch ( e ) {
10985                                                         }
10986                                                 }
10987
10988                                                 value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
10989                                                         backgroundColor :
10990                                                         "_default" );
10991                                         }
10992
10993                                         value = value.toRgbaString();
10994                                 }
10995                                 try {
10996                                         elem.style[ hook ] = value;
10997                                 } catch ( e ) {
10998                                         // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
10999                                 }
11000                         }
11001                 };
11002                 jQuery.fx.step[ hook ] = function( fx ) {
11003                         if ( !fx.colorInit ) {
11004                                 fx.start = color( fx.elem, hook );
11005                                 fx.end = color( fx.end );
11006                                 fx.colorInit = true;
11007                         }
11008                         jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
11009                 };
11010         });
11011
11012 };
11013
11014 color.hook( stepHooks );
11015
11016 jQuery.cssHooks.borderColor = {
11017         expand: function( value ) {
11018                 var expanded = {};
11019
11020                 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
11021                         expanded[ "border" + part + "Color" ] = value;
11022                 });
11023                 return expanded;
11024         }
11025 };
11026
11027 // Basic color names only.
11028 // Usage of any of the other color names requires adding yourself or including
11029 // jquery.color.svg-names.js.
11030 colors = jQuery.Color.names = {
11031         // 4.1. Basic color keywords
11032         aqua: "#00ffff",
11033         black: "#000000",
11034         blue: "#0000ff",
11035         fuchsia: "#ff00ff",
11036         gray: "#808080",
11037         green: "#008000",
11038         lime: "#00ff00",
11039         maroon: "#800000",
11040         navy: "#000080",
11041         olive: "#808000",
11042         purple: "#800080",
11043         red: "#ff0000",
11044         silver: "#c0c0c0",
11045         teal: "#008080",
11046         white: "#ffffff",
11047         yellow: "#ffff00",
11048
11049         // 4.2.3. "transparent" color keyword
11050         transparent: [ null, null, null, 0 ],
11051
11052         _default: "#ffffff"
11053 };
11054
11055 })( jQuery );
11056
11057 /******************************************************************************/
11058 /****************************** CLASS ANIMATIONS ******************************/
11059 /******************************************************************************/
11060 (function() {
11061
11062 var classAnimationActions = [ "add", "remove", "toggle" ],
11063         shorthandStyles = {
11064                 border: 1,
11065                 borderBottom: 1,
11066                 borderColor: 1,
11067                 borderLeft: 1,
11068                 borderRight: 1,
11069                 borderTop: 1,
11070                 borderWidth: 1,
11071                 margin: 1,
11072                 padding: 1
11073         };
11074
11075 $.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
11076         $.fx.step[ prop ] = function( fx ) {
11077                 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
11078                         jQuery.style( fx.elem, prop, fx.end );
11079                         fx.setAttr = true;
11080                 }
11081         };
11082 });
11083
11084 function getElementStyles( elem ) {
11085         var key, len,
11086                 style = elem.ownerDocument.defaultView ?
11087                         elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
11088                         elem.currentStyle,
11089                 styles = {};
11090
11091         if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
11092                 len = style.length;
11093                 while ( len-- ) {
11094                         key = style[ len ];
11095                         if ( typeof style[ key ] === "string" ) {
11096                                 styles[ $.camelCase( key ) ] = style[ key ];
11097                         }
11098                 }
11099         // support: Opera, IE <9
11100         } else {
11101                 for ( key in style ) {
11102                         if ( typeof style[ key ] === "string" ) {
11103                                 styles[ key ] = style[ key ];
11104                         }
11105                 }
11106         }
11107
11108         return styles;
11109 }
11110
11111 function styleDifference( oldStyle, newStyle ) {
11112         var diff = {},
11113                 name, value;
11114
11115         for ( name in newStyle ) {
11116                 value = newStyle[ name ];
11117                 if ( oldStyle[ name ] !== value ) {
11118                         if ( !shorthandStyles[ name ] ) {
11119                                 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
11120                                         diff[ name ] = value;
11121                                 }
11122                         }
11123                 }
11124         }
11125
11126         return diff;
11127 }
11128
11129 // support: jQuery <1.8
11130 if ( !$.fn.addBack ) {
11131         $.fn.addBack = function( selector ) {
11132                 return this.add( selector == null ?
11133                         this.prevObject : this.prevObject.filter( selector )
11134                 );
11135         };
11136 }
11137
11138 $.effects.animateClass = function( value, duration, easing, callback ) {
11139         var o = $.speed( duration, easing, callback );
11140
11141         return this.queue( function() {
11142                 var animated = $( this ),
11143                         baseClass = animated.attr( "class" ) || "",
11144                         applyClassChange,
11145                         allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
11146
11147                 // map the animated objects to store the original styles.
11148                 allAnimations = allAnimations.map(function() {
11149                         var el = $( this );
11150                         return {
11151                                 el: el,
11152                                 start: getElementStyles( this )
11153                         };
11154                 });
11155
11156                 // apply class change
11157                 applyClassChange = function() {
11158                         $.each( classAnimationActions, function(i, action) {
11159                                 if ( value[ action ] ) {
11160                                         animated[ action + "Class" ]( value[ action ] );
11161                                 }
11162                         });
11163                 };
11164                 applyClassChange();
11165
11166                 // map all animated objects again - calculate new styles and diff
11167                 allAnimations = allAnimations.map(function() {
11168                         this.end = getElementStyles( this.el[ 0 ] );
11169                         this.diff = styleDifference( this.start, this.end );
11170                         return this;
11171                 });
11172
11173                 // apply original class
11174                 animated.attr( "class", baseClass );
11175
11176                 // map all animated objects again - this time collecting a promise
11177                 allAnimations = allAnimations.map(function() {
11178                         var styleInfo = this,
11179                                 dfd = $.Deferred(),
11180                                 opts = $.extend({}, o, {
11181                                         queue: false,
11182                                         complete: function() {
11183                                                 dfd.resolve( styleInfo );
11184                                         }
11185                                 });
11186
11187                         this.el.animate( this.diff, opts );
11188                         return dfd.promise();
11189                 });
11190
11191                 // once all animations have completed:
11192                 $.when.apply( $, allAnimations.get() ).done(function() {
11193
11194                         // set the final class
11195                         applyClassChange();
11196
11197                         // for each animated element,
11198                         // clear all css properties that were animated
11199                         $.each( arguments, function() {
11200                                 var el = this.el;
11201                                 $.each( this.diff, function(key) {
11202                                         el.css( key, "" );
11203                                 });
11204                         });
11205
11206                         // this is guarnteed to be there if you use jQuery.speed()
11207                         // it also handles dequeuing the next anim...
11208                         o.complete.call( animated[ 0 ] );
11209                 });
11210         });
11211 };
11212
11213 $.fn.extend({
11214         addClass: (function( orig ) {
11215                 return function( classNames, speed, easing, callback ) {
11216                         return speed ?
11217                                 $.effects.animateClass.call( this,
11218                                         { add: classNames }, speed, easing, callback ) :
11219                                 orig.apply( this, arguments );
11220                 };
11221         })( $.fn.addClass ),
11222
11223         removeClass: (function( orig ) {
11224                 return function( classNames, speed, easing, callback ) {
11225                         return arguments.length > 1 ?
11226                                 $.effects.animateClass.call( this,
11227                                         { remove: classNames }, speed, easing, callback ) :
11228                                 orig.apply( this, arguments );
11229                 };
11230         })( $.fn.removeClass ),
11231
11232         toggleClass: (function( orig ) {
11233                 return function( classNames, force, speed, easing, callback ) {
11234                         if ( typeof force === "boolean" || force === undefined ) {
11235                                 if ( !speed ) {
11236                                         // without speed parameter
11237                                         return orig.apply( this, arguments );
11238                                 } else {
11239                                         return $.effects.animateClass.call( this,
11240                                                 (force ? { add: classNames } : { remove: classNames }),
11241                                                 speed, easing, callback );
11242                                 }
11243                         } else {
11244                                 // without force parameter
11245                                 return $.effects.animateClass.call( this,
11246                                         { toggle: classNames }, force, speed, easing );
11247                         }
11248                 };
11249         })( $.fn.toggleClass ),
11250
11251         switchClass: function( remove, add, speed, easing, callback) {
11252                 return $.effects.animateClass.call( this, {
11253                         add: add,
11254                         remove: remove
11255                 }, speed, easing, callback );
11256         }
11257 });
11258
11259 })();
11260
11261 /******************************************************************************/
11262 /*********************************** EFFECTS **********************************/
11263 /******************************************************************************/
11264
11265 (function() {
11266
11267 $.extend( $.effects, {
11268         version: "1.11.4",
11269
11270         // Saves a set of properties in a data storage
11271         save: function( element, set ) {
11272                 for ( var i = 0; i < set.length; i++ ) {
11273                         if ( set[ i ] !== null ) {
11274                                 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
11275                         }
11276                 }
11277         },
11278
11279         // Restores a set of previously saved properties from a data storage
11280         restore: function( element, set ) {
11281                 var val, i;
11282                 for ( i = 0; i < set.length; i++ ) {
11283                         if ( set[ i ] !== null ) {
11284                                 val = element.data( dataSpace + set[ i ] );
11285                                 // support: jQuery 1.6.2
11286                                 // http://bugs.jquery.com/ticket/9917
11287                                 // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
11288                                 // We can't differentiate between "" and 0 here, so we just assume
11289                                 // empty string since it's likely to be a more common value...
11290                                 if ( val === undefined ) {
11291                                         val = "";
11292                                 }
11293                                 element.css( set[ i ], val );
11294                         }
11295                 }
11296         },
11297
11298         setMode: function( el, mode ) {
11299                 if (mode === "toggle") {
11300                         mode = el.is( ":hidden" ) ? "show" : "hide";
11301                 }
11302                 return mode;
11303         },
11304
11305         // Translates a [top,left] array into a baseline value
11306         // this should be a little more flexible in the future to handle a string & hash
11307         getBaseline: function( origin, original ) {
11308                 var y, x;
11309                 switch ( origin[ 0 ] ) {
11310                         case "top": y = 0; break;
11311                         case "middle": y = 0.5; break;
11312                         case "bottom": y = 1; break;
11313                         default: y = origin[ 0 ] / original.height;
11314                 }
11315                 switch ( origin[ 1 ] ) {
11316                         case "left": x = 0; break;
11317                         case "center": x = 0.5; break;
11318                         case "right": x = 1; break;
11319                         default: x = origin[ 1 ] / original.width;
11320                 }
11321                 return {
11322                         x: x,
11323                         y: y
11324                 };
11325         },
11326
11327         // Wraps the element around a wrapper that copies position properties
11328         createWrapper: function( element ) {
11329
11330                 // if the element is already wrapped, return it
11331                 if ( element.parent().is( ".ui-effects-wrapper" )) {
11332                         return element.parent();
11333                 }
11334
11335                 // wrap the element
11336                 var props = {
11337                                 width: element.outerWidth(true),
11338                                 height: element.outerHeight(true),
11339                                 "float": element.css( "float" )
11340                         },
11341                         wrapper = $( "<div></div>" )
11342                                 .addClass( "ui-effects-wrapper" )
11343                                 .css({
11344                                         fontSize: "100%",
11345                                         background: "transparent",
11346                                         border: "none",
11347                                         margin: 0,
11348                                         padding: 0
11349                                 }),
11350                         // Store the size in case width/height are defined in % - Fixes #5245
11351                         size = {
11352                                 width: element.width(),
11353                                 height: element.height()
11354                         },
11355                         active = document.activeElement;
11356
11357                 // support: Firefox
11358                 // Firefox incorrectly exposes anonymous content
11359                 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
11360                 try {
11361                         active.id;
11362                 } catch ( e ) {
11363                         active = document.body;
11364                 }
11365
11366                 element.wrap( wrapper );
11367
11368                 // Fixes #7595 - Elements lose focus when wrapped.
11369                 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
11370                         $( active ).focus();
11371                 }
11372
11373                 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
11374
11375                 // transfer positioning properties to the wrapper
11376                 if ( element.css( "position" ) === "static" ) {
11377                         wrapper.css({ position: "relative" });
11378                         element.css({ position: "relative" });
11379                 } else {
11380                         $.extend( props, {
11381                                 position: element.css( "position" ),
11382                                 zIndex: element.css( "z-index" )
11383                         });
11384                         $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
11385                                 props[ pos ] = element.css( pos );
11386                                 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
11387                                         props[ pos ] = "auto";
11388                                 }
11389                         });
11390                         element.css({
11391                                 position: "relative",
11392                                 top: 0,
11393                                 left: 0,
11394                                 right: "auto",
11395                                 bottom: "auto"
11396                         });
11397                 }
11398                 element.css(size);
11399
11400                 return wrapper.css( props ).show();
11401         },
11402
11403         removeWrapper: function( element ) {
11404                 var active = document.activeElement;
11405
11406                 if ( element.parent().is( ".ui-effects-wrapper" ) ) {
11407                         element.parent().replaceWith( element );
11408
11409                         // Fixes #7595 - Elements lose focus when wrapped.
11410                         if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
11411                                 $( active ).focus();
11412                         }
11413                 }
11414
11415                 return element;
11416         },
11417
11418         setTransition: function( element, list, factor, value ) {
11419                 value = value || {};
11420                 $.each( list, function( i, x ) {
11421                         var unit = element.cssUnit( x );
11422                         if ( unit[ 0 ] > 0 ) {
11423                                 value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
11424                         }
11425                 });
11426                 return value;
11427         }
11428 });
11429
11430 // return an effect options object for the given parameters:
11431 function _normalizeArguments( effect, options, speed, callback ) {
11432
11433         // allow passing all options as the first parameter
11434         if ( $.isPlainObject( effect ) ) {
11435                 options = effect;
11436                 effect = effect.effect;
11437         }
11438
11439         // convert to an object
11440         effect = { effect: effect };
11441
11442         // catch (effect, null, ...)
11443         if ( options == null ) {
11444                 options = {};
11445         }
11446
11447         // catch (effect, callback)
11448         if ( $.isFunction( options ) ) {
11449                 callback = options;
11450                 speed = null;
11451                 options = {};
11452         }
11453
11454         // catch (effect, speed, ?)
11455         if ( typeof options === "number" || $.fx.speeds[ options ] ) {
11456                 callback = speed;
11457                 speed = options;
11458                 options = {};
11459         }
11460
11461         // catch (effect, options, callback)
11462         if ( $.isFunction( speed ) ) {
11463                 callback = speed;
11464                 speed = null;
11465         }
11466
11467         // add options to effect
11468         if ( options ) {
11469                 $.extend( effect, options );
11470         }
11471
11472         speed = speed || options.duration;
11473         effect.duration = $.fx.off ? 0 :
11474                 typeof speed === "number" ? speed :
11475                 speed in $.fx.speeds ? $.fx.speeds[ speed ] :
11476                 $.fx.speeds._default;
11477
11478         effect.complete = callback || options.complete;
11479
11480         return effect;
11481 }
11482
11483 function standardAnimationOption( option ) {
11484         // Valid standard speeds (nothing, number, named speed)
11485         if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
11486                 return true;
11487         }
11488
11489         // Invalid strings - treat as "normal" speed
11490         if ( typeof option === "string" && !$.effects.effect[ option ] ) {
11491                 return true;
11492         }
11493
11494         // Complete callback
11495         if ( $.isFunction( option ) ) {
11496                 return true;
11497         }
11498
11499         // Options hash (but not naming an effect)
11500         if ( typeof option === "object" && !option.effect ) {
11501                 return true;
11502         }
11503
11504         // Didn't match any standard API
11505         return false;
11506 }
11507
11508 $.fn.extend({
11509         effect: function( /* effect, options, speed, callback */ ) {
11510                 var args = _normalizeArguments.apply( this, arguments ),
11511                         mode = args.mode,
11512                         queue = args.queue,
11513                         effectMethod = $.effects.effect[ args.effect ];
11514
11515                 if ( $.fx.off || !effectMethod ) {
11516                         // delegate to the original method (e.g., .show()) if possible
11517                         if ( mode ) {
11518                                 return this[ mode ]( args.duration, args.complete );
11519                         } else {
11520                                 return this.each( function() {
11521                                         if ( args.complete ) {
11522                                                 args.complete.call( this );
11523                                         }
11524                                 });
11525                         }
11526                 }
11527
11528                 function run( next ) {
11529                         var elem = $( this ),
11530                                 complete = args.complete,
11531                                 mode = args.mode;
11532
11533                         function done() {
11534                                 if ( $.isFunction( complete ) ) {
11535                                         complete.call( elem[0] );
11536                                 }
11537                                 if ( $.isFunction( next ) ) {
11538                                         next();
11539                                 }
11540                         }
11541
11542                         // If the element already has the correct final state, delegate to
11543                         // the core methods so the internal tracking of "olddisplay" works.
11544                         if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
11545                                 elem[ mode ]();
11546                                 done();
11547                         } else {
11548                                 effectMethod.call( elem[0], args, done );
11549                         }
11550                 }
11551
11552                 return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
11553         },
11554
11555         show: (function( orig ) {
11556                 return function( option ) {
11557                         if ( standardAnimationOption( option ) ) {
11558                                 return orig.apply( this, arguments );
11559                         } else {
11560                                 var args = _normalizeArguments.apply( this, arguments );
11561                                 args.mode = "show";
11562                                 return this.effect.call( this, args );
11563                         }
11564                 };
11565         })( $.fn.show ),
11566
11567         hide: (function( orig ) {
11568                 return function( option ) {
11569                         if ( standardAnimationOption( option ) ) {
11570                                 return orig.apply( this, arguments );
11571                         } else {
11572                                 var args = _normalizeArguments.apply( this, arguments );
11573                                 args.mode = "hide";
11574                                 return this.effect.call( this, args );
11575                         }
11576                 };
11577         })( $.fn.hide ),
11578
11579         toggle: (function( orig ) {
11580                 return function( option ) {
11581                         if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
11582                                 return orig.apply( this, arguments );
11583                         } else {
11584                                 var args = _normalizeArguments.apply( this, arguments );
11585                                 args.mode = "toggle";
11586                                 return this.effect.call( this, args );
11587                         }
11588                 };
11589         })( $.fn.toggle ),
11590
11591         // helper functions
11592         cssUnit: function(key) {
11593                 var style = this.css( key ),
11594                         val = [];
11595
11596                 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
11597                         if ( style.indexOf( unit ) > 0 ) {
11598                                 val = [ parseFloat( style ), unit ];
11599                         }
11600                 });
11601                 return val;
11602         }
11603 });
11604
11605 })();
11606
11607 /******************************************************************************/
11608 /*********************************** EASING ***********************************/
11609 /******************************************************************************/
11610
11611 (function() {
11612
11613 // based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
11614
11615 var baseEasings = {};
11616
11617 $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
11618         baseEasings[ name ] = function( p ) {
11619                 return Math.pow( p, i + 2 );
11620         };
11621 });
11622
11623 $.extend( baseEasings, {
11624         Sine: function( p ) {
11625                 return 1 - Math.cos( p * Math.PI / 2 );
11626         },
11627         Circ: function( p ) {
11628                 return 1 - Math.sqrt( 1 - p * p );
11629         },
11630         Elastic: function( p ) {
11631                 return p === 0 || p === 1 ? p :
11632                         -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
11633         },
11634         Back: function( p ) {
11635                 return p * p * ( 3 * p - 2 );
11636         },
11637         Bounce: function( p ) {
11638                 var pow2,
11639                         bounce = 4;
11640
11641                 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
11642                 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
11643         }
11644 });
11645
11646 $.each( baseEasings, function( name, easeIn ) {
11647         $.easing[ "easeIn" + name ] = easeIn;
11648         $.easing[ "easeOut" + name ] = function( p ) {
11649                 return 1 - easeIn( 1 - p );
11650         };
11651         $.easing[ "easeInOut" + name ] = function( p ) {
11652                 return p < 0.5 ?
11653                         easeIn( p * 2 ) / 2 :
11654                         1 - easeIn( p * -2 + 2 ) / 2;
11655         };
11656 });
11657
11658 })();
11659
11660 var effect = $.effects;
11661
11662
11663 /*!
11664  * jQuery UI Effects Highlight 1.11.4
11665  * http://jqueryui.com
11666  *
11667  * Copyright jQuery Foundation and other contributors
11668  * Released under the MIT license.
11669  * http://jquery.org/license
11670  *
11671  * http://api.jqueryui.com/highlight-effect/
11672  */
11673
11674
11675 var effectHighlight = $.effects.effect.highlight = function( o, done ) {
11676         var elem = $( this ),
11677                 props = [ "backgroundImage", "backgroundColor", "opacity" ],
11678                 mode = $.effects.setMode( elem, o.mode || "show" ),
11679                 animation = {
11680                         backgroundColor: elem.css( "backgroundColor" )
11681                 };
11682
11683         if (mode === "hide") {
11684                 animation.opacity = 0;
11685         }
11686
11687         $.effects.save( elem, props );
11688
11689         elem
11690                 .show()
11691                 .css({
11692                         backgroundImage: "none",
11693                         backgroundColor: o.color || "#ffff99"
11694                 })
11695                 .animate( animation, {
11696                         queue: false,
11697                         duration: o.duration,
11698                         easing: o.easing,
11699                         complete: function() {
11700                                 if ( mode === "hide" ) {
11701                                         elem.hide();
11702                                 }
11703                                 $.effects.restore( elem, props );
11704                                 done();
11705                         }
11706                 });
11707 };
11708
11709
11710
11711 }));